標籤:opengl 疑問 藍寶書 紋理映射
遇到一個大問題,明明載入紋理綁定的是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 330in 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 330smooth 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>#endifGLFrame 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");//vplocMV = glGetUniformLocation(ADSDissolveShader, "mvMatrix");locMVP = glGetUniformLocation(ADSDissolveShader, "mvpMatrix");locNM = glGetUniformLocation(ADSDissolveShader, "normalMatrix");locLightPosition = glGetUniformLocation(ADSDissolveShader, "vLightPosition");//fplocAmbient = 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);//vpglUniformMatrix4fv(locMV, 1, GL_FALSE, transfromPipeLine.GetModelViewMatrix());glUniformMatrix4fv(locMVP, 1, GL_FALSE, transfromPipeLine.GetModelViewProjectionMatrix());glUniformMatrix3fv(locNM, 1, GL_FALSE, transfromPipeLine.GetNormalMatrix());glUniform3fv(locLightPosition, 1, vEyeLight);//fpglUniform4fv(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??紋理和頂點間的映射是如何??