2014-10-10 37 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