2016-09-24 2 views
1

OpenGL에서 텍스처를로드하려고하는데, 모두 검은 색입니다. 컴파일 할 때 쉐이더가 GL_TRUE를 반환하는지 확인했습니다. 그래서, 난 ... 그게 문제가주의해야 할왜 OpenGL에서 텍스처를 표시하지 못합니까?

어떤 일을 생각하지 않는다 :

내가 찍은 https://open.gl/content/code/c3_multitexture.txt에서 코드를 수정했습니다. 이것은 튜토리얼이었습니다 https://open.gl/textures

로드하려는 텍스처는 640 x 400 PGM 파일입니다. 로더 pgmImage가 파일을 올바르게로드한다고 가정 할 수 있습니다 (GDB에서 확인했습니다). PGM은 8 비트 B & W 데이터입니다. 여기에서 나는 단지 그것을 B 채널 & W로 표시 할 수 있기를 원하지만, 그것을 적색 채널로 사용하려고합니다.

어디로 잘못 가고 있습니까?

감사합니다.

코드는 다음과 같이 컴파일됩니다. -lglut -lGLU -lGL -lm -lGLEW flags in g ++ (일부는 필요하지 않습니다.) 당신의 glTexImage2D() 통화가 이미 발견 한 것처럼

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 
#include <math.h> 

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

//Glut 
#include <GL/glut.h> 

#include "shader.hpp" 
#include "PGM.hpp" 

GLuint programID; 
GLuint output_image; 

// Shader sources 
const GLchar* vertexSource = 
    "#version 450 core\n" 
    "in vec2 position;" 
    "in vec2 texcoord;" 
    "out vec2 Texcoord;" 
    "void main()" 
    "{" 
    " Texcoord = texcoord;" 
    " gl_Position = vec4(position, 0.0, 1.0);" 
    "}"; 
const GLchar* fragmentSource = 
    "#version 450 core\n" 
    "in vec2 Texcoord;" 
    "out vec4 outColor;" 
    "uniform sampler2D texData;" 
    "void main()" 
    "{" 
    " outColor = texture(texData, Texcoord);" 
    "}"; 



void display() 
{ 

    glClearColor(0.0f, 0.0f, 1.0f, 0.0f); 

    glClear(GL_COLOR_BUFFER_BIT); 

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 

    glFlush(); 
    glutSwapBuffers(); 

}  


void reshape(int width,int height) 
{ 
    double w2h = (height>0) ? (double)width/height : 1; 
    // Set viewport as entire window 
    glViewport(0,0, width,height); 

} 



int main(int argc, char** argv) 
{ 
    // Image setup 

    PGM pgmImage; 
    pgmImage.ReadFile("test.pgm"); 

    // Window Setup 

    glutInitWindowSize(640, 400); 
    glutInitWindowPosition (140, 140); 
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 
    glutInit(&argc, argv); 

    glutCreateWindow("OpenGL Application"); 
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 

    glewExperimental = true; // Needed for core profile 
    if (glewInit() != GLEW_OK) { 
     fprintf(stderr, "Failed to initialize GLEW\n"); 
     return -1; 
    } 

    // Vertices & texture init 

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

    GLuint vbo; 
    glGenBuffers(1, &vbo); 

    GLfloat vertices[] = { 
     // X Y  S T 
     -0.5f, 0.5f, 0.0f, 0.0f, // Top-left 
     0.5f, 0.5f, 1.0f, 0.0f, // Top-right 
     0.5f, -0.5f, 1.0f, 1.0f, // Bottom-right 
     -0.5f, -0.5f, 0.0f, 1.0f // Bottom-left 
    }; 

    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

    GLuint ebo; 
    glGenBuffers(1, &ebo); 

    GLuint elements[] = { 
     0, 1, 2, 
     2, 3, 0 
    }; 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); 

    // Create shaders 

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vertexShader, 1, &vertexSource, NULL); 
    glCompileShader(vertexShader); 


    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL); 
    glCompileShader(fragmentShader); 

    GLuint shaderProgram = glCreateProgram(); 
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader); 
    glBindFragDataLocation(shaderProgram, 0, "outColor"); 
    glLinkProgram(shaderProgram); 
    glUseProgram(shaderProgram); 

    // Vertex data specification 
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); 
    glEnableVertexAttribArray(posAttrib); 
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0); 

    GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord"); 
    glEnableVertexAttribArray(texAttrib); 
    glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void *)(2 * sizeof(GLfloat))); 

    // Load Textures 

    //TODO: don't really need 2 textures, but just following along with example source code for now... 
    GLuint textures[2]; 
    unsigned char* image; 

    int width, height; 

    width = pgmImage.GetWidth(); 
    height = pgmImage.GetHeight(); 
    image = (unsigned char *)pgmImage.GetData(); 

    glGenTextures(2, textures); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, textures[0]); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, image); 


    glUniform1i(glGetUniformLocation(shaderProgram, "texData"), 0); 

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

    // Start program 

    glutMainLoop(); 

    // Teardown 

    glDeleteTextures(2, textures); 

    glDeleteProgram(shaderProgram); 
    glDeleteShader(fragmentShader); 
    glDeleteShader(vertexShader); 

    glDeleteBuffers(1, &ebo); 
    glDeleteBuffers(1, &vbo); 

    glDeleteVertexArrays(1, &vao); 

    return 0; 
} 
+0

어느 시점에서 텍스처 크기는 2의 제곱이어야합니다. 이것이 오늘날 몇몇 상황에서 여전히 관련이 있는지 확신 할 수 없습니다. glTexImage2D 후에 glGetError 검사를 시도 했습니까? 대신 좌표가 화면에 있는지 확인하기 위해 일정한 색상 조각 쉐이더를 사용해 보셨습니까? –

+0

답장을 보내 주셔서 감사합니다. 좌표가 화면에 나타납니다. 내 쿼드가있는 블랙 박스가있는 파란색 배경이 나타납니다. 당신은 2의 강점에 대해서 옳지 만, OpenGL 4.5에서는 이것이 중요하지 않다는 것을 읽었습니다 (잘못되었을 수 있음). glError가 무엇을 말하고 회신하는지 살펴 보겠습니다. – Maxthecat

+0

glTexImage2D 호출에 잘못된 연산이있었습니다. 일치하는 데 필요한 형식 및 내부 형식 매개 변수 오류를 없애 GL_R8UI, 형식을 설정하지만 여전히 검은 쿼드 (질감 없음) 얻고있다. – Maxthecat

답변

4

internalFormat형식이 호환되지 않습니다 :

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, image); 

GL_RED_INTEGER 정수 텍스처 타입입니다. 정규화 된 텍스처 1 구성 요소 텍스처 데이터의 경우, 올바른 형식은 GL_RED입니다 :

새로운 코드에 대한
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, image); 

, 난 항상 GL_RGB 같은 크기를 지정하지 않은 내부 유형은 여전히 ​​이전 버전과의 호환성을 위해 유효하더라도, 크기의 내장 타입을 사용하는 것이 좋습니다 . 3 8 비트 구성 요소와 정규화 된 텍스처 그래서 :

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, image); 

내부 형식으로 GL_R8UI을 사용하여 귀하의 시도는 정수 텍스처를 사용하는 것은 특히 쉐이더 코드에서 추가 변경을 필요로하기 때문에, 당신은 usampler2D를 사용할 필요가 어디에 실패 샘플러 유형으로 사용할 수 있으며 텍스처를 샘플링 할 때 정수 값을 가져옵니다. 그러나 당신의 경우에, 그것은 당신이 처음에 원하는 것이 아닙니다.

관련 문제