【问题标题】:OpenGL VBO access violationOpenGL VBO 访问冲突
【发布时间】:2011-04-07 09:15:22
【问题描述】:

过去几周我一直在学习 OpenGL,在阅读了 Swiftless tuts 和 Nehe 的部分 tuts 以及其他有关法线、场景图、bla bla 的文章之后,我决定创建某种“框架” ",让我可以更轻松地插入新学的代码。所以我决定创建一个场景图/渲染器组合,不是那么漂亮,不是那么快(prolly),但是可以选择添加一个新的派生节点类来渲染一个我可能刚刚读过的新特性。因此,我在 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();
}

场景图“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() 中调用的,场景图的初始化是在窗口创建之后完成的,所以......我很确定它与指针有关......

在以前的程序中,我使用完全相同的代码来创建 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 相同,只是它是静态声明的。提前致谢。

【问题讨论】:

    标签: pointers opengl vbo


    【解决方案1】:

    很可能是因为当您尝试调用init()NodeSphere 不存在(或不再有效)而发生错误。

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

    【讨论】:

    • NodeSphere::init() 在构造函数中被调用,但无论如何,我已经在 NodeSphere::NodeSphere 中移动了 glGenBuffer,这是同样的事情,它给了我访问冲突在 glGenBuffer。
    • glGenBuffersARB 在哪里定义?您是在使用 GLEW 并且没有对其进行初始化,还是类似的方式?
    猜你喜欢
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多