2011-03-22 168 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