2016-05-25 9 views
-2

В настоящее время я работаю над небольшим редактором для игрового движка, который я пишу. Я создал меню файлов с Qt 5.6, в котором есть возможность добавить модель, которая создает новую модель и добавляет ее в менеджер движка рендеринга. В Mac OSX 10.11 (с OpenGL 3 или 4) это работает отлично. На Ubuntu 16.04 он работает только немного. Я могу инициализировать столько моделей, сколько хочу, за пределами основного цикла. Однако внутри основного цикла я могу только инициализировать столько моделей, сколько я инициализировал вне основного цикла. Когда я поднимаю gdb внутри своей IDE, проблема, похоже, связана с VAO. В OSX новое VAO инициализируется для каждой модели независимо от того, где я создаю сетку. На Ubuntu, за пределами основного цикла, новые VAO создаются для каждой сетки. Внутри основного цикла сетки, которые рисуют все, имеют то же самое VAO, что и ранее созданная сетка вне основного цикла. Как только я создаю больше моделей, чем созданные за пределами основного цикла, и создается новое VAO, модель не рисует.glGenVertexArrays Не создает уникальный VAO, когда в основном цикле, но работает иначе

Подводя итог, в Ubuntu все модели вне основного контура получают свое собственное VAO. Внутри основного контура ручка VAO GLuint начинает пересчитывать из 2 снова. Как только метка/метка проходит мимо, однако многие модели были инициализированы вне основного цикла, модели перестают рисовать. Он отлично работает с Mac OSX. Я подозреваю, что это проблема OpenGL/Qt, поэтому, несмотря на то, что для двигателя есть много дополнительного кода, я думаю, что вопрос справедливый. Ссылка: https://github.com/BennetLeff/engine

Поскольку существует немало файлов, я буду включать только то, что, по моему мнению, необходимо, но я также свяжусь с проектом github. Извините за большой свалку кода, но скажите мне, есть ли что-нибудь еще, что я могу предоставить.

Mesh.cpp

#include "Mesh.h" 
#include "Transform.h" 

#include <stdio.h> 

Mesh::Mesh(std::vector<glm::vec3> vertices, std::vector<glm::vec3> normals, std::vector<glm::vec2> textures, std::vector<GLuint> indices) 
{ 
    drawCount_ = indices.size(); 

    glGenVertexArrays(1, &vertexArrayObject_); 
    glBindVertexArray(vertexArrayObject_); 

    glGenBuffers(NUMBUFFERS, vertexBufferObject_); 

    // Position Attrib 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject_[POSITION_VB]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(), GL_STATIC_DRAW); 
    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    // Texture Attrib 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject_[TEXCOORD_VB]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(textures[0]) * textures.size(), textures.data(), GL_STATIC_DRAW); 
    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); 

    // Normals Attrib 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject_[NORMAL_VB]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(normals[0]) * normals.size(), normals.data(), GL_STATIC_DRAW); 
    glEnableVertexAttribArray(2); 
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexBufferObject_[INDEX_VB]); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(), GL_STATIC_DRAW); 

    glBindVertexArray(0); 

    fprintf(stderr, "vao val %d\n", vertexArrayObject_); 
} 

Mesh::~Mesh() 
{ 
    glDeleteVertexArrays(1, &vertexArrayObject_); 
} 

void Mesh::draw() 
{ 
    glBindVertexArray(vertexArrayObject_); 
    glDrawElements(GL_TRIANGLES, drawCount_, GL_UNSIGNED_INT, 0); 
    glBindVertexArray(0); 
    if (glGetError()) 
     printf("GL error %d", glGetError()); 
} 

main.cpp

#include <stdio.h> 

#ifdef __APPLE__ 
    #include <OpenGL/gl3.h> 
#else 
    #include <GL/glew.h> 
#endif 

#include "Camera.h" 
#include "Model.h" 

#include "Editor.h" 
#include "RenderEngine.h" 

#include <QApplication> 

bool quit = false; 

int main(int argc, char* argv[]) 
{ 
    auto WIDTH = 1024; 
    auto HEIGHT = 800; 

    /* 
    * Sets up a QApplication 
    * with the proper formatting. This allows 
    * GL versions to be set and so forth. Then 
    * the QApplication is polled in the main loop 
    * for events. 
    */ 

    QApplication app(argc, argv); 
    QSurfaceFormat format; 
    format.setSamples(16); 
    format.setDepthBufferSize(24); 
    format.setStencilBufferSize(8); 
    format.setVersion(4, 3); 
    format.setProfile(QSurfaceFormat::CoreProfile); 
    QSurfaceFormat::setDefaultFormat(format); 

    // Sets up Rendering Engine and Editor. 
    auto cam = new Camera(glm::vec3(0, 6, -20), 70.0f, (float) WIDTH/(float) HEIGHT, 0.01f, 1000.0f); 
    RenderEngine* engine = new RenderEngine(cam); 
    Editor editor(engine, WIDTH, HEIGHT); 

    editor.showEditor(); 

    /* 
    * Must call Editor.show() before any other 
    * OpenGL calls. This is mostly because of Qt. 
    */ 
    // auto house = Model("./res/farm house/OBJ/Farmhouse OBJ.obj", "./res/farm house/Textures/Farmhouse Texture.jpg"); 
    // house.transform->getPosition()->z = 40; 

    // auto model = Model("./res/Alfred/Alfred.obj", "./res/Alfred/alfred_dif.png"); 
    // auto model2 = Model("./res/Alfred/Alfred.obj", "./res/Alfred/alfred_dif.png"); 

    float counter = 0.0f; 

    while (editor.isVisible()) 
    { 
     app.processEvents(); 
     // model.transform->getRotation()->y = float(editor.getSliderValue())/10; 
     // model.transform->getPosition()->z = editor.getManValue(); 
     counter += 0.1f; 

     /* 
     * Just updating window for now because 
     * it may be faster. Need to benchmark this 
     * and determine what is necessary. 
     */ 
     editor.getWindow()->update(); 
    } 

    return 0; 
} 

GUIWindow.cpp (наследует от QOpenGLWidget, QOpenGLFunctions)

#include <GL/glew.h> 
#include "GUIWindow.h" 

GUIWindow::GUIWindow(QWidget* parent, RenderEngine* engine) : 
    QOpenGLWidget(parent), engine(engine) { } 

void GUIWindow::initializeGL() 
{ 
    // Set up the rendering context, load shaders and other resources, etc.: 
    initializeOpenGLFunctions(); 

    // If not on OSX we need to include 
    // OpenGL as an extension 
    #ifndef __APPLE__ 
     glewExperimental = GL_TRUE; 

     GLenum err = glewInit(); 
     if (GLEW_OK != err) { 
      /* Problem: glewInit failed, something is seriously wrong. */ 
      fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); 
     } 
    #endif 

    // Depth test not enabled by default. 
    glEnable(GL_DEPTH_TEST); 
} 

void GUIWindow::resizeGL(int w, int h) { } 

void GUIWindow::paintGL() 
{ 
    // Draw the scene 
    clear(0.1, 0.4, 0.6, 1.0); 

    // Draw all Models 
    engine->draw(); 
} 

void GUIWindow::clear(float r, float g, float b, float a) 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
    glClearColor(r, g, b, a); 
} 

GUIWindow::~GUIWindow() { } 

model.cpp (за исключением загрузки модели, которая просто получает данные от AssImp)

void Model::draw(Camera* cam) 
{ 
    shader.draw(); 
    shader.update(transform, cam); 
    tex.bind(0); 
    modelMesh->draw(); 
} 

void Model::bindTexture(Texture tex) 
{ 
    this->tex = tex; 
} 

RenderingEngine.cpp

#include "RenderEngine.h" 

RenderEngine::RenderEngine(Camera* cam) 
    : cam(cam) 
{ 
    this->init(); 
} 

void RenderEngine::init() 
{ 
    // If not on OSX we need to include 
    // OpenGL as an extension 
    #ifndef __APPLE__ 
     glewExperimental = GL_TRUE; 

     GLenum err = glewInit(); 
     if (GLEW_OK != err) { 
      /* Problem: glewInit failed, something is seriously wrong. */ 
      fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); 
     } 

     glEnable(GL_DEPTH_TEST); 
    #endif 
} 

void RenderEngine::addModel(Model model) 
{ 
    printf("added model \n"); 
    this->models.push_back(model); 
    for (int i = 0; i < this->models.size(); i++) 
     printf("Model Pos: (%g, %g, %g) \n", models[i].transform->getPosition()->x, 
       models[i].transform->getPosition()->y, 
       models[i].transform->getPosition()->z); 
    printf("there are %d models now \n", this->models.size()); 
} 

void RenderEngine::draw() 
{ 
    for (int i = 0; i < this->models.size(); i++) 
     models[i].draw(this->cam); 
} 

Editor.cpp (минус большинство Qt вызовов, которые только что создали окно)

#include "Editor.h" 

Editor::Editor(RenderEngine* renderEngine, int width, int height) 
{ 
    frame = 0; 
    this->width = width; 
    this->height = height; 
    this->engine = renderEngine; 
    this->window = new GUIWindow(0, renderEngine); 
} 

void Editor::initialize() 
{ 
    // Set up the rendering context, load shaders and other resources, etc.: 
    // initializeOpenGLFunctions(); 
    glViewport(0, 0, width, height); 
    setupWidgets(); 
} 


float Editor::getRandNum() 
{ 
    srand(time(0)); 
    float num = rand() % 10 + 1; 
    fprintf(stderr, "%d \n", num); 
    return num; 
} 

void Editor::addModelToScene() 
{ 
    srand (time(NULL)); 

    auto trans = new Transform(); 
    trans->getPosition()->x = rand() % 10 + 1; 
    trans->getPosition()->y = rand() % 10 + 1; 
    trans->getPosition()->z = rand() % 10 + 1; 
    engine->addModel(Model("./res/Alfred/Alfred.obj", "./res/Alfred/alfred_dif.png", trans)); 
    fprintf(stderr, "Add a Model \n"); 
} 

void Editor::showEditor() 
{ 
    // Sets up the rest of the widgets locations. 
    setupWidgets(); 
    // Sets up the QMainWindow. 
    this->show(); 
} 

void Editor::addModel(Model model) 
{ 
    engine->addModel(model); 
} 

ответ

1

Я не знаю, почему я был вниз проголосовали, но я В конце концов выяснилось, что проблема. В Editor::addModelToScene() Мне нужно было позвонить window.makeCurrent() прямо перед тем, как я позвонил addModel(). У меня нет идеи, почему это будет работать на OSX независимо. Также спасибо this answer за то, что он дал мне идею попробовать это.