Pixel Buffer.cpp

  像素缓冲区,pixel buffer.好几个月以前看书看到这就看得我迷迷糊糊,当时手头没有电脑,书被翻译得好多根本不是人话,我看了两遍也只是知道一个大概意思.大概一个月前,决定把上本书从头带着写代码再学习一遍.一个星期前看到了像素缓冲区这块,起初也是没看懂,示例代码是运动模糊特效,信息量比较大,理解起来很难,对我那时来说.于是我把问题简化,简化到先是渲染一个球,用内置的着色器,之后创建缓冲区对象,绑定到GL_PIXEL_PACK_BUFFER,把像素读取到刚创建的缓冲区中.再将刚创建的缓冲区绑定到GL_PIXEL_UNPACK_BUFFER,把缓冲区中的数据写到纹理中.结果就是刚刚渲染出的图像去到了纹理中,数据的传递在显存之间,也达到了得到渲染出的图像的目的,做一些后期处理什么的.从代码上来看就是渲染好一个白色的球之后,在同一帧对整个屏幕这个四边形进行再次渲染,投影矩阵用到了正投影矩阵,在片段着色器上提取出纹理后将其乘以0.5.最终看到的图像就是灰色的球.这个实现逻辑简单,如果单纯是学习使用缓冲区对象这样的事,还是从这样的例子入手比较好.学习也就是这样,自己动手实践出来,也就掌握得不错了.

  最近工作上事情多多,很多时候压得我很累.我也不知道该对谁去说.跟朋友说,平时不怎么联系,见面就喝酒,听听他们的不开心,我也很少说我自己的不开心.毕竟工作上的事情跟他们说我觉得挺无聊的.亲人就更不用说.跟女朋友说,我也不想办她老相好办过的事,整天和她说什么工作的事情,而她似乎也不会主动关心我这些.前几天装个虚拟机,一整好几天,后来发现之前美术愚蠢地组织贴图的方式,又弄了一个问题,昨天又开始弄SVN管理客户端外管理不到的代码.事情都是我给自己找的.我TM也不是程序的头,我有什么事情还得跟一个美术程序员说清楚,很多事必须他明白了我才能通过.很多时候觉得委屈无处去说,也得不到什么温暖.一天天就这么过着,似乎不管到什么时候,还是我自己最能慰藉我自己,给我自己温暖和动力.也可能是,我更习惯这样.不说了,贴出来代码,洗洗睡了.

//	PixelBuffers.cpp - 2013/09/23 - 22:40
#include "stdafx.h"

#include <GLTools.h>
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>
#include <StopWatch.h>

#define FREEGLUT_STATIC
#include <GL/glut.h>

GLFrame viewFrame;
GLFrustum viewFrustum;
GLTriangleBatch sphereBatch;
GLBatch screenQuad;
GLMatrixStack modelViewMatrix;
GLMatrixStack  projectionMatrix;
M3DMatrix44f orthoMatrix;
GLGeometryTransform transformPipeline;
GLShaderManager shaderManager;
CStopWatch timer ;

GLuint textures[1] ;
GLuint pixelBufferObjects[1];

GLuint pixelDataSize ;
void * pixelData ;

GLuint writeScreen;

GLsizei screenWidth ;
GLsizei screenHeight ;

void SetupRC(void)
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);

	shaderManager.InitializeStockShaders();
	viewFrame.MoveForward(4.0f);

	gltMakeSphere(sphereBatch, 1.0f, 26, 13);

	gltGenerateOrtho2DMat(screenWidth, screenHeight, orthoMatrix, screenQuad);

	writeScreen =  gltLoadShaderPairWithAttributes(
		"writeScreen.vs", "writeScreen.fs",
		2,
		GLT_ATTRIBUTE_VERTEX, "vVertex",
		GLT_ATTRIBUTE_TEXTURE0, "texCoord0");

	glGenTextures(1, textures) ;

	GLuint pixelDataSize = screenWidth * screenHeight * sizeof(GL_UNSIGNED_BYTE) ;
	void * textureData = (void *)malloc(pixelDataSize) ;
	memset(textureData, NULL, pixelDataSize) ;

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, textures[0]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);

	pixelData = malloc(pixelDataSize) ;
	glGenBuffers(1, pixelBufferObjects) ;
	glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBufferObjects[0]) ;
	glBufferData(GL_PIXEL_PACK_BUFFER, screenWidth * screenHeight * sizeof(GL_UNSIGNED_BYTE), NULL, GL_DYNAMIC_COPY) ;
	glBindBuffer(GL_PIXEL_PACK_BUFFER, 0) ;

	gltGenerateOrtho2DMat(screenWidth, screenHeight, orthoMatrix, screenQuad);

	timer.Reset() ;
}

void ShutdownRC(void)
{
	glDeleteTextures(1, textures) ;
	glDeleteBuffers(1, pixelBufferObjects) ;
}

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	modelViewMatrix.PushMatrix(viewFrame);

	float elapsedSceonds = timer.GetElapsedSeconds() ;

	modelViewMatrix.Translate(elapsedSceonds, 0, 0) ;

	if (elapsedSceonds > 1.0f)
		timer.Reset() ;
	
	GLfloat vAmbientColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };

	shaderManager.UseStockShader(GLT_SHADER_FLAT,
		transformPipeline.GetModelViewProjectionMatrix(),
		vAmbientColor);

	sphereBatch.Draw();

	modelViewMatrix.PopMatrix();

	glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBufferObjects[0]) ;
	glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, NULL) ;
	glBindBuffer(GL_PIXEL_PACK_BUFFER, 0) ;

	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pixelBufferObjects[0]) ;
	glActiveTexture(GL_TEXTURE0) ;
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL) ;
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0) ;

	projectionMatrix.PushMatrix() ;
	projectionMatrix.LoadIdentity() ;
	projectionMatrix.LoadMatrix(orthoMatrix) ;
	modelViewMatrix.PushMatrix() ;
	modelViewMatrix.LoadIdentity() ;
	glDisable(GL_DEPTH_TEST) ;
	glUseProgram(writeScreen) ;
	glUniformMatrix4fv(glGetUniformLocation(writeScreen, "mvpMatrix"), 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix()) ;
	glUniform1i(glGetUniformLocation(writeScreen, "textureUnit0"), 0) ;
	screenQuad.Draw() ;
	glEnable(GL_DEPTH_TEST) ;
	modelViewMatrix.PopMatrix() ;
	projectionMatrix.PopMatrix() ;

	glutSwapBuffers();
	glutPostRedisplay();
}

void ChangeSize(int w, int h)
{
	if(h == 0)
		h = 1;

	screenWidth = w ;
	screenHeight = h ;

	gltGenerateOrtho2DMat(screenWidth, screenHeight, orthoMatrix, screenQuad);

	glViewport(0, 0, w, h);

	viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 100.0f);

	projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
	transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);

	free(pixelData) ;
	pixelDataSize = screenWidth * screenHeight * sizeof(GL_UNSIGNED_BYTE) ;
	pixelData = (void *)malloc(pixelDataSize) ;

	glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBufferObjects[0]) ;
	glBufferData(GL_PIXEL_PACK_BUFFER, pixelDataSize, pixelData, GL_DYNAMIC_DRAW) ;
	glBindBuffer(GL_PIXEL_PACK_BUFFER, 0) ;
}

int main(int argc, char* argv[])
{
	gltSetWorkingDirectory(argv[0]);

	screenWidth = 800 ;
	screenHeight = 600 ;

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowSize(screenWidth, screenHeight);
	glutCreateWindow("Pixel Buffer");
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene);

	GLenum err = glewInit();
	if (err != GLEW_OK)
	{
		fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		return 1;
	}

	SetupRC();    
	glutMainLoop();
	ShutdownRC();

	return 0;
}


 

你可能感兴趣的:(Pixel Buffer.cpp)