OpenGL VBO access violation
I've been learning OpenGL the past few weeks and after reading the Swiftless tuts and part of Nehe's tuts, along side with other articles concerning normals, scene graphs, bla bla, i've decided to create some sort of "framework", to allow me to insert newly learned code easier. So I decided to create a scenegraph/renderer combo, not that pretty, not that fast (prolly), but with the option to add just a new derived node class to render a new whatever feature i might just have read. So i look on the interwebz to see various examples on how to implement one and settle on this base class:
#pragma once
#ifndef NODE_H
#define NODE_H
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <math.h>
#include <windows.h>
#include <list>
using namespace std;
class Node
{
public:
Node(void);
~Node(void);
//Node* parent;
void addChild(Node* node);
void removeChilds(Node* node);
virtual void traverse();
void kill();
protected:
std::list<Node*> childs;
};
#endif
.... from which i made this class:
#pragma once
#ifndef NODESPHERE_H
#define NODESPHERE_H
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <math.h>
#include <windows.h>
#include "Various.h"
#include "Node.h"
class NodeSphere : public Node
{
public:
NodeSphere(double R, double H, double K, double Z, const int space);
~NodeSphere(){delete this;}
void traverse();
pr开发者_JAVA百科ivate:
float out[3];
int Radius;
int vhVertexCount;
Vert *vhVertices;
Normal *vhNormals,*vhVNormals;
TexCoord *vhTexCoords;
unsigned int vhVBOVertices;
unsigned int vhVBOTexCoords;
unsigned int vhVBONormals;
bool Init(void);
bool Normals(const int nIndex);
bool ReduceToUnit(void);
};
#endif
Now, i use freeglut to handle the window creation and the loop:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <math.h>
#include "Scenegraph.h"
#include "View.h"
#include "Control.h"
#define WIDTH 800
#define HEIGHT 600
Scenegraph *bob;
View *myView;
Control *controler;
.................
.................
void main(int argc, char **argv)
{
glewInit();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(WIDTH,HEIGHT);
glutInitWindowPosition(0,0);
glutCreateWindow("Mediensoftware - Finale Übung");
bob = new Scenegraph();
myView = new View(WIDTH, HEIGHT, bob);
controler = new Control(myView);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutSpecialFunc(keyboard_s);
glutMainLoop();
}
The Scenegraph "bob" handles the creation of nodes like this:
Scenegraph::Scenegraph()
{
this->root = new Node();
this->sun = new NodeSphere(3,0,0,0,10);
this->sun_transform = new NodeTransform();
this->sun_tex = new NodeTexture("sunmap.bmp");
this->sun_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->planet_earth = new NodeSphere(1,0,0,0,10);
this->planet_earth_transform = new NodeTransform(6,0,0);
this->planet_earth_tex = new NodeTexture("earthmap.bmp");
this->planet_earth_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->moon = new NodeSphere(0.3,0,0,0,10);
this->moon_tex = new NodeTexture("moonmap.bmp");
this->moon_transform = new NodeTransform(1.5,0,0);
this->moon_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->planet_venus = new NodeSphere(0.8,0,0,0,10);
this->planet_venus_transform = new NodeTransform(3,0,0);
this->planet_venus_tex = new NodeTexture("venusmap.bmp");
this->planet_venus_mat = new NodeMaterial(1.0,0,1.0,0.7,0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0);
this->planet_mars = new NodeSphere(0.6,0,0,0,10);
................................................................................................
this->root->addChild(this->sun_transform);
this->sun_transform->addChild(this->sun_mat);
this->sun_mat->addChild(this->sun_tex);
this->sun_tex->addChild(this->sun);
this->sun->addChild(this->planet_venus_transform);
this->planet_venus_transform->addChild(this->planet_venus_mat);
this->planet_venus_mat->addChild(this->planet_venus_tex);
...................................................................................................
}
The compiler doesn't see any errors and executes the code, but it receives an access violation here:
bool NodeSphere::Init(void){
glGenBuffersARB(1, &vhVBOVertices); // DERP here
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vhVBOVertices);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->vhVertexCount * 3 * sizeof(float), this->vhVertices, GL_STATIC_DRAW_ARB);
glGenBuffersARB(1, &vhVBONormals);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vhVBONormals);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->vhVertexCount * 3 * sizeof(float), this->vhVNormals, GL_STATIC_DRAW_ARB);
glGenBuffersARB(1, &vhVBOTexCoords);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vhVBOTexCoords);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, this->vhVertexCount * 2 * sizeof(float), this->vhTexCoords, GL_STATIC_DRAW_ARB);
delete [] vhVertices;
vhVertices = NULL;
delete [] vhTexCoords;
vhTexCoords = NULL;
delete [] vhNormals;
vhNormals = NULL;
delete [] vhVNormals;
vhVNormals = NULL;
return true;
}
The extensions are called in the View::initExtensions(), the init of the Scenegraph is done after the window creation, so.... i'm pretty sure it has something to do with pointers...
on previous programs i used the exact same code for VBO creation and it worked. The only difference is that the code used here is used in a Node*, while the previous ones were used in just Node (no pointer). But in any case, i'm gonna check if glew starts up well. As for what video card i am using, on the laptop i have a crappy Intel integrated card, which should support OpenGL 1.5, but doesn't even have GLSL, and on the PC, a 6850. The thing is that i work a lot on the laptop, because of faculty and other stuff as well.
But anyway, the code for creating VBO's works, i mean, it has worked for the following:
#include <stdlib.h>
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <GL/glew.h>
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
#include <GL/glext.h>
#include <math.h>
#define PI 3.14159265f
class Vert{
public:
float x;
float y;
float z;
};
class Normal{
public:
float x;
float y;
float z;
};
class TexCoord{
public:
float u;
float v;
};
class Scenegraph {
private:
float out[3];
int Radius;
GLuint tID[2];
int vhVertexCount;
Vert *vhVertices;
Normal *vhNormals,*vhVNormals;
TexCoord *vhTexCoords;
unsigned int vhVBOVertices;
unsigned int vhVBOTexCoords;
unsigned int vhVBONormals;
bool Init(void);
bool Normals(const int nIndex);
bool ReduceToUnit(void);
public:
bool Create(double R, double H, double K, double Z, const int space);
void Render();
};
which is identical to NodeSphere, except it was statically declared. Thanks in advance.
Most likely, the error is occurring because the NodeSphere
doesn't exist (or is no longer valid) when you try to call init()
.
You should probably move the resource initialization code into the constructor (that's generally what they're for) unless you need it to occur later on. It makes sense for the VBO to have a similar lifespan to the object, so creating and destroying them in the ctor/dtor should work and saves you the complexity of explicitly initializing.
精彩评论