剪切使用着色器渲染的VBO

时间:2014-03-02 19:29:23

标签: python opengl

我正在使用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中可以完全忘记什么的文章。

1 个答案:

答案 0 :(得分:1)

除非您在着色器中使用内置矩阵(gl_ModelViewProjectionMatrix等),否则glFrustum将不会执行任何操作。如果您没有使用这些矩阵,请不要立即开始使用它们(您认为这是'旧'OpenGL的一部分)。

听起来你想使用glScissor来定义窗口坐标中的剪切矩形(请注意,它们的原点位于窗口的左下角)。您必须使用glEnable(GL_SCISSOR_TEST)启用它。

至于关于“旧”OpenGL中可以完全忘记的内容的文章:谷歌搜索“现代OpenGL”或“OpenGL弃用”应该给你一些起点。