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