2017-01-13 15 views
0

私は最新のOpenGLを学び、キューブ、球体などのさまざまなプリミティブ型のクラスを作成しようとしています。ただし、キューブクラスがDraw()関数で何もレンダリングしない問題に遭遇しましたが、私はすべてそれを私のmain()機能にうまく動作するように動かす。クラスのOpenGLオブジェクトをレンダリングしますか?

#include "cube.h" 

#include <iostream> 
GLuint Cube::indexArr[36] = { 
    0, 1, 2, // front face 
    2, 3, 1, 
    4, 5, 6, 
    6, 7, 4, 
    7, 3, 0, 
    0, 4, 7, 
    6, 2, 1, 
    1, 5, 6, 
    0, 1, 5, 
    5, 4, 0, 
    3, 2, 6, 
    6, 7, 3 
}; 

bool Cube::cubeSetUp = false; 
GLuint Cube::cubeVBO = 0; 
GLuint Cube::cubeVAO = 0; 
GLuint Cube::cubeEBO = 0; 

Cube::Cube() 
{ 
    if (!cubeSetUp) 
     SetUpCube(); 

    //define the 8 vertices that make up a cube 
    objectVerts = new GLfloat[24] { 
     -0.5f, -0.5f, -0.5f, // front bottom left 0 
     0.5f, -0.5f, -0.5f, // front bottom right 1 
     0.5f, 0.5f, -0.5f, // front top right 2 
     -0.5f, 0.5f, -0.5f, // front top left  3 
     -0.5f, -0.5f, 0.5f, // back bottom left 4 
     0.5f, -0.5f, 0.5f, // back bottom right 5 
     0.5f, 0.5f, 0.5f, // back top right  6 
     -0.5f, 0.5f, 0.5f // back top left  7 
    }; 
} 

void Cube::Draw() 
{ 
    glBindVertexArray(cubeVAO); 

    //GLfloat modelMatrix[16]; 
    //transform.affine.ConvertToOpenGLMatrix(modelMatrix); 

    //glUniformMatrix4fv(modelMatrixLoc, 1, GL_FALSE, modelMatrix); 

    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); 
    glBindVertexArray(0); 
} 


void Cube::SetUpCube() 
{ 
    cubeSetUp = true; 
    glGenVertexArrays(1, &cubeVAO); 
    glGenBuffers(1, &cubeVBO); 
    glGenBuffers(1, &cubeEBO); 

    glBindVertexArray(cubeVAO); 

    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(objectVerts), objectVerts, GL_STATIC_DRAW); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cubeEBO); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexArr), indexArr, GL_STATIC_DRAW); 

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

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 
} 

コードcube.hのために:ここで

はcube.cppのためのコードです

#ifndef __CUBE__H_ 
#define __CUBE__H_ 

#include "scene_object.h" 

class Cube : public SceneObject 
{ 
    public: 
     /*************** 
     * Constructor * 
     ***************/ 
     Cube(); 

     /*********************** 
     * Overloaded Function * 
     ***********************/ 
     void Draw(); 

    private: 
     static GLuint indexArr[36]; 
     static bool cubeSetUp; 
     static GLuint cubeVBO, cubeVAO, cubeEBO; 

     void SetUpCube(); 
}; 

#endif 

私が何か間違ったことをやっていますか? OpenGLはインデックス配列に静的配列を使用することに同意しないのですか?私は、要素バッファオブジェクトを取り除き、ちょうどglDrawArrays(...)を使用してみましたが、動作しませんでした。必要に応じて、メインのコードも提供できます。

また、頂点シェーダは何もしていません。それはちょうど頂点情報を受け取り、それをgl_Positionに与えます。

ありがとうございました。 main.cppため

コード:

#define GLEW_STATIC 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 

#include <iostream> 
#include <fstream> 
#include <string> 

#include "shader.h" 
#include "cube.h" 
#include "camera.h" 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    if (argc != 3) 
    { 
     cout << "Incorrect number of arguments!" << endl; 
     cout << "Usage: [executable] vertexShader fragmentShader" << endl; 
     return -1; 
    } 

    glfwInit(); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 

    GLFWwindow* window = glfwCreateWindow(800, 600, "Scene Description Language Generator", nullptr, nullptr); 
    if (window == nullptr) 
    { 
     std::cout << "Failed to create the GLFW window" << std::endl; 
     glfwTerminate(); 
     return -1; 
    } 

    glfwMakeContextCurrent(window); 
    glewExperimental = GL_TRUE; 
    if (glewInit() != GLEW_OK) 
    { 
     std::cout << "Failed to initialize GLEW" << std::endl; 
     return -1; 
    } 

    glEnable(GL_DEPTH_TEST); 

    int width, height; 
    glfwGetFramebufferSize(window, &width, &height); 

    glViewport(0, 0, width, height); 

    Shader shader(argv[1], argv[2]); 

    Cube c; 

    GLuint modelMat = glGetUniformLocation(shader.GetProgram(), "model"); 

    c.SetModelMatrixLoc(modelMat); 

    while (!glfwWindowShouldClose(window)) 
    { 
     glfwPollEvents(); 

     glClearColor(0.2f, 0.3f, 0.3f, 1); 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     shader.Use(); 
     c.Draw(); 

     glfwSwapBuffers(window); 
    } 

    glfwTerminate(); 
    return 0; 
} 

編集:見て価値がある場合、main.cppにしてcube.hためのコードを追加しました。

+0

すべてのコードを投稿してください。部品が動作するとは思わないでください。また、OpenGLはあなたのプログラムにデータをどこに格納するか気にしません。 – xaxxon

+3

'objectVerts'はどこに定義されていますか?これがポインタの場合、 'sizeof'演算子はあなたが望むことをしません。また、VBOを初期化するために使用した後に、 'objectVerts' *のデータを設定します。 – BDL

+0

コンストラクタにOpenGLコードを入れないでください。コンテキストが作成される前に呼び出すことができます。 – pleluron

答えて

1

少なくとも2つは間違っています。

最初に、プレリュロンによって指摘されるように、キューブコンストラクタは、アプリケーションウィンドウとGLコンテキストが作成される前に呼び出されます。古いシステムでは、これは通常クラッシュします。現代のコンピュータでは、おそらくウィンドウシステムによって作成されたデフォルトのGLコンテキストがあるので、そのためにキューブが作成されます。次に、アプリケーションが独自のウィンドウとコンテキストを作成し、キューブが孤立します。

OpenGLの "オブジェクト"を作成するのは、指定された方法でのみ行う必要があります。 Qtでは、ビューのsetupGLメソッドです。MacOS Cocoaでは、prepareOpenGLです。最初のウィンドウが描画される他のシステムです。

第2の問題は、BDLが指摘しているように、sizeof(objectVerts)は、あなたが思うようなことをしないということです。 printステートメントが表示されます。

第3の問題は、glGetError()を呼び出さないということです。 OpenGLは何か間違ったことをしても例外を投げず、しばしばクラッシュしません。代わりに何もしません。各重要な関数やメソッドの最後にglGetError()を呼び出すという習慣を開発して、すべてがOKであることを確認してください。エラーが発生した場合は、より多くのglGetErrors()を入れて原因を絞り込みます。

+0

VBOの設定後に 'objectVerts'を初期化してBDLが私に言ったことと一緒に私の問題を解決しました。ありがとうございました! – kcatt

関連する問題