私は過去数週間 OpenGL を学んでおり、法線、シーン グラフ、ブラ ブラに関する他の記事と一緒に Swiftless のチュートリアルと Nehe のチュートリアルの一部を読んだ後、ある種の「フレームワーク」を作成することにしました。新しく学んだコードを簡単に挿入できるようにします。そこで、シーングラフとレンダラーのコンボを作成することにしました。それほどきれいでもなく、高速でもありません (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 さえも備えていない安っぽい Intel 統合カードがあり、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 と同じです。前もって感謝します。