經過一段相當長的Google Session後,我有足夠的空間!是否可以將gluLookAt與Vertex Shader結合使用?
我有一個python/opengl應用程序,用一些簡單的Quad,我用gluLookAt在場景中移動。然後我只需要一個Quad的紋理,所以我現在明顯使用這個Quad的着色器程序。
現在,當我使用gluLookAt時,帶有紋理的Quad不會移動,我也能理解。
現在有什麼辦法可以讓gluLookAt函數與着色器程序一起工作,獲得當前矩陣堆棧,以便我可以爲它提供着色器程序,或者必須重寫孔應用程序並重新創建glulookup函數like he did(在着色器中還是在CPU上)?
EDIT1: 我使用:
蟒3.5
PyOpenGL 3.1.0
GLSL 1.4(According to this list)
EDIT2(我的解決方案):
自從我開了這個線程,一些事情發生了變化,但與你的guideance我得到了一個現代&穩定的解決方案。
有3個主要部件,我必須畫。一個靜態字段,一些行(爲了更好的可視化)和一些可移動的四邊形。
該字段現在被寫入一個數組中的VBO。 (與單個繪圖命令相比有重大改進)
可移動的正方形和線條以相同的原理工作,但是它們是動態的並且必須隨每個框架重新上傳。
Foreach類型的對象我有一個頂點+片段着色器程序。我知道我可以使用一個大的,但這不是它應該的。
將每個矩陣(模型,視圖,投影)分配給一個統一體,然後與頂點着色器中的VBO的頂點相乘。
場的Vertex Shader(例):
#version 330
uniform mat4 uniform_Model;
uniform mat4 uniform_View;
uniform mat4 uniform_Projection;
in vec3 Quad_Color_Attrib;
in vec3 Quad_Size_Attrib;
out vec3 frag_ColorId;
void main()
{
// Pass the tex coord straight through to the fragment shader
frag_ColorId = Quad_Color_Attrib;
// Remember : inverted !
gl_Position = uniform_Projection * uniform_View * uniform_Model * vec4(Quad_Size_Attrib,1);
}
我問什麼是不該做的正確方法。(新老結合的OpenGL) 不幸的是我不能共享孔代碼,因爲它是,但我在這裏,你可以找到所有的OpenGL鍵碼:
頂點/片斷着色器程序裝載機:
初始化頂點/片段着色器(在這種情況下爲場)
def init_field(self, p_VertexShaderPath, p_FragmentShaderPath, p_FieldList, p_FieldCount):
# ############### Field Shader ###############
# Shader Program
self.m_FieldShader = LoadShaders(p_VertexShaderPath, p_FragmentShaderPath)
glUseProgram(self.m_FieldShader)
# VAO
self.m_FieldVAO = glGenVertexArrays(1)
glBindVertexArray(self.m_FieldVAO)
# Field Definition
self.m_FieldCount = p_FieldCount
t_Vertices = []
for t_FieldNr in p_FieldList:
x = p_FieldList[t_FieldNr].m_XPos
y = p_FieldList[t_FieldNr].m_YPos
cr = p_FieldList[t_FieldNr].m_Color[0]/255
cg = p_FieldList[t_FieldNr].m_Color[1]/255
cb = p_FieldList[t_FieldNr].m_Color[2]/255
t_Vertices.extend([
x - 0.5, y + 0.5, 0.0, cr, cg, cb, # 0----1
x + 0.5, y + 0.5, 0.0, cr, cg, cb, # | |
x + 0.5, y - 0.5, 0.0, cr, cg, cb, # | |
x - 0.5, y - 0.5, 0.0, 0, 0, 0 # 3----2
])
t_FieldVerticesBuffer = numpy.array(t_Vertices, dtype = numpy.float32)
# VBO
self.m_FieldVBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.m_FieldVBO)
glBufferData(GL_ARRAY_BUFFER, t_FieldVerticesBuffer.nbytes, t_FieldVerticesBuffer, GL_STATIC_DRAW)
# VBO Size Attrib
self.m_FieldVerticesAttrib = glGetAttribLocation(self.m_FieldShader, "Quad_Size_Attrib")
glEnableVertexAttribArray(self.m_FieldVerticesAttrib)
glVertexAttribPointer(self.m_FieldVerticesAttrib,
3,
GL_FLOAT,
GL_FALSE,
ctypes.sizeof(6*GLfloat),
ctypes.c_void_p(0))
# VBO Color Attrib
self.m_FieldColorAttrib = glGetAttribLocation(self.m_FieldShader, "Quad_Color_Attrib")
glEnableVertexAttribArray(self.m_FieldColorAttrib)
glVertexAttribPointer(self.m_FieldColorAttrib,
3,
GL_FLOAT,
GL_FALSE,
ctypes.sizeof(6*GLfloat),
ctypes.c_void_p(12))
# Uniform Locations
self.m_Field_ModelMat_Uniform = glGetUniformLocation(self.m_FieldShader, 'uniform_Model')
self.m_Field_ViewMat_Uniform = glGetUniformLocation(self.m_FieldShader, 'uniform_View')
self.m_Field_ProjectionMat_Uniform = glGetUniformLocation(self.m_FieldShader, 'uniform_Projection')
# Detach Shader & VAO
glBindVertexArray(0) # unbind the VAO
glUseProgram(0) # Disable shader
屏幕上繪製週期
這是現在只是psydo代碼:
OpenGLEnv.Clear()
OpenGLEnv.SetCamera()
OpenGLEnv.DrawField()
OpenGLEnv.FlipBuffer()
所以SetCamera設置是在ViewMat和ProjectionMat。
def SetCamera(self, camera, zoom_distance):
self.m_ViewMat = lookAt(glm.vec3(-camera[0], -camera[1], zoom_distance), # Camera is at (x,x,x), in World Space
glm.vec3(-camera[0], -camera[1], -100), # and looks at the origin
glm.vec3(0, 1, 0)) # Head is up (set to 0,-1,0 to look upside-down)
self.m_ProjectionMat = perspective(45, self.m_AspectRatio, 1, 1000.0)
抽獎現場例行
有了這個功能,我將吸取的VBO頂點。
def DrawField(self):
glUseProgram(self.m_FieldShader) # Use shader
self.m_ModelMat = glm.mat4(1) # Reset ModelMat
# ############################
# 1. Scale self.ModelMat = scale(self.ModelMat,glm.vec3(10,10,10))
# 2. Rotation self.ModelMat = rotate(self.ModelMat, self.test, glm.vec3(0,1,0))
# 3. Translate self.ModelMat = translate(self.ModelMat,glm.vec3(0,0,0))
####################################
glUniformMatrix4fv(self.m_Field_ModelMat_Uniform, 1, GL_FALSE, numpy.squeeze(numpy.asarray(self.m_ModelMat.value)))
glUniformMatrix4fv(self.m_Field_ViewMat_Uniform, 1, GL_FALSE, numpy.squeeze(numpy.asarray(self.m_ViewMat.value)))
glUniformMatrix4fv(self.m_Field_ProjectionMat_Uniform, 1, GL_FALSE, numpy.squeeze(numpy.asarray(self.m_ProjectionMat.value)))
glBindVertexArray(self.m_FieldVAO)
glBindBuffer(GL_ARRAY_BUFFER, self.m_FieldVBO)
# Draw Field
glDrawArrays(GL_QUADS, 0, 4*self.m_FieldCount)
# Disable shader and unbind VAO
glBindVertexArray(0)
glUseProgram(0)
使用圖書館的:
- GLM(我認爲這是這一個https://github.com/Zuzu-Typ/PyGLM)
- 的OpenGL(PyOpenGL 3.1.0)
- numpy的
- 數學
我建議使用數學庫而不是試圖擺弄矩陣堆棧。 [glm](https://glm.g-truc.net/0.9.8/index.html)可能是一個不錯的選擇,同時也提供了一個lookat功能。對於您的其餘問題:這取決於您使用的是哪個版本和配置文件。 – BDL
對不起沒有提及它,我使用Python工作^^ 好吧,你會去手動計算矩陣...感謝您的建議。 – noscript
還有glm的python版本。請參閱以下鏈接 https://github.com/mackst/glm。它不像glm那樣功能齊全,但有你需要的功能。 –