2015-02-21 3 views
-1

Я делаю простую OPENGL программу, следуя за «learnopengl.com» учебник, прямо сейчас код должен просто показать оранжевый треугольник мой код: ScreenManager.hПочему моя программа вылетает при использовании конструктора? [C++]

#ifndef SCREEN_MANAGER_H 
#define SCREEN_MANAGER_H 

#define GLEW_STATIC 
#include <GL\glew.h> 
#include <GLFW\glfw3.h> 
#include <iostream> 
#include "Input.h" 
#include "Renderer.h" 

class ScreenManager 
{ 
public: 
ScreenManager(void); 
bool isCloseRequested(); 
void render(); 
void update(); 
void dispose(); 
private: 
GLFWwindow* window; 
Renderer renderer; 

}; 

#endif 

ScreenManager.cpp

#include "ScreenManager.h" 

ScreenManager::ScreenManager(void) 
{ 
    //Initialize GLFW library 
    glfwInit(); 
    //Specify the opengl version to 3 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3); 
    //Specify opengl profile to core profile 
    glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); 
    //Disable resizing 
    glfwWindowHint(GLFW_RESIZABLE,GL_FALSE); 

    //Create the window object 
    window = glfwCreateWindow(800,600,"test",nullptr,nullptr); 
    //Make the GL context the active context in the thread 
    glfwMakeContextCurrent(window); 

    //Error check 
    if(window==NULL){ 
     std::cout<<"falied to create GLFW window :("<< std::endl; 
     dispose();  
    } 

    //Make sure that GLEW use modern techniques to manage opengl functionality 
    glewExperimental =GL_TRUE; 

    //Initialize GLEW and check for errors 
    if(glewInit() != GLEW_OK){ 
     std::cout<<"failed to initialize glew :(" <<std::endl; 
    } 

    //Specify opengl viewport => bottom left coordinates and window size 
    glViewport(0,0,800,600); 

    //Register the events for GLFW => currently :keyboard 
    Input input(window); 

    renderer.init(); 
} 

//Check if window is closed 
bool ScreenManager::isCloseRequested(){ 
    if(glfwWindowShouldClose(window)) 
     return true; 
    return false; 
} 

//Clear screen and swap buffers 
void ScreenManager::render(){ 
    glClearColor(0,0,0,0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    renderer.render(); 

    glfwSwapBuffers(window); 
} 

//Check for events (registered events) 
void ScreenManager::update(){ 
    glfwPollEvents(); 
} 

void ScreenManager::dispose(){ 
    glfwTerminate(); 
} 

Renderer.h

#ifndef RENDERER_H 
#define RENDERER_H 

#define GLEW_STATIC 
#include <GL\glew.h> 
#include <iostream> 

class Renderer 
{ 
public: 
    Renderer(void); 
    void init(); 
    void render(); 
private: 
    void testShape(); 
    GLuint createVertexShader(GLuint &shader); 
    GLuint createFragmentShader(GLuint &shader); 
    void createShaderProgram(GLuint &program); 
}; 

#endif 

Renderer.cpp

#include "Renderer.h" 


GLuint program; 
GLuint vertexShader; 
GLuint fragmentShader; 
GLuint VAO; 

Renderer::Renderer(){ 
    //init(); 
} 

void Renderer::init(){ 
    testShape();  

    createShaderProgram(program); 
} 

void Renderer::render(){ 
    glUseProgram(program); 
    glBindVertexArray(VAO); 
    glDrawArrays(GL_TRIANGLES,0,3); 
    glBindVertexArray(0); 
} 

void Renderer::testShape(){ 
    GLfloat vertices[]={ 
     -0.5f, -0.5f, 0.0f, 
     0.5f, -0.5f, 0.0f, 
     0.0f, 0.5f, 0.0f 
    }; 

    GLuint VBO; 
    glGenBuffers(1 ,&VBO); 
    glGenVertexArrays(1 ,&VAO); 

    glBindVertexArray(VAO); 

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

    glVertexAttribPointer(0 ,3 ,GL_FLOAT ,GL_FALSE ,3* sizeof(GLfloat) ,(GLvoid*)0); 
    glEnableVertexAttribArray(0); 

    glBindBuffer(VBO,0); 

    glBindVertexArray(0); 
} 

GLuint Renderer::createVertexShader(GLuint &shader){ 
    const GLchar* vertexShaderSource= 
     "#version 330 core\n" 
     "layout (location = 0) in vec3 position;\n" 
     "void main(){\n" 
     " gl_Position= vec4(position.x ,position.y ,position.z ,1.0);\n" 
     "}"; 

    vertexShader =glCreateShader(GL_VERTEX_SHADER); 

    glShaderSource(vertexShader ,1 , &vertexShaderSource ,NULL); 
    glCompileShader(vertexShader); 

    GLint success; 
    GLchar info[512]; 
    glGetShaderiv(vertexShader ,GL_COMPILE_STATUS ,&success); 

    if(!success){ 
     glGetShaderInfoLog(vertexShader,512 ,NULL ,info); 
     std::cout<<"couldn't compile shader :(/n" << info <<std::endl; 
    } 

    return vertexShader; 
} 

GLuint Renderer::createFragmentShader(GLuint &shader){ 
    const GLchar* fragmentShaderSource= 
     "#version 330 core\n" 
     "out vec4 color;\n" 
     "void main(){\n" 
     " color=vec4(1.0 ,0.5 ,0.2 ,0);\n" 
     "}";  

    fragmentShader =glCreateShader(GL_FRAGMENT_SHADER); 

    glShaderSource(fragmentShader ,1 ,&fragmentShaderSource ,NULL); 
    glCompileShader(fragmentShader); 

    GLint success; 
    GLchar info[512]; 
    glGetShaderiv(fragmentShader ,GL_COMPILE_STATUS ,&success); 

    if(!success){ 
     glGetShaderInfoLog(fragmentShader,512 ,NULL ,info); 
     std::cout<<"couldn't compile shader :(\n" << info << "\n" << std::endl; 
    } 

    return fragmentShader; 
} 

void Renderer::createShaderProgram(GLuint &program){ 
    program =glCreateProgram(); 

    glAttachShader(program ,createVertexShader(vertexShader)); 
    glAttachShader(program ,createFragmentShader(fragmentShader)); 
    glLinkProgram(program); 

    GLint success; 
    GLchar info[512]; 

    glGetProgramiv(program ,GL_LINK_STATUS ,&success); 

    if(!success){ 
     glGetProgramInfoLog(program,512 ,NULL ,info); 
     std::cout<<"couldn't link program :(\n" << info << "\n" << std::endl; 
    } 

    glDeleteShader(vertexShader); 
    glDeleteShader(fragmentShader); 
} 

хорошо, код отлично работает, если я не использую конструктор класса Renderer и просто использовать функцию инициализации(), если я использовал конструктор вместо (после раскомментировав Init() и комментирования renderer.init ()) программа аварии.

основная функция заключается в отдельном классе и все это делает называют ScreenManager визуализации функции в цикле

+4

Вам нужно будет показать код (например, функцию main()), которая фактически создает экземпляр Renderer и/или вызывает функцию init(). Попробуйте предоставить наименьший полный компилируемый пример кода, который иллюстрирует вашу проблему (в настоящее время вы включили много потенциально отвлекающих вещей, которые будут отвлекать людей, пытающихся помочь). Также нет законного способа, которым код может избежать использования конструктора Renderer перед вызовом init() - поэтому ваше описание подсказывает, что вы не указали соответствующую информацию. – Rob

+0

Я получил его сейчас, когда я вызывал конструктор Renderer (в ScreenManager.h), прежде чем фактически инициализировать opengl в конструкторе ScreenManager: D –

ответ

0

При вызове init в конструкторе, он вызывается во время строительства члена ScreenManager «s, который происходит до того, как выполняется тело конструктора ScreenManager.

В этот момент OpenGL еще не был инициализирован, поэтому вы терпите крах.

+0

oooooooooooh, теперь я понял, почему я не думаю, что это просто: P, спасибо, что вы помогли лот: D –

Смежные вопросы