OpenGL蓝宝书第六章代码疑虑:为什么使用了GL_TEXTURE_1D??纹理和顶点间的映射是如何实现?

遇到一个大问题,明明加载纹理绑定的是GL_TEXTURE_2D

glUniform1i(locCloudTex, 1); //明明默认为0,参数却不是0.

可是原书中代码确是

glGenTextures(1, &uiTexture);

glBindTexture(GL_TEXTURE_1D, uiTexture); //

LoadTGATexture("Clouds.tga", GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);

glUniform1i(locCloudTex, 1);// ??

却实现了同样的效果。

另外也不知道此工程代码中纹理和顶点是如何映射的?表示没看懂 //todo

来自百度百科,看来我的层次只需要使用百度就能满足需求

图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.

部分参数功能说明如下:

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

  GL_TEXTURE_2D: 操作2D纹理.

  GL_TEXTURE_WRAP_S: S方向上的贴图模式.

  GL_CLAMP: 将纹理坐标限制在0.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充.

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

  这里同上,只是它是T方向

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  这是纹理过滤

  GL_TEXTURE_MAG_FILTER: 放大过滤   在纹理被放大时使用的过滤函数

  GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值.

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);

  GL_TEXTURE_MIN_FILTER: 缩小过滤 在纹理被缩小时使用的过滤函数

  GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.

/*

//http://www.cnblogs.com/sunnyjones/articles/798237.html

這個函数是對應著 glDrawPixels 而來的, 因為效率考慮, 所以,

OpenGL 預設, 你給 glDrawPixels 的圖檔資料, 它的每一個 row 的大小 ( 以 byte 來算 ), 也是可以給 4 整除的.

假設你的圖檔是 150x150, 每一個 row 的大小就會是 150 * 3 = 450 , 450 不能被 4 整除的. 如果要強行把它換成可以被 4 整除, 一般的做法, 就是在每一個 row 多加 2 bytes 沒用途的資料 (這個步驟我們叫 padding ), 如此 450 就會變成 452, 452 就可以被 4 整除了.

但是, 每 row 大小, 需要是多少的倍數, 雖然預設了是 4, 但是, 你是可以把它改成 1, 2, 4, 8, 其中任意一個的, 如果你設成 1, 這麼你就可以不用管 padding 的問題了 ( 因為什麼整數也可以被 1 整除呀 ), 但是, 懶散的結果, 就是程式 run-time 時慢一點點.

最好的做法, 應該直接使用 寬 可被 4 整除的圖.

*/

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //设置尾端对齐参数

glTexImage2D(GL_TEXTURE_2D, 0, nComponets, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);

//vp

#version 330
in vec4 vVertex;
in vec3 vNormal;
in vec2 vTexCoords0;

uniform mat4 mvMatrix;
uniform mat4 mvpMatrix;
uniform mat3 normalMatrix;
uniform vec3 vLightPosition;

smooth out vec2 vVaryingTexCoord;
smooth out vec3 vVaryingNormal;
smooth out vec3 vVaryingLightDir;

void main(void)
{
	vVaryingTexCoord = vTexCoords0;
	// normalMatrix 是模型在世界坐标系中的朝向矩阵
	//作用法线之后,法线就是其在世界坐标中的朝向
	vVaryingNormal = normalMatrix * vNormal;

	vec4 vPosition4 = mvMatrix * vVertex;

	vec3 vPosition3 = vPosition4.xyz/vPosition4.w;

	vVaryingLightDir = normalize(vLightPosition - vPosition3);

	gl_Position = mvpMatrix * vVertex;

}

//fp

#version 330

smooth in vec2 vVaryingTexCoord;
smooth in vec3 vVaryingNormal;
smooth in vec3 vVaryingLightDir;

uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
uniform sampler2D cloudTexture;
uniform float dissolveFactor;

out vec4 vFragColor;

void main(void)
{
	vec4 vCloudSample = texture(cloudTexture,vVaryingTexCoord);
	if(vCloudSample.r < dissolveFactor)
		discard;

	float diff = max(0.0f,dot(normalize(vVaryingNormal),normalize(vVaryingLightDir)));
	//自身颜色在点光源作用下
	vFragColor = diff * diffuseColor;
	//环境
	vFragColor += ambientColor;
	//镜面
	vec3 vReflection = normalize(reflect(-normalize(vVaryingLightDir),normalize(vVaryingNormal)));

	float spec = max(0.0f,dot(normalize(vVaryingNormal),vReflection));

	if(diff != 0)
	{
		float fSpec = pow(spec,128.0f);
		vFragColor.rgb += vec3(fSpec,fSpec,fSpec);
	}
}

//cpp

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

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

GLFrame viewFrame;
GLFrustum viewFrustum;
GLMatrixStack projctionMatrix;
GLMatrixStack modelViewMatrix;
GLMatrixStack mvpMatrix;
GLGeometryTransform transfromPipeLine;

GLShaderManager shaderManager;
GLTriangleBatch torusBatch;

GLuint ADSDissolveShader;
GLuint uiTexture;
GLint locMV;
GLint locMVP;
GLint locNM;
GLint locLightPosition;

GLint locAmbient;
GLint locDiffuse;
GLint locSpec;
GLint locCloudTex;
GLint locDissolveFactor;

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

	glViewport(0, 0, w, h);
	viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 100.0f);
	projctionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
	transfromPipeLine.SetMatrixStacks(modelViewMatrix, projctionMatrix);

}

bool LoadTGATexture(const char * szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
	GLbyte * pBytes;
	GLint nWidth, nHeight, nComponets;
	GLenum eFormat;

	pBytes = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponets, &eFormat);
	if (pBytes == NULL)
	{
		return false;
	}

	/* 来自百度百科,看来我的层次只需要使用百度就能满足需求

	图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.
	部分参数功能说明如下:
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  GL_TEXTURE_2D: 操作2D纹理.
  GL_TEXTURE_WRAP_S: S方向上的贴图模式.
  GL_CLAMP: 将纹理坐标限制在0.0,1.0的范围之内.如果超出了会如何呢.不会错误,只是会边缘拉伸填充.
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  这里同上,只是它是T方向
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  这是纹理过滤
  GL_TEXTURE_MAG_FILTER: 放大过滤   在纹理被放大时使用的过滤函数
  GL_LINEAR: 线性过滤, 使用距离当前渲染像素中心最近的4个纹素加权平均值.
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  GL_TEXTURE_MIN_FILTER: 缩小过滤 在纹理被缩小时使用的过滤函数
  GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST对最接近当前多边形的解析度的两个层级贴图进行采样,然后用这两个值进行线性插值.
	*/
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);

	/*
	//http://www.cnblogs.com/sunnyjones/articles/798237.html

	這個函数是對應著 glDrawPixels 而來的, 因為效率考慮, 所以,

	OpenGL 預設, 你給 glDrawPixels 的圖檔資料, 它的每一個 row 的大小 ( 以 byte 來算 ), 也是可以給 4 整除的.

	假設你的圖檔是 150x150, 每一個 row 的大小就會是 150 * 3 = 450 , 450 不能被 4 整除的. 如果要強行把它換成可以被 4 整除, 一般的做法, 就是在每一個 row 多加 2 bytes 沒用途的資料 (這個步驟我們叫 padding ), 如此 450 就會變成 452, 452 就可以被 4 整除了.

	但是, 每 row 大小, 需要是多少的倍數, 雖然預設了是 4, 但是, 你是可以把它改成 1, 2, 4, 8, 其中任意一個的, 如果你設成 1, 這麼你就可以不用管 padding 的問題了 ( 因為什麼整數也可以被 1 整除呀 ), 但是, 懶散的結果, 就是程式 run-time 時慢一點點.

	最好的做法, 應該直接使用 寬 可被 4 整除的圖.

	*/
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexImage2D(GL_TEXTURE_2D, 0, nComponets, nWidth, nHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);

	free(pBytes);

	if (minFilter == GL_LINEAR_MIPMAP_LINEAR || minFilter == GL_LINEAR_MIPMAP_NEAREST || minFilter == GL_NEAREST_MIPMAP_LINEAR || minFilter == GL_NEAREST_MIPMAP_NEAREST)
	{
		glGenerateMipmap(GL_TEXTURE_2D);
	}

	return true;
}

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

	glEnable(GL_DEPTH_TEST);

	shaderManager.InitializeStockShaders();

	viewFrame.MoveForward(4.0f);

	gltMakeTorus(torusBatch, 0.8f, 0.25f, 52, 26);

	ADSDissolveShader = shaderManager.LoadShaderPairWithAttributes("Dissolve.vp", "Dissolve.fp", 3, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_NORMAL, "vNormal", GLT_ATTRIBUTE_TEXTURE0, "vTexCoords0");

	//vp
	locMV = glGetUniformLocation(ADSDissolveShader, "mvMatrix");
	locMVP = glGetUniformLocation(ADSDissolveShader, "mvpMatrix");
	locNM = glGetUniformLocation(ADSDissolveShader, "normalMatrix");
	locLightPosition = glGetUniformLocation(ADSDissolveShader, "vLightPosition");

	//fp
	locAmbient = glGetUniformLocation(ADSDissolveShader, "ambientColor");
	locDiffuse = glGetUniformLocation(ADSDissolveShader, "diffuseColor");
	locSpec = glGetUniformLocation(ADSDissolveShader, "specularColor");
	locCloudTex = glGetUniformLocation(ADSDissolveShader, "cloudTexture");
	locDissolveFactor = glGetUniformLocation(ADSDissolveShader, "dissolveFactor");

	glGenTextures(1, &uiTexture);
	glBindTexture(GL_TEXTURE_2D, uiTexture); //
	LoadTGATexture("Clouds.tga", GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE);

}

void RenderScene(void)
{
	static CStopWatch rotTimer;
	static GLfloat vEyeLight[] = { -100.0f, 100.0f, 100.0f };
	static GLfloat vAmbientColor[] = { 0.1f, 0.1f, 0.1f, 1.0f };
	static GLfloat vDiffuseColor[] = { 0.1f, 1.0f, 0.1f, 1.0f };
	static GLfloat vSpecularColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	modelViewMatrix.PushMatrix(viewFrame);
	{
		modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds() * 10.0f,0.0f,1.0f,0.0f);
		glUseProgram(ADSDissolveShader);
		//vp
		glUniformMatrix4fv(locMV, 1, GL_FALSE, transfromPipeLine.GetModelViewMatrix());
		glUniformMatrix4fv(locMVP, 1, GL_FALSE, transfromPipeLine.GetModelViewProjectionMatrix());
		glUniformMatrix3fv(locNM, 1, GL_FALSE, transfromPipeLine.GetNormalMatrix());
		glUniform3fv(locLightPosition, 1, vEyeLight);

		//fp
		glUniform4fv(locAmbient, 1, vAmbientColor);
		glUniform4fv(locDiffuse, 1, vDiffuseColor);
		glUniform4fv(locSpec, 1, vSpecularColor);
		glUniform1i(locCloudTex, 0);// 

		float fFactor = fmod(rotTimer.GetElapsedSeconds(), 10.0f);
		fFactor /= 10.0f;

		glUniform1f(locDissolveFactor, fFactor);

		torusBatch.Draw();
	}
	modelViewMatrix.PopMatrix();

	glutSwapBuffers();

	glutPostRedisplay();

}

void ShutdownRC(void)
{
	glDeleteTextures(1, &uiTexture);
	glDeleteProgram(ADSDissolveShader);
}

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

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
	glutInitWindowSize(800, 600);
	glutCreateWindow("Dissolve Jingz");
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene);

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

	SetupRC();
	glutMainLoop();
	ShutdownRC();
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 01:48:47

OpenGL蓝宝书第六章代码疑虑:为什么使用了GL_TEXTURE_1D??纹理和顶点间的映射是如何实现?的相关文章

OpenGL蓝宝书第五章代码勘误以及惯性坐标系去解释模型变换

如果你也发现按照教程代码完成贴图时,你会底面的坐标和平常顶点坐标正负相反,比如-1.0f, -1.0f, -1.0f这个顶点对应的却是世界坐标中1.0f,-1.0f,1.0f 问题究竟出现在哪里? 原来是:objectFrame.GetCameraMatrix(mObjectFrame); //原书中的代码为GetMatrix,获取了objectFrame的朝向,导致顶点和纹理的对象关系出现了相反内容 objectFrame中的朝向和OpenGL的默认朝向相反,getMatrix的操作会导致mo

OpenGL蓝宝书第五章5.4Tunnuel 纹理映射和过滤:较好的可读性代码

主要处理了纹理贴图和顶点映射的关系.根据法线先确认环绕方向.然后根据绘制的primitive_type完成纹理顶点直接的映射. 哪里来,哪里回:根据法线来确认逆时针方向.strip的画法要熟悉,从其实的两个顶点开始已折线的形式前进 GL_TRIANGLES_STRIP是常用的绘制方式,在循环代码中使用四个顶点+循环控制量能完成大量的几何图形绘制.这里我犯了个错误,没意识到折线的的前进方向问题,导致纹理映射出现了偏差,一度去怀疑modelViewMatrix的配置是否正确.但是我发现原书中的代码没

OpenGL蓝宝书第七章:立体天空和纹理折射、双纹理(下)

对比了蓝宝书,才知道红宝书的优点. reflect函数的原理在红宝书中有说明,只有对比了红宝书,才知道红宝书的定位:高级工具书. 蓝宝书作为入门级书籍,以较快的速度让读者敲到代码去思考,总遗留了需要探索的内容. 蓝宝书要看完. 红宝书要看完. C++11 标准版英文版也看了小部分. 多线程入门都不算. Socket只能实现基础网络连接,离真正的数据通信都算,何况多人在线对战网络模型的实现 设计模式看了又忘了,忘了又看,如果没有机会去设计模块级别的代码实现,真的血了没用,难道改UI?加班赶工哪有魄

20190902 On Java8 第十六章 代码校验

第十六章 代码校验 你永远不能保证你的代码是正确的,你只能证明它是错的. 测试 测试覆盖率的幻觉 测试覆盖率,同样也称为代码覆盖率,度量代码的测试百分比.百分比越高,测试的覆盖率越大. 当分析一个未知的代码库时,测试覆盖率作为一个粗略的度量是有用的.如果覆盖率工具报告的值特别低(比如,少于百分之40),则说明覆盖不够充分.然而,一个非常高的值也同样值得怀疑,这表明对编程领域了解不足的人迫使团队做出了武断的决定.覆盖工具的最佳用途是发现代码库中未测试的部分.但是,不要依赖覆盖率来得到测试质量的任何

第六章代码记录1

record_def.s 1 .equ RECORD_FIRSTNAME, 0 #记录数据:firstName:40字节 0-39 2 .equ RECORD_LASTNAME, 40 #记录数据:lastName:40字节 40-79 3 .equ RECORD_ADDRESS, 80 #记录数据:address:240字节 80-319 4 .equ RECORD_AGE, 320 #记录数据:age:4字节 320-323 5 .equ RECORD_SIZE, 324 #记录数据:siz

20190903 On Java8 第十六章 代码校验

第十七章 文件 在Java7中对 文件的操作 引入了巨大的改进.这些新元素被放在 java.nio.file 包下面,过去人们通常把nio中的n理解为new即新的io,现在更应该当成是non-blocking非阻塞io(io就是input/output输入/输出). 文件操作的两个基本组件: 文件或者目录的路径: 文件本身. 文件和目录路径 Paths 一个Path对象表示一个文件或者目录的路径,是一个跨操作系统(OS)和文件系统的抽象,目的是在构造路径时不必关注底层操作系统,代码可以在不进行修

《机器学习》西瓜书第六章支持向量机

支持向量机分为:线性可分支持向量机.线性支持向量机.非线性支持向量机 线性可分支持向量机:训练数据线性可分,通过硬间隔最大化,学习一个线性的分类器: 线性支持向量机:训练数据近似线性可分,通过软间隔最大化,学习一个线性分类器 非线性支持向量机:训练数据线性不可分,通过使用核技巧以及软间隔最大化,学习一个非线性支持向量机. 6.1 间隔与支持向量 在样本空间中,划分超平面课通过如下线性方程来描述:  ωT x+ b = 0   其中ω = (ω1:ω2:...:ωd  )为法向量,决定超平面的方向

OpenGL ES着色器语言之语句和结构体(官方文档第六章)内建变量(官方文档第七、八章)

OpenGL ES着色器语言之语句和结构体(官方文档第六章) OpenGL ES着色器语言的程序块基本构成如下: 语句和声明 函数定义 选择(if-else) 迭代(for, while, do-while) 跳跃(discard, return, break, continue) 6.1函数定义   着色器是由一系列全局声明和函数定义组成的.函数声明规范如下: // prototype returnType functionName (type0 arg0, type1 arg1, ...,

Mac OSX下搭建OpenGL超级宝典5(蓝宝书)开发环境(运行第一个三角形程序)

1.下载OpenGL超级宝典5(蓝宝书)的资源,链接如下:http://pan.baidu.com/s/1c02PtYC,解压得到SB5文件夹,里面有书籍的课程源码以及GLTools库. 2.依次点击Xcode-->Preferences-->Locations-->Sources Trees,再点“+”号按钮添加Name:  GLTOOLS_INCLUDE,  Display Name:  GLTools include Folder, Path: ~/Desktop/SB5/src/