是否可以将gluLookAt与Vertex Shader结合使用?
经过一段相当长的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的
- 数学
你可以去cider:
你可能会使用OpenGL 2,它使得事情变得更容易,并且意味着没有着色器编程,但效率更低。
-
如果您必须绘制至少1000个三角形或想要添加bumpmapping或其他特殊效果,则应该考虑着色器。 这意味着:
- 在你的Vertex Shader,你需要一个
uniform mat4 modelviewMatrix;
,它必须与您的顶点位置相乘。 http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/#the-model-matrix
- 在你的Vertex Shader,你需要一个
-
不要使用 Python的& Pyopengl,如果你的目标是在高效率(亲身经历)
- 编号建议你Java和JOGL(目前我的配置)。然后我可以为你提供我的相机课程。
我会也许还口我的相机类Python,但它取决于JOGL Matrix4类等,但很容易,如果pyopengl也提供了同样的数学辅助类(Matrix4,四元数,...)
编辑:
顶点着色器:
#version 330
uniform mat4 uniform_Transformation;
uniform mat4 uniform_Modelview;
uniform mat4 uniform_Projection;
in vec4 attribute_Position;
in vec4 texcoords;
out vec4 texcoords_pass;
void main(void)
{
texcoords_pass=texcoords;
vec4 transformedPoint=attribute_Position*uniform_Transformation;
vec4 toCamera=transformedPoint*uniform_Modelview;
gl_Position = vec4(toCamera*uniform_Projection);
}
片段着色器:
#version 330
uniform sampler2D tex;
in vec2 texcoords_pass;
out vec4 mgl_FragColor;
void main (void)
{
vec4 texture_color = texture(tex,texcoords_pass);
if (texture_color.w == 0) {
discard;
}
mgl_FragColor=vec4(texture_color.x,texture_color.y,texture_color.z,1.0f);
}
关于矩阵:
uniform_Transformation
是变换矩阵。它用于旋转,缩放,翻转,镜像和移动模型,在您的情况四边形。uniform_Modelview
是查看矩阵。它基本上是相机。它定义了相机如何旋转以及它的位置。uniform_Projection
是投影矩阵。这是关于透视投影。阅读更多关于它的地方:http://www.songho.ca/opengl/gl_projectionmatrix.html
希望它有帮助!
“OpenGL 2 ...表示无着色器”OpenGL 2.0和2.1都有着色器。 – genpfault
我必须使用此解决方案绘制大约800至1000个四边形。事实上,它是2D环境,但我必须能够移动,缩放等等。 它背后有一个更大的脚本,这部分只是图形界面部分,所以改变是痛苦的^^如果我从一开始就知道这将是C++。我想你们都知道这个改变目标的东西... 它看起来并不大有希望后,pyopengl会提供这个,但也许一些其他的lib。 现在我必须决定我将采取哪种方式。 – noscript
@genpfault是的,我知道,但对于GL 2,你有默认着色器,你不能自己做。 – user7185318
我建议使用数学库而不是试图摆弄矩阵堆栈。 [glm](https://glm.g-truc.net/0.9.8/index.html)可能是一个不错的选择,同时也提供了一个lookat功能。对于您的其余问题:这取决于您使用的是哪个版本和配置文件。 – BDL
对不起没有提及它,我使用Python工作^^ 好吧,你会去手动计算矩阵...感谢您的建议。 – noscript
还有glm的python版本。请参阅以下链接 https://github.com/mackst/glm。它不像glm那样功能齐全,但有你需要的功能。 –