FBO 渲染到纹理

  这是书中第八章的最后一节内容,在我机制的简化问题后,写出了想要的效果.应用FBO渲染到纹理,可以直接用.这个用来实现镜面效果什么的,好啊.再一个,貌似我现在已经可以去写延迟渲染流水线了,那个用到多渲染目标,之后再处理.呼,继续学习吧,这些东西还真得实践才行啊.

//	RenderToTexture.cpp -- 2013/10/11-20:49
#include "stdafx.h"
#include <iostream>
#include <GLTools.h>
#include <GLShaderManager.h>
#define FREEGLUT_STATIC
#include <GL/glut.h>

GLBatch	triangleBatch;
GLBatch texturedTriangleBatch ;
GLShaderManager	shaderManager;
GLint triangleShader ;
GLint texturedTriangleShader ;

GLuint fboName ;
GLuint generatedTexutre ;

GLenum windowBuffer[] = {GL_BACK_LEFT,} ;
GLenum fboBuffers[] = {GL_COLOR_ATTACHMENT0,} ;

GLsizei const generatedTextureWidth = 400 ;
GLsizei const generatedTextureHeight = 300 ;

GLint screenWidth = 800 ;
GLint screenHeight = 600 ;

void ShutdownRC(void)
{
	glDeleteProgram(triangleShader) ;
	glDeleteProgram(texturedTriangleShader) ;

	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) ;
	glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) ;

	glActiveTexture(GL_TEXTURE0) ;
	glBindTexture(GL_TEXTURE_2D, 0) ;

	glDeleteTextures(1, &generatedTexutre) ;

	glDeleteFramebuffers(1, &fboName) ;
}

void ChangeSize(int w, int h)
{
	glViewport(0, 0, w, h);
	screenWidth = w ;
	screenHeight = h ;
}

void SetupRC()
{
	shaderManager.InitializeStockShaders();

	triangleShader = shaderManager.LoadShaderPairWithAttributes(
		"triangle.vp", "triangle.fp",
		1,
		GLT_ATTRIBUTE_VERTEX, "vVertex") ;

	texturedTriangleShader = shaderManager.LoadShaderPairWithAttributes(
		"texturedTriangle.vp", "texturedTriangle.fp",
		2,
		GLT_ATTRIBUTE_VERTEX, "vVertex",
		GLT_ATTRIBUTE_TEXTURE0, "vTexCoords") ;

	GLfloat vVerts[] = {
		-0.5f, 0.0f, 0.0f, 
		0.5f, 0.0f, 0.0f,
		0.0f, 0.5f, 0.0f };

	GLfloat vTexCoords[] = {
		0, 0,
		1.0f, 0,
		0.5f, 1.0f,
		} ;

	triangleBatch.Begin(GL_TRIANGLES, 3);
	triangleBatch.CopyVertexData3f(vVerts);
	triangleBatch.End();

	texturedTriangleBatch.Begin(GL_TRIANGLES, 3, 1) ;
	texturedTriangleBatch.CopyVertexData3f(vVerts) ;
	texturedTriangleBatch.CopyTexCoordData2f(vTexCoords, 0) ;
	texturedTriangleBatch.End();

	glGenFramebuffers(1, &fboName) ;
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboName) ;

	glGenTextures(1, &generatedTexutre) ;
	glBindTexture(GL_TEXTURE_2D, generatedTexutre) ;
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
	glGenerateMipmap(GL_TEXTURE_2D);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, generatedTextureWidth, generatedTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
	glBindTexture(GL_TEXTURE_2D, 0);

	glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, generatedTexutre, 0) ;

	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) ;
}

void RenderScene(void)
{
	//	先以黑底画红色三角形到纹理中
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0, 0, 0, 1.0f);
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboName) ;
	glDrawBuffers(1, fboBuffers) ;
	glViewport(0, 0, generatedTextureWidth, generatedTextureHeight) ;
	glUseProgram(triangleShader) ;
	GLint iColorLocation = glGetUniformLocation(triangleShader, "vColor") ;
	GLfloat vColor[] = { 1.0f, 0.0f, 0.0f, 1.0f };
	glUniform4fv(iColorLocation, 1, vColor) ;
	triangleBatch.Draw();

	//	再以白底将刚生成的纹理贴到三角形上画出来,汉字好难组织说啊...
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) ;
	glDrawBuffers(1, windowBuffer) ;
	glViewport(0, 0, screenWidth, screenHeight) ;
	glUseProgram(texturedTriangleShader) ;
	glBindTexture(GL_TEXTURE_2D, generatedTexutre) ;
	GLint iTextureUniform = glGetUniformLocation(texturedTriangleShader, "colorMap") ;
	glUniform1i(iTextureUniform, 0) ;
	texturedTriangleBatch.Draw() ;

	glutSwapBuffers();
}

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

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(screenWidth, screenHeight);
	glutCreateWindow("Render To Texture");
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene);

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

	SetupRC();

	glutMainLoop();

	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值