OpenGL GLSL 一维纹理的使用

我们这节将使用一维纹理实现下图中的效果



我们首先会创建一个红色分量逐渐增大的一维纹理数据

<pre name="code" class="cpp">		//纹理对象颜色值
		GLubyte textureData[4][3] = { 
						32,  0, 0,
						64,  0, 0,
						128, 0, 0,
						255, 0, 0
					     };


 该一维纹理只有颜色值,纹理的坐标从0到1,我们根据漫反射的光照强度来决定使用的纹理坐标颜色值 

下面是顶点着色器ToonShader.vp中的全部代码

// 要求OpenGL的版本最低是1.3
#version 130

// 需要从外界传入的字段
//顶点
in vec4 vVertex;
//顶点法线
in vec3 vNormal;

smooth out float textureCoordinate;

//下面是需要外界设置的统一值
//光源的位置
uniform vec3	vLightPosition;
//模型视图变换矩阵
uniform mat4	mvpMatrix;
//视图变换矩阵
uniform mat4	mvMatrix;
//模型视图变换矩阵法线矩阵
uniform mat3	normalMatrix;


void main(void) 
    { 
		// 得到法线在照相机坐标系下的位置
		vec3 vEyeNormal = normalMatrix * vNormal;

		// 得到顶点在照相机坐标系下的位置
		vec4 vPosition4 = mvMatrix * vVertex;
		vec3 vPosition3 = vPosition4.xyz / vPosition4.w;

		// 得到光源方向
		vec3 vLightDir = normalize(vLightPosition - vPosition3);

		// 漫反射光照强度
		textureCoordinate = max(0.0, dot(vEyeNormal, vLightDir));

		// 把顶点变换到照相机坐标系下
		gl_Position = mvpMatrix * vVertex;
    }


下面是片段着色器ToonShader.fp中的全部代码

// 要求OpenGL的版本最低是1.3
#version 130

//纹理对象
uniform sampler1D colorTable;
//传出到光栅化阶段的颜色值
out vec4 vFragColor;
//从顶点着色器传入的漫反射光照强度值
smooth in float textureCoordinate;


void main(void)
   { 
		vFragColor = texture(colorTable, textureCoordinate);
   }


下面是工程中的代码


首先我们来看一下需要包含的头文件和全局变量部分

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

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


GLFrame             viewFrame;
GLFrustum           viewFrustum;
GLTriangleBatch     torusBatch;
GLMatrixStack       modelViewMatrix;
GLMatrixStack       projectionMatrix;
GLGeometryTransform transformPipeline;
GLShaderManager     shaderManager;

//着色器统一值位置索引
GLuint	toonShader;	        
GLint	locLight;			
GLint	locMVP;				
GLint	locMV;				
GLint	locNM;				
GLint   locColorTable;		

//纹理对象
GLuint	texture;

下面是主函数main

int main(int argc, char* argv[])
{
	//设置工程路径
	gltSetWorkingDirectory(argv[0]);
	//初始化GLUT
	glutInit(&argc, argv);
	//设置需要使用的窗口模式
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
	//窗口的大小
	glutInitWindowSize(800, 600);
	//窗口的名字
	glutCreateWindow("ToomShader");
	//窗口大小改变时的回调函数
	glutReshapeFunc(ChangeSize);
	//渲染时的回调函数
	glutDisplayFunc(RenderScene);
	//初始化glew
	GLenum err = glewInit();
	if (GLEW_OK != err) {
		fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		return 1;
	}
	//初始化函数
	SetupRC();
	//消息循环
	glutMainLoop();
	//程序退出时的清理工作
	ShutdownRC();
	return 0;
}

下面是窗口大小改变时的回调函数ChangeSize

void ChangeSize(int w, int h)
{
	// Prevent a divide by zero
	if (h == 0)
		h = 1;

	//设置视口大小
	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);
}


下面是初始化函数SetupRC

void SetupRC(void)
	{
		glClearColor(0.025f, 0.25f, 0.25f, 1.0f );

		glEnable(GL_DEPTH_TEST);

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

		// 创建泳圈模型数据
		gltMakeTorus(torusBatch, .80f, 0.25f, 52, 26);
		//加载自己写的着色器
		toonShader = gltLoadShaderPairWithAttributes("ToonShader.vp", "ToonShader.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex",
				GLT_ATTRIBUTE_NORMAL, "vNormal");

		//得到着色器中的uniform值的位置引用,以便对它赋值
		locLight = glGetUniformLocation(toonShader, "vLightPosition");
		locMVP = glGetUniformLocation(toonShader, "mvpMatrix");
		locMV  = glGetUniformLocation(toonShader, "mvMatrix");
		locNM  = glGetUniformLocation(toonShader, "normalMatrix");
		locColorTable = glGetUniformLocation(toonShader, "colorTable");

		//创建纹理对象
		glGenTextures(1, &texture);
		//绑定纹理对象
		glBindTexture(GL_TEXTURE_1D, texture);
		//纹理对象颜色值
		GLubyte textureData[4][3] = { 32,  0, 0,
									  64,  0, 0,
									  128, 0, 0,
									  255, 0, 0};
		//创建一维纹理
		glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
		//设置过滤模式
		glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		//设置环绕模式
		glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	}


下面是渲染函数RenderScene

void RenderScene(void)
	{
		static CStopWatch rotTimer;

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		
		modelViewMatrix.PushMatrix(viewFrame);
		modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds() * 10.0f, 0.0f, 1.0f, 0.0f);

		GLfloat vEyeLight[] = { -100.0f, 100.0f, 100.0f };
		GLfloat vAmbientColor[] = { 0.1f, 0.1f, 0.1f, 1.0f };
		GLfloat vDiffuseColor[] = { 0.1f, 1.0f, 0.1f, 1.0f };
		GLfloat vSpecularColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
		//使用自己写的着色器
		glUseProgram(toonShader);
		//设置着色器中的uniform值
		glUniform3fv(locLight, 1, vEyeLight);
		glUniformMatrix4fv(locMVP, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix());
		glUniformMatrix4fv(locMV, 1, GL_FALSE, transformPipeline.GetModelViewMatrix());
		glUniformMatrix3fv(locNM, 1, GL_FALSE, transformPipeline.GetNormalMatrix());
		//设置纹理对象
		glUniform1i(locColorTable, 0);
		//绘制模型
		torusBatch.Draw();

		modelViewMatrix.PopMatrix();


		glutSwapBuffers();
		glutPostRedisplay();
	}


下面是程序退出时的清理函数ShutdownRC

void ShutdownRC(void)
{
	//删除纹理对象
	glDeleteTextures(1, &texture);
}





















  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值