2013-03-16 15 views
1

看起來我的金字塔在前面更小,後面更大。OpenGL GLSL,從「後面」卡住觀看金字塔

-(void)drawRect:(NSRect)dirtyRect 
{ 
    // get the dimensions of the window 
    NSSize dim = [self frame].size; 

    // clear the background with color 
    glClearColor(0.0, 0.0, 0.0, 0.4); 
    glViewport(0, 0, dim.width, dim.height); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // cube position data 
    GLfloat vertices[] = {0.0, 100.0, 0.0, -50.0, 0.0, 50.0, 50.0, 0.0, 50.0, 50.0, 0.0, -50.0, -50.0, 0.0, -50.0}; 

    // cube indices data 
    GLubyte indices[] = {0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 1, 4, 3, 1, 3, 2}; 

    // cube color data 
    GLfloat color[] = {0.0, 1.0, 0.0, 1.0, 
    0.0, 0.3, 0.8, 1.0, 
    1.0, 0.0, 0.0, 1.0, 
    0.5, 0.0, 0.8, 1.0, 
    0.5, 0.6, 0.3, 1.0}; 

    // bind each array of data to separate buffers 
    // bind cube position data to the first buffer 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    // bind the cube color data to the second buffer 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    // enable the shader program 
    GLuint programID = [self loadShaders]; 
    glUseProgram(programID); 

    // enable vertex attributes 
    // enable cube position attributes 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]); 
    glEnableVertexAttribArray(VERTEX_POS_INDEX); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    // enable cube color attributes 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]); 
    glEnableVertexAttribArray(VERTEX_COLOR_INDEX); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    // point to the enabled attribute data 
    glVertexAttribPointer(VERTEX_POS_INDEX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, 0, vertices); 
    glVertexAttribPointer(VERTEX_COLOR_INDEX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE, 0, color); 

    GLfloat offset[] = {0.0, 0.0, -200.0}; 
    GLint offsetUnif = glGetUniformLocation(programID, "offset"); 
    GLint zNearUnif = glGetUniformLocation(programID, "zNear"); 
    GLint zFarUnif = glGetUniformLocation(programID, "zFar"); 
    GLint frustumScaleUnif = glGetUniformLocation(programID, "frustumScale"); 

    glUniform3fv(offsetUnif, 1, offset); 
    glUniform1f(frustumScaleUnif, 1.0f); 
    glUniform1f(zNearUnif, 0.1); 
    glUniform1f(zFarUnif, 1000.0); 

    // draw the elements 
    glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, indices); 

    glDisableVertexAttribArray(VERTEX_POS_INDEX); 
    glDisableVertexAttribArray(VERTEX_COLOR_INDEX); 
    glUseProgram(0); 

    // flush buffer 
    glFlush(); 
    [[self openGLContext] flushBuffer]; 

} 

這裏是頂點着色器:

#version 120 

attribute vec3 position; 
attribute vec4 inColor; 

uniform vec3 offset; 
uniform float zNear; 
uniform float zFar; 
uniform float frustumScale; 

varying vec4 outColor; 

void main() 
{ 
    vec4 cameraPos = vec4(position.x, position.y, -position.z, 1.0) + vec4(offset.x, offset.y, offset.z, 0.0); 
    vec4 clipPos; 

    clipPos.xy = cameraPos.xy * frustumScale; 

    clipPos.z = cameraPos.z * (zNear + zFar)/(zNear - zFar); 
    clipPos.z += 2 * zNear * zFar/(zNear - zFar); 

    clipPos.w = -cameraPos.z; 

    gl_Position = clipPos; 
    outColor = inColor; 
} 

當我運行代碼,我得到這個形象,注意它看起來好像與金字塔更大的在後面比前面:

Pyramid

我圍繞着「前」角(儘管我應該從另一側看這個,因此他們實際上是后角)。關於問題可能出在哪裏的任何想法或建議?

+0

好吧,圖片是正確的,它顯示了真正的前沿(在檢查頂點與指定的顏色之後)。神祕還在後面看起來比前面更大...... – xBACP 2013-03-16 13:32:13

回答

1

看來,您並未在着色器中應用透視投影矩陣,因此缺少視角/深度,導致某種正交投影。

你想要到着色器中應用矩陣是gl_ModelViewMatrix(對象&攝像頭變換),gl_ProjectionMatrix(投影)或gl_ModelViewProjectionMatrix(對象&相機變換&投影)。由於這些內裝制服已被棄用,你需要自己通過。

+0

那些矩陣可以在頂點着色器本身中構建嗎? – xBACP 2013-03-16 13:52:48

+0

儘管可以在着色器中初始化矩陣,但它們會根據對象,相機位置和視角而不同,因此建議使用C計算它們並使用'glUniformMatrix4fv()'傳遞它們。 – Sam 2013-03-16 13:59:30

+0

我在做投影數學,只是沒有矩陣形式。我將它的基礎排除在外:http://arcsynthesis.org/gltut/Positioning/Tut04%20Perspective%20Projection.html,Example 4.2 – xBACP 2013-03-16 14:00:30