2014-10-10 40 views
0

因此,我正尝试在C++中使用GLFW和GLEW编写一个简单的3D渲染引擎。但是该程序在glDrawArrays(GL_TRIANGLES, 0, model.indicesCount);调用中崩溃。我很确定我做错了什么,但我无法弄清楚需要改变/改变的地方或者什么。我实际上是从Java重写了一个完美的工作引擎。openGL在glDrawArrays上未处理的异常(GL_TRIANGLES,0,model.indicesCount);请致电

我的代码:

COMMON.H:

#ifndef _COMMON 
#define _COMMON 

// standard stuff 
#include <iostream> 
#include <list> 

// openGL stuff 
#include "GL\glew.h" 
#include "GLFW\glfw3.h" 

// my stuff 
#include "DisplayManager.h" 
#include "RawModel.h" 
#include "Loader.h" 
#include "Renderer.h" 

#endif 

DisplayManager.h:

#pragma once 

#include "common.h" 

class DisplayManager{ 
private: 
    GLFWwindow* window; 
public: 
    void create(int width = 1280, int height = 720, std::string title = "Untitled"){ 
     if(!glfwInit()){ 
      std::cerr << "GLFW init failed\n"; 
      system("pause"); 
      exit(EXIT_FAILURE); 
     } 

     glfwWindowHint(GLFW_SAMPLES, 4); 
     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 
     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
     window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL); 
     glfwMakeContextCurrent(window); 

     if(!window){ 
      std::cerr << "Failed to create a window\n"; 
      system("pause"); 
      exit(EXIT_FAILURE); 
     } 

     glewExperimental = GL_TRUE; 
     if(glewInit() != GLEW_OK){ 
      std::cerr << "GLEW init failed\n"; 
      system("pause"); 
      glfwTerminate(); 
      exit(EXIT_FAILURE); 
     } 
    } 

    void update(){ 
     glfwSwapBuffers(window); 
     glfwPollEvents(); 
    } 

    int isCloseRequested(){ 
     return glfwWindowShouldClose(window); 
    } 

    void close(){ 
     glfwDestroyWindow(window); 
     glfwTerminate(); 
    } 

}; 

RawModel.h:

#pragma once 

struct RawModel{ 

public: 
    GLuint vaoID; 
    GLuint indicesCount; 

    RawModel(GLuint vaoID, GLuint indicesCount){ 
     this->vaoID = vaoID; 
     this->indicesCount = indicesCount; 
    } 

}; 

Loader.h:

#pragma once 

#include "common.h" 

#define VERTEX_ATTRIB_INDEX 0 
#define VERTEX_SIZE 3 

class Loader{ 
public: 
    // functions 
    RawModel loadModel(const GLfloat vertices[], GLuint verticesCount){ 
     GLuint vaoID = createAndBindVao(); 
     storeFloatDataInVAO(VERTEX_ATTRIB_INDEX, vertices, verticesCount, VERTEX_SIZE); 
     unbindVAO(); 
     return RawModel(vaoID, verticesCount); 
    } 

    void cleanUp(){ 
     std::list<GLuint>::iterator vao_it = vaos.begin(); 
     for(; vao_it != vaos.end(); ++vao_it){ 
      const GLuint vao = *vao_it; 
      glDeleteVertexArrays(1, &vao); 
     } 

     std::list<GLuint>::iterator vbo_it = vbos.begin(); 
     for(; vbo_it != vbos.end(); ++vbo_it){ 
      const GLuint vbo = *vbo_it; 
      glDeleteBuffers(1, &vbo); 
     } 
    } 
private: 
    // variables 
    std::list<GLuint> vaos; 
    std::list<GLuint> vbos; 

    // functions 
    GLuint createAndBindVao(){ 
     GLuint vaoID; 
     glGenVertexArrays(1, &vaoID); 
     vaos.push_back(vaoID); 
     glBindVertexArray(vaoID); 
     return vaoID; 
    } 

    void storeFloatDataInVAO(const GLuint attributeIndex, const GLfloat data[], const GLuint dataLength, const GLuint chunkSize){ 
     GLuint vboID; 
     glGenBuffers(1, &vboID); 
     vbos.push_back(vboID); 
     glBindBuffer(GL_VERTEX_ARRAY, vboID); 
     glBufferData(GL_VERTEX_ARRAY, sizeof(GLfloat) * dataLength * chunkSize, data, GL_STATIC_DRAW); 
     glVertexAttribPointer(attributeIndex, chunkSize, GL_FLOAT, GL_FALSE, 0, (void*)0); 
     glBindBuffer(GL_VERTEX_ARRAY, 0); 
    } 

    void unbindVAO(){ 
     glBindVertexArray(0); 
    } 
}; 

Renderer.h:

#pragma once 

#include "common.h" 

#define BLACK 0.0f, 0.0f, 0.0f, 1.0f 
#define WHITE 1.0f, 1.0f, 1.0f, 1.0f 
#define RED  1.0f, 0.0f, 0.0f, 1.0f 
#define GREEN 0.0f, 1.0f, 0.0f, 1.0f 
#define BLUE 0.0f, 0.0f, 1.0f, 1.0f 
#define YELLOW 1.0f, 1.0f, 0.0f, 1.0f 

class Renderer{ 
public: 
    void prepare(){ 
     glClear(GL_COLOR_BUFFER_BIT); 
     glClearColor(YELLOW); 
    }; 

    void render(RawModel model){ 
     glBindVertexArray(model.vaoID); 
     glEnableVertexAttribArray(VERTEX_ATTRIB_INDEX); 
     glDrawArrays(GL_TRIANGLES, 0, model.indicesCount); 
     glDisableVertexAttribArray(VERTEX_ATTRIB_INDEX); 
     glBindVertexArray(0); 
    } 
}; 

,并与主要功能的Source.cpp:

#include "common.h" 

static const GLfloat VERTICES[] = { 
// X  Y  Z 
    -0.5f, 0.5f, 0, 
    -0.5f, -0.5f, 0, 
    0.5f, 0.5f, 0 
}; 

int main(){ 

    DisplayManager display; 
    display.create(); 

    Loader loader; 
    RawModel model = loader.loadModel(VERTICES, 3); 

    Renderer renderer; 

    // main loop 
    while(!display.isCloseRequested()){ 
     renderer.prepare(); 
     renderer.render(model); 
     display.update(); 
    } 

    loader.cleanUp(); 
    display.close(); 
    return EXIT_SUCCESS; 
} 

如果我注释掉它接缝要工作glDrawArrays(GL_TRIANGLES, 0, model.indicesCount);,我也得到一个绿色的窗口。

回答

3

的错误是在这里:

glBindBuffer(GL_VERTEX_ARRAY, vboID); 
    glBufferData(GL_VERTEX_ARRAY, sizeof(GLfloat) * dataLength * chunkSize, data, GL_STATIC_DRAW); 
    glVertexAttribPointer(attributeIndex, chunkSize, GL_FLOAT, GL_FALSE, 0, (void*)0); 
    glBindBuffer(GL_VERTEX_ARRAY, 0); 

GL_VERTEX_ARRAY不是在OpenGL有效的缓冲区的目标,正确的是GL_ARRAY_BUFFER。因此,这些命令都应该生成GL错误。 attrib指针函数将生成GL_INVALID_OPERATION,因为在调用时没有绑定GL_ARRAY_BUFFER,所以其他应该只生成GL_INVALID_ENUM。现在基本上有一个未初始化的顶点属性指针,您稍后启用该属性数组并尝试从其中绘制,导致崩溃。

另一件事:我没有看到代码中的任何着色器。着色器在您使用的核心配置文件中是强制性的。现在glDrawElements()实际上应该失败,虽然一些实现者忽略了这一点,并在这种情况下使用一些平凡的着色器。

+0

非常感谢!我想我需要更多地关注我的代码。至于着色器,我确实拥有它们,而且我使用'glDrawElements()'使用索引,我只是将代码划分到最低限度(无法发布大量代码)。在投票结束后,我实际上已经失去了希望。再次感谢你! – 2014-10-10 23:48:53