OpenGL加載BMP紋理圖片

摘自: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;

//---------------------------------------------------------------------------------------------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章