Vertex Array Object

Vertex Array Object нь оройн аттрибутуудын төлөвүүдийг бүлэглэж ажилладаг.
Оройнуудыг агуулсан олон массивууд байвал зурах үйлдэл хийгдэх үед тэдгээрийн хооронд маш түргэнээр шилжилт хийн ашиглах боломжийг олгодог.

    glBindVertexArray(vaods[i]);

Үүсгэхдээ бусад OpenGL объектүүдтэй ажилладаг шиг Gen, Bind, Delete функцүүд хэрэглэгддэг.
    GLuint vaods[N];
    glGenVertexArrays(GLsizei N, GLuint *vaods);
жишээлбэл
    GLuint vaod[2];
    glGenVertexArrays(2, vaod);

Ашиглахаар болвол
    glBindVertexArray(GLuint voads[int i]);

VAO-уудын хооронд шилжилт хийх жишээ

float cone[N][3], ccolors[N][3]; 
float cube[M][3], bcolors[M][3]; 
 
glBindVertexArray(vaods[CONE]); 
glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, 0, cone);
glEnableClientState(GL_COLOR_ARRAY); 
glColorPointer(3, GL_FLOAT, 0, ccolors); 
 
glBindVertexArray(vaods[CUBE]); 
glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, 0, cube);!
glEnableClientState(GL_COLOR_ARRAY); 
glColorPointer(3, GL_FLOAT, 0, bcolors); 
 
glBindVertexArray(vaods[CONE]); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, N); 
glBindVertexArray(vaods[CUBE]); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, M); 
glBindVertexArray(vaods[CONE]); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, N)


VAO-г VBO-тэй хамт ашиглах
эхлээд VBO буюу Vertex Buffer Object-ээ үүсгэх хэрэгтэй
float cone[N][3], ccolors[N][3]; 
float cube[M][3], bcolors[M][3]; 
enum {CONE=0, CUBE, NSHAPES}; 
 
GLuint vbods[NSHAPES]; 
glGenBuffers(NSHAPES, vbods); 
 
// хоёр ширхэг vertex buffer object тохируулах
glBindBuffer(GL_ARRAY_BUFFER, vbods[CONE]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(cones)+sizeof(ccolors), 0, GL_STATIC_DRAW)); 
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cone), cone);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(cone), sizeof(ccolors), ccolors);
 
glBindBuffer(GL_ARRAY_BUFFER, vbods[CUBE]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(cube)+sizeof(bcolors), 0, GL_STATIC_DRAW)); 
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cube), cube);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube), sizeof(bcolors), bcolors);

VAO буюу Vertex Array Object-ээ үүсгэх
GLuint vaods[NSHAPES]; 
glGenVertexArrays(NSHAPES, vaods); 
 
// хоёр ширхэг vertex array object үүсгэх
glBindVertexArray(vaods[CONE]); 
glBindBuffer(GL_ARRAY_BUFFER, vbods[CONE]); 
glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, 0, 0 /* buffer byte offset */);
glEnableClientState(GL_COLOR_ARRAY); 
glColorPointer(3, GL_FLOAT, 0, sizeof(cone) /* byte offset */); 
 
glBindVertexArray(vaods[CUBE]); 
glBindBuffer(GL_ARRAY_BUFFER, vbods[CONE]); 
glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(3, GL_FLOAT, 0, 0 /* byte offset */);
glEnableClientState(GL_COLOR_ARRAY); 
glColorPointer(3, GL_FLOAT, 0, sizeof(cube) /* byte offset */);

Ингээд бэлэн болсон тул дүрснүүдийн хооронд шилжин VAO-ийн тусламжтай зурах үйлдлийг маш түргэн хийнэ.
glBindVertexArray(vaods[CONE]); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, N); 
 
glBindVertexArray(vaods[CUBE]); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, M); 
 
glBindVertexArray(vaods[CONE]); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, N);

Бүрэн код нь
/* 
 * File:   main.cpp
 * Author: Sharavsambuu
 *
 * Created on November 17, 2013, 8:18 PM
 */

#define GLEW_STATIC
#include "GL/glew.h"
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>

using namespace std;

int main(int argc, char** argv) {
    GLdouble width = 800.0;
    GLdouble height = 600.0;

    GLFWwindow* window;
    if (!glfwInit())
        return EXIT_FAILURE;

    window = glfwCreateWindow((int) width, (int) height, "OpenGL VBO VAO", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return EXIT_FAILURE;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (GLEW_OK != err) {
        cout << "error in glewInit " << glewGetErrorString(err) << endl;
        return EXIT_FAILURE;
    }

    cout << "start cooking" << endl;

    enum {
        TRIAD = 0, QUAD, NumVAOs
    };
    GLuint vaods[NumVAOs];
    GLfloat triad[3][2] = {// (0,0) бол зүүн доод булан
        { 0.0, 64.0},
        { 0.0, 0.0},
        { 64.0, 0.0}
    };
    GLfloat quad[4][2] = {// (0,0) нь зүүн доод булан
        { 0.0, 64.0}, // v0
        { 0.0, 0.0}, // v1
        { 64.0, 64.0}, // v2; T0: v0-v1-v2
        { 64.0, 0.0} // v3; T1: v2-v1-v3
    };
    GLfloat colors[4][3] = {
        { 1.0, 0.0, 0.0},
        { 0.0, 1.0, 0.0},
        { 0.0, 0.0, 1.0},
        { 0.0, 1.0, 1.0}
    };

    GLuint vbods[2]; // VBO 
    glGenBuffers(2, vbods);

    glBindBuffer(GL_ARRAY_BUFFER, vbods[QUAD]);
    glBufferData(GL_ARRAY_BUFFER, sizeof (quad) + sizeof (colors), quad, GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER, sizeof (quad), sizeof (colors), colors);

    glBindBuffer(GL_ARRAY_BUFFER, vbods[TRIAD]);
    glBufferData(GL_ARRAY_BUFFER, sizeof (triad) + sizeof (colors), triad, GL_STATIC_DRAW);

    glBufferSubData(GL_ARRAY_BUFFER, sizeof (triad), sizeof (colors), colors);

    glGenVertexArrays(NumVAOs, vaods); // VAO

    glBindVertexArray(vaods[TRIAD]);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, 0);
    glColorPointer(3, GL_FLOAT, 0, (GLvoid *) sizeof (triad));

    glBindVertexArray(vaods[QUAD]);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER, vbods[QUAD]);
    glVertexPointer(2, GL_FLOAT, 0, 0);
    glColorPointer(3, GL_FLOAT, 0, (GLvoid *) sizeof (quad));


    glViewport(0, 0, (GLsizei) width, (GLsizei) height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, width, 0.0, height);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


    float deltaTime = 0.0f;
    float startTime = glfwGetTime();
    float buffTime = 0.0;
    int counter = 0;
    while (!glfwWindowShouldClose(window)) {
        int x, y;

        glClearColor(1.0, 1.0, 1.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);

        for (y = 0; y < 10; y++) {
            glLoadIdentity();
            glTranslatef(0.0, y * 64.0, 0.0);
            for (x = 0; x < 10; x++) {
                glBindVertexArray(vaods[TRIAD]);
                glDrawArrays(GL_TRIANGLES, 0, 3);

                glTranslatef(64.0, 0.0, 0.0);
                glBindVertexArray(vaods[QUAD]);
                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

                glTranslatef(64.0, 0.0, 0.0);
            }
        }

        glfwSwapBuffers(window);
        glfwPollEvents();

        double lastTime = glfwGetTime();
        deltaTime = lastTime - startTime;
        startTime = lastTime;
        counter++;
        buffTime += deltaTime;
        if (buffTime > 1.0f) {
            buffTime = 0.0f;
            cout << "fps " << counter << endl;
            counter = 0;
        }
    }

    glfwTerminate();
    return 0;
}


Popular posts from this blog

Apache Spark + Cassandra. Hello World