2017-07-26 133 views
0

所以首先,我是一名初學者,我從learnopengl.com學習opengl。所以我明白主要方法的代碼中發生了什麼。代碼在主要方法中起作用。但是當我試圖爲它創建一個類時,它不會呈現任何東西!我完全不知道出了什麼問題!Open gl sprite class not working

Sprite.h

#pragma once 

#include"Shader.h" 
#include<GL\glew.h> 

class Sprite { 
    GLuint vao; 
    GLuint vbo; 

    int vertexCount; 

    Shader shader; 

public: 

    Sprite(const GLfloat vertices[9], int noOfVertices, Shader s = Shader()) : vertexCount(noOfVertices) , shader(s) 
    { 

     glGenVertexArrays(1, &vao); 
     glGenBuffers(1, &vbo); 

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

     glVertexAttribPointer(0, this->vertexCount, GL_FLOAT, GL_FALSE, 0, nullptr); 
     glEnableVertexAttribArray(0); 
     glBindBuffer(GL_ARRAY_BUFFER, 0); 

     glBindVertexArray(0); 
    } 

    void draw() { 
     glBindVertexArray(this->vao); 
     glDrawArrays(GL_TRIANGLES, 0, this->vertexCount); 
     glBindVertexArray(0); 
    } 
}; 

Shader.h

#pragma once 
#include<iostream> 
#include<fstream> 
#include<sstream> 
#include<string> 
#include<vector> 

#include<GL\glew.h> 

class Shader { 
    GLuint programID; 

    GLuint vertID; 
    GLuint fragID; 

public: 
    Shader(std::string vertex = "Shaders/Dvert.vert", std::string fragment = "Shaders/Dfrag.frag") 
    { 
     this->programID = glCreateProgram(); 
     this->vertID = glCreateShader(GL_VERTEX_SHADER); 
     this->fragID = glCreateShader(GL_FRAGMENT_SHADER); 

     this->CompileShaders(vertex, fragment); 
     this->LinkProgram(); 
    } 

    GLuint getProgramId() { 
     return this->programID; 
    } 

private: 

    void CompileShaders(std::string vertexShaderPath, std::string FragShaderPath) { 

     std::string vCode = GetContentsFrom(vertexShaderPath).c_str(); 
     const char * vertexCode = vCode.c_str(); 
     glShaderSource(this->vertID, 1, &vertexCode, NULL); 
     glCompileShader(this->vertID); 

     this->HandleShaderErrors(this->vertID); 

     std::string fCode = GetContentsFrom(FragShaderPath).c_str(); 
     const char * fragCode = fCode.c_str(); 
     glShaderSource(this->fragID, 1, &fragCode, NULL); 
     glCompileShader(this->fragID); 

     std::cout << fragCode << std::endl; 

     this->HandleShaderErrors(this->fragID); 
    } 

    void LinkProgram() { 
     glAttachShader(this->programID, this->vertID); 
     glAttachShader(this->programID, this->fragID); 

     glLinkProgram(this->programID); 
     this->HandleLinkErrors(); 
    } 

    std::string GetContentsFrom(std::string path) { 
     std::ifstream file(path); 
     std::ostringstream stream; 

     if (!file) { 
      std::cout << "Specified file path is invalid" << std::endl; 
      return ""; 
     } 
     stream << file.rdbuf(); 

     std::cout << stream.str() << std::endl << std::endl; 

     return stream.str(); 
    } 

    void HandleLinkErrors() { 
     int result; 
     glGetProgramiv(this->programID, GL_LINK_STATUS, &result); 

     if (result == GL_FALSE) { 
      int length; 
      glGetProgramiv(this->programID, GL_INFO_LOG_LENGTH, &length); 

      std::vector<char> error(length); 

      glGetProgramInfoLog(this->programID, length , &length, &error[0]); 
      std::cout << &error[0] << std::endl; 

      glDetachShader(this->programID, this->vertID); 
      glDetachShader(this->programID, this->fragID); 
     } 
    } 

    void HandleShaderErrors(GLuint shader) { 
     int status; 
     glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 

     if (status == GL_FALSE) { 
      int length; 
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); 

      std::vector<char> error(length); 

      glGetShaderInfoLog(shader, length, &length, &error[0]); 
      std::cout << &error[0] << std::endl; 

      glDeleteShader(shader); 
     } 
    } 
}; 

Main.cpp的

#include<GL\glew.h> 
#include<GLFW\glfw3.h> 

#include"Console.h" 
#include"Headers\Shader.h" 
#include"Headers\Sprite.h" 

#include<iostream> 

static const GLfloat vertices[] = { 
    0.5f, -0.5f ,0.0f , 
    -0.5f, -0.5f, 0.0f, 
    0.0f, 0.5f, 0.0f 
}; 

int main() { 
    if (!glfwInit()) { 
     Console.Log("GLFW could not be initialised!!"); 
     Console.Wait(); 
    } 

    GLFWwindow *window = glfwCreateWindow(600, 400, "Open GL", nullptr, nullptr); 
    glfwMakeContextCurrent(window); 

    if (glewInit() != GLEW_OK) { 
     Console.Log("GLEW could not be initialised!!"); 
     Console.Wait(); 
    } 

    Sprite s(vertices, 3); 

    glClearColor(0, 0, 0, 1); 
    glfwWindowHint(GLFW_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_VERSION_MINOR, 3); 

    while (!glfwWindowShouldClose(window)) { 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glfwPollEvents(); 
     s.draw(); 
     glfwSwapBuffers(window); 
    } 
} 

請幫我!

注意: - 主要方法中的代碼呈現沒有着色器的白色三角形,所以我的圖形卡無需着色器。

另外,我創建的控制檯類只是打印到控制檯,並與opengl的東西沒有關係。 Console.Log isstd :: cout < < and Console.Wait is std :: cin.get();

+0

你應該之前'glfwCreateWindow'調用'glfwWindowHint'。 – SurvivalMachine

回答

0

至少有兩個問題。首先是你的Sprite中的sizeof(vertices)產生錯誤的結果,因爲它給出了指針的大小,而不是數組的大小。要修復它,請用sizeof(GLfloat) * 9替換它。

第二個問題是您在創建窗口和上下文後指定的OpenGL上下文版本太晚。爲了解決這個問題,調用這些方法glfwCreateWindow之前,而不是之後:

glfwWindowHint(GLFW_VERSION_MAJOR, 3); 
glfwWindowHint(GLFW_VERSION_MINOR, 3);