天天看點

OpenGLES---緩沖區

{
	1:頂點緩沖區 GL_ARRAY_BUFFER
	2:索引緩沖區 GL_ELEMENT_ARRAY_BUFFER
	3:幀緩沖區 GL_FRAMEBUFFER/GL_RENDERBUFFER
	4:封裝
}
           
{1:頂點緩沖區 GL_ARRAY_BUFFER
	
	OpenGL-ES 中 Vertex Arrays/Buffer Objects 在這個階段發生

	struct VX{
		float x, y, z;
		float u,v;
		float r, g, b,a;
	};

	float zOff=-2.1f;
	VX vertexs[] ={
		{ -1.0f,-1.0f, zOff,	0.0f,0.0f,	1.0f,1.0f, 1.0f,1.0f },
		{  1.0f,-1.0f, zOff,	1.0f,0.0f,	1.0f,1.0f, 1.0f,1.0f },
		{  1.0f, 1.0f, zOff,	1.0f,1.0f,	1.0f,1.0f, 1.0f,1.0f },

		{ -1.0f,-1.0f, zOff,	0.0f,0.0f,	1.0f,1.0f, 1.0f,1.0f },
		{  1.0f, 1.0f, zOff,	1.0f,1.0f,	1.0f,1.0f, 1.0f,1.0f },
		{ -1.0f, 1.0f, zOff,	0.0f,1.0f,	1.0f,1.0f, 1.0f,1.0f },
	};

	unsigned vbId; //資料id

	{建立資料
		glGenBuffers(1,&vbId);
		glBindBuffer(GL_ARRAY_BUFFER,vbId); //綁定/取消緩沖區
		glBufferData(GL_ARRAY_BUFFER,sizeof(vertexs),vertexs,GL_STATIC_DRAW);//設定緩沖區資料
		glBindBuffer(GL_ARRAY_BUFFER,0);//綁定/取消緩沖區
	}

	{使用資料
		glBindBuffer(GL_ARRAY_BUFFER,vbId);//綁定/取消緩沖區
		glVertexAttribPointer(shader._position,3,  GL_FLOAT,   false,  sizeof(VX),(void*)0);
		glVertexAttribPointer(shader._tpos,    2,  GL_FLOAT,   false,  sizeof(VX),(void*)(3*sizeof(float)));
		glVertexAttribPointer(shader._color,   4,  GL_FLOAT,   false,  sizeof(VX),(void*)(3*sizeof(float)+2*sizeof(float)));
		glDrawArrays(GL_TRIANGLES,0,6);//三角形 (三個點畫一個三角形)
		glBindBuffer(GL_ARRAY_BUFFER,0);//綁定/取消緩沖區 注意:使用完就制空,OpenGL-ES是狀态機
	}

	切記:緩沖資料在什麼地方用在什麼地方制空,不指空的話,下面的資料全是這個緩沖資料

	注意:
		glBufferData(,size,,) size->sizeof(vertexs)是資料大小不是偏移量大小
		glVertexAttribPointer (,,,,stride,);stride->sizeof(VX)是偏移量大小不是資料大小

}
           
{2:索引緩沖區 GL_ELEMENT_ARRAY_BUFFER
	OpenGL-ES 中 Vertex Arrays/Buffer Objects 在這個階段發生

	unsigned ibId; //資料id
	{建立資料
		glGenBuffers(1,&ibId);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibId); //綁定/取消緩沖區
		glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vertexs),vertexs,GL_STATIC_DRAW);//設定緩沖區資料
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); //綁定/取消緩沖區
	}

	{使用資料
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibId);//綁定/取消緩沖區
		glDrawElements(繪制模式,繪制資料大小,資料類型,);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);//綁定/取消緩沖區 注意:使用完就制空,OpenGL-ES是狀态機
	}

	{code
		struct Vertex {
			float x, y, z;
			float u,v;
			float r, g, b,a;
		};
		Vertex positionData[] = {
			-1.0f, 1.0f,-1.0f,		0.0f,0.0f,     1.0f, 1.0f, 1.0f,1.0f, //  上左後
			-1.0f, 1.0f, 1.0f,		0.0f,1.0f,     1.0f, 1.0f, 1.0f,1.0f, //  上左前
			1.0f, 1.0f,-1.0f,		1.0f,0.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,		0.0f,0.0f,     1.0f, 1.0f, 1.0f,1.0f, //  下左後
			-1.0f,-1.0f, 1.0f,		0.0f,1.0f,     1.0f, 1.0f, 1.0f,1.0f, //  下左前
			1.0f,-1.0f,-1.0f,		1.0f,0.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  //  下右前
		};
		byte indexData[]={
			0,1,2,2,3,1,  //上
			0,4,5,5,2,0,  //左
			0,4,6,6,2,0,  //後
			2,7,6,6,2,3,  //右
			1,5,7,7,2,1,  //前
			4,5,6,6,7,4,  //下
		};


		unsigned  vbId;//頂點緩沖區 id
		unsigned  ibId;//索引緩沖區 id

		//頂點緩沖區 id
		glGenBuffers(1,&vbId);
		glBindBuffer(GL_ARRAY_BUFFER,vbId);
		glBufferData(GL_ARRAY_BUFFER,sizeof(positionData),positionData,GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER,0);

		//索引緩沖區 id
		glGenBuffers(1,&ibId);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibId);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indexData),indexData,GL_STATIC_DRAW);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

		執行個體1
		glBindBuffer(GL_ARRAY_BUFFER,vbId);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibId);
		...
		glVertexAttribPointer(shader._position,3,  GL_FLOAT,   false,  sizeof(Vertex),(void*)0);
		glVertexAttribPointer(shader._tpos,    2,  GL_FLOAT,   false,  sizeof(Vertex),(void*)(3*sizeof(float)));
		glVertexAttribPointer(shader._color,   4,  GL_FLOAT,   false,  sizeof(Vertex),(void*)(3*sizeof(float)+2*sizeof(float)));

		glDrawElements(GL_TRIANGLES,sizeof(indexData)/sizeof(indexData[0]),GL_UNSIGNED_BYTE,0);

		glBindBuffer(GL_ARRAY_BUFFER,0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

		執行個體2
		...
		glVertexAttribPointer(shader._position,3,  GL_FLOAT,   false,  sizeof(Vertex),(void*)0);
		glVertexAttribPointer(shader._tpos,    2,  GL_FLOAT,   false,  sizeof(Vertex),(void*)(3*sizeof(float)));
		glVertexAttribPointer(shader._color,   4,  GL_FLOAT,   false,  sizeof(Vertex),(void*)(3*sizeof(float)+2*sizeof(float)));

		glDrawElements(GL_TRIANGLES,sizeof(indexData)/sizeof(indexData[0]),GL_UNSIGNED_BYTE,indexData);

		glBindBuffer(GL_ARRAY_BUFFER,0);

	}

}
           
{3:幀緩沖區 GL_FRAMEBUFFER/GL_RENDERBUFFER
	OpenGL-ES 中 Framebuffer 在這個階段發生

	{
		1:建立一張幀緩沖大小
		2:把要畫的東西畫的一張紋理上(幀緩沖和紋理id綁定)
		3:渲染這種紋理
	}

	{code

		struct FBO{
			unsigned fb;//幀緩沖
			unsigned rb;//渲染緩沖
		};

		FBO createFBO(int width,int height){
			FBO frb;
			glGenFramebuffers(1,&frb.fb);//生成幀緩沖的索引
			glBindFramebuffer(GL_FRAMEBUFFER,frb.fb);//綁定幀緩沖

			glGenRenderbuffers(1,&frb.rb);//生成渲染緩沖的索引
			glBindRenderbuffer(GL_RENDERBUFFER,frb.rb);//綁定渲染緩沖

			/** 繪制渲染緩沖區的存儲大小
			 * @param  target  類型(GL_RENDERBUFFER ...)
			 * @param  internalformat 存儲資料格式(GL_DEPTH_COMPONENT16 深度資訊)
			 * @param  width 存儲的寬
			 * @param  height 存儲的高
			 */
			glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT16,width,height);

			glBindRenderbuffer(GL_RENDERBUFFER,0);

			/** 幀緩沖區與渲染緩沖區綁定
			 * @param  target  幀緩沖區類型(GL_FRAMEBUFFER 幀緩沖區)
			 * @param  attachment  關聯的類型(GL_DEPTH_ATTACHMENT 深度)
			 * @param  renderbuffertarget  渲染緩沖區類型(GL_RENDERBUFFER 渲染緩沖區)
			 * @param  renderbuffer  渲染緩沖區id
			 */
			glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,frb.rb);

			glBindFramebuffer(GL_FRAMEBUFFER,0);

			return frb;
		}

		void beginFBO(unsigned fboId,uniform textureId){
			glBindFramebuffer(GL_FRAMEBUFFER,fboId);
			/** 幀緩沖區資料渲染到紋理上
			 * @param  target 幀緩沖類型(GL_RENDERBUFFER ...)
			 * @param  attachment 緩存區類型 (GL_COLOR_ATTACHMENT0 顔色緩存區)
			 * @param  textarget 紋理類型 (GL_TEXTURE_2D ...)
			 * @param  texture 紋理id
			 * @param  level 層級别(資料渲染到紋理的什麼層級别上)
			 */
			glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,textureId,0);
		}
		void endFBO(){
			glBindFramebuffer(GL_FRAMEBUFFER,0);
		}

1:建立一張幀緩沖大小
		FBO  fboId;
		unsigned textureFboId;//幀緩沖資料儲存到這張紋理上

		{//幀緩沖區
			fboId=createFBO(_width,_height);
			textureFboId=createTexture(_width,_height);
		}
2:把要畫的東西畫的一張紋理上(幀緩沖和紋理id綁定)
		beginFBO(fboId.fb,textureFboId);
			.... //是以要添加到幀緩沖的資料
		endFBO();
3:渲染這種紋理
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		//設定視口的大小
		glViewport(0,0,_width,_height);
		shader.begin();
				
			glBindTexture(GL_TEXTURE_2D,textureFboId);
			CELL::matrix4 mat=CELL::ortho<float>(0,(float)_width,(float)_height,0,-100,100);
			glUniformMatrix4fv(shader._MVP,1,false,mat.data());

			glVertexAttribPointer(shader._position,3,GL_FLOAT,false,sizeof(Vertex),&xt[0].pos);
			glVertexAttribPointer(shader._tpos,2,GL_FLOAT,false,sizeof(Vertex),&xt[0].uvpos);
			glVertexAttribPointer(shader._color,4,GL_FLOAT,false,sizeof(Vertex),&xt[0].rgba);
			glDrawArrays(GL_TRIANGLE_STRIP,0,sizeof(xt)/sizeof(xt[0]));

		shader.end();
	}

}
           
{4:封裝
	VertexBuffer 頂點緩沖區  create,begin,end
	ElementBuffer 建立索引緩沖區  create,begin,end
	FrameBefferObject 幀緩沖  create,begin,end
}

//DataBuffer.hpp
#pragma once
#include "gles2/gl2.h"


class DataBuffer {
public:
	virtual~DataBuffer() {};
	virtual void begin() = 0;
	virtual void end() = 0;
	virtual void destroy() = 0;//銷毀
protected:
	DataBuffer() {};
private:

};


/** 頂點緩沖區
*	struct VX{
*		float x, y, z;
*		float u,v;
*		float r, g, b,a;
*	};
*	VX vertexs[] ={
*		{ -1.0f,-1.0f, zOff,	0.0f,0.0f,	1.0f,1.0f, 1.0f,1.0f },
*		{  1.0f,-1.0f, zOff,	1.0f,0.0f,	1.0f,1.0f, 1.0f,1.0f }
*	}
*	//建立
*	VertexBuffer vbId=VertexBuffer::create(sizeof(vertexs),vertexs,GL_STATIC_DRAW);
*	//使用
*	vbId.begin();
*		...使用過程
*		glVertexAttribPointer(shader._position,3,  GL_FLOAT,   false,  sizeof(VX),(void*)0);
*		glVertexAttribPointer(shader._tpos,    2,  GL_FLOAT,   false,  sizeof(VX),(void*)(3*sizeof(float)));
*		//glVertexAttribPointer(shader._position,3,  GL_FLOAT,   false,  sizeof(VX),vertexs[0].x);
*		//glVertexAttribPointer(shader._tpos,    2,  GL_FLOAT,   false,  sizeof(VX),vertexs[0].u);
*	vbId.end();
*/
class VertexBuffer :public DataBuffer {
public:
	unsigned vbId;
public:
	virtual~VertexBuffer() {}

	/** 建立頂點緩沖區
	* @param  dataSize 資料大小
	* @param  data     資料
	* @param  dataType
	*		GL_STREAM_DRAW   偶爾需要改動資料
	*		GL_STATIC_DRAW   不改動(靜态的)資料
	*		GL_DYNAMIC_DRAW  經常改動(動态的)資料
	* @return          [description]
	*/
	static VertexBuffer  create(int dataSize, void *data, int dataType = GL_STATIC_DRAW) {
		VertexBuffer vb;
		glGenBuffers(1, &vb.vbId);
		glBindBuffer(GL_ARRAY_BUFFER, vb.vbId); //綁定/取消緩沖區
		glBufferData(GL_ARRAY_BUFFER, dataSize, data, dataType);//設定緩沖區資料(更新全部資料)
		//glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);//設定緩沖區資料(更新局部資料)
		glBindBuffer(GL_ARRAY_BUFFER, 0);//綁定/取消緩沖區
		return vb;
	}
	virtual void begin() {
		glBindBuffer(GL_ARRAY_BUFFER, vbId); //綁定/取消緩沖區
	}
	virtual void end() {
		glBindBuffer(GL_ARRAY_BUFFER, 0); //綁定/取消緩沖區
	}
	virtual void destroy() {
		glDeleteBuffers(1, &vbId);
	}
public:
	VertexBuffer() {}
};

/** 建立索引緩沖區
*	byte indexData[] = {
*		0, 1, 2, 2, 3, 0,  //上
*		0, 4, 5, 5, 1, 0,  //左
*		0, 4, 6, 6, 3, 0,  //後
*		2, 7, 6, 6, 3, 2,  //右
*		1, 5, 7, 7, 2, 1,  //前
*		4, 5, 7, 7, 6, 4,  //下
*	};
*
*	//建立
*	int drawSize = sizeof(indexData) / sizeof(indexData[0]);
*	ElementBuffer eb= ElementBuffer::create(drawSize,sizeof(indexData),indexData,GL_STATIC_DRAW);
*	//使用
*	eb.begin();
*		...使用過程(注意 頂點說索引同時使用eb.data 就不許添了,添0就可以了)
*		glDrawElements(GL_TRIANGLES, eb.drawSize, GL_UNSIGNED_BYTE, eb.data);
*	eb.end();
*/
class ElementBuffer :public DataBuffer {
public:
	unsigned ebId;
	int drawSize;//渲染資料個數
	void *data;//資料
public:
	virtual~ElementBuffer() {}

	/** 建立索引緩沖
	* @param  drawSize 渲染資料個數
	* @param  dataSize 資料大小
	* @param  data     資料
	* @param  dataType
	GL_STREAM_DRAW   偶爾需要改動資料
	GL_STATIC_DRAW   不改動(靜态的)資料
	GL_DYNAMIC_DRAW  經常改動(動态的)資料
	* @return          [description]
	*/
	static ElementBuffer  create(int drawSize, int dataSize, void *data, int dataType = GL_STATIC_DRAW) {
		ElementBuffer eb;
		eb.drawSize = drawSize;
		eb.data = data;
		glGenBuffers(1, &eb.ebId);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eb.ebId); //綁定/取消緩沖區
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, dataSize, data, dataType);//設定緩沖區資料(更新全部資料)
		//glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, data);//設定緩沖區資料(更新局部資料)
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //綁定/取消緩沖區

		return eb;
	}
	virtual void begin() {
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebId); //綁定/取消緩沖區
	}
	virtual void end() {
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //綁定/取消緩沖區
	}
	virtual void destroy() { glDeleteBuffers(1, &ebId); }
public:
	ElementBuffer() {
		drawSize = -1;
		data = NULL;
	}

};

/** 幀緩沖
*	FrameBefferObject fboId=FrameBefferObject::create(100,100);
*	fboId.begin(textureFboId);
*		.... //是以要添加到幀緩沖的資料
*	fboId.end();
*	最後畫這張 textureFboId 紋理就可以了
*/
class FrameBefferObject {
public:
	unsigned fb;//幀緩沖
	unsigned rb;//渲染緩沖

public:
	virtual ~FrameBefferObject() {}
	static FrameBefferObject  create(int width, int height) {
		FrameBefferObject frb;
		glGenFramebuffers(1, &frb.fb);//生成幀緩沖的索引
		glBindFramebuffer(GL_FRAMEBUFFER, frb.fb);//綁定幀緩沖

		glGenRenderbuffers(1, &frb.rb);//生成渲染緩沖的索引
		glBindRenderbuffer(GL_RENDERBUFFER, frb.rb);//綁定渲染緩沖

		/** 繪制渲染緩沖區的存儲大小
		* @param  target  類型(GL_RENDERBUFFER ...)
		* @param  internalformat 存儲資料格式(GL_DEPTH_COMPONENT16 深度資訊)
		* @param  width 存儲的寬
		* @param  height 存儲的高
		*/
		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);

		glBindRenderbuffer(GL_RENDERBUFFER, 0);

		/** 幀緩沖區與渲染緩沖區綁定
		* @param  target  幀緩沖區類型(GL_FRAMEBUFFER 幀緩沖區)
		* @param  attachment  關聯的類型(GL_DEPTH_ATTACHMENT 深度)
		* @param  renderbuffertarget  渲染緩沖區類型(GL_RENDERBUFFER 渲染緩沖區)
		* @param  renderbuffer  渲染緩沖區id
		*/
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frb.rb);

		glBindFramebuffer(GL_FRAMEBUFFER, 0);

		return frb;
	}

	virtual void begin(unsigned textureId) {
		glBindFramebuffer(GL_FRAMEBUFFER, fb);
		/** 幀緩沖區資料渲染到紋理上
		* @param  target 幀緩沖類型(GL_RENDERBUFFER ...)
		* @param  attachment 緩存區類型 (GL_COLOR_ATTACHMENT0 顔色緩存區)
		* @param  textarget 紋理類型 (GL_TEXTURE_2D ...)
		* @param  texture 紋理id
		* @param  level 層級别(資料渲染到紋理的什麼層級别上)
		*/
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
	}

	virtual void end() {
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}
	virtual void destroy() {
		glDeleteRenderbuffers(1, &rb);
		glDeleteFramebuffers(1, &fb);
	}
public:
	FrameBefferObject() {}

};
           

源碼位址

http://pan.baidu.com/s/1geVargZ   緩沖區.zip

main.cpp
	//頭檔案不能都開,裡面有重複定義的類或函數,不解釋了自己看吧
	//#include "VertexBufferWin.hpp"
	//#include "ElementWin.hpp"
	#include "FraneBufferWin.hpp" 

	//VertexBufferWin app(hInstance);//頂點緩沖區資料
	//ElementWin app(hInstance);//索引緩沖區資料
	FraneBufferWin app(hInstance);//幀緩沖
           

幀緩沖效果圖,就畫的角上了,也可以全屏,代碼住了,自己看吧(在渲染過程中)

OpenGLES---緩沖區

繼續閱讀