难点如下:
坐标轴绘制
选定一个原点,将坐标轴正方向和反方向的俩个点进行连线,代码及效果如上图所示(本次程序中由于渲染原因,坐标轴颜色统一为棕色)
如何实现鼠标响应
OPENGL中封存有对鼠标进行相应的函数,但使用起来无法实现效果,于是我们需要进行一些偏移量计算以完成角度的拖拽,这在一定程度上给参考了solidworks中3D物品旋转的方式。
1.计算鼠标距上一帧的偏移量。
2.把偏移量添加到摄像机的俯仰角和偏航角中。
3.对偏航角和俯仰角进行最大和最小值的限制。
4.计算方向向量。
5.将其封装到函数中
关键代码如上图所示文章来源:https://www.toymoban.com/news/detail-796862.html
完整代码如下:文章来源地址https://www.toymoban.com/news/detail-796862.html
import numpy as np
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
IS_PERSPECTIVE = True # 透视投影
VIEW = np.array([-0.8, 0.8, -0.8, 0.8, 0.5, 20.0]) # 视景体的left/right/bottom/top/near/far六个面
LEFT_IS_DOWNED = False
CameraPos = np.array([0.0, 0.0, 2])
CameraFront = np.array([0, 0, 0])
CameraUp = np.array([0, 1, 0])
SCALE_K = np.array([1, 1, 1])
yaw = 0
pitch = 0
MOUSE_X, MOUSE_Y = 0, 0
WIN_W = 640
WIN_H = 480
class MyPyOpenGLTest:
def Mouse_click(self,button, state, x, y):
global LEFT_IS_DOWNED
global MOUSE_X, MOUSE_Y
global SCALE_K
MOUSE_X = x
MOUSE_Y = y
if button == GLUT_LEFT_BUTTON:
LEFT_IS_DOWNED = state == GLUT_DOWN
def Mouse_motion(self,x, y):
global LEFT_IS_DOWNED
global MOUSE_X, MOUSE_Y
global yaw, pitch
global CameraPos
if LEFT_IS_DOWNED:
dx = x - MOUSE_X
dy = MOUSE_Y - y
MOUSE_X = x
MOUSE_Y = y
sensitivity = 0.2
dx = dx * sensitivity
dy = dy * sensitivity
yaw = yaw + dx
pitch = pitch + dy
if pitch > 89:
pitch = 89
if pitch < -89:
pitch = -89
CameraPos[0] = np.cos(np.radians(yaw)) * np.cos(np.radians(pitch))
CameraPos[1] = np.sin(np.radians(pitch))
CameraPos[2] = np.sin(np.radians(yaw)) * np.cos(np.radians(pitch))
glutPostRedisplay()
def __init__(self,width=640,height=480,title=b'SolidTeapot'):
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH)
glutInitWindowSize(width,height)
self.window=glutCreateWindow(title)
glutDisplayFunc(self.Draw)
glutKeyboardFunc(self.BarPress)
glutIdleFunc(self.Draw)
self.InitGL(width,height)
glutMouseFunc(self.Mouse_click)
glutMotionFunc(self.Mouse_motion)
self.x=0.0
self.y=0.0
self.z=0.0
self.s=0.2
def BarPress(self, key, x, y):
if key==b'a':
self.x+=1
elif key ==b'd':
self.x-=1
elif key ==b'w':
self.y+=1
elif key ==b's':
self.y-=1
elif key ==b'q':
self.z-=1
elif key ==b'e':
self.z+=1
elif key ==b'x':
self.s-=0.1
elif key ==b'z':
self.s+=0.1
def Draw(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslate(0.0,0.0,-8.0)
global IS_PERSPECTIVE, VIEW
global CameraPos, CameraFront, CameraUp
global SCALE_K
global WIN_W, WIN_H
global vertices2
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# 设置投影(透视投影)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
if IS_PERSPECTIVE:
glFrustum(VIEW[0], VIEW[1], VIEW[2], VIEW[3], VIEW[4], VIEW[5])
# 设置模型视图
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
# 几何变换
glScale(SCALE_K[0], SCALE_K[1], SCALE_K[2])
# 视点
gluLookAt(
CameraPos[0], CameraPos[1], CameraPos[2],
CameraFront[0], CameraFront[1], CameraFront[2],
CameraUp[0], CameraUp[1], CameraUp[2]
)
glViewport(0, 0, WIN_W, WIN_H)
glBegin(GL_LINES)
# 以红色绘制x轴
glColor3f(1.0, 0.0, 0.0) # 设置当前颜色为红色不透明
glVertex3f(-0.5, 0.0, 0.0) # 设置x轴顶点(x轴负方向)
glVertex3f(0.5, 0.0, 0.0) # 设置x轴顶点(x轴正方向)
# 以绿色绘制y轴
glColor3f(0.0, 1.0, 0.0) # 设置当前颜色为绿色不透明
glVertex3f(0.0, -0.5, 0.0) # 设置y轴顶点(y轴负方向)
glVertex3f(0.0, 0.5, 0.0) # 设置y轴顶点(y轴正方向)
# 以蓝色绘制z轴
glColor3f(0.0, 0.0, 1.0) # 设置当前颜色为蓝色不透明
glVertex3f(0.0, 0.0, -0.5) # 设置z轴顶点(z轴负方向)
glVertex3f(0.0, 0.0, 0.5) # 设置z轴顶点(z轴正方向)
glEnd()
glRotate(self.x,1.0,0.0,0.0)
glRotate(self.y, 0.0, 1.0, 0.0)
glRotate(self.z, 0.0, 0.0, 1.0)
glScalef(self.s,self.s,self.s)
glColor3f(0.0,0.0,1.0)
glutSolidTeapot(1.0)
glutSwapBuffers()
def InitGL(self,width,height):
glClearColor(1.0,1.0,1.0,0.0)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
mat_SP=(1.0,1.0,1.0,1.0)
mat_sh=[50.0]
light_position=(-0.5,1.5,1,0)
yellow_l=(1.0,0.1,0,1)
ambient=(0.1,0.8,0.2,1.0)
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_SP)
glMaterialfv(GL_FRONT,GL_SHININESS,mat_sh)
glLightfv(GL_LIGHT0,GL_POSITION,light_position)
glLightfv(GL_LIGHT0,GL_DIFFUSE ,yellow_l )
glLightfv(GL_LIGHT0,GL_SPECULAR ,yellow_l )
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glShadeModel(GL_SMOOTH)
glEnable(GL_POINT_SMOOTH)
glEnable(GL_LINE_SMOOTH)
glEnable(GL_POLYGON_SMOOTH)
glMatrixMode(GL_PROJECTION)
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST)
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST)
glLoadIdentity()
gluPerspective(45.0,float(width)/float(height),0.1,100.0)
glMatrixMode(GL_MODELVIEW)
def MainLoop(self):
glutMainLoop()
if __name__=='__main__':
w=MyPyOpenGLTest()
w.MainLoop()
到了这里,关于使用opengl绘制茶壶并实现鼠标拖动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!