我正在使用PyOpenGL开发2D游戏引擎。
为了与使用SDL的我的引擎的先前版本保持一致,图形元素首先存储在VBO中,其中2D坐标系(其中(0,0)在左上方,而(640,448)在底部 - 对(因此y轴反转)。我们称之为SDL坐标。
由于我的图形使用了调色板效果,因此我使用着色器渲染它们。我的顶点着色器只是将我的2D坐标系转换为[-1; 1]立方体。
现在,我需要剪辑显示。我的第一个想法是通过像素着色器,通过将剪切区域外的所有顶点发送到[-1; 1]立方体(我拍摄(2.0,0.0,0.0,1.0))但它出错了:它变形了方形瓷砖,它们的一些边缘在裁剪区域外但不是全部。
所以我考虑使用glFrustum,但我不明白我必须在哪个坐标系中指定params。
事实上,在尝试运行代码时,我试图将或多或少的任何内容作为参数而不会注意到任何事情。我做错了什么?
目前,我的绘图程序如下:
def draw(self):
glClearColor(1.0, 1.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
glEnable( GL_TEXTURE_2D )
glActiveTexture( GL_TEXTURE0 )
glBindTexture( GL_TEXTURE_2D, self.v_texture)
glEnable( GL_TEXTURE_1D )
glActiveTexture( GL_TEXTURE1 )
shaders.glUseProgram(self.shaders_program)
shaders.glUniform1i(self.texture_uniform_loc, 0)
shaders.glUniform1i(self.palette_uniform_loc, 1)
shaders.glUniform2f(self.offset_uniform_loc, 0, 0)
shaders.glUniform4f(self.color_uniform_loc, 1, 1, 1, 1)
# Draw layers
for layer in self.layers: #[0:1]:
layer.draw()
shaders.glUseProgram( 0 )
pygame.display.flip()
在课程图层中:
def draw(self):
glFrustum(0.0, 0.5, 0.0, 0.5, 0.1, 1.0) # I tried anything here...
# offset is an offset to add to coordinates (in SDL_coordinates)
shaders.glUniform2f(self.vdp.offset_uniform_loc, self.x, self.y)
# color is likely irrelevant here
shaders.glUniform4f(self.vdp.color_uniform_loc, *self.color_modifier)
glBindTexture( GL_TEXTURE_1D, self.palette.get_id())
self.vbo.bind()
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glVertexPointer(3, GL_FLOAT, 20, self.vbo)
glTexCoordPointer(2, GL_FLOAT, 20, self.vbo + 12)
glDrawArrays(GL_QUADS, 0, len(self.vbo))
self.vbo.unbind()
glDisableClientState(GL_TEXTURE_COORD_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY)
注意:我必须说我是OpenGL的新手。我通过阅读教程来学习,并且对“旧”和“新”OpenGL非常困惑。
我觉得视锥体更像'旧'OpenGL,就像许多转换矩阵操作一样(大部分都可以通过顶点着色器处理)。我可能完全错了,glFrustum(或其他东西)在我的情况下可能是不可避免的。我想读一篇关于“旧的”OpenGL中可以完全忘记什么的文章。
答案 0 :(得分:1)
除非您在着色器中使用内置矩阵(gl_ModelViewProjectionMatrix
等),否则glFrustum
将不会执行任何操作。如果您没有使用这些矩阵,请不要立即开始使用它们(您认为这是'旧'OpenGL的一部分)。
听起来你想使用glScissor
来定义窗口坐标中的剪切矩形(请注意,它们的原点位于窗口的左下角)。您必须使用glEnable(GL_SCISSOR_TEST)
启用它。
至于关于“旧”OpenGL中可以完全忘记的内容的文章:谷歌搜索“现代OpenGL”或“OpenGL弃用”应该给你一些起点。