2011-03-22 188 views
-2

我想添加多個紋理到我的場景我有一個紋理工作,但我不知道如何包括其他紋理以及。opengl多紋理

#include <windows.h> 
#include <gl\gl.h> 
#include <gl\glut.h> 

#include <stdlib.h> 
#include <iostream> 

void init(void); 
void display(void); 
void keyboard(unsigned char, int, int); 
void resize(int, int); 
void drawcube(float, float, float, float, float, float, int); 

int is_depth; 

#define ROAD 0 


struct Image 
{ 
    unsigned long size_x; 
    unsigned long size_y; 
    char *data; 
}; 

typedef struct Image Image; 

const int textureCount = 1; 

Image myTextureData[textureCount]; 
GLuint theTexture[textureCount]; 


char* textureFilenames[textureCount] = {"road.bmp"}; 


int main (int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowSize(600, 600); 
    glutInitWindowPosition(40, 40); 
    glutCreateWindow("3D World"); 
    init(); 
    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 

    glEnable(GL_TEXTURE_2D); 

    glutReshapeFunc(resize); 


    glutMainLoop(); 
    return 0; 
} 


int imageLoader(const char *filename, Image *image) 
{ 
    FILE *file; 

    unsigned long size; 
    unsigned long i; 
    unsigned short int planes; 
    unsigned short int bpp; 

    char temp; 
    char finalName[80]; 

    glTexCoord2f(1.0, 0.0); 

    strcpy(finalName, ""); 
    strcat(finalName, filename); 

    if ((file = fopen(finalName, "rb"))==NULL) 
    { 
     printf("File Not Found : %s\n",finalName); 
     return 0; 
    } 

    fseek(file, 18, SEEK_CUR); 

    glTexCoord2f(1.0, 0.0); 

    if ((i = fread(&image->size_x, 4, 1, file)) != 1) 
    { 
     printf("Error reading width from %s.\n", finalName); 
     return 0; 
    } 

    if ((i = fread(&image->size_y, 4, 1, file)) != 1) 
    { 
     printf("Error reading height from %s.\n", finalName); 
     return 0; 
    } 

    size = image->size_x * image->size_y * 3; 

    if ((fread(&planes, 2, 1, file)) != 1) 
    { 
     printf("Error reading planes from %s.\n", finalName); 
     return 0; 
    } 

    if (planes != 1) 
    { 
     printf("Planes from %s is not 1: %u\n", finalName, planes); 
     return 0; 
    } 

    if ((i = fread(&bpp, 2, 1, file)) != 1) 
    { 
     printf("Error reading bpp from %s.\n", finalName); 
     return 0; 
    } 

    if (bpp != 24) 
    { 
     printf("Bpp from %s is not 24: %u\n", finalName, bpp); 
     return 0; 
    } 

    fseek(file, 24, SEEK_CUR); 

    image->data = (char *) malloc(size); 

    if (image->data == NULL) 
    { 
     printf("Error allocating memory for color-corrected image data"); 
     return 0; 
    } 

    if ((i = fread(image->data, size, 1, file)) != 1) 
    { 
     printf("Error reading image data from %s.\n", finalName); 
     return 0; 
    } 

    for (i=0;i<size;i+=3) 
    { 
     temp = image->data[i]; 
     image->data[i] = image->data[i+2]; 
     image->data[i+2] = temp; 
    } 
    return 1; 
} 

void textureLoader() 
{ 

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

    for(int k=0; k < textureCount; k++) 
    { 
     if(!imageLoader(textureFilenames[k], &myTextureData[k])) 
      exit(1); 


     glGenTextures(1, &theTexture[k]); 

     glBindTexture(GL_TEXTURE_2D, theTexture[k]); 


     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 
     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); 

     gluBuild2DMipmaps(GL_TEXTURE_2D, 3, myTextureData[k].size_x, myTextureData[k].size_y, GL_RGB, GL_UNSIGNED_BYTE, myTextureData[k].data); 
    } 
} 
void init(void) 
{ 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glEnable(GL_DEPTH_TEST); 
    glMatrixMode(GL_MODELVIEW); 

    is_depth = 1; 
} 
void display(void) 
{ 

    if (is_depth) 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    else 
     glClear(GL_COLOR_BUFFER_BIT); 

    textureLoader(); 

    glBegin(GL_QUADS); 
     glTexCoord2f(0.0,0.0); 
     glVertex3f(-75.0, 0.0, -400.0); 
     glTexCoord2f(0.0,1.0); 
     glVertex3f(-75.0, 0.0, 100.0); 
     glTexCoord2f(1.0,0.0); 
     glVertex3f(75.0, 0.0, 100.0); 
     glTexCoord2f(1.0,1.0); 
     glVertex3f(75.0, 0.0, -400.0); 

     drawcube(-70,15,72,8,15,28,4); 
     drawcube(-70,10,10,8,10,28,0); 
     drawcube(-70,15,-45,8,15,18,0); 
     drawcube(-70,15,-85,8,15,18,0); 
     drawcube(-70,35,-125,8,35,12,0); 
     drawcube(-70,9,-170,8,9,28,0); 
     drawcube(-70,15,-220,8,15,18,0); 
     drawcube(-70,15,-265,8,15,28,0); 
     drawcube(-70,15,-330,8,15,28,0); 
     drawcube(67,15,72,8,15,28,0); 
     drawcube(67,10,10,8,10,28,0); 
     drawcube(67,15,-45,8,15,18,0); 
     drawcube(67,15,-85,8,15,18,0); 
     drawcube(67,35,-125,8,35,12,0); 
     drawcube(67,9,-170,8,9,28,0); 
     drawcube(67,15,-220,8,15,18,0); 
     drawcube(67,15,-265,8,15,28,0); 
     drawcube(67,15,-330,8,15,28,0); 
     drawcube(-33,18,-364,25,18,10,0); 
     drawcube(25,28,-364,30,28,10,0); 
     drawcube(25,28,90,30,28,10,0); 
     drawcube(-33,18,90,25,18,10,0); 
     drawcube(0,60,-125,18,60,22,0); 
     drawcube(0,25,-225,8,25,28,0); 
     drawcube(0,25,0,8,25,28,0); 




    glEnd(); 


    glutSwapBuffers(); 
} 

void keyboard(unsigned char key, int x, int y) 
{ 
    switch (key) 
    { 
    case 'a': 
     glTranslatef(5.0, 0.0, 0.0); 
     break; 
    case 'd': 
     glTranslatef(-5.0, 0.0, 0.0); 
     break; 
    case 'w': 
     glTranslatef(0.0, 0.0, 5.0); 
     break; 
    case 's': 
     glTranslatef(0.0, 0.0, -5.0); 
     break; 
    } 
    display(); 
} 

void resize(int width, int height) 
{ 
    if (height == 0) height = 1; 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    gluPerspective(45.0, width/height, 1.0, 400.0); 
    glTranslatef(0.0, -5.0, -150.0); 
    glMatrixMode(GL_MODELVIEW); 
} 

void drawcube(float xc, float yc, float zc, float x_offset, float y_offset, float z_offset, int color) 
{ 

    switch(color) 
    { 
    case 1: 
     glColor3f(1.0,0.0,0.0); 
     break; 
    case 2: 
     glColor3f(0.0,1.0,0.0); 
     break; 
    case 3: 
     glColor3f(0.0,0.0,1.0); 
     break; 
    } 
    glBegin(GL_QUADS); 
     glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset); 

     glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset); 

     glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset); 

     glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset); 

     glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset); 

     glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset); 


    glEnd(); 
} 
+0

我已經格式化的代碼,但我無法想象這會得到多少牽引 - 要求人們重寫*大量的代碼,用一個簡單的「請做這個做我想做的事」。不太可能走得太遠。您確實需要將問題縮小到您嘗試加載更多紋理時遇到的問題,並將代碼縮減爲顯示問題的最小數量。 – 2011-03-22 09:02:50

+0

即時通訊要求添加第二個演講,我的抽屜功能是更好? – pepe 2011-03-22 09:11:36

+0

[opengl紋理]的可能重複(http://stackoverflow.com/questions/5380717/opengl-texturing) – genpfault 2011-03-22 15:10:23

回答

0

您需要啓用要渲染的紋理。

看看this example它是如何完成的。這個例子可能有點複雜,但它接近於做你正在做的事情。

編輯

順便說一句不產生紋理要渲染他們每一次。您只需創建一次,稍後使用它們(在渲染之前啓用並綁定到紋理)。

18

我只是註釋代碼

#include <windows.h> 
#include <gl\gl.h> 
#include <gl\glut.h> 

#include <stdlib.h> 
#include <iostream> 

void init(void); 
void display(void); 
void keyboard(unsigned char, int, int); 
void resize(int, int); 
void drawcube(float, float, float, float, float, float, int); 

int is_depth; 

#define ROAD 0 

struct Image 
{ 
    unsigned long size_x; 
    unsigned long size_y; 
    char *data; 
}; 

typedef struct Image Image; 

const int textureCount = 1; 

您使用的是const int數組sizeing。這告訴我,你使用的是C++,那麼爲什麼你不使用STL std :: vector或std :: list呢?

Image myTextureData[textureCount]; 
GLuint theTexture[textureCount]; 
char* textureFilenames[textureCount] = {"road.bmp"}; 


int main (int argc, char **argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowSize(600, 600); 
    glutInitWindowPosition(40, 40); 
    glutCreateWindow("3D World"); 
    init(); 
    glutDisplayFunc(display); 
    glutKeyboardFunc(keyboard); 

    glEnable(GL_TEXTURE_2D); 

OpenGL狀態根據需要設置。 glEnable在這裏沒有意義。

glutReshapeFunc(resize); 


    glutMainLoop(); 
    return 0; 
} 


int imageLoader(const char *filename, Image *image) 
{ 
    FILE *file; 

    unsigned long size; 
    unsigned long i; 
    unsigned short int planes; 
    unsigned short int bpp; 

    char temp; 
    char finalName[80]; 

    glTexCoord2f(1.0, 0.0); 

WTF ?!你在電話裝載機中叫glTexCoord?這是一個繪圖命令。

strcpy(finalName, ""); 
    strcat(finalName, filename); 

WTF ?!你爲filename複製了什麼?還有80個字符可能不夠用。

if ((file = fopen(finalName, "rb"))==NULL) 
    { 

沒有正確打開的文件可能比只是錯誤的路徑有更多的原因。

 printf("File Not Found : %s\n",finalName); 
     return 0; 
    } 

    fseek(file, 18, SEEK_CUR); 

你不應該盲目地嘗試讀取文件,假設它是你所期望的。二進制文件,比如你在這裏試圖閱讀的DIB有一些原因,所以你也應該閱讀並解析這個頭文件!

glTexCoord2f(1.0, 0.0); 

再次?!

if ((i = fread(&image->size_x, 4, 1, file)) != 1) 
    { 
     printf("Error reading width from %s.\n", finalName); 
     return 0; 
    } 

    if ((i = fread(&image->size_y, 4, 1, file)) != 1) 
    { 
     printf("Error reading height from %s.\n", finalName); 
     return 0; 
    } 

您正在讀取文件中的值,假設您的系統的永久性和對齊規則與文件格式相匹配?你一定有鋼球!

size = image->size_x * image->size_y * 3; 

整數溢出,是啊!你只是讓你的程序被利用。

if ((fread(&planes, 2, 1, file)) != 1) 
    { 
     printf("Error reading planes from %s.\n", finalName); 
     return 0; 
    } 

    if (planes != 1) 
    { 
     printf("Planes from %s is not 1: %u\n", finalName, planes); 
     return 0; 
    } 

    if ((i = fread(&bpp, 2, 1, file)) != 1) 
    { 
     printf("Error reading bpp from %s.\n", finalName); 
     return 0; 
    } 

再次讀取二進制值W/O妥善照顧字節序和對齊......

if (bpp != 24) 
    { 
     printf("Bpp from %s is not 24: %u\n", finalName, bpp); 
     return 0; 
    } 

    fseek(file, 24, SEEK_CUR); 

你爲什麼要進行相對尋求在這裏?BITMAPFILEHEADER(你知道你以前無意中跳過的那18個字節)告訴你像素數據的起始位置。

image->data = (char *) malloc(size); 

    if (image->data == NULL) 
    { 
     printf("Error allocating memory for color-corrected image data"); 
     return 0; 
    } 

    if ((i = fread(image->data, size, 1, file)) != 1) 
    { 
     printf("Error reading image data from %s.\n", finalName); 
     return 0; 
    } 

順便說一句:你應該關閉文件,如果中止。

for (i=0;i<size;i+=3) 
    { 
     temp = image->data[i]; 
     image->data[i] = image->data[i+2]; 
     image->data[i+2] = temp; 
    } 

這不是做顏色校正,它只是交換元素。較新的OpenGL直接支持DIB文件的BGR對齊。

return 1; 

還沒關閉文件...

} 

void textureLoader() 
{ 

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 

    for(int k=0; k < textureCount; k++) 
    { 
     if(!imageLoader(textureFilenames[k], &myTextureData[k])) 
      exit(1); 

好吧,好吧,這樣做通過這些全局數組做這項工作。但嚴重:textureLoader應該返回加載紋理的紋理ID。

 glGenTextures(1, &theTexture[k]); 

     glBindTexture(GL_TEXTURE_2D, theTexture[k]);  

     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); 
     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); 
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); 

     gluBuild2DMipmaps(GL_TEXTURE_2D, 3, myTextureData[k].size_x, myTextureData[k].size_y, GL_RGB, GL_UNSIGNED_BYTE, myTextureData[k].data); 
    } 
} 

void init(void) 
{ 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glEnable(GL_DEPTH_TEST); 
    glMatrixMode(GL_MODELVIEW); 

    is_depth = 1; 
} 

你在這裏「初始化」屬於顯示功能。

void display(void) 
{ 

    if (is_depth) 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    else 
     glClear(GL_COLOR_BUFFER_BIT); 

WTF是這樣的嗎?你認爲這有什麼影響?是的,有多通道技術只能部分清除幀緩衝區,但你並沒有這樣做。擺脫is_depth

textureLoader(); 

textureLoader屬於成init;加載紋理頂點緩衝區對象是OpenGL「初始化程序」無論如何可以做的唯一有用的東西。隨着更多的經驗,你也開始從顯示路由中做這樣的事情,以實現諸如交錯紋理加載之類的東西,這樣你就可以在不加載延遲的情況下導航大型場景。

重要的是缺少這裏:你不設置你的矩陣。在渲染函數中應該設置投影模型視圖變換矩陣。

所以你想繪製紋理四邊形。那麼,爲什麼你不:你想在這裏使用

  • glEnable(GL_TEXTURE_2D);
  • glBindTexture(GL_TEXTURE_2D, theTexture[0]);或任何ID?

    glBegin(GL_QUADS); 
        glTexCoord2f(0.0,0.0); 
        glVertex3f(-75.0, 0.0, -400.0); 
        glTexCoord2f(0.0,1.0); 
        glVertex3f(-75.0, 0.0, 100.0); 
        glTexCoord2f(1.0,0.0); 
        glVertex3f(75.0, 0.0, 100.0); 
        glTexCoord2f(1.0,1.0); 
        glVertex3f(75.0, 0.0, -400.0); 
    

看起來不錯,到目前爲止,除了你不提供法線。你需要那些照明。

但跆拳道是這樣的:

 drawcube(-70,15,72,8,15,28,4); 
     drawcube(-70,10,10,8,10,28,0); 
     drawcube(-70,15,-45,8,15,18,0); 
     drawcube(-70,15,-85,8,15,18,0); 
     drawcube(-70,35,-125,8,35,12,0); 
     drawcube(-70,9,-170,8,9,28,0); 
     drawcube(-70,15,-220,8,15,18,0); 
     drawcube(-70,15,-265,8,15,28,0); 
     drawcube(-70,15,-330,8,15,28,0); 
     drawcube(67,15,72,8,15,28,0); 
     drawcube(67,10,10,8,10,28,0); 
     drawcube(67,15,-45,8,15,18,0); 
     drawcube(67,15,-85,8,15,18,0); 
     drawcube(67,35,-125,8,35,12,0); 
     drawcube(67,9,-170,8,9,28,0); 
     drawcube(67,15,-220,8,15,18,0); 
     drawcube(67,15,-265,8,15,28,0); 
     drawcube(67,15,-330,8,15,28,0); 
     drawcube(-33,18,-364,25,18,10,0); 
     drawcube(25,28,-364,30,28,10,0); 
     drawcube(25,28,90,30,28,10,0); 
     drawcube(-33,18,90,25,18,10,0); 
     drawcube(0,60,-125,18,60,22,0); 
     drawcube(0,25,-225,8,25,28,0); 
     drawcube(0,25,0,8,25,28,0); 

你在這裏glBegin(…)...glEnd()塊,所以唯一有效的OpenGL調用是glColor,glNormal,glTexCoord,glVertexAttrix,glVertex和glEnd。因此,讓我們看看有什麼在drawcube然後...

glEnd(); 


    glutSwapBuffers(); 
} 

void keyboard(unsigned char key, int x, int y) 
{ 
    switch (key) 
    { 
    case 'a': 
     glTranslatef(5.0, 0.0, 0.0); 
     break; 
    case 'd': 
     glTranslatef(-5.0, 0.0, 0.0); 
     break; 
    case 'w': 
     glTranslatef(0.0, 0.0, 5.0); 
     break; 
    case 's': 
     glTranslatef(0.0, 0.0, -5.0); 
     break; 
    } 
    display(); 
} 

NO!沒有!沒有!這不是OpenGL的工作原理。 glTranslate是一個矩陣操作函數,它只適用於渲染過程的上下文中。你只是在這裏打亂OpenGL狀態。

void resize(int width, int height) 
{ 
    if (height == 0) height = 1; 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    gluPerspective(45.0, width/height, 1.0, 400.0); 
    glTranslatef(0.0, -5.0, -150.0); 
    glMatrixMode(GL_MODELVIEW); 

這東西屬於展示。我知道,很多(大多數)教程都是這樣寫的,就像你一樣,但是相信我:只要你想實現類似HUD或多通道渲染設置的東西,調整大小處理程序中的投影就會咬你。

} 

void drawcube(float xc, float yc, float zc, float x_offset, float y_offset, float z_offset, int color) 
{ 

啊,在drawcube功能

switch(color) 
    { 
    case 1: 
     glColor3f(1.0,0.0,0.0); 
     break; 
    case 2: 
     glColor3f(0.0,1.0,0.0); 
     break; 
    case 3: 
     glColor3f(0.0,0.0,1.0); 
     break; 
    } 

    glBegin(GL_QUADS); 

你調用從glBegin(…)...glEnd()塊內drawcube,但然後嘗試打開另一個塊。這是一個OpenGL錯誤。 glBegin(…)...glEnd()不要嵌套。

 glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset); 

     glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset); 

     glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset); 

     glVertex3f(xc + x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset); 

     glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc - z_offset); 
     glVertex3f(xc - x_offset,yc - y_offset,zc - z_offset); 

     glVertex3f(xc + x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc - x_offset,yc + y_offset,zc + z_offset); 
     glVertex3f(xc - x_offset,yc - y_offset,zc + z_offset); 
     glVertex3f(xc + x_offset,yc - y_offset,zc + z_offset); 

是不是你的問題如何使用紋理?我沒有看到來電glTexCoord那裏...

glEnd(); 
} 

http://www.osnews.com/story/19266/WTFs_m

+1

代碼徹底破壞的榮譽+1。 – zenzelezz 2011-03-22 11:19:06