How to load and fill cubes with texture image in o

2019-07-08 03:00发布

I have a grid with cubes and i want to fill the cubes with two different colors and with 3 different images(.bmp). So every cube is filled with colours or images. I wrote a code and when i press the <> button the grid is filled with 5 different colours. Can anyone tell me how can i change my code to fill the grid with 3 different images(randomly)? Here is my code:

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

1条回答
混吃等死
2楼-- · 2019-07-08 03:23

Here I post code to display images(textures) instead of colors.

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

The result will be like:

enter image description here

The two essential parts is to load textures to memory and specifying texture coordinates to primitives for proper texture wrapping.

Texture loading process is displayed here.

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

And texture coord maping process.

        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();

As you cannot load tga bitmaps directly. I post code to deal with this problem.

// 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;
    }
查看更多
登录 后发表回答