【问题标题】:How to load and fill cubes with texture image in openGL如何在openGL中使用纹理图像加载和填充立方体
【发布时间】:2015-11-29 18:17:00
【问题描述】:

我有一个带有立方体的网格,我想用两种不同的颜色和 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();
}

【问题讨论】:

    标签: c opengl graphics textures glut


    【解决方案1】:

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

    // 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;
        }
    

    和纹理坐标映射过程。

            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;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-29
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 2011-07-08
      相关资源
      最近更新 更多