
Новичок
Профиль
Группа: Участник
Сообщений: 42
Регистрация: 12.6.2008
Где: где-то тут
Репутация: нет Всего: нет
|
Привет, всем)) Пишу игру с использованием OpenGL. Проблема возникла с VBO. Я натянул на расширение это два класса, первой VBO, который инициализирует это расширение, а второй GPUBuffer неопсредственно работающий с буфером, чтобы было проще с ним работать. Проблема заключается в том, что применяя свой же класс ландшафт рендрендиться отлично и без вылетов, а чтобы отрендрендить какую-нить модель из файла ASE (тоже реализовано этой в отдельном классе ModelASE) , то вылетает на glDrawArray с ошибкой 0xC000005 что обращение идет к 0x0000000 адресу. Как побороть данный баг? привожу код ниже: Код | ModelASE::ModelASE(char *path, bool buf_) { ........... isbuf = buf_; ............. arr_obj[i].buf_vertex = GPUBuffer(); arr_obj[i].buf_normal = GPUBuffer(); if (t_sub_obj.num_mat != -1) { arr_obj[i].buf_texcoord = GPUBuffer(); }
arr_obj[i].buf_vertex.InitBuf(GL_ARRAY_BUFFER_ARB,GL_STATIC_DRAW_ARB); arr_obj[i].buf_normal.InitBuf(GL_ARRAY_BUFFER_ARB,GL_STATIC_DRAW_ARB); if (t_sub_obj.num_mat != -1) { arr_obj[i].buf_texcoord.InitBuf(GL_ARRAY_BUFFER_ARB,GL_STATIC_DRAW_ARB); }
arr_obj[i].buf_vertex.ActBuf((GLubyte *)vertex_arr,arr_obj[i].num_face_cl*9*sizeof(GLfloat)); arr_obj[i].buf_normal.ActBuf((GLubyte *)normal_arr,arr_obj[i].num_face_cl*9*sizeof(GLfloat)); if (t_sub_obj.num_mat != -1) arr_obj[i].buf_texcoord.ActBuf((GLubyte *)tex_arr,arr_obj[i].num_face_cl*6*sizeof(GLfloat)); arr_obj[i].buf_vertex.BindBuf(3,GL_FLOAT,0,GL_VERTEX_ARRAY,GL_VERTEX_ARRAY); arr_obj[i].buf_normal.BindBuf(3,GL_FLOAT,0,GL_NORMAL_ARRAY,GL_NORMAL_ARRAY); if (t_sub_obj.num_mat != -1) arr_obj[i].buf_texcoord.BindBuf(2,GL_FLOAT,0,GL_TEXTURE_COORD_ARRAY,GL_TEXTURE_COORD_ARRAY); free(vertex_arr); free(normal_arr); if (t_sub_obj.num_mat != -1) free(tex_arr); DisableAllStateClient(); } }
} void ModelASE::Render() //Рендрендинг модели на сцену { sub_obj t_sub_obj; mat_obj t_mat_obj; glEnable(GL_TEXTURE_2D); for(int i = 0; i<arr_obj.size();i+=1) { glPushMatrix(); t_sub_obj = arr_obj[i]; ..... if (!t_sub_obj.isbuf) { ..... } } else { arr_obj[i].buf_vertex.BindBuf(); arr_obj[i].buf_normal.BindBuf(); if (arr_obj[i].num_mat != -1) arr_obj[i].buf_texcoord.BindBuf(); glColor3f(1.0f,1.0f,1.0f); glDrawArrays(GL_TRIANGLES,0,arr_obj[i].num_face_cl*3); // здесь вылетает DisableAllStateClient(); } ..... } }
|
Код | typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);
class VBO { public: PFNGLGENBUFFERSARBPROC glGenBuffersARB; // VBO Name Generation Procedure PFNGLBINDBUFFERARBPROC glBindBufferARB; // VBO Bind Procedure PFNGLBUFFERDATAARBPROC glBufferDataARB; // VBO Data Loading Procedure PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB; bool isdelete; VBO(); bool InitVBO(); bool IsExtensionSupported(char* szTargetExtension ); void DeleteVBO(); ~VBO(); }; class GPUBuffer { private: GLuint id; GLenum target; GLenum usage; VBO vbo; GLint size; GLint size_p; GLenum type; GLint stride; GLenum typebuf; GLenum typeclient; public: bool Error; bool isdelete; GPUBuffer(); void InitBuf(GLenum target_,GLenum usage_); void ActBuf(GLubyte *data,GLuint size_); void ActBuf(GLubyte *data,GLuint size_,GLenum target_,GLenum usage_); void BindBuf(); void BindBuf(GLint size_,GLenum type_,GLint stride_,GLenum typebuf_,GLenum typeclient_); GLuint GetId(); GLenum GetTarget(); GLenum GetUsage(); GLint GetSize(); GLenum GetType(); GLint GetStride(); GLenum GetTypebuf(); GLenum GetTypeClient(); void SetTarget(GLenum _target); void SetUsage(GLenum _usage); void SetSize(GLint _size); void SetType(GLenum _type); void SetStride(GLint _stride); void SetTypebuf(GLenum _typebuf); void DeleteGPUBuffer(); void SetTypeClient(GLenum typeclient_); ~GPUBuffer(); };
VBO::VBO() { glGenBuffersARB = NULL; // VBO Name Generation Procedure glBindBufferARB = NULL; // VBO Bind Procedure glBufferDataARB = NULL; // VBO Data Loading Procedure glDeleteBuffersARB = NULL; isdelete = false; } bool VBO::InitVBO() { // if(IsExtensionSupported( "GL_ARB_vertex_buffer_object" )) { glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffersARB"); glBindBufferARB = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBufferARB"); glBufferDataARB = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferDataARB"); glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffersARB"); return true; } return false; } bool VBO::IsExtensionSupported(char* szTargetExtension ) { const unsigned char *pszExtensions = NULL; const unsigned char *pszStart; unsigned char *pszWhere, *pszTerminator; // Имя расширения не должно содержать пробелы pszWhere = (unsigned char *) strchr( szTargetExtension, ' ' ); if( pszWhere || *szTargetExtension == '\0' ) return false; // Получить строку расширения
pszExtensions = (unsigned char *)glGetString(GL_VERSION); // Поиск в строке расширений pszStart = pszExtensions; for(;;) { pszWhere = (unsigned char *) strstr( (const char *) pszStart, szTargetExtension ); if( !pszWhere ) break; pszTerminator = pszWhere + strlen( szTargetExtension ); if( pszWhere == pszStart || *( pszWhere - 1 ) == ' ' ) if( *pszTerminator == ' ' || *pszTerminator == '\0' ) return true; pszStart = pszTerminator; } return false; } void VBO::DeleteVBO() {
} VBO::~VBO() { if(isdelete) DeleteVBO(); }
GPUBuffer::GPUBuffer() { Error = false; isdelete = false; vbo = VBO(); if (vbo.InitVBO()) return; Error = true; } void GPUBuffer::InitBuf(GLenum target_,GLenum usage_) { target = target_; usage = usage_; vbo.glGenBuffersARB(1,&id); } void GPUBuffer::ActBuf(GLubyte *data,GLuint size_) { ActBuf(data,size_,target,usage); } void GPUBuffer::ActBuf(GLubyte *data,GLuint size_,GLenum target_,GLenum usage_) { size = size_; target = target_; usage = usage_; vbo.glBindBufferARB(target,id); vbo.glBufferDataARB(target,size,data,usage_); } void GPUBuffer::BindBuf() { BindBuf(size_p,type,stride,typebuf,typeclient); } void GPUBuffer::BindBuf(GLint size_,GLenum type_,GLint stride_,GLenum typebuf_,GLenum typeclient_) { size_p = size_; type = type_; stride = stride_; typebuf = typebuf_; typeclient = typeclient_; glEnableClientState(typeclient_); vbo.glBindBufferARB(target,id); switch(typeclient_) { case GL_VERTEX_ARRAY: glVertexPointer(size_p,type,stride,NULL); break; case GL_TEXTURE_COORD_ARRAY: glTexCoordPointer(size_p,type,stride,NULL); break; case GL_NORMAL_ARRAY: glNormalPointer(type,stride,NULL); break; case GL_COLOR_ARRAY: glColorPointer(size_p,type,stride,NULL); break; } } void GPUBuffer::SetTypeClient(GLenum typeclient_) { typeclient = typeclient_; } GLenum GPUBuffer::GetTypeClient() { return typeclient; } GLuint GPUBuffer::GetId() { return id; } GLenum GPUBuffer::GetTarget() { return target; } GLenum GPUBuffer::GetUsage() { return usage; } GLint GPUBuffer::GetSize() { return size; } GLenum GPUBuffer::GetType() { return type; } GLint GPUBuffer::GetStride() { return stride; } GLenum GPUBuffer::GetTypebuf() { return typebuf; }
void GPUBuffer::SetTarget(GLenum _target) { target = _target; } void GPUBuffer::SetUsage(GLenum _usage) { usage = _usage; } void GPUBuffer::SetSize(GLint _size) { size = _size; } void GPUBuffer::SetType(GLenum _type) { type = _type; } void GPUBuffer::SetStride(GLint _stride) { stride = _stride; } void GPUBuffer::SetTypebuf(GLenum _typebuf) { typebuf = _typebuf; } void GPUBuffer::DeleteGPUBuffer() { vbo.glDeleteBuffersARB(1,&id); } GPUBuffer::~GPUBuffer() { if (isdelete) DeleteGPUBuffer(); } void DisableAllStateClient() { glDisableClientState( GL_VERTEX_ARRAY ); // запрет вершинных массивов glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_NORMAL_ARRAY ); glDisableClientState( GL_COLOR_ARRAY ); }
|
|