您的位置:首页 > 运维架构

OpenGL GLSL 一维纹理的使用

2015-09-03 13:12 471 查看
我们这节将使用一维纹理实现下图中的效果



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

<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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: