2017-12-06 3 views
1

현재 OpenGL을 배우려고합니다. 성공적으로 화면에 무지개 삼각형을 렌더링했습니다. 화면에서 무지개 삼각형을 성공적으로 움직였습니다. 그러나 텍스처를 두 개의 삼각형에 올바르게 렌더링 할 수 없습니다.OpenGL 텍스처가 렌더링되지 않습니다.

이 프로그램을 실행할 때마다 렌더링이없는 검은 색 화면이 표시됩니다. (이것은 그렇지 않으면 실행되지 않을 것입니다!) 나는 확인했습니다, 그리고 이미지 파일이 올바른 디렉토리에 확실히이다 컴파일하고 쉐이더를 링크 할 때 모든

define STB_IMAGE_IMPLEMENTATION 

#include <GL/glew.h> 
#include <GLFW/glfw3.h> 
#include <iostream> 
#include <stb/stb_image.h> 

int main() 
{ 
    //Initialize glfw 
    if (!glfwInit()) 
    { 
     fprintf(stderr, "ERROR: Could not start GLFW3.\n"); 
     return 1; 
    } 

    //Create the rendering context 
    GLFWwindow* window = glfwCreateWindow(480, 600, "Hello Rendering", 
              nullptr, nullptr); 

    if(!window) 
    { 
     fprintf(stderr, "ERROR: Could not create a rendering context with " 
      "GLFW3.\n"); 
     return 1; 
    } 

    glfwMakeContextCurrent(window); 

    //Start GLEW 
    glewExperimental=GL_TRUE; 
    GLenum err=glewInit(); 
    if(err!=GLEW_OK) 
    { 
     //Problem: glewInit failed, something is seriously wrong. 
     std::cout<<"glewInit failed, aborting."<<std::endl; 
    } 



    //////////////////////// 
    //Loading PNG 
    //////////////////////// 
    int x = 0; 
    int y = 0; 
    int n = 0; 
    int force_channels = 4; 
    unsigned char* image_data = stbi_load("spooky.png", &x, &y, &n, 
              force_channels); 
    if(!image_data) 
    { 
     fprintf(stderr, "ERROR: Could not load spooky.png\n."); 
     return 1; 
    } 

    //NPOT Check 
    if((x & (x - 1)) != 0 || (y & (y - 1)) != 0) 
    { 
     fprintf(stderr, "ERROR: Image is not a power of 2.\n"); 
     fprintf(stderr, "h: %d w: %d", y, x); 
     return 1; 
    } 

    //Flip the image 
    int width_in_bytes = x * 4; 
    unsigned char* top = nullptr; 
    unsigned char* bottom = nullptr; 
    unsigned char temp = 0; 
    int half_height = y/2; 

    for(int row = 0; row < half_height; row++) 
    { 
     top = image_data + row * width_in_bytes; 
     bottom = image_data + (y - row - 1) * width_in_bytes; 
     for(int col = 0; col < width_in_bytes; col++) 
     { 
      temp = *top; 
      *top = *bottom; 
      *bottom = temp; 
      top++; 
      bottom++; 
     } 
    } 


    GLuint tex = 0; 
    glGenTextures(1, &tex); 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, tex); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, 
       GL_UNSIGNED_BYTE, image_data); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 


    ////////////////////////////////// 
    //Vertex shader 
    ////////////////////////////////// 
    const char* vertShader = 
     "#version 330 core" 
     "layout(location = 0) in vec3 vertexPosition_modelspace;" 
     "layout(location = 1) in vec2 vt;" 
     "out vec2 texture_coordinates;" 
     "void main() {" 
     " texture_coordinates = vt;" 
     " gl_Position.xyz = vertexPosition_modelspace;" 
     " gl_Position.w = 1.0;" 
     "}"; 

    /////////////////////////////////// 
    //Frag shader 
    /////////////////////////////////// 
    const char* fragShader = 
     "#version 330 core" 
     "uniform sampler2D basic_texture;" 
     "out vec4 frag_color;" 
     "void main() {" 
     " vec4 texel = texture(basic_texture, texture_coordinates);" 
     " frag_color = texel;" 
     "}"; 


    //////////////////////////////////// 
    //Create shader program 
    /////////////////////////////////// 
    GLuint vsp = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vsp, 1, &vertShader, nullptr); 
    glCompileShader(vsp); 

    GLuint fsp = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fsp, 1, &fragShader, nullptr); 
    glCompileShader(fsp); 

    GLuint shader_program = glCreateProgram(); 
    glAttachShader(shader_program, fsp); 
    glAttachShader(shader_program, vsp); 
    glLinkProgram(shader_program); 

    glUseProgram(shader_program); 



    //////////////////////////////////// 
    //Texture coordinates 
    //////////////////////////////////// 
    GLfloat texcoords[] = { 
     0.0f, 1.0f, 
     0.0f, 0.0f, 
     1.0f, 0.0f, 
     1.0f, 0.0f, 
     1.0f, 1.0f, 
     0.0f, 1.0f 
    }; 

    GLuint vt_vbo; 
    glGenBuffers(1, &vt_vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vt_vbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords, 
       GL_STATIC_DRAW); 

    GLuint vao;; 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 
    glBindBuffer(GL_ARRAY_BUFFER, vt_vbo); 
    int dimensions = 2; 
    glVertexAttribPointer(1, dimensions, GL_FLOAT, GL_FALSE, 0, nullptr); 
    glEnableVertexAttribArray(1); 

    while(!glfwWindowShouldClose(window)) 
    { 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     //Use the shader 
     glUseProgram(shader_program); 
     //Draw the two triangles (6 points) 
     glDrawArrays(GL_TRIANGLES, 0, 6); 
     glfwPollEvents(); 
     glfwSwapBuffers(window); 
     if(GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE)) 
     { 
      glfwSetWindowShouldClose(window, 1); 
     } 
    } 

    std::cout << "Hello, World!" << std::endl; 
    return 0; 
} 
+0

glGetError로 오류를 검사하고 GLSL 프로그램 연결 상태를 확인하는 것이 좋습니다. 회로처럼 분할 할 수 있습니다. – vincent

+0

속성 위치'0'에서 'vertexPosition_modelspace'에 정점 위치 데이터를 바인딩하지 않는 이유는 무엇입니까? 젠장, 당신은 * attrib * 0을 활성화하지 않았다. 그리고 정점 위치 데이터는 어디에 있습니까? 텍스쳐 객체를'basic_texture' 샘플러에 바인딩하지 않는 이유는 무엇입니까? – genpfault

답변

1

먼저, 오류 메시지를 검색해야합니다

0 (1) : 오류 C0205 : 오류 C0206 :
0 (1) "corelayout"잘못된 프로필 유효하지 않은 토큰 ""당신이 얻을 것이다

GLint status = GL_TRUE; 
char error_msg[1024]; 
GLsizei read; 

GLuint vsp = glCreateShader(GL_VERTEX_SHADER); 
glShaderSource(vsp, 1, &vertShader, nullptr); 
glCompileShader(vsp); 
glGetShaderiv(vsp, GL_COMPILE_STATUS, &status); 
if (status != GL_TRUE) 
{ 
    glGetShaderInfoLog(vsp, 1024, &read, error_msg); 
    std::cout << "compile error:" << std::endl << error_msg << std::endl; 
} 

GLuint fsp = glCreateShader(GL_FRAGMENT_SHADER); 
glShaderSource(fsp, 1, &fragShader, nullptr); 
glCompileShader(fsp); 
glGetShaderiv(fsp, GL_COMPILE_STATUS, &status); 
if (status != GL_TRUE) 
{ 
    glGetShaderInfoLog(fsp, 1024, &read, error_msg); 
    std::cout << "compile error:" << std::endl << error_msg << std::endl; 
} 

GLuint shader_program = glCreateProgram(); 
glAttachShader(shader_program, fsp); 
glAttachShader(shader_program, vsp); 
glLinkProgram(shader_program); 
glGetProgramiv(shader_program, GL_LINK_STATUS, &status); 
if (status != GL_TRUE) 
{ 
    glGetProgramInfoLog(shader_program, 1024, &read, error_msg); 
    std::cout << "compile error:" << std::endl << error_msg << std::endl; 
} 

첫 번째 오류 메시지는 다음과 같이 어떻게 든 ~에 당신이 쉐이더 코드 ("#version 330 core")의 첫 번째 줄 이후 "\n" 끝 라인을 작성하지 않았기 때문에 rsion 라인은

이다.

당신이 관념 때 당신은 다음 오류 메시지가 얻을 :

0 (2) : 오류 C1008 : 정의되지 않은 변수 "texture_coordinates"

당신은 in의 선언을 추가 할 필요를 변수 texture_coordinates을 프래그먼트 셰이더에 적용합니다.

in vec2 texture_coordinates; 

는 마지막 코드는 다음과 같습니다

GLfloat texcoords[] = { 
    0.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
    1.0f, 0.0f, 
    1.0f, 1.0f, 
    0.0f, 1.0f 
}; 

GLfloat vertex[] = { 
    -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 vert_vbo; 
glGenBuffers(1, &vert_vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vert_vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); 

GLuint vt_vbo; 
glGenBuffers(1, &vt_vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vt_vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords, GL_STATIC_DRAW); 

GLuint vao; 
glGenVertexArrays(1, &vao); 
glBindVertexArray(vao); 
glBindBuffer(GL_ARRAY_BUFFER, vert_vbo); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); 
glEnableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, vt_vbo); 
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr); 
glEnableVertexAttribArray(1); 


마지막으로 사용자가 설정해야합니다

const char* vertShader = 
    "#version 330 core\n" 
    "layout(location = 0) in vec3 vertexPosition_modelspace;" 
    "layout(location = 1) in vec2 vt;" 
    "out vec2 texture_coordinates;" 
    "void main() {" 
    " texture_coordinates = vt;" 
    " gl_Position.xyz = vertexPosition_modelspace;" 
    " gl_Position.w = 1.0;" 
    "}"; 

const char* fragShader = 
    "#version 330 core\n" 
    "uniform sampler2D basic_texture;" 
    "out vec4 frag_color;" 
    "in vec2 texture_coordinates;" 
    "void main() {" 
    " vec4 texel = texture(basic_texture, texture_coordinates);" 
    " frag_color = texel;" 
    "}"; 
물론


당신이 정점 속성 vertexPosition_modelspace에 대한 정점 데이터를 제공해야 텍스처 유닛의 인덱스, 텍스처가 바인드되고있는 곳의 텍스처 샘플러의 유니폼 변수 basic_texture :

int texture_unit_index = 0; 
GLuint tex = 0; 
glGenTextures(1, &tex); 
glActiveTexture(GL_TEXTURE0 + texture_unit_index); 
glBindTexture(GL_TEXTURE_2D, tex); 

..... 

// to do after glLinkProgram(shader_program); 
int tex_sampler_loc = glGetUniformLocation(shader_program, "basic_texture"); 

..... 

// to do after glUseProgram(shader_program); 
glUniform1i(tex_sampler_loc, texture_unit_index); 
관련 문제