摘自:http://hi.baidu.com/davidgabriel/item/009cd7987a9ee1db7b7f019c
纹理图片的一些标准:
图像的宽度和高度需要遵循一定的标准,(宽和高可以调换):
比如. 64x64, 128x128, 256x128, 128x256, 256x256. 宽和高最好是2的n次幂。还有就是图像的宽高比例不能超过256x256, 这个原因应该和GPU有关......。
一个简单读取bmp像素,并将其作为多边形的纹理的代码:
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include "bmp.h"
int imageWidth = 0;
int imageHeight = 0;
const char * fileName = "aaa.bmp\0";
unsigned char *image = NULL;
GLuint texName;
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
long dword_to_long(unsigned char * dwordPtr) {
long result = ((int)(dwordPtr[0]) * 1) + ((int)(dwordPtr[1]) * 16)+ ((int)(dwordPtr[2]) * 256) + ((int) (dwordPtr[3]) * 4096);
return result;
}
void makeImage() {
FILE * file = fopen(fileName, "rb");
if (file == NULL) {
printf("纹理不存在!\r\n");
exit(0);
}
memset(&fileHeader, 0, sizeof(fileHeader));
fread(&fileHeader, sizeof(fileHeader), 1, file);
memset(&infoHeader, 0, sizeof(infoHeader));
fread(&infoHeader, sizeof(infoHeader), 1, file);
imageWidth = dword_to_long(infoHeader.biWidth);
imageHeight = dword_to_long(infoHeader.biHeight);
printf("Width=%d;Height=%d\r\n",imageWidth,imageHeight);
if ((infoHeader.biBitCount[0]) != 0x18) {
printf("纹理不是24位图!\r\n");
exit(0);
}
long index=0;
image = (unsigned char *)malloc(imageHeight*imageWidth*4);
fseek(file, 54, SEEK_SET);
int i,j,k;
for(i=0;i<imageHeight;i++){
for(j=0;j<imageWidth;j++){
for(k=2;k>=0;k--){
image[index] = fgetc(file);
index ++;
}
}
}
fclose(file);
}
void init(void) {
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
makeImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0,GL_BGR, GL_UNSIGNED_BYTE, image);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texName);
glBegin(GL_POLYGON);
glTexCoord2f(0.0, 0.0);
glVertex2f(-2.0, -2.0);
glTexCoord2f(0.0, 1.0);
glVertex2f(-2.0, 2.0);
glTexCoord2f(1.0, 1.0);
glVertex2f(2.0, 2.0);
glTexCoord2f(1.0, 0.0);
glVertex2f(2.0, -2.0);
glEnd();
glFlush();
}
void reshape(int w, int h) {
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(250, 200);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
//---------------------------------------------------------------------------------------------------
bmp.h
typedef struct tagBITMAPFILEHEADER {
unsigned char bfType[2];
unsigned char bfSize[4];
unsigned char bfReserved1[2];
unsigned char bfReserved2[2];
unsigned char bfOffBits[4];
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned char biSize[4];
unsigned char biWidth[4];
unsigned char biHeight[4];
unsigned char biPlanes[2];
unsigned char biBitCount[2];
unsigned char biCompression[4];
unsigned char biSizeImage[4];
unsigned char biXPelsPerMeter[4];
unsigned char biYPelsPerMeter[4];
unsigned char biClrUsed[4];
unsigned char biClrImportant[4];
} BITMAPINFOHEADER;
//---------------------------------------------------------------------------------------------------