CCGLBufferedNode(作为CCGrid3D CCLayerColor CCProgressTimer CCSprite CCTexture2D的基类(提供渲染接口))

来源:互联网 发布:51单片机p0口上拉电阻 编辑:程序博客网 时间:2024/05/16 03:37

.COcos2d-X 节点(CCGLBufferedNode)API 从 GL的缓冲区加载数据 

class CC_DLL CCGrid3D : public CCGridBase

#ifdef EMSCRIPTEN

, public CCGLBufferedNode

#endif // EMSCRIPTEN


class CC_DLL CCLayerColor : public CCLayerRGBA, public CCBlendProtocol

#ifdef EMSCRIPTEN

, public CCGLBufferedNode

#endif // EMSCRIPTEN


class CC_DLL CCProgressTimer : public CCNodeRGBA

#ifdef EMSCRIPTEN

, public CCGLBufferedNode

#endif // EMSCRIPTEN


class CC_DLL CCSprite : public CCNodeRGBA, public CCTextureProtocol

#ifdef EMSCRIPTEN

, public CCGLBufferedNode

#endif // EMSCRIPTEN


class CC_DLL CCTexture2D : public CCObject

#ifdef EMSCRIPTEN

, public CCGLBufferedNode

#endif // EMSCRIPTEN

#ifndef __CC_GL_BUFFERED_NODE__

#define __CC_GL_BUFFERED_NODE__


#include <CCGL.h>


class CCGLBufferedNode

{

public:

    CCGLBufferedNode(void);

CCGLBufferedNode::CCGLBufferedNode(void)

{

    for(int i = 0; i < BUFFER_SLOTS; i++)

    {

        m_bufferObject[i] = 0;

        m_bufferSize[i] = 0;

        m_indexBufferObject[i] = 0;

        m_indexBufferSize[i] = 0;

    }

}


    /**

     * Load the given data into this CCNode's GL Buffer. Needed for WebGL, as it does not support client-side arrays.

     */

    void setGLBufferData(void *buf, GLuint bufSize, int slot);


void CCGLBufferedNode::setGLBufferData(void *buf, GLuint bufSize, int slot)

{

    // WebGL doesn't support client-side arrays, so generate a buffer and load the data first.

    if(m_bufferSize[slot] < bufSize)

    {

        if(m_bufferObject[slot])

        {

           glDeleteBuffers(1, &(m_bufferObject[slot]));

        }

       glGenBuffers(1, &(m_bufferObject[slot]));

       m_bufferSize[slot] = bufSize;


       glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[slot]);

       glBufferData(GL_ARRAY_BUFFER, bufSize, buf, GL_DYNAMIC_DRAW);

    }

    else

    {

       glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[slot]);

       glBufferSubData(GL_ARRAY_BUFFER, 0, bufSize, buf);

    }

}


    void setGLIndexData(void *buf, GLuint bufSize, int slot);


void CCGLBufferedNode::setGLIndexData(void *buf, GLuint bufSize, int slot)

{

    // WebGL doesn't support client-side arrays, so generate a buffer and load the data first.

    if(m_indexBufferSize[slot] < bufSize)

    {

        if(m_indexBufferObject[slot])

        {

           glDeleteBuffers(1, &(m_indexBufferObject[slot]));

        }

       glGenBuffers(1, &(m_indexBufferObject[slot]));

        m_indexBufferSize[slot] = bufSize;


       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferObject[slot]);

       glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufSize, buf, GL_DYNAMIC_DRAW);

    }

    else

    {

       glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBufferObject[slot]);

       glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, bufSize, buf);

    }

}



    // We allocate 4 buffer objs per node, and index into them as slots.

//每个节点分配4个缓存 

#define BUFFER_SLOTS 4

    GLuint m_bufferObject[BUFFER_SLOTS]; //typedef unsigned int    GLuint

    GLuint m_bufferSize[BUFFER_SLOTS];


    GLuint m_indexBufferObject[BUFFER_SLOTS];

    GLuint m_indexBufferSize[BUFFER_SLOTS];

};

#endif // __CC_GL_BUFFERED_NODE__



关于gl



一:为什么要有opengl缓冲区对象

前面的顶点数组使得几何图元的显示方便了很多,但是如果每次都要向OPENGL发送一大块数据,而这数据其实并没有修改过,那么这传输就是冗余的。所以这里添加了缓冲区对象,将顶点数组存储在服务器端的缓冲区对象中。


二:如何创建和使用缓冲区对象

1.创建缓冲区对象
    glGenBuffers():OpenGL分配n个当前未使用的名称(非 0),表示缓冲区对象。
    原型 : void glGenBuffers(GLsizei n,GLuint *buffers);
    GLboolean glIsBuffer(GLuint buffer):判断一个标识符是否是当前使用的缓冲区对象的标识符。

  2.激活缓冲区对象
    激活缓冲区对象,首先需要对他进行绑定。绑定缓冲区对象表示选择未来的操作将影响到哪个缓冲区    对象。
    glBindBuffer(GLenum target ,GLuint buffer): 指定了当前的活动缓冲区对象 。

  3.用数据分配和初始化缓冲区对象
     一旦绑定了一个缓冲区对象,就需要保留空间以存储数据。
    void glBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage );
    功能是分配size个存储单位的OpenGL服务器内存,用于存储顶点数据或索引。以前有与当前缓冲区对象相关联的数据将删除。
    glBufferData()首先在OpenGL拂去其中分配内存以存储数据。如果成功分配,data!=NULL,size个单位就会从客户机内存复制到这个对象中。如果data=NULL,为数据保留适当的空间,但不会初始化。

4.更新缓冲区对象的数据值
    方法一:假设已经在用用程序的一个缓冲区中准备了相同类型的数据,glBufferSubData()将用我们提供的数据替换被绑定的缓冲区对象的一些数据子集。
            void glBufferSubData(GLenum target,GLuint offset,GLsizei size,const GLvoid *data); 用data 指向的数据更新 与target 相关联的当前绑定缓冲区对象中从offset开始的size个字节数据。
             
    方法二:允许灵活的选择需要更新的数据。
            GLvoid *glMapBuffer(GLenum target,GLuenum access):返回一个指向缓冲区对象的指针,可以在这个缓冲区对象中写入新值及更新之后,再调用GLboolean glUnMapBuffer(GLenum target)表示已经完成了对数据的更新,取消对这个缓冲区的映射。如果只需要更新所需范围内的数据值,也可调用GLvoid *glMapBuffwerRange(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)

   5.在缓冲区对象之间复制数据
     void glCopyBufferSubData(readbuffer,writebuffer,resdoffset,writeoffset,size);
     把数据从与readbuffer相关联的缓冲区对象复制到绑定到writebuffer的缓冲区对象。

   6. 清除缓冲区对象
      glDeleteBuffer(GLsizei n,const GLuint *buffers):删除n个缓冲区对象。被删除的当前缓冲区对象的所有绑定都重置为零。如果一个缓冲区对象是在绑定时删除的,这个对象的所有绑定都重置为默认的缓冲区对象。

   7.使用缓冲区对象来存储顶点数组数据
      需要以下步骤:
       (1)生成缓冲区对象标识符;
       (2)绑定缓冲区对象,确定是存储顶点数据还是索引;
       (3)请求数据的存储空间,并对数据元素进行初始化;
       (4)指定相对于缓冲区起始位置的偏移量;
       (5)绑定适当的缓冲区对象,用于渲染;
       (6)使用适当的顶点数组渲染函数进行渲染,比如glDrawArrays()
      如果想初始化多个缓冲区对象,就需要为每个缓冲区对象重复以上。顶点数组数据的所有格式都适用于缓冲区对象。

流程图如下:

image


0 0
原创粉丝点击