欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python 3学习笔记(13):PyOpenGL之正交投影

程序员文章站 2022-03-25 17:28:01
...
  • 目的

1、建立金属螺钉的模型(三个组成:螺帽、螺杆、螺纹)

2、创建一个正交投影立方体框架,可用箭头键切换视角。

3、掌握OpenGL的顶点数组功能。

4、掌握OpenGL绘制图元函数。

5、 了解OpengGL键盘控制及回调函数glutSpecialFunc

Python 3学习笔记(13):PyOpenGL之正交投影

  • 内容 

1、用较小、较简单的图形生成一个较复杂的图形。如建立一个建立金属螺钉的模型(三个组成:螺帽、螺杆、螺纹)

2、开始构造之前,需要一个投影,一个用于放置对象的参考框架。对螺钉模型来说,最后的选择是正交投影(CAD类)。

3、程序将创建一个正交投影,并给出一个沿x轴和y轴有100单元的坐标系。z轴上还有另外100个单元,观察者就位于此处。

  • 函数  

1、Void glVertexPointer(int size,int type,int stride,void *pointer)

函数glVertexPointer的作用是把一数组与图形的顶点关联在一起。

size 指绑定数组后,每个图形的顶点会用到数组中多少个数据做为顶点的数据
           type 规定调用数组的数据时应该用什么类型。一般与定义的数组的类型是一至的。
          stride 规定每个顶点应该从数组中移动的字节。一般情况下写0系统会自动识别。识别方式为size*sizeof(数组定义时报类型)
           pointer 要绑定数组的地址。

2Void glDrawElements(int mode,int count,int type,void *indices)

从数组数据绘制图元。可以事先指定几组顶点数组、法向量数组和颜色数组,调用一次绘制。

第一个参数是点的类型,

第二个参数是点的个数,

第三个是第四个参数的类型,

第四个参数是点的存储绘制顺序。

如正方形:存储的点顺序是0123   绘图的时候是每三个点就会绘制一个三角形,因此012 可以为三角形,123则与前面的三角形重复切不会覆盖整个矩形,因此就需要我们认为的设定绘图点的顺序,第四个参数的作用就是如此,我们把点的顺序设置为0132 这样013132 2个三角形且刚好形成矩阵。

因此,在利用glDrawElements时候只需记住所有定点,在第四个参数中来描述所需面的顶点顺序即可,且每取三个点绘图一个三角形。

下面的demo只记住了立方体的8个点,利用18个点的顺序就可以绘图成一个立方体,而不是4*6个点。第一个三角形是逆时针第二个是顺时针,依次循环否则不对应的就不会绘出。

  •  代码 

#coding:utf-8

import sys
from math import pi as PI
from math import sin, cos

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

def RenderScene():
	global xRot,yRot
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)	
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)					

	# Save the matrix state
	glMatrixMode(GL_MODELVIEW) 
	glPushMatrix() 
    # 绕X轴和Y轴旋转(角度,x,y,z)
	glRotatef(xRot, 1.0, 0.0, 0.0)
	glRotatef(yRot, 0.0, 0.0, 1.0)
    # 启用并指定顶点数组 Enable and specify the vertex array
	glEnableClientState(GL_VERTEX_ARRAY)
	glVertexPointer(3, GL_FLOAT, 0, corners)
   
    # Using Drawarrays
	glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, indexes)
	glPopMatrix()
    #双缓冲的刷新模式; Swap buffers
	glutSwapBuffers()					

#设置渲染状态
def SetupRC():
	glClearColor(0.0, 0.0, 0.0, 1.0)  #背景黑色
	glColor3ub(0,0,255);

#改变窗口大小时调用
def ChangeSize(w,h):
	nRange = 100.0
	if(h == 0):     #防止除数为0
		h = 1
	glViewport(0, 0, w, h)						#设置视区大小
	glMatrixMode(GL_PROJECTION)					#投影矩阵模式
	glLoadIdentity()							#矩阵堆栈清空
	#设置裁剪窗口大小
	if (w <= h): 
		glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange*2.0, nRange*2.0)	
	else: 
		glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange*2.0, nRange*2.0)	
						
	glMatrixMode(GL_MODELVIEW)					#模型矩阵模式
	glLoadIdentity()

def SpecialKeys(key,x,y):
	global xRot,yRot
	if(key == GLUT_KEY_UP):
		xRot-= 5.0
	if(key == GLUT_KEY_DOWN):
		xRot += 5.0
	if(key == GLUT_KEY_LEFT):
		yRot -= 5.0
	if(key == GLUT_KEY_RIGHT):
		yRot += 5.0
	if(key > 356.0):
		xRot = 0.0
	if(key < -1.0):
		xRot = 355.0
	if(key > 356.0):
		yRot = 0.0
	if(key < -1.0):
		yRot = 355.0
	glutPostRedisplay()

#  顶点Front of cube #0 1# 2 # 3 Back of cube # 4# 5# 6# 7
corners= [-25.0, 25.0, 25.0,\
			25.0, 25.0, 25.0,\
			25.0, -25.0, 25.0,\
			-25.0, -25.0, 25.0,\
			-25.0, 25.0, -25.0,\
			25.0, 25.0, -25.0,\
			25.0, -25.0, -25.0,\
			-25.0, -25.0, -25.0 ]  
#  面Front Face#  Top Face# Bottom Face# Back Face# Right Face# Left Face
indexes = [ 0, 1, 2, 3,	\
			4, 5, 1, 0,	\
			3, 2, 6, 7,	\
			5, 4, 7, 6,	\
			1, 5, 6, 2,	\
			4, 0, 3, 7 ]	
xRot=0.0
yRot=0.0
print("三维立方体,按箭头键改变视角!")
#使用glut初始化OpenGL
glutInit()
glutInitWindowSize(700,700)
#设置显示模式;(注意双缓冲)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB| GLUT_DEPTH)
glutCreateWindow("Cube DX")

glutReshapeFunc(ChangeSize)
glutSpecialFunc(SpecialKeys)     #注册键盘回调函数
#调用函数绘制图像
glutDisplayFunc(RenderScene)
SetupRC()
#主循环
glutMainLoop()

 

相关标签: OpenGL