一、目的

1、画一个球体;

二、程序运行结果

三、球体的生成

  1、将球体横向向切成30片, 纵向切30片,共900个点,见示意图
  2、循环生成900个点的空间坐标(x,y,z),球面上点C的坐标
  3、 x= R * cos(NumAngleHy) * cos(NumAngleZx)
  4、 y = R * sin(NumAngleHy)
  5、 z = R * cos(NumAngleHy) * sin(NumAngleZx)
  6、将900个点按顺序存入顶点缓冲区,
  7、将相邻的三个点的顺序索引值存入索引缓冲区。
  8、调用OpenGL动态管线进行渲染。

四、glPolygonMode函数

功能:用于控制多边形的显示方式
glPolygonMode是一个函数,原型是:void glPolygonMode(GLenum face,GLenum mode);

  • face这个参数确定显示模式将适用于物体的哪些部分,控制多边形的正面和背面的绘图模式:
    GL_FRONT表示显示模式将适用于物体的前向面(也就是物体能看到的面)
    GL_BACK表示显示模式将适用于物体的后向面(也就是物体上不能看到的面)
    GL_FRONT_AND_BACK表示显示模式将适用于物体的所有面
  • mode这个参数确定选中的物体的面以何种方式显示(显示模式):
    GL_POINT表示显示顶点,多边形用点显示
    GL_LINE表示显示线段,多边形用轮廓显示
    GL_FILL表示显示面,多边形采用填充形式

五、源代码

"""
程序名称:GL_DrawSphere01.py
编程: dalong10
功能: 画一个球体
参考资料:
"""
import myGL_Funcs    #Common OpenGL utilities,see myGL_Funcs.py
import sys, random, math
import OpenGL
from OpenGL.GL import *
from OpenGL.GL.shaders import *
import numpy
import numpy as np
import glfwstrVS = """
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform float a;
uniform float b;
uniform float c;
uniform float Rx;
uniform float Ry;
uniform float Rz;
uniform float theta1;void main(){mat4 rot1=mat4(vec4(1.0, 0.0,0.0,0),vec4(0.0, 1.0,0.0,0),vec4(0.0,0.0,1.0,0.0),vec4(a,b,c,1.0));mat4 rot3=mat4( vec4(cos(theta1)+Rx*Rx*(1-cos(theta1)),  Rx*Ry*(1-cos(theta1))-Rz*sin(theta1), Rx*Rz*(1-cos(theta1))+Ry*sin(theta1), 0),vec4(Rx*Ry*(1-cos(theta1))+Rz*sin(theta1),cos(theta1)+Ry*Ry*(1-cos(theta1)),Ry*Rz*(1-cos(theta1))-Rx*sin(theta1),0),vec4(Rx*Rz*(1-cos(theta1))-Ry*sin(theta1),Ry*Rz*(1-cos(theta1))+Rx*sin(theta1),cos(theta1)+Rz*Rz*(1-cos(theta1)), 0.0),vec4(0.0,         0.0,0.0, 1.0));gl_Position=uPMatrix * uMVMatrix* rot1 *rot3  *vec4(position.x, position.y, position.z, 1.0);}
"""strFS = """
#version 330 core
out vec3 color;
void main(){color = vec3(0,1,1);}
"""VIEW=np.array([-0.8, 0.8, -0.8, 0.8, 1.0, 20.0])  # 视景体的left/right/bottom/top/near/far六个面
SCALE_K=np.array([1.0, 1.0, 1.0])  # 模型缩放比例
cameraPos=np.array([0.0, 0.0, 1.2])  # 眼睛的位置(默认z轴的正方向)
cameraFront=np.array([0.0, 0.0, 0.0])  # 瞄准方向的参考点(默认在坐标原点)
cameraUp=np.array([0.0, 1.0, 0.0])  # 定义对观察者而言的上方(默认y轴的正方向)
WIN_W, WIN_H = 640, 480  # 保存窗口宽度和高度的变量class FirstSphere:def __init__(self, cube_verticeside ,indices):# load shadersself.program = myGL_Funcs.loadShaders(strVS, strFS)glUseProgram(self.program)self.vertIndex = glGetAttribLocation(self.program, b"position")cube_vertices = cube_verticeside    self.indices = indices  # set up vertex array object (VAO)self.vao = glGenVertexArrays(1)glBindVertexArray(self.vao)            # set up VBOsvertexData = numpy.array(cube_vertices, numpy.float32)self.vertexBuffer = glGenBuffers(1)glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer)glBufferData(GL_ARRAY_BUFFER, 4*len(vertexData), vertexData, GL_STATIC_DRAW)       # set up EBOsindiceData = numpy.array(indices, numpy.int32)self.eboID = glGenBuffers(1)glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,self.eboID)glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 *len(indiceData), indiceData, GL_STATIC_DRAW)              # enable arraysglEnableVertexAttribArray(self.vertIndex)# Position attributeglBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer)glVertexAttribPointer(self.vertIndex, 3, GL_FLOAT, GL_FALSE, 0,None)               # unbind VAOglBindVertexArray(0)glBindBuffer(GL_ARRAY_BUFFER, 0)    def render(self, xx, yy, zz,  Rx,Ry,Rz,r1,pMatrix,mvMatrix):       # use shaderglUseProgram(self.program)# set proj matrixglUniformMatrix4fv(glGetUniformLocation(self.program, 'uPMatrix'), 1, GL_FALSE, pMatrix)       # set modelview matrixglUniformMatrix4fv(glGetUniformLocation(self.program, 'uMVMatrix'), 1, GL_FALSE, mvMatrix)glUniform1f(glGetUniformLocation(self.program, "a"), xx)glUniform1f(glGetUniformLocation(self.program, "b"), yy)glUniform1f(glGetUniformLocation(self.program, "c"), zz) glUniform1f(glGetUniformLocation(self.program, "Rx"), Rx)glUniform1f(glGetUniformLocation(self.program, "Ry"), Ry)glUniform1f(glGetUniformLocation(self.program, "Rz"), Rz)theta1 = r1*PI/180.0glUniform1f(glGetUniformLocation(self.program, "theta1"), theta1)# bind VAOglBindVertexArray(self.vao)# drawglDrawElements(GL_TRIANGLES, self.indices.size, GL_UNSIGNED_INT, None)# unbind VAOglBindVertexArray(0)def drawglobeVBO():PI = 3.14159265358979323846264statcky = 30 # 横向向切成多少片stlicex = 30 # 纵向切多少片R = 1.0      # 半径angleHy =  (2*PI)/statcky  # 横向每份的角度        算出弧度值angleZx =  (2*PI)/stlicex; # 纵向每份的角度      算出弧度值NumAngleHy = 0.0 # 当前横向角度NumAngleZx = 0.0 # 当前纵向角度x=0.0y=0.0z=0.0c=numpy.array([], numpy.float32)for j in range(statcky):for i in range(stlicex):NumAngleHy = angleHy*i # NumAngleZx = angleZx*j #  起点都是轴指向的方向。根据右手定则决定转向,只要转向相同,那么两个就合适x = R*np.cos(NumAngleHy)*np.cos(NumAngleZx)  y = R*np.sin(NumAngleHy) z = R*np.cos(NumAngleHy)*np.sin(NumAngleZx) c=np.hstack((c,numpy.array([x,y,z], numpy.float32) ))return cdef drawglobeEBO():PI = 3.14159265358979323846264    statcky = 30 # 横向向切成多少片stlicex = 30 # 纵向切多少片vbo = drawglobeVBO()only = vbo.sizenum = (int)((only/(3*statcky))*2)ebo=numpy.array([], numpy.int)for x in range(int(stlicex/2)):  for y in range(statcky):ebo=np.hstack((ebo,numpy.array([y+x*stlicex,y+x*stlicex+1,y+x*stlicex+stlicex,y+x*stlicex+stlicex+1,y+x*stlicex+stlicex,y+x*stlicex+1]))) return ebo#Is called whenever a key is pressed/released via GLFW
def on_key(window, key, scancode, action, mods):if key == glfw.KEY_ESCAPE and action == glfw.PRESS:glfw.set_window_should_close(window,1)if __name__ == '__main__':import sysimport glfwimport OpenGL.GL as glkeys=numpy.zeros(1024)deltaTime = 0.0lastFrame = 0.0   # Time of last frame# Initialize the libraryif not glfw.init():sys.exit()# Create a windowed mode window and its OpenGL contextwindow = glfw.create_window(640, 480, "GL_DrawSphere01 ", None, None)if not window:glfw.terminate()sys.exit()# Make the window's context currentglfw.make_context_current(window)# Install a key handlerglfw.set_key_callback(window, on_key)PI = 3.14159265358979323846264# 画球面 vert = drawglobeVBO()ind  = drawglobeEBO()                  # Loop until the user closes the windowa=0          firstSphere1 = FirstSphere(vert,ind)while not glfw.window_should_close(window):currentFrame = glfw.get_time()deltaTime = currentFrame - lastFrame       lastFrame = currentFrame# Render herewidth, height = glfw.get_framebuffer_size(window)WIN_W, WIN_H =width, heightratio = width / float(height)glfw.poll_events()gl.glViewport(0, 0, width, height)gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);  #用于控制多边形的显示方式gl.glMatrixMode(gl.GL_PROJECTION)gl.glLoadIdentity()gl.glOrtho(-ratio, ratio, -1, 1, 1, -1)gl.glMatrixMode(gl.GL_MODELVIEW)gl.glLoadIdentity()gl.glClearColor(0.0,0.1,0.1,1.0)# modelview matrixmvMatrix = myGL_Funcs.lookAt(cameraPos, cameraFront, cameraUp)     # 设置视点if WIN_W > WIN_H:zLeft=VIEW[0] * WIN_W / WIN_HzRight=VIEW[1] * WIN_W / WIN_HzBottom=VIEW[2]zTop=VIEW[3]zNear=VIEW[4]zFar=VIEW[5]else:zLeft=VIEW[0] zRight=VIEW[1] zBottom=VIEW[2] * WIN_H / WIN_WzTop=VIEW[3] * WIN_H / WIN_WzNear=VIEW[4]zFar=VIEW[5]pMatrix =myGL_Funcs.perspective(zLeft,zRight,zTop,zBottom, zNear, zFar)     firstSphere1.render( 0, 0, 0, 0,  1,1, a ,pMatrix, mvMatrix) #地球# a=a+1# if a>360:# a=0         # Swap front and back buffersglfw.swap_buffers(window)       # Poll for and process eventsglfw.poll_events()glfw.terminate()

六、参考资料

1、大龙10的简书:https://www.jianshu.com/p/49dec482a291
2、xhm01291212的博客:https://blog.csdn.net/xhm01291212/article/details/79198652

Python之OpenGL笔记(25):动态管线绘制球体相关推荐

  1. OpenGL 笔记1 固定管线实例 + 双缓存测试实例

    欲以此分类来记录opengl的学习历程,此为第一篇,所以先来一个固定管线的例子,以及对双缓存的测试. 一.配置环境 写之前,先进行配置,然后再讲内容. 注:第一部分涉及的代码均忽略. [环境配置传送门 ...

  2. Python之OpenGL笔记(34):采用了顶点常量属性方法画多彩六角星

    一.目的 1.采用了顶点常量属性方法画多彩六角星: 二.程序运行结果 三.顶点常量属性    吴亚峰<OpenGL ES 3.x游戏开发>(上卷)内容    前面的很多案例中,给每一个顶点 ...

  3. Python之OpenGL笔记(26):不动点与旋转和缩放

    一.目的 1.画一组绕不动点旋转的正方体: 二.程序运行结果 三.为什么需要模型变换   OpenGL中的坐标处理过程包括模型变换.视变换.投影变换.视口变换等内容 具体过程如下图2所示:   我们在 ...

  4. Python之OpenGL笔记(38):三种光照通道的合成

    一.目的 1.实现镜面光照射下的棋盘球体: 2.环境光.散射光.镜面光三种光照通道的合成 二.程序运行结果 三.镜面光    现实世界中,当光滑表面被照射时会有方向很集中的反射光.这就是镜面光(Spe ...

  5. Python之OpenGL笔记(33):透视投影画六角星

    一.目的 1.摄像机应用,透视投影画六角星: 二.程序运行结果 三.透视投影    吴亚峰<OpenGL ES 3.x游戏开发>(上卷)内容    现实世界中人眼观察物体时会有" ...

  6. Python之OpenGL笔记(17):键盘鼠标控制摄像机移动旋转

    一.目的 1.键盘控制摄像机自由移动: 2.鼠标控制摄像机旋转: 3.鼠标滚轮放大缩小视野. 二.程序运行结果 三.自由移动 view = lookAt(cameraPos, cameraPos + ...

  7. Python之OpenGL笔记(37):散射光下的棋盘球体

    一.目的 1.实现散射光照射下的棋盘球体: 二.程序运行结果 三.散射光    上一小节中给出了仅仅使用环境光进行照射的案例,读者可能觉得效果并不好.确实如此,仅仅有环境光的场景效果是很差的,没有层次 ...

  8. Qt OpenGL(07)递归细分四面体法绘制球体

    文章目录 Qt OpenGL通过递归细分逼近球面 思路 下面就是绘制的代码: Widget.cpp 顶点着色器 片段着色器 Qt OpenGL通过递归细分逼近球面 在OpenGL中绘制球面,不是太简单 ...

  9. OpenGL学习笔记(一)绘制点线面及多面体

    OpenGL学习笔记(一)绘制点线面及多面体 绘制点线面 #include <iostream> #include <GL/GLUT.h> #define PI 3.14159 ...

  10. python如何下载安装glfw_Python之OpenGL笔记(1):窗口工具包GLFW的安装

    一.OpenGL简介 OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言.跨平台的编程接口(Application programming interface)的规 ...

最新文章

  1. html页面视频标签,html5基础标签(html5视频标签 html5新标签用法)
  2. GdiPlus[44]: IGPGraphics (三) 关于文本绘制续 - IGPStringFormat
  3. 德国小哥1人“黑掉”谷歌地图:99部手机就能造成交通拥堵
  4. 初级ABAPer考题
  5. [转]最流行的android组件大全
  6. 程序员必收藏的五个网站
  7. python面向对象初识
  8. 使用Apache CXF进行Web服务学习
  9. RTX5 | 消息队列04 - (实战技巧)串口中断回调函数ISR同步线程
  10. 人工智能TensorFlow工作笔记007---认识张量
  11. matplotlib柱状图上方显示数据_使用 matplotlib 的两种姿势
  12. 华为顶尖应届生最高年薪超 200 万;抖音服务器宕机;GitLab 12.1 发布 | 极客头条...
  13. NAACL2021 | 苏大阿里提出:一种统一的基于跨度的意见挖掘方法
  14. crontab使用环境变量
  15. linux常用命令行编辑快捷键
  16. 手机mstsc远程工具_手机远程连接服务器工具:RD client远程桌面使用教程
  17. EasyAR4.0简单使用说明
  18. Flash入门:动画制作基础知识
  19. 如何让那些模糊的照片变得高清?不会PS也能解决
  20. android电视安装app

热门文章

  1. 速达软件登录远程客户端总提示检查卡号密码
  2. Windows 安装 labelimg 图片标注工具
  3. IT,大一,这里我有点建议
  4. 国军标GJB 151B-2013军用设备和分系统电磁发射和敏感度要求与测量(海军10项)
  5. MYSQL 开窗函数
  6. 数据库的内连接和外连接的区别
  7. SERC2013 J You Win!
  8. 开源的项目管理软件——OpenProj
  9. python实现动态壁纸_如何实现一个 windows 桌面动态壁纸
  10. [一定要看完]住在隔壁的刚毕业的大学生小夫妻