2014-03-02 43 views
0

我正在開發一個使用PyOpenGL的2D遊戲引擎。剪下一個着色器渲染的VBO

爲了與使用SDL的先前版本的引擎保持一致,圖形元素首先存儲在VBO中,並具有2D座標系,其中(0,0)是左上角,(640,448)是底部 - 右(所以y軸反轉)。我們稱之爲SDL座標。

由於我的圖形使用調色板效果,我用着色器渲染它們。我的頂點着色器只是將我的2D座標系轉換爲[-1; 1]立方體。

現在,我需要剪輯顯示。我的第一個想法是通過像素着色器,通過將剪輯區域外的所有頂點發送到[-1; 1]立方體(我拿(2.0,0.0,0.0,1.0)),但它出錯了:它使得它們的一些邊緣在裁剪區外但不是全部都變形的方形瓷磚變形。

所以我考慮使用glFrustum,但我不明白在哪個座標系中我必須指定參數。

事實上,我試圖在運行代碼時不會注意到任何東西,或多或少地作爲參數。我究竟做錯了什麼 ?

就目前而言,我的繪圖程序看起來像這樣:

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

除非您在着色器中使用內置矩陣(gl_ModelViewProjectionMatrix等),否則glFrustum將不會執行任何操作。如果你不使用這些矩陣,現在不要開始使用它們(你是正確的,這是'舊'OpenGL的一部分)。

聽起來好像你想要使用glScissor它定義了窗口座標中的一個剪切矩形(注意它們的原點位於窗口的左下角)。您必須使用glEnable(GL_SCISSOR_TEST)啓用它。至於關於什麼可以完全忘記在'舊'OpenGL:谷歌搜索「現代OpenGL」或「OpenGL棄用」的文章應該給你幾個出發點。