遇到一个大问题,明明加载纹理绑定的是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;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
OpenGL蓝宝书第六章代码疑虑:为什么使用了GL_TEXTURE_1D??纹理和顶点间的映射是如何实现?
原文地址:http://blog.csdn.net/jingzhewangzi/article/details/46853755