• OPENGL学习笔记整理(三):缓冲区对象


    缓冲区对象对于OPENGL来说,很重要,虽然我并不经常用它,在红宝书上它属于高级话题。

    “在许多OPENGL操作中,我们都向OPENGL发送一大块数据,例如向它传递需要处理得顶点数组数据。传输这种数据可能非常简单,例如把数据从系统的内存中复制到图形卡。但是,由于OPENGL是按照客户机-服务器模式设计的,在OPENGL需要数据的任何时候,都必须把数据从客户机内存传到服务器。如果数据并没有修改,或者客户机和服务器位于不同的计算机(分布式渲染),数据的传输可能会比较缓慢,或者是冗余的。
    OPENGL 1.5版本增加了缓冲区对象(buffer object),允许应用程序显式地指定把哪些数据存储在图形服务器中。”

    由此可知,缓冲区对象在个人PC上,它存在于图形卡的显存中。最近经常需要用到缓冲区,因为开始接触到CUDA。CUDA是NVIDIA推出的GPU上的通用计算产品。因为是在显卡上做计算,想要和OPENGL进行互操作,用缓冲区比较方便。当然,在这里,我没打算把这两者结合起来说。这里只是简单的理一下缓冲怎么用而已。

    在OPENGL中,我们经常看到glGen*、glBind*这样的函数,缓冲区的操作也不例外。

    1.创建缓冲区对象 void glGenBuffers(GLsizei n, GLuint *buffers);(这个函数。。。顾名思义,就不用解释了)

    2.激活缓冲区对象 void glBindBuffer(GLenum target, GLuint buffer);

    3.用数据分配和初始化缓冲区对象 void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);

      (data为NULL,则缓冲区仅仅分配了空间,没有有意义的初始值;如果不是NULL,那就是data所指向的大小为size的内存的数据)

    上面的很机械,也很好理解。本人刚开始接触OPENGL的时候,创建和初始化都没问题,但老是搞不清楚该怎么用,尤其是如何把它和纹理联系在一起。后来发现关键在下面这个函数GLvoid *glMapBuffer(GLenum target, GLenum access),这个函数的返回值是一个指针,就是指向这个缓冲区的指针,只要注意设置,确实能返回指向缓冲区的指针。

    缓冲一经具体使用之后,只需要改变缓冲区的内容,即在glMapBuffer和glUnmapBuffer之间改变数据即可。

    下面是个简单程序,其实就是红宝书上的,我简单的修改了一下而已,-_-! 

    在键盘处理事件中可以看到如何更新缓冲区,让它放大,但如果改成缩小,貌似就会有问题,很奇怪的一个现象。

    #include "stdafx.h"
    #include
    "stdlib.h"
    #include
    "gl/glew.h"
    #include
    "gl/glut.h"

    #define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes))
    #define VERTICES 0
    #define INDICES 1
    #define NUM_BUFFERS 2
    GLuint buffers[NUM_BUFFERS];

    GLfloat vertices[][
    3] = {
    {
    -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}
    };
    GLubyte indices[][
    4] = {
    {
    0,1,2,3},
    {
    4,7,6,5},
    {
    0,4,5,1},
    {
    3,2,6,7},
    {
    0,3,7,4},
    {
    1,5,6,2}
    };

    GLfloat
    * bdata;

    void changeSize(int w, int h)
    {
    glViewport(
    0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(
    45.0,(double)w/(double)h,0.01,30);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    }

    void keyDown(unsigned char key, int x, int y)
    {
    switch (key)
    {
    case'b':
    bdata
    = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER,GL_READ_WRITE);
    for (int i =0; i <24; i ++)
    {
    *(bdata + i) *=1.1f;
    }
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glutPostRedisplay();
    break;
    }
    }

    void mouse(int button, int state, int x, int y)
    {

    }
    void display(void)
    {
    glLoadIdentity();
    glTranslatef(
    0.0f,0.0f,-5.0f);
    glRotatef(
    30.0f,1.0f,1.0f,0.0f);


    glDrawElements(GL_QUADS,
    24,GL_UNSIGNED_BYTE,BUFFER_OFFSET(0));

    glutSwapBuffers();
    }

    void init(void)
    {
    glClearColor(
    0.0f,0.0f,0.0f,0.0f);
    glShadeModel(GL_FLAT);
    glClear(GL_COLOR_BUFFER_BIT
    | GL_DEPTH_BUFFER_BIT);
    glewInit();
    glGenBuffers(NUM_BUFFERS,buffers);
    glBindBuffer(GL_ARRAY_BUFFER,buffers[VERTICES]);
    glBufferData(GL_ARRAY_BUFFER,
    sizeof(vertices),vertices,GL_DYNAMIC_DRAW);
    glVertexPointer(3,GL_FLOAT,0,BUFFER_OFFSET(0));

    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,buffers[INDICES]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
    sizeof(indices),indices,GL_STATIC_DRAW);
    }

    int main(int argc, char* argv[])
    {
    glutInit(
    &argc, argv);
    glutInitDisplayMode(GL_DOUBLE
    | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(
    512, 512);
    glutCreateWindow(
    "Buffer Demo");
    glutReshapeFunc(changeSize);
    glutMouseFunc(mouse);
    glutKeyboardFunc(keyDown);
    glutDisplayFunc(display);
    init();
    glutMainLoop();
    return0;
    }
  • 相关阅读:
    Redis持久化——AOF日志
    设计原则:接口隔离原则(ISP)
    设计原则:里式替换原则(LSP)
    新入职一家公司如何快速进入工作状态
    又是一年毕业季——如何入坑程序员
    设计原则:开闭原则(OCP)
    设计原则:单一职责(SRP)原则
    Redis持久化——内存快照(RDB)
    工作中应该如何管理自己的情绪?
    如何成为一个精力充沛的程序员——掌控
  • 原文地址:https://www.cnblogs.com/unsigned/p/1963875.html
Copyright © 2020-2023  润新知