Нарушение доступа OpenGL VBO - PullRequest
       13

Нарушение доступа OpenGL VBO

1 голос
/ 07 апреля 2011

Я изучал OpenGL последние несколько недель, и после прочтения сучков Swiftless и части срезов Nehe, наряду с другими статьями, касающимися нормалей, графов сцен, бла-бла, я решил создать своего рода «фреймворк». msgstr ", чтобы мне было проще вставить недавно выученный код. Поэтому я решил создать комбо сцены / рендерера, но не такое красивое, не такое быстрое, но с возможностью добавить только новый производный класс узла, чтобы отобразить новую функцию, которую я только что прочитал. Итак, я смотрю на 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 выполняется после создания окна, так что ... я почти уверен, что это как-то связано с указателями ...

в предыдущих программах я использовал точно такой же код для создания VBO, и это сработало. Единственное отличие состоит в том, что используемый здесь код используется в узле *, тогда как предыдущие использовались только в узле (без указателя). Но в любом случае, я проверю, хорошо ли запускается глю. Что касается того, какую видеокарту я использую, на ноутбуке у меня есть дрянная интегрированная карта Intel, которая должна поддерживать OpenGL 1.5, но даже не имеет GLSL, а на ПК - 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 голосов
/ 07 апреля 2011

Скорее всего, ошибка возникает из-за того, что NodeSphere не существует (или больше не действителен) при попытке вызвать init().

Вероятно, вам следует переместить код инициализации ресурса вконструктор (это обычно то, для чего они), если вам не нужно, чтобы это произошло позже.Для VBO имеет смысл иметь продолжительность жизни, аналогичную объекту, поэтому создание и уничтожение их в ctor / dtor должно работать и избавляет вас от сложности явной инициализации.

...