2015-02-05 5 views
-1

깊이 버퍼 렌더링 문제가 있습니다. 내 깊이 버퍼를 텍스처로 렌더링하려고하면 이상한 유물이 생깁니다. 결국에는 지형 데이터를 렌더링하려고합니다. 장난감의 예로서 사각형을 렌더링하고 싶습니다. 사각형의 색은 카메라까지의 거리 여야합니다. 마지막에는 각 픽셀이 카메라와의 거리를 보여주는 깊이 맵을 갖고 싶습니다.깊이 버퍼가 제대로 렌더링되지 않습니다.

// Include standard headers 
#include <stdio.h> 
#include <stdlib.h> 
#include <vector> 
#include <iostream> 

// Include GLEW 
#include <GL/glew.h> 

// Include GLFW 
#include <glfw3.h> 
GLFWwindow* window; 

// Include GLM 
#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
using namespace glm; 

#include "common/shader.hpp" 
//#include "common/texture.hpp" 
//#include "common/controls.hpp" 
//#include "common/objloader.hpp" 
//#include "common/vboindexer.hpp" 

using namespace std; 


int main(void) 
{ 
    cout << "Error 1: " << glGetError() << endl; 
    // Initialise GLFW 
    if(!glfwInit()) 
    { 
      fprintf(stderr, "Failed to initialize GLFW\n"); 
      return -1; 
    } 
    cout << "Error 2: " << glGetError() << endl; 
    glfwWindowHint(GLFW_SAMPLES, 4); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    cout << "Error 3: " << glGetError() << endl; 

    // Open a window and create its OpenGL context 
    window = glfwCreateWindow(1024, 768, "Toydata", NULL, NULL); 
    if(window == NULL){ 
     fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n"); 
     glfwTerminate(); 
     return -1; 
    } 
    cout << "Error 4: " << glGetError() << endl; 
    glfwMakeContextCurrent(window); 
    cout << "Error 5: " << glGetError() << endl; 
    // Initialize GLEW 
    glewExperimental = true; // Needed for core profile 
    if (glewInit() != GLEW_OK) { 
      fprintf(stderr, "Failed to initialize GLEW\n"); 
      return -1; 
    } 
    cout << "Error 6: " << glGetError() << endl; 
    // Ensure we can capture the escape key being pressed below 
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); 


    cout << "Error 7: " << glGetError() << endl; 
    // Dark blue background 
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f); 
    cout << "Error 7a: " << glGetError() << endl; 
    glClearDepth(1.0f); 
    cout << "Error 7b: " << glGetError() << endl; 

    glClearBufferData(GL_ARRAY_BUFFER, GL_TEXTURE_2D, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 
    cout << "Error 9: " << glGetError() << endl; 

    // Enable depth test 
    glEnable(GL_DEPTH_TEST); 
    glDepthRange(0.1f, 100.0f); 
    glDepthFunc(GL_LESS); 
    glDepthMask(GL_TRUE); 
    // Cull triangles which normal is not towards the camera 
    glCullFace(GL_BACK); 
    glEnable(GL_CULL_FACE); 



    GLuint VertexArrayID; 
    glGenVertexArrays(1, &VertexArrayID); 
    glBindVertexArray(VertexArrayID); 

    // Create and compile our GLSL program from the shaders 
    GLuint programID = LoadShaders("../SimpleTransform.vertexshader", "../SingleColor.fragmentshader"); 
    // Get a handle for our "MVP" uniform 
    GLuint MatrixID = glGetUniformLocation(programID, "MVP"); 
    // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units 
    glm::mat4 Projection = glm::perspective(45.0f, 4.0f/3.0f, 1.0f, 100.0f); 

    // Camera matrix 
    glm::mat4 View  = glm::lookAt(
     glm::vec3(0,1,3), // Camera is at (0,1,3), in World Space 
     glm::vec3(0,0,0), // and looks at the origin 
     glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down) 
    ); 
    glm::mat4 Model  = glm::mat4(1.0f); 
    glm::mat4 MVP  = Projection * View * Model; // Remember, matrix multiplication is the other way around 


    static const GLfloat g_vertex_buffer_data[] = { 
     -1.0f, -1.0f, 0.0f, 
     1.0f, -1.0f, 0.0f, 
     0.0f, 1.0f, -50.0f, 

     1.0f, -1.0f, 0.0f, 
     2.0f, 1.0f, -50.0f, 
     0.0f, 1.0f, -50.0f, 
    }; 


    cout << "Generate Framebuffer..." << endl; 
    GLuint vertexbuffer; 
    glGenBuffers(1, &vertexbuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_DYNAMIC_DRAW); 
    cout << "Error: " << glGetError() << endl; 

    //////////////////////////////////////////////////////////////////////////// 
    // TEXTURE RENDERING 
    //////////////////////////////////////////////////////////////////////////// 

    // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer. 
    GLuint FramebufferName = 0; 
    glGenFramebuffers(1, &FramebufferName); 
    glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); 
    cout << "Error: " << glGetError() << endl; 


    // Alternative : Depth texture. Slower, but you can sample it later in your shader 
    GLuint depthTexture = 0; 
    glGenTextures(1, &depthTexture); 
    glBindTexture(GL_TEXTURE_2D, depthTexture); 
    glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT32, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    cout << "Error: " << glGetError() << endl; 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); 
    cout << "Error 9a: " << glGetError() << endl; 

    glDrawBuffer(GL_NONE); 
    glReadBuffer(GL_NONE); 

    // Depth texture alternative : 
    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0); 
    cout << "Error: " << glGetError() << endl; 

    // Set the list of draw buffers. 
    GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; 
    glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers 
    cout << "Error 10: " << glGetError() << endl; 
    // Always check that our framebuffer is ok 
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 
    { 
      cout << "Framebuffer not complete!" << endl; 
      return false; 
    } 
    cout << "Error 11: " << glGetError() << endl; 

    // The fullscreen quad's FBO 
    static const GLfloat g_quad_vertex_buffer_data[] = { 
      -1.0f, -1.0f, 0.0f, 
      1.0f, -1.0f, 0.0f, 
      -1.0f, 1.0f, 0.0f, 
      -1.0f, 1.0f, 0.0f, 
      1.0f, -1.0f, 0.0f, 
      1.0f, 1.0f, 0.0f, 
    }; 


    GLuint quad_vertexbuffer; 
    glGenBuffers(1, &quad_vertexbuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW); 

    cout << "Error 12: " << glGetError() << endl; 
    // Create and compile our GLSL program from the shaders 
    GLuint quad_programID = LoadShaders("../Passthrough.vertexshader", "../WobblyTexture.fragmentshader"); 
    GLuint texID = glGetUniformLocation(quad_programID, "depthTexture"); 

    cout << "Error 13: " << glGetError() << endl; 


    do{ 

     // Clear the screen 
     glClear(GL_COLOR_BUFFER_BIT); 

     // Use our shader 
     glUseProgram(programID); 

     // Send our transformation to the currently bound shader, 
     // in the "MVP" uniform 
     glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); 

     // 1rst attribute buffer : vertices 
     glEnableVertexAttribArray(0); 
     glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); 
     glVertexAttribPointer(
       0,     // attribute. No particular reason for 0, but must match the layout in the shader. 
       3,     // size 
       GL_FLOAT,   // type 
       GL_FALSE,   // normalized? 
       0,     // stride 
       (void*)0   // array buffer offset 
     ); 

     // Draw the triangle ! 
     glDrawArrays(GL_TRIANGLES, 0, 6); // 3 indices starting at 0 -> 1 triangle 

     glDisableVertexAttribArray(0); 

     // Render to the screen 
     glBindFramebuffer(GL_FRAMEBUFFER, 0); 
     glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right 

     // Clear the screen 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     // Use our shader 
     glUseProgram(quad_programID); 

     // Bind our texture in Texture Unit 0 
     glActiveTexture(GL_TEXTURE0); 
     glBindTexture(GL_TEXTURE_2D, depthTexture); 
     // Set our "depthTexture" sampler to user Texture Unit 0 
     glUniform1i(texID, 0); 


     // 1rst attribute buffer : vertices 
     glEnableVertexAttribArray(0); 
     glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer); 
     glVertexAttribPointer(
       0,     // attribute 0. No particular reason for 0, but must match the layout in the shader. 
       3,     // size 
       GL_FLOAT,   // type 
       GL_FALSE,   // normalized? 
       0,     // stride 
       (void*)0   // array buffer offset 
     ); 

     // Draw the triangles ! 
     glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles 

     glDisableVertexAttribArray(0); 



     // Swap buffers 
     glfwSwapBuffers(window); 
     glfwPollEvents(); 

    } // Check if the ESC key was pressed or the window was closed 
    while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && 
       glfwWindowShouldClose(window) == 0); 

    // Cleanup VBO and shader 
    glDeleteBuffers(1, &vertexbuffer); 
    glDeleteProgram(programID); 
    glDeleteBuffers(1, &quad_vertexbuffer); 
    glDeleteProgram(quad_programID); 
    glDeleteVertexArrays(1, &VertexArrayID); 
    glDeleteFramebuffers(1, &FramebufferName); 
    glDeleteTextures(1, &depthTexture); 


    // Close OpenGL window and terminate GLFW 
    glfwTerminate(); 

    return 0; 
} 

내 쉐이더 :

정점 :

#version 330 core 

// Input vertex data, different for all executions of this shader. 
layout(location = 0) in vec3 vertexPosition_modelspace; 

// Output data ; will be interpolated for each fragment. 
out vec2 UV; 

void main(){ 
    gl_Position = vec4(vertexPosition_modelspace,1); 
    UV = (vertexPosition_modelspace.xy+vec2(1,1))/2.0; 
} 

조각 :

#version 330 core 

in vec2 UV; 

out vec4 color; 

uniform sampler2D depthTexture; 


void main(){ 

    float z = texture2D(depthTexture, UV).x; 
    float n = 1.0; 
    float f = 100.0; 
    float c = (2.0 * n)/(f + n - z * (f - n)); 


    color = vec4(c,c,c,1.0);  
} 

사람이 어떻게 문제를 해결하는 아이디어가 있습니까?

답변

0

깊이 텍스처를 렌더링하려면 깊이 버퍼 첨부 파일을 추가 한 다음 정상적으로 렌더링해야합니다.

프래그먼트 셰이더에서 수행중인 작업은 깊이 텍스처에 이미있는 렌더링 버퍼로 렌더링됩니다. 이해 한 바로는 이제 FROM이 아닌 해당 깊이 텍스처로 렌더링하려고합니다.

FROM (깊이 텍스처를 보는 것을 의미)을 렌더링하려면 색상 만 취하면 충분합니다 (추가 변환을 할 필요가 없습니다. 모든 것은 이미 0과 1 사이에 있습니다).

GPU에 깊이 버퍼 첨부 파일 확장자가없는 경우 정점 셰이더의 Z를 out 매개 변수로 전달하여 프레임 버퍼 첨부 파일에 렌더링 할 수 있습니다. 그러면 조각 쉐이더는 다음과 같아야합니다.

// vs to send depth information to fs -> case without depth buffer attachment 
    ... 
    out float outz; 
    ... 
    void main() 
    { 
     ... 
     outz = vertexposition_modelspace.z; // btw, shouldn't this be projection space ? 
     ... 
    } 

    // fs to render depth information without depth buffer attachment 
    in float outz; 
    out vec4 color; 
    void main() 
    { 
     color = vec4(outz,outz,outz,1); 
    } 
+0

감사합니다. – Thomas

관련 문제