2016-03-19 171 views
0

我已经经历这里的OpenGL教程: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/的OpenGL纹理立方体教程 - 示例代码不工作

该网站为您提供的每个教程的完整版本,所以你可以用自己的实现进行比较。不幸的是,教程5似乎不适用于我(无论是我的实现还是提供的)。我附上了我认为应该看起来像什么的图片,以及我运行从其代码生成的可执行文件时获得的图片。

我正在使用运行Windows 10的2015 MacBook Pro,在VS2015中编译,使用Intel的Iris 6100集成GPU。

what I think the right output is

my output

下面的代码是从教程。

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

// 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> 

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

glfwWindowHint(GLFW_SAMPLES, 4); 
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed 
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 

// Open a window and create its OpenGL context 
window = glfwCreateWindow(1024, 768, "Tutorial 05 - Textured Cube", 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; 
} 
glfwMakeContextCurrent(window); 

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

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

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

// Enable depth test 
glEnable(GL_DEPTH_TEST); 
// Accept fragment if it closer to the camera than the former one 
glDepthFunc(GL_LESS); 

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

// Create and compile our GLSL program from the shaders 
GLuint programID = LoadShaders("TransformVertexShader.vertexshader", "TextureFragmentShader.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, 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 (set to 0,-1,0 to look upside-down) 
         ); 
// 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; // Remember, matrix multiplication is the other way around 

// Load the texture using any two methods 
//GLuint Texture = loadBMP_custom("uvtemplate.bmp"); 
GLuint Texture = loadDDS("uvtemplate.DDS"); 

// Get a handle for our "myTextureSampler" uniform 
GLuint TextureID = glGetUniformLocation(programID, "myTextureSampler"); 

// Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle. 
// A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices 
static const GLfloat g_vertex_buffer_data[] = { 
    -1.0f,-1.0f,-1.0f, 
    -1.0f,-1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f,-1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    -1.0f,-1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f,-1.0f, 
    -1.0f, 1.0f,-1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f 
}; 

// Two UV coordinatesfor each vertex. They were created withe Blender. 
static const GLfloat g_uv_buffer_data[] = { 
    0.000059f, 1.0f-0.000004f, 
    0.000103f, 1.0f-0.336048f, 
    0.335973f, 1.0f-0.335903f, 
    1.000023f, 1.0f-0.000013f, 
    0.667979f, 1.0f-0.335851f, 
    0.999958f, 1.0f-0.336064f, 
    0.667979f, 1.0f-0.335851f, 
    0.336024f, 1.0f-0.671877f, 
    0.667969f, 1.0f-0.671889f, 
    1.000023f, 1.0f-0.000013f, 
    0.668104f, 1.0f-0.000013f, 
    0.667979f, 1.0f-0.335851f, 
    0.000059f, 1.0f-0.000004f, 
    0.335973f, 1.0f-0.335903f, 
    0.336098f, 1.0f-0.000071f, 
    0.667979f, 1.0f-0.335851f, 
    0.335973f, 1.0f-0.335903f, 
    0.336024f, 1.0f-0.671877f, 
    1.000004f, 1.0f-0.671847f, 
    0.999958f, 1.0f-0.336064f, 
    0.667979f, 1.0f-0.335851f, 
    0.668104f, 1.0f-0.000013f, 
    0.335973f, 1.0f-0.335903f, 
    0.667979f, 1.0f-0.335851f, 
    0.335973f, 1.0f-0.335903f, 
    0.668104f, 1.0f-0.000013f, 
    0.336098f, 1.0f-0.000071f, 
    0.000103f, 1.0f-0.336048f, 
    0.000004f, 1.0f-0.671870f, 
    0.336024f, 1.0f-0.671877f, 
    0.000103f, 1.0f-0.336048f, 
    0.336024f, 1.0f-0.671877f, 
    0.335973f, 1.0f-0.335903f, 
    0.667969f, 1.0f-0.671889f, 
    1.000004f, 1.0f-0.671847f, 
    0.667979f, 1.0f-0.335851f 
}; 

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); 

GLuint uvbuffer; 
glGenBuffers(1, &uvbuffer); 
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW); 

do{ 

    // Clear the screen 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_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]); 

    // Bind our texture in Texture Unit 0 
    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, Texture); 
    // 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. 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 
    ); 

    // 2nd attribute buffer : UVs 
    glEnableVertexAttribArray(1); 
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); 
    glVertexAttribPointer(
     1,        // attribute. No particular reason for 1, but must match the layout in the shader. 
     2,        // size : U+V => 2 
     GL_FLOAT,       // type 
     GL_FALSE,       // normalized? 
     0,        // stride 
     (void*)0       // array buffer offset 
    ); 

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

    glDisableVertexAttribArray(0); 
    glDisableVertexAttribArray(1); 

    // 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); 
glDeleteBuffers(1, &uvbuffer); 
glDeleteProgram(programID); 
glDeleteTextures(1, &TextureID); 
glDeleteVertexArrays(1, &VertexArrayID); 

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

return 0; 
} 

任何帮助,非常感谢。

回答

2

我想这是因为你不反相UV-COORDS的y分量(因为DDS具有为主不同,D3D坐标系统相对于OpenGL的)。您应该在片段着色器(与1.0f-uv.y一样简单)或对图像进行压缩之前将其反转。看看这个教程(顺便提一下,这很棒)。最后,它讨论了反转UV:

DXT压缩来自DirectX世界,其中V纹理坐标与OpenGL相比反转。所以如果你使用压缩纹理,你必须使用(coord.u,1.0-coord.v)来获取正确的纹理。只要你愿意,你可以这样做:在你导出脚本,在你的装载机,着色器...

+0

我有点糊涂了,我想我已经在做,当g_uv_buffer_data初始化?你能否详细说明一下?感谢您的帮助。 – ArcticWhite

+0

我不这么认为,我检查了这个实现,并且在'g_uv_buffer_data'和'color = texture(textureSampler,vec2(UV.x,1.0-UV.y))中确实有'1.0f'。 rgb;'在我的片段着色器中。 – fordcars

+0

我认为他把'1.0f'放在'g_uv_buffer_data'中只是为了让手动值输入更容易? – fordcars