如何在openGL中使用纹理图像加载和填充立方体

我有一个带有立方体的网格,我想用两种不同的颜色和3种不同的图像(.bmp)填充立方体。 所以每个立方体都充满了颜色或图像。 我写了一个代码,当我按下按钮时,网格中充满了5种不同的颜色。 任何人都可以告诉我如何更改我的代码以3个不同的图像(随机)填充网格? 这是我的代码:

void randomFilling(); void myprint(); struct square{ int v1x, v1y; int v2x, v2y; int v3x, v3y; int v4x, v4y; int color; }; struct square Squares[12][15]; struct flags{ int b; }flags; void drawScene(); void findVerticesPosition(){ int counter=0; for(int i=0; i<600; i+=40){ for(int j=0; j<480; j+=40){ Squares[j/40][i/40].v1x = i; Squares[j/40][i/40].v1y = j; Squares[j/40][i/40].v2x = i; Squares[j/40][i/40].v2y = j+40; Squares[j/40][i/40].v3x = i+40; Squares[j/40][i/40].v3y = j+40; Squares[j/40][i/40].v4x = i+40; Squares[j/40][i/40].v4y = j; } } for(int i=0; i<12; i++){ for(int j=0; j<15; j++){ Squares[i][j].color = rand()%5 + 1; } } } void handleKeypress(unsigned char key, int x, int y) { switch (key) { case 27: //Escape key exit(0); case 98: //b randomFilling(); flags.b = 1; drawScene(); } } void randomFilling(){ int randomNumber; srand(time(NULL)); //randomNumber = rand() % 5 + 1; for(int i=0; i<12; i++){ for(int j=0; j<15; j++){ randomNumber = Squares[i][j].color; if(randomNumber == 1){ glBegin(GL_QUADS); glColor3f(1.0,0.9,0.1); glVertex2f(Squares[i][j].v1x, Squares[i][j].v1y); glVertex2f(Squares[i][j].v2x, Squares[i][j].v2y); glVertex2f(Squares[i][j].v3x, Squares[i][j].v3y); glVertex2f(Squares[i][j].v4x, Squares[i][j].v4y); glEnd(); } else if(randomNumber == 2){ glBegin(GL_QUADS); glColor3f(1.0,0.0,0.1); glVertex2f(Squares[i][j].v1x, Squares[i][j].v1y); glVertex2f(Squares[i][j].v2x, Squares[i][j].v2y); glVertex2f(Squares[i][j].v3x, Squares[i][j].v3y); glVertex2f(Squares[i][j].v4x, Squares[i][j].v4y); glEnd(); } else if(randomNumber == 3){ glBegin(GL_QUADS); glColor3f(0,0.9,0.1); glVertex2f(Squares[i][j].v1x, Squares[i][j].v1y); glVertex2f(Squares[i][j].v2x, Squares[i][j].v2y); glVertex2f(Squares[i][j].v3x, Squares[i][j].v3y); glVertex2f(Squares[i][j].v4x, Squares[i][j].v4y); glEnd(); } else if(randomNumber == 4){ glBegin(GL_QUADS); glColor3f(0,0,1); glVertex2f(Squares[i][j].v1x, Squares[i][j].v1y); glVertex2f(Squares[i][j].v2x, Squares[i][j].v2y); glVertex2f(Squares[i][j].v3x, Squares[i][j].v3y); glVertex2f(Squares[i][j].v4x, Squares[i][j].v4y); glEnd(); } else if(randomNumber == 5){ glBegin(GL_QUADS); glColor3f(0,0.9,1); glVertex2f(Squares[i][j].v1x, Squares[i][j].v1y); glVertex2f(Squares[i][j].v2x, Squares[i][j].v2y); glVertex2f(Squares[i][j].v3x, Squares[i][j].v3y); glVertex2f(Squares[i][j].v4x, Squares[i][j].v4y); glEnd(); } else{ printf("WTF\n"); } } } } //Initialize OpenGL void init(void) { glClearColor(1.0,1.0,1.0,1.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,600.0,-60.0,480.0); flags.b=0; } void drawScene(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0,0.0,0.0); //glPointSize(3.0); if(flags.b==1){ randomFilling(); //------------ } glColor3f(0,0,0); glBegin(GL_LINES); for(int i = 0; i <= 600; i += 40) { glVertex2f((float)i, 0.0f); glVertex2f((float)i, 480.0f); glVertex2f(0.0f, (float)i); glVertex2f(600.0f, (float)i); } glEnd(); glFlush(); } int main(int argc, char**argv) { findVerticesPosition(); //myprint(); glutInit(&argc, argv); glutInitWindowPosition(300,80); glutInitWindowSize(600,540); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutCreateWindow("BraXaPsa II"); init(); glutDisplayFunc(drawScene); //glutDisplayFunc(randomFilling); glutKeyboardFunc(handleKeypress); glutMainLoop(); } 

在这里,我发布代码来显示图像(纹理)而不是颜色。

 // relative path to texture bitmaps char* texture_names[] = { "textures\\grass.tga", "textures\\wood\\brown wood.tga", "textures\\ceiling.tga" }; void randomFilling(); void myprint(); struct square{ int v1x, v1y; int v2x, v2y; int v3x, v3y; int v4x, v4y; int texture; }; struct square Squares[12][15]; struct flags{ int b; }flags; void drawScene(); void findVerticesPosition(){ int counter=0; for(int i=0; i<600; i+=40){ for(int j=0; j<480; j+=40){ Squares[j/40][i/40].v1x = i; Squares[j/40][i/40].v1y = j; Squares[j/40][i/40].v2x = i; Squares[j/40][i/40].v2y = j+40; Squares[j/40][i/40].v3x = i+40; Squares[j/40][i/40].v3y = j+40; Squares[j/40][i/40].v4x = i+40; Squares[j/40][i/40].v4y = j; } } for(int i=0; i<12; i++){ for(int j=0; j<15; j++){ Squares[i][j].texture = rand()%3; } } } void handleKeypress(unsigned char key, int x, int y) { switch (key) { case 27: //Escape key exit(0); case 98: //b randomFilling(); flags.b = 1; drawScene(); } } // creating texture objects array GLuint g_pnTextures[3]; void randomFilling(){ for(int i=0; i<12; i++){ for(int j=0; j<15; j++){ glColor3f(1.0f, 1.0f, 1.0f); glBindTexture(GL_TEXTURE_2D, g_pnTextures[Squares[i][j].texture]); glBegin(GL_QUADS); // specify texture coords glTexCoord2f(0.0f, 0.0f); glVertex2f(Squares[i][j].v1x, Squares[i][j].v1y); // specify texture coords glTexCoord2f(0.0f, 1.0f); glVertex2f(Squares[i][j].v2x, Squares[i][j].v2y); // specify texture coords glTexCoord2f(1.0f, 1.0f); glVertex2f(Squares[i][j].v3x, Squares[i][j].v3y); // specify texture coords glTexCoord2f(1.0f, 0.0f); glVertex2f(Squares[i][j].v4x, Squares[i][j].v4y); glEnd(); } } } //Initialize OpenGL void init(void) { GLbyte* pImage = NULL; GLint width = 0; GLint height = 0; GLint components = 0; GLenum format; glClearColor(1.0,1.0,1.0,1.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,600.0,-60.0,480.0); flags.b=0; // Generate texture object glGenTextures(3, g_pnTextures); for (int i = 0; i < 3; i++) { // bind current texture object glBindTexture(GL_TEXTURE_2D,g_pnTextures[i]); // load texture data pImage = gltLoadTGA(texture_names[i],&width,&height,&components,&format); glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,GL_TRUE); printf("texture: \"%s\" - %p\n",texture_names[i],pImage); // Load texture data to video memory glTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width,height,0,format,GL_UNSIGNED_BYTE,pImage); 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_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,8); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE); delete [] pImage; pImage = NULL; } glEnable(GL_TEXTURE_2D); } void drawScene(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0,0.0,0.0); //glPointSize(3.0); if(flags.b==1){ randomFilling(); //------------ } glColor3f(0,0,0); glBegin(GL_LINES); for(int i = 0; i <= 600; i += 40) { glVertex2f((float)i, 0.0f); glVertex2f((float)i, 480.0f); glVertex2f(0.0f, (float)i); glVertex2f(600.0f, (float)i); } glEnd(); glFlush(); } int main(int argc, char**argv) { findVerticesPosition(); //myprint(); glutInit(&argc, argv); glutInitWindowPosition(300,80); glutInitWindowSize(600,540); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutCreateWindow("BraXaPsa II"); init(); glutDisplayFunc(drawScene); //glutDisplayFunc(randomFilling); glutKeyboardFunc(handleKeypress); glutMainLoop(); // Unload texture data glDeleteTextures(3, g_pnTextures); } 

结果如下:

在此处输入图像描述

两个基本部分是将纹理加载到内存并指定纹理坐标到基元以进行适当的纹理包装。

此处显示纹理加载过程。

  for (int i = 0; i < 3; i++) { // bind current texture object glBindTexture(GL_TEXTURE_2D,g_pnTextures[i]); // load texture data pImage = gltLoadTGA(texture_names[i],&width,&height,&components,&format); glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,GL_TRUE); printf("texture: \"%s\" - %p\n",texture_names[i],pImage); // Load texture data to video memory glTexImage2D(GL_TEXTURE_2D,0,GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width,height,0,format,GL_UNSIGNED_BYTE,pImage); 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_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,8); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_MODULATE); delete [] pImage; pImage = NULL; } 

和纹理coord maping过程。

  glBegin(GL_QUADS); // specify texture coords glTexCoord2f(0.0f, 0.0f); glVertex2f(Squares[i][j].v1x, Squares[i][j].v1y); // specify texture coords glTexCoord2f(0.0f, 1.0f); glVertex2f(Squares[i][j].v2x, Squares[i][j].v2y); // specify texture coords glTexCoord2f(1.0f, 1.0f); glVertex2f(Squares[i][j].v3x, Squares[i][j].v3y); // specify texture coords glTexCoord2f(1.0f, 0.0f); glVertex2f(Squares[i][j].v4x, Squares[i][j].v4y); glEnd(); 

因为你无法直接加载tga位图。 我发布代码来处理这个问题。

 // Define targa header. #pragma pack(1) typedef struct { GLbyte identsize; // Size of ID field that follows header (0) GLbyte colorMapType; // 0 = None, 1 = paletted GLbyte imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle unsigned short colorMapStart; // First colour map entry unsigned short colorMapLength; // Number of colors unsigned char colorMapBits; // bits per palette entry unsigned short xstart; // image x origin unsigned short ystart; // image y origin unsigned short width; // width in pixels unsigned short height; // height in pixels GLbyte 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 pointer TGAHEADER tgaHeader; // TGA file header unsigned long lImageSize; // Size in bytes of image short 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 fil pFile = 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 buffer lImageSize = tgaHeader.width * tgaHeader.height * sDepth; // Allocate memory and check for success pBits = new GLbyte[lImageSize]; 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 recognize if(fread(pBits, lImageSize, 1, pFile) != 1) { free(pBits); return NULL; } // Set OpenGL format expected switch(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 File fclose(pFile); // Return pointer to image data return pBits; }