问题描述
我正在尝试像在任何3d编辑器中一样实现3d相机。我已经绕一个点旋转并沿Z轴缩放。实施平移将是很棒的,但是我遇到了缺乏数学知识的问题。似乎可以更改四元数轴,但最终只有抖动和怪异的旋转。那么如何平移呢?
下面是仅旋转/缩放的示例代码:
//fragment
#version 420 core
out vec4 fragColor;
sample smooth in vec2 f_TexCoord;
in vec3 f_vertexPos;
vec4 gridColor;
void main()
{
//Main grid pattern
if(fract(f_TexCoord.x / 0.0005f) < 0.025f || fract(f_TexCoord.y / 0.0005f) < 0.025f)
gridColor = vec4(0.75,0.75,1.0);
else
gridColor = vec4(0);
// Check for alpha transparency
if(gridColor.a != 1)
discard;
vec2 point_center = vec2(0.5,0.5);
float distance = length(f_TexCoord.xy - vec2(0.5,0.5));
gridColor *= mix(vec4(0.75,1.0),vec4(0.25,0.25,1.),distance);
fragColor = gridColor;
}
//vertex
#version 420 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
sample smooth out vec2 f_TexCoord;
out vec3 f_vertexPos;
uniform mat4 u_modelMatrix;
uniform mat4 u_viewMatrix;
uniform mat4 u_projectionMatrix;
void main()
{
mat4 mv_matrix = u_viewMatrix * u_modelMatrix;
gl_Position = u_projectionMatrix * mv_matrix * vec4(aPos,1.0);
f_TexCoord = aTexCoord;
f_vertexPos = aPos;
}
from OpenGL import GL as gl
from OpenGL.GL.shaders import compileShader,compileProgram
from pyside2 import QtWidgets,QtCore,QtGui
import sys
import ctypes
import numpy as np
class GLSurfaceFormat(QtGui.QSurfaceFormat):
"""Setup OpenGL preferences."""
def __init__(self):
super(GLSurfaceFormat,self).__init__()
self.setRenderableType(QtGui.QSurfaceFormat.OpenGL)
self.setMinorVersion(4)
self.setProfile(QtGui.QSurfaceFormat.CoreProfile)
self.setoption(QtGui.QSurfaceFormat.DebugContext)
self.setColorSpace(QtGui.QSurfaceFormat.sRGBColorSpace)
self.setSwapBehavior(QtGui.QSurfaceFormat.DoubleBuffer)
self.setSamples(4)
class PlyViewportWidget(QtWidgets.qopenglwidget):
"""Main 3D scene viewer."""
def __init__(self):
super(PlyViewportWidget,self).__init__(parent=None)
self.setAttribute(QtCore.Qt.WA_Hover)
self.installEventFilter(self)
self.m_projectionMatrix = QtGui.QMatrix4x4()
self.m_viewMatrix = QtGui.QMatrix4x4()
self.m_mousePos = QtGui.QVector2D()
self.m_viewRotation = QtGui.QQuaternion()
self.m_zoom = -10.0
self.vao = None
self.vbo = None
self.ebo = None
self.shaderProg = None
def initializeGL(self):
gl.glEnable(gl.GL_DEPTH_TEST)
gl.glClearColor(0.4,0.4,1)
gl.glClear(gl.GL_COLOR_BUFFER_BIT,gl.GL_DEPTH_BUFFER_BIT)
with open("frag.glsl",'r') as f:
fragment = compileShader(f.read(),gl.GL_FRAGMENT_SHADER)
with open("vert.glsl","r") as f:
vertex = compileShader(f.read(),gl.GL_VERTEX_SHADER)
self.shaderProg = compileProgram(vertex,fragment)
vertices = np.array(
[
# Vertex positions # UVs
0.5,0.5,0.0,1.0,-0.5,1.0
],dtype=ctypes.c_float
)
indices = np.array(
[
0,1,3,2,3
],dtype=ctypes.c_uint
)
self.vao = gl.glGenVertexArrays(1)
self.vbo = gl.glGenBuffers(1)
self.ebo = gl.glGenBuffers(1)
gl.glBindVertexArray(self.vao)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER,self.vbo)
gl.glBufferData(gl.GL_ARRAY_BUFFER,vertices.nbytes,vertices,gl.GL_STATIC_DRAW)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER,self.ebo)
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER,indices.nbytes,indices,gl.GL_STATIC_DRAW)
# Position attribute
gl.glEnabLevertexAttribArray(0)
gl.glVertexAttribPointer(0,gl.GL_FLOAT,gl.GL_FALSE,5 * ctypes.sizeof(ctypes.c_float),ctypes.c_void_p(0))
# Texture coordinates attribute
gl.glEnabLevertexAttribArray(1)
gl.glVertexAttribPointer(1,ctypes.c_void_p(3 * ctypes.sizeof(ctypes.c_float)))
def paintGL(self):
gl.glClearColor(0.4,1.0)
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
# This is a *grid* model matrix
modelMatrix = QtGui.QMatrix4x4()
modelMatrix.setToIdentity()
modelMatrix.rotate(90,QtGui.QVector3D(1.0,0.0))
modelMatrix.scale(1000)
self.m_viewMatrix.setToIdentity()
self.m_viewMatrix.translate(0.0,self.m_zoom)
self.m_viewMatrix.rotate(15,0.0))
self.m_viewMatrix.rotate(self.m_viewRotation)
gl.gluseProgram(self.shaderProg)
u_projection_loc = gl.glGetUniformlocation(self.shaderProg,"u_projectionMatrix")
gl.gluniformMatrix4fv(u_projection_loc,self.m_projectionMatrix.data())
u_view_loc = gl.glGetUniformlocation(self.shaderProg,"u_viewMatrix")
gl.gluniformMatrix4fv(u_view_loc,self.m_viewMatrix.data())
u_model_loc = gl.glGetUniformlocation(self.shaderProg,"u_modelMatrix")
gl.gluniformMatrix4fv(u_model_loc,modelMatrix.data())
gl.glBindVertexArray(self.vao)
gl.glDrawElements(gl.GL_TRIANGLES,6,gl.GL_UNSIGNED_INT,ctypes.c_void_p(0))
def resizeGL(self,w: int,h: int):
aspect = w / h
self.m_projectionMatrix.setToIdentity()
self.m_projectionMatrix.perspective(45,aspect,0.1,1000.0)
def mousepressEvent(self,event: QtGui.QMouseEvent):
if event.buttons() == QtCore.Qt.LeftButton:
self.m_mousePos = QtGui.QVector2D(event.localPos())
def mouseMoveEvent(self,event: QtGui.QMouseEvent):
if event.buttons() == QtCore.Qt.LeftButton:
diff = QtGui.QVector2D(event.localPos()) - self.m_mousePos
self.m_mousePos = QtGui.QVector2D(event.localPos())
angle = diff.length() / 2.0
axis = QtGui.QVector3D(diff.y(),diff.x(),0.0)
self.m_viewRotation = QtGui.QQuaternion.fromAxisAndAngle(axis,angle) * self.m_viewRotation
self.update()
event.accept()
def wheelEvent(self,event:QtGui.QWheelEvent):
if event.delta() > 0:
self.m_zoom += 0.5
elif event.delta() < 0:
self.m_zoom -= 0.5
self.update()
if __name__ == '__main__':
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseDesktopOpenGL)
QtGui.QSurfaceFormat.setDefaultFormat(GLSurfaceFormat())
app = QtWidgets.QApplication()
window = PlyViewportWidget()
window.show()
sys.exit(app.exec_())
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)