opengl纹理示例
一 一個簡單例子
首先做一個簡單例子;繪制一個簡單的二維紋理圖,并將該圖像映射到一個四邊形上;代碼;
效果:
二 示例2
編譯如下一個例子;需要用到《OpenGL超級寶典》中的一些庫和頭文件;未編譯成功;不過過程和用到的一些資源比較有用;記錄一下;
1 代碼
#include "gltools.h" //#include "math3d.h" #include <GL/glut.h> #include <stdio.h>// Define targa header. #pragma pack(1) typedef struct{GLbyte identsize; // Size of ID field that follows header (0)GLbyte colorMapType; // 0 = None, 1 = palettedGLbyte imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rleunsigned short colorMapStart; // First colour map entryunsigned short colorMapLength; // Number of colorsunsigned char colorMapBits; // bits per palette entryunsigned short xstart; // image x originunsigned short ystart; // image y originunsigned short width; // width in pixelsunsigned short height; // height in pixelsGLbyte bits; // bits per pixel (8 16, 24, 32)GLbyte descriptor; // image descriptor} TGAHEADER; #pragma pack(8)GLbyte *gltLoadTGA(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat){FILE *pFile; // File pointerTGAHEADER tgaHeader; // TGA file headerunsigned long lImageSize; // Size in bytes of imageshort sDepth; // Pixel depth;GLbyte *pBits = NULL; // Pointer to bits// Default/Failed values*iWidth = 0;*iHeight = 0;*eFormat = GL_BGR_EXT;*iComponents = GL_RGB8;// Attempt to open the filpFile = fopen(szFileName, "rb");if(pFile == NULL)return NULL;// Read in header (binary)fread(&tgaHeader, 18/* sizeof(TGAHEADER)*/, 1, pFile);// Do byte swap for big vs little endian #ifdef __APPLE__BYTE_SWAP(tgaHeader.colorMapStart);BYTE_SWAP(tgaHeader.colorMapLength);BYTE_SWAP(tgaHeader.xstart);BYTE_SWAP(tgaHeader.ystart);BYTE_SWAP(tgaHeader.width);BYTE_SWAP(tgaHeader.height); #endif// Get width, height, and depth of texture*iWidth = tgaHeader.width;*iHeight = tgaHeader.height;sDepth = tgaHeader.bits / 8;// Put some validity checks here. Very simply, I only understand// or care about 8, 24, or 32 bit targa's.if(tgaHeader.bits != 8 && tgaHeader.bits != 24 && tgaHeader.bits != 32)return NULL;// Calculate size of image bufferlImageSize = tgaHeader.width * tgaHeader.height * sDepth;// Allocate memory and check for successpBits = (signed char *)malloc(lImageSize * sizeof(GLbyte));if(pBits == NULL)return NULL;// Read in the bits// Check for read error. This should catch RLE or other // weird formats that I don't want to recognizeif(fread(pBits, lImageSize, 1, pFile) != 1){free(pBits);return NULL;}// Set OpenGL format expectedswitch(sDepth){case 3: // Most likely case*eFormat = GL_BGR_EXT;*iComponents = GL_RGB8;break;case 4:*eFormat = GL_BGRA_EXT;*iComponents = GL_RGBA8;break;case 1:*eFormat = GL_LUMINANCE;*iComponents = GL_LUMINANCE8;break;};// Done with Filefclose(pFile);// Return pointer to image datareturn pBits;}static GLint iWidth, iHeight, iComponents; static GLenum eFormat; static GLfloat xRot, yRot;static GLfloat noLight[4] = {0.0f, 0.0f, 0.0f, 1.0f}; static GLfloat ambientLight[4] = {0.3f, 0.3f, 0.3f, 1.0f}; static GLfloat diffuseLight[4] = {0.7f, 0.7f, 0.7f, 1.0f}; static GLfloat brightLight[4] = {1.0f, 1.0f, 1.0f, 1.0f};//光的位置在右上角 static GLfloat lightPos[] = { 5.0f, 5.0f, 5.0f, 1.0f};void SetupRC() {glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glCullFace(GL_BACK);glFrontFace(GL_CCW);glEnable(GL_CULL_FACE);glEnable(GL_DEPTH_TEST);//設置光照環境glEnable(GL_LIGHTING);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, noLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, brightLight);glLightfv(GL_LIGHT0, GL_POSITION, lightPos);glEnable(GL_LIGHT0);//開啟顏色追蹤glEnable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);glMaterialfv(GL_FRONT, GL_SPECULAR, brightLight);//鏡面光加亮的范圍設置大一點glMateriali(GL_FRONT, GL_SHININESS, 30);//讀取圖像文件glPixelStorei(GL_UNPACK_ALIGNMENT, 1);void *pImage = NULL;pImage = gltLoadTGA("..\\stone.tga", &iWidth, &iHeight, &iComponents, &eFormat);if (pImage){//加載紋理,然后釋放臨時的內存glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pImage);free(pImage);pImage = NULL;}//設置紋理過濾glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);//設置紋理環境glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);glEnable(GL_TEXTURE_2D); }void RenderScene() {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);/*金字塔頂點下標為0,底部坐標如下1______2| ||______|3 4*///金字塔頂點數組M3DVector3f vertices[5] = {{0.0f, 0.8f, 0.0f},{-.50f, 0.0f, -.50f},{.50f, 0.0f, -.50f},{-.50f, 0.0f, .50f},{.50f, 0.0f, .50f}};//表面法線向量M3DVector3f normal;glPushMatrix();//先往里和往下平移一點glTranslatef(0.0f, -0.3f, -4.0f);if (xRot > 360.5f){xRot = 0.0f;}if (yRot > 360.5f){yRot = 0.0f;}//進行旋轉glRotatef(xRot, 1.0f, 0.0f, 0.0f);glRotatef(yRot, 0.0f, 1.0f, 0.0f);xRot += 0.5f;yRot += 0.5f;glBegin(GL_TRIANGLES);//底面的四方形由兩個三角形組成glColor3f(1.0f, 0.0f, 0.0f);//注意法線和紋理都要在頂點之前設置glNormal3f(0.0f, -1.0f, 0.0f);glTexCoord2f(0.0f, 1.0f);glVertex3fv(vertices[1]);glTexCoord2f(1.0f, 1.0f);glVertex3fv(vertices[2]);glTexCoord2f(1.0f, 0.0f);glVertex3fv(vertices[4]);glTexCoord2f(1.0f, 0.0f);glVertex3fv(vertices[4]);glTexCoord2f(0.0f, 0.0f);glVertex3fv(vertices[3]);glTexCoord2f(0.0f, 1.0f);glVertex3fv(vertices[1]);//前面glColor3f(0.0f, 1.0f, 0.0f);m3dFindNormal(normal, vertices[0], vertices[3], vertices[4]);glNormal3fv(normal);glTexCoord2f(0.5f, 0.5f);glVertex3fv(vertices[0]);glTexCoord2f(0.0f, 0.0f);glVertex3fv(vertices[3]);glTexCoord2f(1.0f, 0.0f);glVertex3fv(vertices[4]);//左側面glColor3f(0.0f, 0.0f, 1.0f);m3dFindNormal(normal, vertices[1], vertices[3], vertices[0]);glNormal3fv(normal);glTexCoord2f(0.0f, 0.0f);glVertex3fv(vertices[1]);glTexCoord2f(1.0f, 0.0f);glVertex3fv(vertices[3]);glTexCoord2f(0.5f, 0.5f);glVertex3fv(vertices[0]);//右側面glColor3f(0.0f, 1.0f, 1.0f);m3dFindNormal(normal, vertices[0], vertices[4], vertices[2]);glNormal3fv(normal);glTexCoord2f(0.5f, 0.5f);glVertex3fv(vertices[0]);glTexCoord2f(0.0f, 0.0f);glVertex3fv(vertices[4]);glTexCoord2f(1.0f, 0.0f);glVertex3fv(vertices[2]);//后面glColor3f(1.0f, 0.0f, 1.0f);m3dFindNormal(normal, vertices[0], vertices[2], vertices[1]);glNormal3fv(normal);glTexCoord2f(0.5f, 0.5f);glVertex3fv(vertices[0]);glTexCoord2f(0.0f, 0.0f);glVertex3fv(vertices[2]);glTexCoord2f(1.0f, 0.0f);glVertex3fv(vertices[1]);glEnd();glPopMatrix();glutSwapBuffers(); }void ChangeSize(GLsizei w, GLsizei h) {if (h == 0)h = 1;glViewport(0, 0, w, h);float fAspect = (GLfloat)w/(GLfloat)h;glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(35.0, fAspect, 1.0, 100.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glutPostRedisplay(); }void TimerFunc(int value) {glutPostRedisplay();glutTimerFunc(60, TimerFunc, 1); }int main(int args, char *arv[]) {glutInit(&args, arv);glutInitDisplayMode(GL_RGB | GL_DOUBLE | GL_DEPTH);glutInitWindowSize(800, 600);glutCreateWindow("pyramid");glutDisplayFunc(RenderScene);glutReshapeFunc(ChangeSize);SetupRC();glutTimerFunc(50, TimerFunc, 1);glutMainLoop();return 0; }2 LNK 1103錯誤
Linking...
LINK : warning LNK4098: defaultlib "LIBCMT" conflicts with use of other libs; use /NODEFAULTLIB:library
gltools.lib(math3d.obj) : fatal error LNK1103: debugging information corrupt; recompile module
執行 link.exe 時出錯.
在VC6下選中上圖的 忽略全部默認庫后;不再出現此錯誤;我用的VC6,估計在VS2008以上不會出現此錯誤;
3 關于gltLoadTGA
參閱此文
http://larrycheung.blog.163.com/blog/static/13172966120129284281428/
另外還需要一個輔助函數gltLoadTGA;
我已經加入到上面代碼中;
另外還有一個opengl讀取tga文件的類,在此處;
http://download.csdn.net/detail/jiangcaiyang123/4823365
如果出現下述錯誤,
wenli2.cpp(69) : error C2440: '=' : cannot convert from 'void *' to 'signed char *'
把
pBits = malloc(lImageSize * sizeof(GLbyte));
改為
pBits = (signed char *)malloc(lImageSize * sizeof(GLbyte));
4 用到的庫
gltools.h, gltools.lib,OpenGL超級寶典完整源碼 中附帶;
glew庫;偶又額外下了一個glew-1.9.0;?
在后面鏈接中有;
另外還有一個
http://blog.csdn.net/van_2013/article/details/47165953
5 LNK 2001錯誤
弄好上面;再編譯,還有下述錯誤;
Linking...
wenli2.obj : error LNK2001: unresolved external symbol _fclose
wenli2.obj : error LNK2001: unresolved external symbol _free
wenli2.obj : error LNK2001: unresolved external symbol _malloc
wenli2.obj : error LNK2001: unresolved external symbol _fread
wenli2.obj : error LNK2001: unresolved external symbol _fopen
wenli2.obj : error LNK2001: unresolved external symbol __chkesp
wenli2.obj : error LNK2001: unresolved external symbol __fltused
gltools.lib(math3d.obj) : error LNK2001: unresolved external symbol __fltused
LINK : error LNK2001: unresolved external symbol _mainCRTStartup
gltools.lib(math3d.obj) : error LNK2001: unresolved external symbol __CIcos
gltools.lib(math3d.obj) : error LNK2001: unresolved external symbol __CIsin
gltools.lib(math3d.obj) : error LNK2001: unresolved external symbol __CIsqrt
gltools.lib(math3d.obj) : error LNK2001: unresolved external symbol __CItan
Debug/wenli2.exe : fatal error LNK1120: 12 unresolved externals
執行 link.exe 時出錯.
CIcos、CIsin等這些都是3d的數學計算函數;看樣子需要把?OpenGL超級寶典完整源碼 中相關工程編譯;除了gltools.lib外,再獲得math3d的lib和dll,才可以;
目前只有VC6;先到這里吧;
6 資源下載
上面兩個工程;glew庫1.9.0, gltools庫,OpenGL超級寶典完整源碼(第五版);包含在下面;
http://pan.baidu.com/s/1eRF0LTS
總結
以上是生活随笔為你收集整理的opengl纹理示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PostgreSQL源码分析
- 下一篇: easyui左侧导航菜单右侧载入百度地图