OpenGL VBO访问冲突

时间:2011-04-07 01:01:06

标签: pointers opengl vbo

过去几周我一直在学习OpenGL,在阅读了Swiftless tuts和Nehe's tuts的一部分之后,与其他关于法线,场景图,bla bla的文章一起,我决定创建某种“框架” “,允许我更容易地插入新学习的代码。所以我决定创建一个场景图/渲染器组合,不是那么漂亮,不是那么快(很多),而是可以选择添加一个新的派生节点类来渲染我可能刚刚读过的新功能。所以我看看interwebz,看看如何实现一个并解决这个基类的各种例子:

#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

....从中我开始上课:

#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();

private:
        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

现在,我使用freeglut来处理窗口创建和循环:

    #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();
}

Scenegraph“bob”处理如下节点的创建:

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);
...................................................................................................
        }

编译器没有看到任何错误并执行代码,但它在此处收到访问冲突:

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;
}

扩展在View :: initExtensions()中调用,Scenegraph的init在窗口创建之后完成,所以....我很确定它与指针有关...

在之前的程序中,我使用完全相同的代码进行VBO创建,并且工作正常。唯一的区别是这里使用的代码用于Node *,而之前的代码只用于Node(无指针)。但无论如何,我要检查一下glew是否启动良好。 至于我使用的是什么显卡,在笔记本电脑上我有一个糟糕的英特尔集成卡,应该支持OpenGL 1.5,但是甚至没有GLSL,而在PC上是6850。事情是,我在笔记本电脑上工作很多,因为教师和其他东西也是如此。

但无论如何,用于创建VBO的代码的工作原理,我的意思是,它适用于以下内容:

#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();

};

与NodeSphere相同,除了它是静态声明的。提前谢谢。

1 个答案:

答案 0 :(得分:0)

最有可能发生错误,因为当您尝试拨打NodeSphereinit()不存在(或不再有效)。

您应该将资源初始化代码移动到构造函数中(这通常是它们的用途),除非您以后需要它。 VBO与对象具有相似的生命周期是有意义的,因此在ctor / dtor中创建和销毁它们应该可以工作并为您节省显式初始化的复杂性。