Opengl 4.2纹理映射不显示

时间:2013-12-31 11:57:11

标签: c++ opengl ubuntu texture2d

我正在使用跨平台库(glfw,glew,glm)来制作一个简单的纹理映射OpenGl示例程序。它只是从我的计算机拍摄的图像,这是一个512 x 512 PNG,并且应该将它映射到我显示的正方形。没有纹理映射的程序工作得很好,方块是可见的。使用纹理映射Nothing是可见的,你能帮我找到错误的位置吗?

编辑:也许我在“do”画图到画面循环中缺少一个装订或其他东西?

主程序(LoadShaders和stbi_Image在外部正确定义)

if( !glfwInit() )
{
    fprintf( stderr, "Failed to initialize GLFW\n" );
    return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

// Open a window and create its OpenGL context
GLFWwindow* window = glfwCreateWindow (640, 480, "Hello Triangle", NULL, NULL);
if(!window)
{
    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;
}

glfwMakeContextCurrent(window);

// Initialize GLEW
glewExperimental = GL_TRUE; // Needed for core profile
GLenum err = glewInit();
if (err != GLEW_OK) {
  fprintf(stderr, "Failed to initialize GLEW\n");
  fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
  return -1;
}


const GLubyte* renderer = glGetString (GL_RENDERER); // get renderer string
const GLubyte* version = glGetString (GL_VERSION); // version as a string
printf ("Renderer: %s\n", renderer);
printf ("OpenGL version supported %s\n", version);

// tell GL to only draw onto a pixel if the shape is closer to the viewer
glEnable (GL_DEPTH_TEST); // enable depth-testing
glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer"


 // Ensure we can capture the escape key being pressed below
glfwSetInputMode(window,GLFW_STICKY_KEYS,GL_TRUE );

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", 
"SimpleFragmentShader.fragmentshader" );

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, 0.1f, 100.0f);
// Camera matrix
glm::mat4 View       = glm::lookAt(
                            glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space
                            glm::vec3(0,0,0), // and looks at the origin
                            glm::vec3(0,1,0)  // Head is up
                       );
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model      = glm::mat4(1.0f);
// Our ModelViewProjection : multiplication of our 3 matrices
glm::mat4 MVP        = Projection * View * Model; 


unsigned char* image_data;
int x, y, n;
char* file_name;
file_name = "/home/syk435/Pictures/texture_sample.png";
int force_channels = 4;
image_data = stbi_load(file_name, &x, &y, &n, force_channels); 

if (!image_data)
{
       fprintf (stderr, "ERROR: could not load %s\n", file_name);
}

//check if not normal dims
if (x & (x - 1) != 0 || y & (y - 1) != 0)
{
        fprintf (stderr, "WARNING: texture %s is not power-of-2 dimensions\n",
file_name);
}
//invert to norm
int width_in_bytes = x * 4;
unsigned char *top = NULL;
unsigned char *bottom = NULL;
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++;
        }
}


static const GLfloat g_vertex_buffer_data[] = {
    -0.75f,-0.75f,0.0f,
    -0.75f, 0.75f,0.0f,
     0.75f,-0.75f,0.0f,
     0.75f, 0.75f,0.0f,
    -0.75f, 0.75f,0.0f,
     0.75f,-0.75f,0.0f,
   };

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data,   
GL_STATIC_DRAW);

// Dark blue background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

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

//texture stuff
unsigned int tex = 0;
glGenTextures (1, &tex);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, tex);
GLuint TextureID  = glGetUniformLocation(programID, "basic_texture");
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);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

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

unsigned int vt_vbo;
glGenBuffers (1, &vt_vbo);
glBindBuffer (GL_ARRAY_BUFFER, vt_vbo);
int dimensions = 2; // 2d data for texture coords
int length = 6; // 6 vertices

glBufferData (
  GL_ARRAY_BUFFER,
  dimensions * length * sizeof (float),
  texcoords,
  GL_STATIC_DRAW
);

   do{

    // Clear the screen
    glClear( GL_COLOR_BUFFER_BIT );

    // Use our shader
    glUseProgram(programID);
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex);
    // Set our "myTextureSampler" sampler to user Texture Unit 0
    glUniform1i(TextureID, 0);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    glVertexAttribPointer(
        0,                  // attribute 0
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );


    // note: this is your existing VAO
    glEnableVertexAttribArray(1);
    glBindBuffer (GL_ARRAY_BUFFER, vt_vbo);
    // note: I assume that vertex positions are location 0
    dimensions = 2; // 2d data for texture coords
    glVertexAttribPointer (1, dimensions, GL_FLOAT, GL_FALSE, 0, NULL);

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

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    // Swap buffers
    glfwSwapBuffers(window);

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

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

// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &vt_vbo);
glDeleteProgram(programID);
glDeleteTextures(1, &TextureID);
glDeleteVertexArrays(1, &vao);

return 0;

VertexShader:

#version 420

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

layout (location = 1) in vec2 vt; // per-vertex texture co-ords

out vec2 texture_coordinates;

uniform mat4 MVP;

void main(){

   gl_Position = MVP * vec4(vertexPosition_modelspace,1);

   texture_coordinates =  vt;
}

FragmentShader:

#version 420

// Ouput data
//texture stuff
in vec2 texture_coordinates;

uniform sampler2D basic_texture;

out vec3 frag_colour;

void main()
{

frag_colour = texture2D(basic_texture, texture_coordinates).rgb;

}

1 个答案:

答案 0 :(得分:0)

对于那些不想搜索评论的人......

删除这两行(即不启用深度测试)。

glEnable (GL_DEPTH_TEST); // enable depth-testing
glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer"

或者在启用深度缓冲区的情况下,在do while循环开始时清除深度缓冲区

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

(答案在Andon Coleman的问题下面的评论中。当我正在阅读Anton's OpenGL 4 Tutorials时,我想我会练习一下,看看我是否能让代码正常工作。做上述任何一项显示纹理。)