2017-09-13 85 views
0

我正在关注Udemy - Modern Opengl 3.0教程。我已经设法进入基本教程第5部分“投影和坐标系统”。这在Mac上完美工作,使用相同的代码,但我无法在Windows上使用它。我甚至重新启动了教程,以确保我没有错过任何东西,以前的所有教程都可以使用,但是我得到了相同的结果。它只是不会正确渲染。我在Windows上的Visual Studio 2015上做了这个。在Mac上,我通过使用vim和Makefile来处理它......你会认为使用为你编译的IDE会更容易,但显然不是。Opengl 3D立方体将无法在Windows上正确呈现

the rendered cube

这就是我的显示屏幕上,只有它闪烁非常快,并移动了不少,而不是旋转的立方体我应该得到。

下面是代码:

Shader.h:

#ifndef SHADER_H 
#define SHADER_H 

#include <string> 
#include <fstream> 
#include <sstream> 
#include <iostream> 

#include <GL/glew.h> 

class Shader 
{ 
public: 
    GLuint Program; 
    // Constructor generates the shader on the fly 
    Shader(const GLchar *vertexPath, const GLchar *fragmentPath) 
    { 
     // 1. Retrieve the vertex/fragment source code from filePath 
     std::string vertexCode; 
     std::string fragmentCode; 
     std::ifstream vShaderFile; 
     std::ifstream fShaderFile; 
     // ensures ifstream objects can throw exceptions: 
     vShaderFile.exceptions(std::ifstream::badbit); 
     fShaderFile.exceptions(std::ifstream::badbit); 
     try 
     { 
      // Open files 
      vShaderFile.open(vertexPath); 
      fShaderFile.open(fragmentPath); 
      std::stringstream vShaderStream, fShaderStream; 
      // Read file's buffer contents into streams 
      vShaderStream << vShaderFile.rdbuf(); 
      fShaderStream << fShaderFile.rdbuf(); 
      // close file handlers 
      vShaderFile.close(); 
      fShaderFile.close(); 
      // Convert stream into string 
      vertexCode = vShaderStream.str(); 
      fragmentCode = fShaderStream.str(); 
     } 
     catch (std::ifstream::failure e) 
     { 
      std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; 
     } 
     const GLchar *vShaderCode = vertexCode.c_str(); 
     const GLchar *fShaderCode = fragmentCode.c_str(); 
     // 2. Compile shaders 
     GLuint vertex, fragment; 
     GLint success; 
     GLchar infoLog[512]; 
     // Vertex Shader 
     vertex = glCreateShader(GL_VERTEX_SHADER); 
     glShaderSource(vertex, 1, &vShaderCode, NULL); 
     glCompileShader(vertex); 
     // Print compile errors if any 
     glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); 
     if (!success) 
     { 
      glGetShaderInfoLog(vertex, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; 
     } 
     // Fragment Shader 
     fragment = glCreateShader(GL_FRAGMENT_SHADER); 
     glShaderSource(fragment, 1, &fShaderCode, NULL); 
     glCompileShader(fragment); 
     // Print compile errors if any 
     glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); 
     if (!success) 
     { 
      glGetShaderInfoLog(fragment, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; 
     } 
     // Shader Program 
     this->Program = glCreateProgram(); 
     glAttachShader(this->Program, vertex); 
     glAttachShader(this->Program, fragment); 
     glLinkProgram(this->Program); 
     // Print linking errors if any 
     glGetProgramiv(this->Program, GL_LINK_STATUS, &success); 
     if (!success) 
     { 
      glGetProgramInfoLog(this->Program, 512, NULL, infoLog); 
      std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; 
     } 
     // Delete the shaders as they're linked into our program now and no longer necessery 
     glDeleteShader(vertex); 
     glDeleteShader(fragment); 

    } 
    // Uses the current shader 
    void Use() 
    { 
     glUseProgram(this->Program); 
    } 
}; 

#endif 

core.frag:

#version 330 core 
in vec2 TexCoord; 

out vec4 color; 

uniform sampler2D ourTexture1; 

void main() 
{ 
    color = texture(ourTexture1, TexCoord); 
} 

core.vs:

#version 330 core 
layout (location = 0) in vec3 position; 
layout (location = 2) in vec2 texCoord; 

out vec2 TexCoord; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    gl_Position = projection * view * model * vec4(position, 1.0f); 
    TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); 
} 

main.cpp中:

#include <iostream> 

// GLEW 
#define GLEW_STATIC 
#include <GL/glew.h> 

// GLFW 
#include <GLFW/glfw3.h> 

// Other Libs 
#include "SOIL2/SOIL2.h" 

#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp> 

// Other includes 
#include "Shader.h" 

// Window dimensions 
const GLuint WIDTH = 800, HEIGHT = 600; 

// The MAIN function, from here we start the application and run the game loop 
int main() 
{ 
    // Init GLFW 
    glfwInit(); 

    // Set all the required options for GLFW 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 

    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 

    // Create a GLFWwindow object that we can use for GLFW's functions 
    GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); 

    int screenWidth, screenHeight; 
    glfwGetFramebufferSize(window, &screenWidth, &screenHeight); 

    if (nullptr == window) 
    { 
     std::cout << "Failed to create GLFW window" << std::endl; 
     glfwTerminate(); 

     return EXIT_FAILURE; 
    } 

    glfwMakeContextCurrent(window); 

    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions 
    glewExperimental = GL_TRUE; 
    // Initialize GLEW to setup the OpenGL Function pointers 
    if (GLEW_OK != glewInit()) 
    { 
     std::cout << "Failed to initialize GLEW" << std::endl; 
     return EXIT_FAILURE; 
    } 

    // Define the viewport dimensions 
    glViewport(0, 0, screenWidth, screenHeight); 

    glEnable(GL_DEPTH_TEST); 
    // enable alpha support 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//enables jpegs and alphas 

    // Build and compile our shader program 
    Shader ourShader("res/shaders/core.vs", "res/shaders/core.frag"); 

    // use with Perspective Projection 
    GLfloat vertices[] = { 
     //x  y  z  normalized texture coordinates 
     -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 
     0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 
     -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 
     -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 

     -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 
     0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 
     -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 
     -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 

     -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 
     -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 
     -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 
     -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 
     -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 
     -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 

     0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 
     0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 
     0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 
     0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 

     -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 
     0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 
     0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 
     0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 
     -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 
     -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 

     -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 
     0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 
     0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 
     -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 
     -0.5f, 0.5f, -0.5f, 0.0f, 1.0f 
    }; 

    GLuint VBO, VAO;//Vertex Buffer Object, Vertex Array Object 
    glGenVertexArrays(1, &VAO); 
    glGenBuffers(1, &VBO); 

    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). 
    glBindVertexArray(VAO); 

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

    // Position attribute 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)0); 
    glEnableVertexAttribArray(0); 
    // TexCoord attribute 
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid *)(3 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(2); 

    glBindVertexArray(0); // Unbind VAO 

    // Load and create a texture 
    GLuint texture; 

    int width, height; 

    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    // Set our texture parameters 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    // Set texture filtering 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    // Load, create texture and generate mipmaps 
    unsigned char *image = SOIL_load_image("res/images/image1.jpg", &width, &height, 0, SOIL_LOAD_RGBA); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); 
    glGenerateMipmap(GL_TEXTURE_2D); 
    SOIL_free_image_data(image); 
    glBindTexture(GL_TEXTURE_2D, 0); 


    glm::mat4 projection; 
    projection = glm::perspective(45.0f, (GLfloat)screenWidth/(GLfloat)screenHeight, 0.1f, 1000.0f); 

    // Game loop 
    while (!glfwWindowShouldClose(window)) 
    { 
     // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 
     glfwPollEvents(); 

     // Render 
     // Clear the colorbuffer 
     glClearColor(0.9f, 0.5f, 0.3f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 


     glActiveTexture(GL_TEXTURE0); 
     glBindTexture(GL_TEXTURE_2D, texture); 
     glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture"), 0); 
     ourShader.Use(); 

     glm::mat4 model; 
     glm::mat4 view; 
     model = glm::rotate(model, (GLfloat)glfwGetTime() * 1.0f, glm::vec3(0.5f, 1.0f, 0.0f)); 
     view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); 

     GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); 
     GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); 
     GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); 

     glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); 
     glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); 
     glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); 

     glBindVertexArray(VAO); 
     glDrawArrays(GL_TRIANGLES, 0, 36); 
     glBindVertexArray(0); 

     // Swap the screen buffers 
     glfwSwapBuffers(window); 
    }  

    // Properly de-allocate all resources once they've outlived their purpose 
    glDeleteVertexArrays(1, &VAO); 
    glDeleteBuffers(1, &VBO); 

    // Terminate GLFW, clearing any resources allocated by GLFW. 
    glfwTerminate(); 

    return EXIT_SUCCESS; 
} 
+0

有你每次调用后检查glGetError()? – Robinson

+0

您是否检查预期的着色器代码是否已加载?文件“res/shaders/core.vs”和“res/shaders/core.frag”是否合适的着色器文件? (不要只检查文件名,检查卷上的文件的内容,太) – Rabbid76

+0

@ Rabbid76烨我没有检查,它们加载 – questions

回答

4

在片段着色器纹理采样统一的名称为"ourTexture1"

uniform sampler2D ourTexture1; 

但是当你试图让你使用的名称"ourTexture"纹理采样均匀的位置:

glGetUniformLocation(ourShader.Program, "ourTexture") 


第二个问题是,你的程序之前设置纹理采样器均匀ourTexture1是当前渲染状态的一部分。

glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture"), 0); 
ourShader.Use(); 

制服的位置,可以检索(glGetUniformLocation)在程序链接之后的任何时间(glLinkProgram)。

glLinkProgram(ourShader.Program); 

GLint modelLoc = glGetUniformLocation(ourShader.Program, "model"); 
GLint viewLoc = glGetUniformLocation(ourShader.Program, "view"); 
GLint projLoc = glGetUniformLocation(ourShader.Program, "projection"); 
GLint texLoc = glGetUniformLocation(ourShader.Program, "ourTexture1"); 

但制服不能设定(glUniform)直到程序是活动程序(glUseProgram)。

glUseProgram(ourShader.Program); 

glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); 
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); 
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); 
glUniform1i(texLoc, 0); 
+0

作出一切必要的修改,但仍是同样的结果 – questions

+0

@questions我复制并测试你的代码,它为我工作正常,有没有错误。 – Rabbid76

+0

@questions可能有当加载的问题你可以尝试[** this **](https://ideone.com/DIiWsD)(复制粘贴到你的代码) - 这段代码不会加载位图,DOS不会使用'SOIL_load_image',但会创建一个 – Rabbid76

2

您激活着色器,看上去是错之前,你要设置的着色均匀。