代码之家  ›  专栏  ›  技术社区  ›  Makka

OpenGL简单VBO故障

  •  2
  • Makka  · 技术社区  · 10 年前

    我没能用VBO画画。

    Iv成功地使用了这段代码来绘制顶点数组,但当我尝试将它弹出到vbo中并绘制它时,我得到的只是一个空白的白色屏幕。

    Iv尝试将vbo的初始化添加到gluitit函数,但这会导致中断。Iv还尝试在一个单独的函数中调用VBO初始化一次,以查看是否多次调用VBO会导致问题,Iv还将我的项目简化为仅渲染此函数,以查看这是否可行;但是,唉,我还是在白屏幕上脱颖而出。

    • 只是一个提示,我已经了解到这可能与我的卡驱动程序不支持>有关;OGL 2.0(我很幸运,我的代码没有任何问题,事实就是如此)

      float f[] = {0, 2, -4, -2, -2, -4, 2, -2, -4};
      GLuint vbo;
      
      void DisplayGL()  // the update display callback?
      {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear out the stuff from the old window.     
      
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      
      //translate and rotate SWAP X AND Y DERP
      glRotatef(camera->rot.x, 0.0f, 1.0f, 0.0f); // deg, xflag, yflag, zflag
      glRotatef(camera->rot.y, 1.0f, 0.0f, 0.0f); // deg, xflag, yflag, zflag
      glTranslatef(camera->pos.x, camera->pos.y, camera->pos.z); // move us back a bit
      
      glGenBuffers(1, &vbo); // make a buffer
      glBindBuffer(GL_ARRAY_BUFFER, vbo); // bind the buffer - type, buffer add
      glBufferData(GL_ARRAY_BUFFER, sizeof(f), f, GL_STATIC_DRAW); //type, size of the data, the data, flag (GL_A_B)
      
      glBindBuffer(GL_ARRAY_BUFFER, vbo); // rebind?
      
      glEnableClientState(GL_VERTEX_ARRAY); // enable the client state 
      
      glVertexPointer(3, GL_FLOAT, sizeof(float), 0); // how may elemets per vertex, data type, how many bytes between vertex, starting point of data
      
      glDrawArrays(GL_TRIANGLES, 0, 3); // draw type, starting point (vertex), how many vertex
      
      glDisableClientState(GL_VERTEX_ARRAY); // disable the client state
      
      // render some text
      std::string text = "Mouse x, y: " + std::to_string(testx) + ", " + std::to_string(testy);
      drawText(text.data(), text.length(), 0, 575);
      
      text = "Cam x, y rotation: " + std::to_string(camera->rot.x) + ", " + std::to_string(camera->rot.y);
      drawText(text.data(), text.length(), 0, 560);
      
      glutSwapBuffers(); // swap our active buffer to our unactive buffer
      

      }

    -另一个快速问题是,我使用GLM(opengl数学库)。我想知道是否可以使用glm::vec3的向量来代替浮点数的数组或向量。如果可以的话,您需要告诉openGL使用glm::vec3数据类型中的数据吗?我只问,因为它的数据在一个结构中,并且在for循环中是这样访问的 (*i).x ……等不可访问,如标准数组或浮点数矢量,如: (*i)

    编辑-

    以下是问题的主要原因:

    #include <iostream>
    #include <vector>
    
    #include "..\..\externals\glm\glm\glm.hpp" // openGL Math header.
    #include <gl/glew.h> // include glew depend's
    #define FREEGLUT_STATIC     // defign the lib for glut
    #include <gl/freeglut.h> // include glut
    
    int g_iWindowWidth = 800; // our global window width and height
    int g_iWindowHeight = 600;
    
    int g_hWindowHandle = 0;  // out handler for our main window
    
    void initGLUT(int argc, char* argv[]);  // the initalise func for glut
    
    //call back funcs
    void DisplayGL();  // the update display func callback's
    void IdleGL(); // idle function
    
    GLuint vbo;
    std::vector< glm::vec3 > verts;
    
    void makeVbo();
    
    int main(int argc, char* argv[])
    {
        verts.push_back(glm::vec3(0, 2, -4));
        verts.push_back(glm::vec3(-2, -2, -4));
        verts.push_back(glm::vec3(2, -2, -4));
    
        initGLUT(argc, argv); // initalise glut
        makeVbo(); // ***no matter where this is placed, i get a break or a white screen?***
        glutMainLoop(); // run our grafix
    }
    
    void initGLUT(int argc, char* argv[])
    {
        glutInit(&argc, argv); // initalise the widow with out global params
    
        glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); // when we close the window return to the main func or previous func
    
        int iScreenWidth = glutGet(GLUT_SCREEN_WIDTH); // our window W and H
        int iScreenHeight = glutGet(GLUT_SCREEN_HEIGHT);
    
        glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH); // rgb with alpha and a depth to our view
    
        glutInitWindowPosition((iScreenWidth - g_iWindowWidth) / 2, (iScreenHeight - g_iWindowHeight) / 2); // set the window pos on screen
        glutInitWindowSize(g_iWindowWidth, g_iWindowHeight); // windwow size
    
        g_hWindowHandle = glutCreateWindow("My OpenGL Template!"); // title & our window_H
    
        glutDisplayFunc(DisplayGL); // bind callback functions
        glutIdleFunc(IdleGL);
    
        glEnable(GL_DEPTH_TEST);
    }
    
    void DisplayGL()  // the update display func callback?
    {
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear out the stuff from the old window.
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        //translate
    
        glTranslatef(0, 0,-6); // move us back a bit
    
        glEnableClientState(GL_VERTEX_ARRAY);
    
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glVertexPointer(3, GL_FLOAT, 0, 0);
    
        glDrawArrays(GL_TRIANGLES, 0, 3);
    
        glDisableClientState(GL_VERTEX_ARRAY);
    
        glutSwapBuffers(); // swap our active buffer to our unactive buffer
    }
    void IdleGL() // logic here
    {
        glutPostRedisplay(); // redrawwindow
    }
    void makeVbo()
    {
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData
            (
            GL_ARRAY_BUFFER,
            sizeof(glm::vec3) * verts.size(),
            &verts[0],
            GL_STATIC_DRAW
            );
    }
    

    编辑2- 一整天都在看这个,到处乱摸。似乎很多评论都说要调用glewinit();在进行vbo之前,请确保gl调用指针正确。

    void makeVbo()
    {
    
        glewInit();
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData
            (
            GL_ARRAY_BUFFER,
            sizeof(glm::vec3) * verts.size(),
            &verts[0],
            GL_STATIC_DRAW
            );
    }
    

    如果它在主窗口内调用,如我之前的编辑所示,现在就可以了,但屏幕是一个没有绘制对象的空白黑色窗口?in尝试用我的“相机”四处移动,但在视口中任何地方都看不到它?

    编辑3- 我唯一注意到的代码之间的不同之处是我们看待世界的方式。您正在使用 glortho(...); 当我使用 gltranslatef(...); 在我把它改出来之后,我让它在屏幕上呈现:

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-5, 5, -5, 5, -5, 5);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render...
    

    所以,我现在的问题是,为什么它在数组循环中渲染良好,而在VBO中渲染不好 glTranslatef(...); ?

    编辑4-最终解决方案 我似乎没有使用透视图来正确设置一个,经过一点挖掘和玩了一下iv交换 glOrtho(...); 具有 gluPerspective(45, g_iWindowWidth / g_iWindowHeight, 1.0, 500.0); 然后在模型视图中执行我的相对翻译,简而言之,这给了我想要的。-看到我还有很多书要读:)

    1 回复  |  直到 10 年前
        1
  •  2
  •   genpfault    10 年前
    glVertexPointer(3, GL_FLOAT, sizeof(float), 0);
                                 ^^^^^^^^^^^^^
    

    您的顶点数据被紧密压缩,因此 stride 应该是 0 .

    drawText() 可能会破坏你的状态;没办法知道。

    类似于:

    screenshot

    #include <GL/glew.h>
    #include <GL/glut.h>
    #include <glm/glm.hpp>
    #include <vector>
    
    GLuint vbo = 0;
    void init()
    {
        std::vector< glm::vec3 > verts;
        verts.push_back( glm::vec3( 0, 2, -4 ) );
        verts.push_back( glm::vec3( -2, -2, -4 ) );
        verts.push_back( glm::vec3( 2, -2, -4 ) );
    
        glGenBuffers( 1, &vbo );
        glBindBuffer( GL_ARRAY_BUFFER, vbo );
        glBufferData
            ( 
            GL_ARRAY_BUFFER, 
            sizeof( glm::vec3 ) * verts.size(), 
            &verts[0], 
            GL_STATIC_DRAW 
            ); 
    }
    
    void display()
    {
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    
        glMatrixMode( GL_PROJECTION );
        glLoadIdentity();
        glOrtho( -5, 5, -5, 5, -5, 5 );
    
        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();
    
        glEnableClientState( GL_VERTEX_ARRAY );
    
        glBindBuffer( GL_ARRAY_BUFFER, vbo );
        glVertexPointer( 3, GL_FLOAT, 0, 0 );
    
        glDrawArrays( GL_TRIANGLES, 0, 3 );
    
        glDisableClientState( GL_VERTEX_ARRAY );
    
        glutSwapBuffers();
    }
    
    int main( int argc, char **argv )
    {
        glutInitWindowSize( 600, 600 );
        glutInit( &argc, argv );
        glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
        glutCreateWindow( "GLUT" );
        glewInit();
    
        glutDisplayFunc( display );
        init();
        glutMainLoop();
        return 0;
    }
    

    我想知道是否可以使用glm::vec3的向量来代替浮点数的数组或向量。

    是的。参见示例。

    如果可以的话,您需要告诉openGL使用glm::vec3数据类型中的数据吗?

    不。