0x00000000 glGenBuffer 尝试将 lib3ds 与 opengl 一起使用时出现未处理的异常
我喜欢将 3ds 模型加载到简单的 opengl 程序中,我所做的就是使用我找到的参考 2 个链接:
http:// Pastebin.com/CZ82VYWT 和 http://www.donkerdump.nl/node/207 我从红皮书立方体示例中获取代码,并尝试在 2 之间进行 Marage
但我一直在 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
更新 经过挖掘和搜索后发现,glew 的 init 需要最后在创建窗口之后进行。但现在我有另一个问题。我没有看到型号。 我修复了代码,它应该是这样的:
#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() 之后;作为代码中的最后一行,我仍然收到缓冲区的旧异常错误。 那么我还需要做什么......
I like to load 3ds model into simple opengl program, what I did is to use as refernce 2 links I found:
http://pastebin.com/CZ82VYWT and http://www.donkerdump.nl/node/207 i take the code from the redbook the cube example and tryed to marage between the 2
but all the time i keep getting Unhandled exception at 0x00000000 glGenBuffer exception . in the CModel3DS::CreateVBO() method
here is my code:
// 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
well after digging and searching it seams that the init of the glew needs to be at last after the window is created . but now i have another problem . i dont see the model .
i fixed the code and it should be like this :
#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;
}
UPDATE 2
i found out why only the window is showing , the glew code never executed beacose the glutMainLoop(); but it in a loop
when i put the glutMainLoop(); after the glewInit(); as the last line in the code i still getting the the old exception error with the buffers.
so what else i have to do ....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 GLEW 您需要检查扩展是否确实可用。如果不支持
glGenBuffers
或者任何其他不支持的扩展函数就是空指针,所以你需要仔细检查。请参阅 GLEW 文档如何正确检查扩展的可用性:Use GLEW you need to check if an extension is actually available. If it is not supported
glGenBuffers
or any other unsupported extension function is a null pointer, so you need to double check. See the GLEW documentation how to properly check for the availability of extensions:需要使用
wglGetProcAddress
或glXGetProcAddress
操作系统相关函数来检索glGenBuffers
函数指针。您似乎使用GLEW。您可以在glutMainLoop
函数之前调用glewInit
吗?您还应该测试glGenBuffers!=NULL
。glGenBuffers
function pointer needs to be retrieved usingwglGetProcAddress
orglXGetProcAddress
OS dependents functions. You seems to use GLEW. Could you callglewInit
just before theglutMainLoop
function? You should also test thatglGenBuffers!=NULL
.