Grafikprogrammierung
Buffer Objects
Thorsten Thormählen
10. Dezember 2021
Teil 8, Kapitel 1
Thorsten Thormählen
10. Dezember 2021
Teil 8, Kapitel 1
Dies ist die Druck-Ansicht.
Weiterschalten der Folien durch die → Taste oder
durch das Klicken auf den rechten Folienrand.
Das Weiterschalten der Folien kann ebenfalls durch das Klicken auf den rechten bzw. linken Folienrand erfolgen.
| Typ | Schriftart | Beispiele |
|---|---|---|
| Variablen (Skalare) | kursiv | $a, b, x, y$ |
| Funktionen | aufrecht | $\mathrm{f}, \mathrm{g}(x), \mathrm{max}(x)$ |
| Vektoren | fett, Elemente zeilenweise | $\mathbf{a}, \mathbf{b}= \begin{pmatrix}x\\y\end{pmatrix} = (x, y)^\top,$ $\mathbf{B}=(x, y, z)^\top$ |
| Matrizen | Schreibmaschine | $\mathtt{A}, \mathtt{B}= \begin{bmatrix}a & b\\c & d\end{bmatrix}$ |
| Mengen | kalligrafisch | $\mathcal{A}, B=\{a, b\}, b \in \mathcal{B}$ |
| Zahlenbereiche, Koordinatenräume | doppelt gestrichen | $\mathbb{N}, \mathbb{Z}, \mathbb{R}^2, \mathbb{R}^3$ |
... glColor3f(1.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); glTexCoord2f(0.25f,0.50f); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.25f,0.25f); glVertex3f(-1.0f,-1.0f, 1.0f); glTexCoord2f(0.50f,0.25f); glVertex3f( 1.0f,-1.0f, 1.0f); glTexCoord2f(0.50f,0.50f); glVertex3f( 1.0f, 1.0f, 1.0f); glEnd(); ...
glBegin, glVertex, etc.)
seit OpenGL >= 3.1 nur noch im "Compatibility Profile" unterstütztinit()
glGenBuffers(1, &bufID) kann ein eindeutiger Kennzeichner generiert werdenglBindBuffer(GL_ARRAY_BUFFER, bufID) wird ein neues VBO erzeugt.
Mögliche Ziele sind GL_ARRAY_BUFFER oder GL_ELEMENT_ARRAY_BUFFERglBufferData(GL_ARRAY_BUFFER, size, inData, GL_STATIC_DRAW) werden die Vertex-Daten übergebenglBindBuffer(GL_ARRAY_BUFFER, bufID) glEnableClientState(GL_VERTEX_ARRAY).
Mögliche Parameter sind: GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_SECONDARY_COLOR_ARRAY, GL_INDEX_ARRAY,
GL_NORMAL_ARRAY, GL_TEXTURE_COORD_ARRAY usw.glDrawArrays(GL_POLYGON, first, count);Mögliche Argumente sind die gleichen wie bei
glBegin(...), wie z.B. GL_POLYGON, GL_LINE_LOOP, GL_LINES, GL_POINTS, usw.
glDeleteBuffers(1, &bufID) wieder
freigegeben werden
class Renderer {
public:
float t;
int mode;
private:
GLuint bufID;
int bufSize;
public:
// constructor
Renderer() : t(0.0), mode(0), bufID(0), bufSize(0) {}
//destructor
~Renderer() {
if(bufID !=0) glDeleteBuffers( 1, &bufID);
}
public:
void init() {
glEnable(GL_DEPTH_TEST);
// generating VBO input data
std::vector<float> dataIn;
unsigned ayimutSegs = 1000;
unsigned polarSegs = 1000;
float ayimutStep = 2.0f * M_PI / float(ayimutSegs);
float polarStep = M_PI / float(polarSegs);
float r = 1.0;
bufSize = 0;
for(unsigned m=0; m < ayimutSegs; m++) {
for(unsigned n=0; n < polarSegs; n++) {
float phi = ayimutStep*m;
float theta = polarStep * n;
// compute xyz from spherical coordinates
float x = r * sin(theta) * cos(phi);
float y = r * sin(theta) * sin(phi);
float z = r * cos(theta);
dataIn.push_back(x);
dataIn.push_back(y);
dataIn.push_back(z);
bufSize++;
}
}
// generating VBO
glGenBuffers(1, &bufID);
glBindBuffer(GL_ARRAY_BUFFER, bufID);
glBufferData(GL_ARRAY_BUFFER, dataIn.size()*sizeof(float),
&dataIn[0], GL_STATIC_DRAW);
}
void resize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (30.0, (float)w/(float)h, 0.1, 50.0);
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// set camera
gluLookAt(3.5, -1.0, 3.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
// draw scene
glRotatef(t, 0.0f, 0.0f, 1.0f);
// activating VBO
glBindBuffer(GL_ARRAY_BUFFER, bufID);
int stride = 0;
glVertexPointer(3, GL_FLOAT, stride, NULL);
glEnableClientState(GL_VERTEX_ARRAY);
if(mode == 0) {
glColor3f(1.0f,1.0f,1.0f);
}else{
glColorPointer(3, GL_FLOAT, stride, NULL);
glEnableClientState(GL_COLOR_ARRAY);
}
// render VBO
glDrawArrays(GL_POINTS, 0, bufSize);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
};
float vertexData[] =
{-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f
};
int indicesData[] =
{ 0, 1, 2, 3,
0, 4, 5, 1,
4, 7, 6, 5,
2, 6, 7, 3,
1, 5, 6, 2,
3, 7, 4, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufID) erzeugt und aktiviert
glDrawElements(GL_POLYGON, count, GL_UNSIGNED_INT);
class Renderer {
public:
float t;
int mode;
unsigned ayimutSegs;
unsigned polarSegs;
private:
GLuint vertBufID, indicesBufID;
int vertSize;
public:
// constructor
Renderer() : t(0.0), mode(1), ayimutSegs(10), polarSegs(10),
vertBufID(0), indicesBufID(0), vertSize(0) {}
//destructor
~Renderer() {
if(vertBufID !=0) glDeleteBuffers( 1, &vertBufID);
if(indicesBufID !=0) glDeleteBuffers( 1, &indicesBufID);
}
public:
void init() {
glEnable(GL_DEPTH_TEST);
recreateVBOs();
}
void recreateVBOs() {
if(vertBufID !=0) glDeleteBuffers( 1, &vertBufID);
if(indicesBufID !=0) glDeleteBuffers( 1, &indicesBufID);
// generating VBO input data
std::vector<float> vertexData;
std::vector<int> indicesData;
int totalSegs = ayimutSegs * polarSegs;
float ayimutStep = 2.0f * M_PI / float(ayimutSegs);
float polarStep = M_PI / float(polarSegs);
float r = 1.0;
vertSize = 0;
for(unsigned m=0; m < ayimutSegs; m++) {
for(unsigned n=0; n < polarSegs; n++) {
float phi = ayimutStep*m;
float theta = polarStep * n;
// random radius
int rval = rand();
r = 1.0 - 0.3 * (fabs(float(rval))/float(RAND_MAX));
// create xyz from spherical coordinates
float x = r * sin(theta) * cos(phi);
float y = r * sin(theta) * sin(phi);
float z = r * cos(theta);
vertexData.push_back(x);
vertexData.push_back(y);
vertexData.push_back(z);
// create vertex indices
indicesData.push_back(vertSize % totalSegs);
indicesData.push_back((vertSize+ayimutSegs)%totalSegs);
indicesData.push_back((vertSize+ayimutSegs+1)%totalSegs);
indicesData.push_back((vertSize+1)%totalSegs);
vertSize++;
}
}
// generating vertex VBO
glGenBuffers(1, &vertBufID);
glBindBuffer(GL_ARRAY_BUFFER, vertBufID);
glBufferData(GL_ARRAY_BUFFER,
vertexData.size()*sizeof(float),
&vertexData[0], GL_STATIC_DRAW);
// generating index VBO
// generating index VBO
glGenBuffers(1, &indicesBufID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBufID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
indicesData.size()*sizeof(int),
&indicesData[0], GL_STATIC_DRAW);
}
void resize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (30.0, (float)w/(float)h, 0.1, 50.0);
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// set camera
gluLookAt(3.5, -1.0, 3.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
// draw scene
glRotatef(t, 0.0f, 0.0f, 1.0f);
// activating VBO
glBindBuffer(GL_ARRAY_BUFFER, vertBufID);
int stride = 0;
glVertexPointer(3, GL_FLOAT, stride, NULL);
glEnableClientState(GL_VERTEX_ARRAY);
if(mode == 0) {
glColor3f(1.0f,1.0f,1.0f);
}else{
glColorPointer(3, GL_FLOAT, stride, NULL);
glEnableClientState(GL_COLOR_ARRAY);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBufID);
glDrawElements(GL_QUADS, vertSize*4, GL_UNSIGNED_INT, NULL);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
};
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)die kompletten Daten neu zu übergeben
GL_STATIC_DRAW
der Parameter GL_DYNAMIC_DRAW angegeben werdenGL_STREAM_DRAW anglBufferSubData(GL_ARRAY_BUFFER, offset, size, data)
struct Vertex
{
float position[3];
float color[4];
float texCoord[2];
float normal[3];
};
std::vector<Vertex> vertexData;
vertexData als ein großes VBO angelegt, so muss der Speicherzugriff auf die einzelnen Komponenten durch
Angabe der Schrittweite stride und der Startadresse offset definiert werden, z.B.:
int stride = sizeof(Vertex); char* offset = (char*) NULL + (3+4+2)*sizeof(float); glNormalPointer(GL_FLOAT, stride, offset);
class Renderer {
private:
struct Vertex
{
float position[3];
float color[4];
float texCoord[2];
float normal[3];
};
public:
float t;
int mode;
private:
GLuint vertBufID;
GLuint texID;
int vertNo;
public:
// constructor
Renderer() : t(0.0), mode(0),
vertBufID(0), texID(0), vertNo(0) {}
//destructor
~Renderer() {
if(vertBufID !=0) glDeleteBuffers( 1, &vertBufID);
if(texID !=0) glDeleteTextures( 1, &texID);
}
public:
void init() {
glEnable(GL_DEPTH_TEST);
// generating VBO input data
float vertexData[] = {
0.0f, 0.0f, 2.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 1.0f, 0.0000f,-0.9701f, 0.2425f,
-0.5f,-0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0000f,-0.9701f, 0.2425f,
0.5f,-0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0000f,-0.9701f, 0.2425f,
0.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.5f, 1.0f, 0.9701f, 0.0000f, 0.2425f,
0.5f,-0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.9701f, 0.0000f, 0.2425f,
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.9701f, 0.0000f, 0.2425f,
0.0f, 0.0f, 2.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, 1.0f, 0.0000f, 0.9701f, 0.2425f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0000f, 0.9701f, 0.2425f,
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0000f, 0.9701f, 0.2425f,
0.0f, 0.0f, 2.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.5f, 1.0f,-0.9701f, 0.0000f, 0.2425f,
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f,-0.9701f, 0.0000f, 0.2425f,
-0.5f,-0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f,-0.9701f, 0.0000f, 0.2425f
};
vertNo = 12;
// generating vertex VBO
glGenBuffers(1, &vertBufID);
glBindBuffer(GL_ARRAY_BUFFER, vertBufID);
glBufferData(GL_ARRAY_BUFFER, vertNo*sizeof(Vertex),
vertexData, GL_STATIC_DRAW);
std::string fileName("checkerboard.ppm");
texID = loadTexture(fileName);
}
void resize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (30.0, (float)w/(float)h, 0.1, 50.0);
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// set camera
gluLookAt(3.0, -1.0, 4.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0);
// draw scene
glRotatef(t, 0.0f, 0.0f, 1.0f);
// activating VBO
glBindBuffer(GL_ARRAY_BUFFER, vertBufID);
int stride = sizeof(Vertex);
char *offset = (char*)NULL;
// position
glVertexPointer(3, GL_FLOAT, stride, offset);
glEnableClientState(GL_VERTEX_ARRAY);
// color
offset = (char*)NULL + 3*sizeof(float);
glColorPointer(4, GL_FLOAT, stride, offset);
glEnableClientState(GL_COLOR_ARRAY);
// texture
offset = (char*)NULL + (3+4)*sizeof(float);
glTexCoordPointer(2, GL_FLOAT, stride, offset);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// normals
offset = (char*)NULL + (3+4+2)*sizeof(float);
glNormalPointer(GL_FLOAT, stride, offset);
glEnableClientState(GL_NORMAL_ARRAY);
// bind texture
if(mode == 0) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texID);
}else{
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
// render data
glDrawArrays(GL_TRIANGLES, 0, vertNo);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_TEXTURE_2D);
}
...
};
display() Funktion des letzten Beispiels betrachtet wird, fällt auf, dass neben des eigentlichen Renderaufrufs mittels glDrawArrays(...) zusätzlich noch mehrere Funktionsaufrufe von glBindBuffer(...),
glXXXPointer(...) und glEnableClientState(...) benötigt werden, um ein Objekt darzustellen
glGenVertexArrays(1, &vaoID);
glBindVertexArray(...) und Setzen der VBO Zustände, diese werden vom aktuell gebundenen VAO gespeichert
glBindVertexArray(vaoID); glBindBuffer(GL_ARRAY_BUFFER, bufID); glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); glVertexPointer(3, GL_FLOAT, stride, offset); glEnableClientState(GL_VERTEX_ARRAY); ...
glBindVertexArray(vaoID); glDrawArrays(GL_TRIANGLES, 0, numOfTris);
glDeleteVertexArrays(1, &vaoID);Durch Löschen des VAOs werden die zugehörigen VBOs nicht gelöscht. Falls gewünscht, müssen diese separat freigegeben werden.
class Renderer {
private:
struct Vertex
{
float position[3];
float color[4];
};
public:
float t;
int mode;
private:
enum {Pyramid, Cube, numVAOs};
enum {PyramidAll, CubePos, CubeCol, CubeIndices, numVBOs};
GLuint vaoID[numVAOs];
GLuint bufID[numVBOs];
int pyramidVertNo;
int cubeIndicesNo;
public:
// constructor
Renderer() : t(0.0), pyramidVertNo(0), cubeIndicesNo(0) {}
//destructor
~Renderer() {
glDeleteVertexArrays(numVAOs, vaoID);
glDeleteBuffers(numVBOs, bufID);
}
public:
void init() {
glEnable(GL_DEPTH_TEST);
// now we create 2 Vertex Array Objects (VAO):
// one for a pyramid and one for a cube.
// The pyramid uses one interleaved VBO
// which is later drawn with "glDrawArrays",
// while the cube uses 3 separate VBOs
// which are later drawn with "glDrawElements"
// create the Vertex Array Objects
glGenVertexArrays(numVAOs, vaoID);
// generating Vertex Buffer Objects (VBO)
glGenBuffers(numVBOs, bufID);
// specifying the pyramid VAO
glBindVertexArray(vaoID[Pyramid]);
float pyramidVertexData[] = {
0.0f, 0.0f, 2.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f,-0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.5f,-0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f,-0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 2.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 2.0f, 1.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
-0.5f,-0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
};
pyramidVertNo = 12;
glBindBuffer(GL_ARRAY_BUFFER, bufID[PyramidAll]);
glBufferData(GL_ARRAY_BUFFER, pyramidVertNo*sizeof(Vertex),
pyramidVertexData, GL_STATIC_DRAW);
int stride = sizeof(Vertex);
char *offset = (char*)NULL;
// position
glVertexPointer(3, GL_FLOAT, stride, offset);
glEnableClientState(GL_VERTEX_ARRAY);
// color
offset = (char*)NULL + 3*sizeof(float);
glColorPointer(4, GL_FLOAT, stride, offset);
glEnableClientState(GL_COLOR_ARRAY);
// specifying the cube VAO
glBindVertexArray(vaoID[Cube]);
float cubePosData[] = {
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f
};
float cubeColorData[] = {
1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
};
int cubeIndicesData[] =
{ 0, 1, 2, 3,
0, 4, 5, 1,
4, 7, 6, 5,
2, 6, 7, 3,
1, 5, 6, 2,
3, 7, 4, 0
};
cubeIndicesNo = 24;
// position
glBindBuffer(GL_ARRAY_BUFFER, bufID[CubePos]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubePosData),
cubePosData, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, NULL);
glEnableClientState(GL_VERTEX_ARRAY);
// color
glBindBuffer(GL_ARRAY_BUFFER, bufID[CubeCol]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColorData),
cubeColorData, GL_STATIC_DRAW);
glColorPointer(3, GL_FLOAT, 0, NULL);
glEnableClientState(GL_COLOR_ARRAY);
// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufID[CubeIndices]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndicesData),
cubeIndicesData, GL_STATIC_DRAW);
}
void resize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60.0, (float)w/(float)h, 0.1, 50.0);
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// set camera
gluLookAt(3.0, -1.0, 4.5, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0);
// draw scene
glRotatef(t, 0.0f, 0.0f, 1.0f);
// bind cube VAO
glBindVertexArray(vaoID[Cube]);
// render data
glDrawElements(GL_QUADS, cubeIndicesNo,
GL_UNSIGNED_INT, NULL);
glTranslatef(0.0f, 0.0f, 1.0f);
// bind pyramid VAO
glBindVertexArray(vaoID[Pyramid]);
// render data
glDrawArrays(GL_TRIANGLES, 0, pyramidVertNo);
}
};
v 0.6 -2.5 0.1
vt 0.5 0.75
vn 0.0 -1.0 0.0
f v/vt/vn v/vt/vn v/vt/vn v/vt/vnDabei beziehen sich der jeweils erste Index auf die Liste der Positionen, der zweite auf die Liste der Texturkoordinaten und der dritte auf die Liste der Normalen
# Wavefront OBJ file example # o Cube v -1.0 1.0 1.0 v -1.0 -1.0 1.0 v 1.0 -1.0 1.0 v 1.0 1.0 1.0 v -1.0 1.0 -1.0 v -1.0 -1.0 -1.0 v 1.0 -1.0 -1.0 v 1.0 1.0 -1.0 # 8 vertices vt 0.0 0.0 vt 1.0 0.0 vt 1.0 1.0 vt 0.0 1.0 # 4 texture coordinates vn 0.0 0.0 1.0 vn -0.0 -0.0 -1.0 vn -1.0 -0.0 0.0 vn 0.0 -1.0 0.0 vn 1.0 0.0 -0.0 vn -0.0 1.0 -0.0 # 6 normals f 1/1/1 2/2/1 3/3/1 4/4/1 f 5/1/2 8/2/2 7/3/2 6/4/2 f 1/1/3 5/2/3 6/3/3 2/4/3 f 2/1/4 6/2/4 7/3/4 3/4/4 f 3/1/5 7/2/5 8/3/5 4/4/5 f 5/1/6 1/2/6 4/3/6 8/4/6 # 6 quads # indices start with 1 not 0
f v/vt/vn v/vt/vn v/vt/vn
f v v v
f v/vt v/vt v/vt
f v//vn v//vn v//vn
includedPerVertexData[] das erzeugte Float-Array so anzupassen, dass
es dem jeweils benötigten Format des VBOs entspricht (Details im Quelltext)
struct Vertex
{
float position[3];
float color[4];
float texCoord[2];
float normal[3];
};
int includedPerVertexData[] = {POS_3f, DIFFUSE_3f, ALPHA_1f, TEXCOORD_2f, NORMAL_3f};
class Renderer {
private:
struct Vertex {
float position[3];
float color[4];
};
public:
float t;
private:
enum {Triangle, numVAOs};
enum {TriangleAll, numVBOs};
GLuint vaoID[numVAOs];
GLuint bufID[numVBOs];
int triangleVertNo;
int cubeIndicesNo;
public:
// constructor
Renderer() : t(0.0), triangleVertNo(0), cubeIndicesNo(0) {}
//destructor
~Renderer() {
glDeleteVertexArrays(numVAOs, vaoID);
glDeleteBuffers(numVBOs, bufID);
}
public:
void init() {
initExtensions();
glEnable(GL_DEPTH_TEST);
// create a Vertex Array Objects (VAO)
glGenVertexArrays(numVAOs, vaoID);
// generate a Vertex Buffer Object (VBO)
glGenBuffers(numVBOs, bufID);
// binding the Triangle VAO
glBindVertexArray(vaoID[Triangle]);
float triangleVertexData[] = {
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-0.5f,-0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.5f,-0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,
};
triangleVertNo = 3;
glBindBuffer(GL_ARRAY_BUFFER, bufID[TriangleAll]);
glBufferData(GL_ARRAY_BUFFER, triangleVertNo*sizeof(Vertex),
triangleVertexData, GL_STATIC_DRAW);
int stride = sizeof(Vertex);
char *offset = (char*)NULL;
// position
int vertexLoc = 0;
glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE,
stride, offset);
glEnableVertexAttribArray(vertexLoc);
}
void resize(int w, int h) {
glViewport(0, 0, w, h);
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// bind Triangle VAO
glBindVertexArray(vaoID[Triangle]);
// render data
glDrawArrays(GL_TRIANGLES, 0, triangleVertNo);
}
};
Anregungen oder Verbesserungsvorschläge können auch gerne per E-mail an mich gesendet werden: Kontakt