Необработанное исключение в 0x00000000 glGenBuffer при попытке использовать lib3ds с opengl - PullRequest
0 голосов
/ 21 июня 2011

Я начинающий, так со мной здесь, мне нравится загружать 3ds модель в простую программу opengl, я использовал только ссылки, которые нашел:
http://pastebin.com/CZ82VYWT и http://www.donkerdump.nl/node/207 Я беру код из Красного учебника на примере куба и пытался переключиться между 2
, но все время получаю исключение Unhandled с исключением 0x00000000 glGenBuffer.в методе CModel3DS :: CreateVBO () вот мой код:

// main.cpp
#include <stdlib.h>
#include "CModel3DS.h"

CModel3DS * monkey;
// Initialize some OpenGL settings
void initializeGL(void)
{
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glShadeModel(GL_SMOOTH);

        // Enable lighting and set the position of the light
        glEnable(GL_LIGHT0);
        glEnable(GL_LIGHTING);
        GLfloat pos[] = { 0.0, 4.0, 4.0 };
        glLightfv(GL_LIGHT0, GL_POSITION, pos);

        // Generate Vertex Buffer Objects
        monkey->CreateVBO();
}

// Reset viewport and projection matrix after the window was resized
void resizeGL(int width, int height)
{
        // Reset the viewport
        glViewport(0, 0, width, height);
        // Reset the projection and modelview matrix
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        // 10 x 10 x 10 viewing volume
        glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
}

// Do all the OpenGL rendering
void paintGL(void)
{
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw our model
        monkey->Draw();

        // We don't need to swap the buffers, because QT does that automaticly for us
}

void init(void) 
{
   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_FLAT);

}

void display(void)
{
   glClear (GL_COLOR_BUFFER_BIT);
   glColor3f (1.0, 1.0, 1.0);
   glLoadIdentity ();           /* clear the matrix */
        /* viewing transformation  */
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
   glScalef (1.0, 2.0, 1.0);      /* modeling transformation */ 
   //glutWireCube (1.0);
   paintGL();
   glFlush ();
}

void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
   glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
        exit(0);
        break;
   }
}




int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   GLenum err = glewInit();
        if (GLEW_OK != err)
        {
        /* Problem: glewInit failed, something is seriously wrong. */
        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));

        }

        try
        {
                monkey = new CModel3DS("monkey.3ds");
                initializeGL();
        }
        catch(std::string error_str)
        {
                std::cerr << "Error: " << error_str << std::endl;


                exit(1);
        }
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutMainLoop();
   return 0;
} 

//the CModel3DS.h

#ifndef CMODEL3DS_H
#define CMODEL3DS_H
#include <GL/glew.h>
#include <GL/glut.h>
#include <string>
#include <iostream>
#include <string>
#include <cstring>
#include <cassert>
#include <lib3ds/file.h>
#include <lib3ds/mesh.h> 
// Our 3DS model class
class CModel3DS
{
        public:
                CModel3DS(std:: string filename);
                virtual void Draw() const;
                virtual void CreateVBO();
                virtual ~CModel3DS();
        protected:
                void GetFaces();
                unsigned int m_TotalFaces;
                Lib3dsFile * m_model;
                GLuint m_VertexVBO, m_NormalVBO;
};

and the cpp

#include "CModel3DS.h"





// Load 3DS model
CModel3DS::CModel3DS(std:: string filename)
{
        m_TotalFaces = 0;

        m_model = lib3ds_file_load(filename.c_str());
        // If loading the model failed, we throw an exception
        if(!m_model)
        {
                throw strcat("Unable to load ", filename.c_str());
        }
}


// Count the total number of faces this model has
void CModel3DS::GetFaces()
{
        assert(m_model != NULL);

        m_TotalFaces = 0;
        Lib3dsMesh * mesh;
        // Loop through every mesh
        for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
        {
                // Add the number of faces this mesh has to the total faces
                m_TotalFaces += mesh->faces;
        }
}


// Copy vertices and normals to the memory of the GPU
void CModel3DS::CreateVBO()
{
        assert(m_model != NULL);

        // Calculate the number of faces we have in total
        GetFaces();

        // Allocate memory for our vertices and normals
        Lib3dsVector * vertices = new Lib3dsVector[m_TotalFaces * 3];
        Lib3dsVector * normals = new Lib3dsVector[m_TotalFaces * 3];

        Lib3dsMesh * mesh;
        unsigned int FinishedFaces = 0;
        // Loop through all the meshes
        for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
        {
                lib3ds_mesh_calculate_normals(mesh, &normals[FinishedFaces*3]);
                // Loop through every face
                for(unsigned int cur_face = 0; cur_face < mesh->faces;cur_face++)
                {
                        Lib3dsFace * face = &mesh->faceL[cur_face];
                        for(unsigned int i = 0;i < 3;i++)
                        {
                                memcpy(&vertices[FinishedFaces*3 + i], mesh->pointL[face->points[ i ]].pos, sizeof(Lib3dsVector));
                        }
                        FinishedFaces++;
                }
        }

        // Generate a Vertex Buffer Object and store it with our vertices
        glGenBuffers(1, &m_VertexVBO);   <<<---------------------------------------------------------------------------------HERE IS MY EXCEPTION 
        glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, vertices, GL_STATIC_DRAW);

        // Generate another Vertex Buffer Object and store the normals in it
        glGenBuffers(1, &m_NormalVBO);
        glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, normals, GL_STATIC_DRAW);

        // Clean up our allocated memory
        delete vertices;
        delete normals;

        // We no longer need lib3ds
        lib3ds_file_free(m_model);
        m_model = NULL;
}


// Render the model using Vertex Buffer Objects
void CModel3DS:: Draw() const
{
        assert(m_TotalFaces != 0);

        // Enable vertex and normal arrays
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_NORMAL_ARRAY);

        // Bind the vbo with the normals
        glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
        // The pointer for the normals is NULL which means that OpenGL will use the currently bound vbo
        glNormalPointer(GL_FLOAT, 0, NULL);

        glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
        glVertexPointer(3, GL_FLOAT, 0, NULL);

        // Render the triangles
        glDrawArrays(GL_TRIANGLES, 0, m_TotalFaces * 3);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_NORMAL_ARRAY);
}


// Destructor
CModel3DS::~CModel3DS()
{
        glDeleteBuffers(1, &m_VertexVBO);
        glDeleteBuffers(1, &m_NormalVBO);

        if(m_model != NULL)
        {
                lib3ds_file_free(m_model);
        }
}
#endif

UPDATE , после того, как выкопали и обыскали его, кажется, что инициализация glew должна быть, наконец, послеокно создано.но теперь у меня есть другая проблема.я не вижу модель.я исправил код, и он должен выглядеть следующим образом:

#include <stdlib.h>
#include "CModel3DS.h"

CModel3DS * monkey;
// Initialize some OpenGL settings
void initializeGL(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH);

    // Enable lighting and set the position of the light
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);
    GLfloat pos[] = { 0.0, 4.0, 4.0 };
    glLightfv(GL_LIGHT0, GL_POSITION, pos);

    // Generate Vertex Buffer Objects
    monkey->CreateVBO();
}

// Reset viewport and projection matrix after the window was resized
void resizeGL(int width, int height)
{
    // Reset the viewport
    glViewport(0, 0, width, height);
    // Reset the projection and modelview matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    // 10 x 10 x 10 viewing volume
    glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

// Do all the OpenGL rendering
void paintGL(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    // Draw our model
    monkey->Draw();

    // We don't need to swap the buffers, because QT does that automaticly for us
}

void init(void) 
{
   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_FLAT);

}

void display(void)
{
   glClear (GL_COLOR_BUFFER_BIT);
   glColor3f (1.0, 1.0, 1.0);
   glLoadIdentity ();             /* clear the matrix */
           /* viewing transformation  */
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
   glScalef (1.0, 2.0, 1.0);      /* modeling transformation */ 
   //glutWireCube (1.0);

   glFlush ();
}

void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
   glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}




int main(int argc, char** argv)
{
   glutInit(&argc, argv);

   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutMainLoop();
   GLenum err = glewInit();
    if (GLEW_OK != err)
    {
      /* Problem: glewInit failed, something is seriously wrong. */
      fprintf(stderr, "Error: %s\n", glewGetErrorString(err));

    }

    try
    {
        monkey = new CModel3DS("monkey.3ds");
        initializeGL();
        paintGL();
    }
    catch(std::string error_str)
    {
        std::cerr << "Error: " << error_str << std::endl;


        exit(1);
    }
   return 0;
} 

ОБНОВЛЕНИЕ 2
Я выяснил, почему отображается только окно, код glew никогда не выполнялся, так как glutMainLoop ();но это в цикле, когда я положил glutMainLoop ();после glewInit ();как последняя строка в коде, я все еще получаю старую ошибку исключения с буферами.так что еще я должен сделать ....

Ответы [ 2 ]

1 голос
/ 21 июня 2011

Используйте GLEW, вам нужно проверить, действительно ли расширение доступно.Если он не поддерживается glGenBuffers или любая другая неподдерживаемая функция расширения является нулевым указателем, то вам необходимо дважды проверить.См. Документацию GLEW, как правильно проверить наличие расширений:

Проверка расширений

Начиная с GLEW 1.1.0, вы можете узнать, доступно ли конкретное расширение навашей платформы путем запроса глобально определенных переменных в форме GLEW_ {extension_name}:

if (GLEW_ARB_vertex_program)
{
  /* It is safe to use the ARB_vertex_program extension here. */
  glGenProgramsARB(...);
}
0 голосов
/ 21 июня 2011

glGenBuffers указатель на функцию необходимо получить с помощью функций wglGetProcAddress или glXGetProcAddress зависимых от ОС. Вы, кажется, используете GLEW . Не могли бы вы позвонить glewInit непосредственно перед функцией glutMainLoop? Вы также должны проверить, что glGenBuffers!=NULL.

...