4

I am working on an Environment Map for a skybox in OpenGL and have run into a problem with the textures. My code produces tiles of the texture that I am trying to map, rather than one big texture. The tiles have also lost most of their resolution and are very small.

Here is my code:

#include <windows.h>
#include <stdio.h>
#include <glew.h>
#include <glut.h>
#include "Camera.h"

Camera cam;
GLuint texture [6]; //the array for our texture

GLfloat angle = 0.0;

GLuint LoadTexture( const char * filename, int width, int height) {
    GLuint texture;
    unsigned char * data;
    FILE* file;

    file = fopen( filename, "rb" );
    if ( file == NULL ) return 0;
    data = (unsigned char *)malloc( width * height * 3 );
    fread( data, width * height * 3, 1, file );
    fclose( file );

    glGenTextures( 1, &texture ); 
    glBindTexture( GL_TEXTURE_2D, texture ); 
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); 

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data );    
    free(data);
    return texture; 
}    

void FreeTexture( GLuint texture )
{
    glDeleteTextures( 1, &texture );
}

void skybox (void) {
float x = 0;
float y = 0;
float z = 0;
float width  = 100;
float height = 100;
float length = 100;
// Bind the BACK texture of the sky map to the BACK side of the cube
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Center the skybox
x = x - width  / 2;
y = y - height / 2;
z = z - length / 2;
glBegin(GL_QUADS);      
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y,  z);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height, z); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y,  z);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_QUADS);  
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,  z + length);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z + length);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z + length); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,  z + length);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[4]);
glBegin(GL_QUADS);      

    glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,  z);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y,  z + length);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y,  z + length); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,  z);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[5]);
glBegin(GL_QUADS);      
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y + height, z);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y + height, z + length); 
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z + length);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[2]);
glBegin(GL_QUADS);      
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z + length); 
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y,  z + length);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,  z);     

glEnd();
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin(GL_QUADS);  
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,  z);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y,  z + length);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height, z + length); 
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z);
glEnd();
//glBindTexture( GL_TEXTURE_CUBE_MAP, texture[0] ); //bind the texture
//glRotatef( angle, 1.0f, 1.0f, 1.0f );
//glutSolidSphere(2, 40, 40);
}

void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
cam.camera();
//gluLookAt (20.0, 20.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
texture[0] = LoadTexture( "Back.bmp", 256, 256 ); //load the texture
texture[1] = LoadTexture( "Front.bmp", 256, 256 ); //load the texture
texture[2] = LoadTexture( "Left.bmp", 256, 256 ); //load the texture
texture[3] = LoadTexture( "Right.bmp", 256, 256 ); //load the texture
texture[4] = LoadTexture( "Bottom.bmp", 256, 256 ); //load the texture
texture[5] = LoadTexture( "Top.bmp", 256, 256 ); //load the texture
glEnable(GL_TEXTURE_2D); //enable 2D texturing
glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
glEnable(GL_TEXTURE_GEN_T);
skybox();
for (int i = 0; i < 6; i++) {
    FreeTexture( texture[i] );
}
glutSwapBuffers();
angle = angle + 0.5;
cam.incAngle();
}

void keyboard (unsigned char key, int x, int y) {
switch (key) {
case 'q': cam.lookUpwards(); break;
case 'z': cam.lookDownwards(); break;
case 'w': cam.slideForward(); break;
case 's': cam.slideBackward(); break;
case 'a': cam.strafeLeft(); break;
case 'd': cam.strafeRight(); break;
case 'e': exit(0); break;
default: break;
}
}

void reshape(int x, int y) {
cam.reshape(x, y);
}

void mouseMovement(int x, int y) {
cam.mouseMovement(x, y);
}

int main (int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("A basic OpenGL Window");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(mouseMovement);
glutMainLoop();
}
msell
  • 2,168
  • 13
  • 30
  • This is fixed-function OpenGL, which is quite dated. Please consider using the programmable pipeline with shaders. – Stephan van den Heuvel Nov 21 '12 at 05:20
  • 11
    @StephanvandenHeuvel: Please consider replying to actual question instead of suggesting something OP doesn't need. Dated or not, fixed function has a lot of uses even today. Making a GL4 shader just to draw a skybox is overkill. – SigTerm Nov 21 '12 at 05:30
  • @SigTerm that is why it is a comment and not an answer. I appreciate the fact that OpenGL fixed function still has a following. The fact is that all cards these days are programmable, and the driver converts your code to programmable pipeline at a performance cost anyway. I am sorry if I aggravated you, I thought that a question posed with programmable pipeline might get more answers. And I am not suggesting OpenGL 4, just using techniques that appeared with OpenGL 2 which came out 9 years ago. – Stephan van den Heuvel Nov 21 '12 at 16:01
  • 1
    @StephanvandenHeuvel: I replied to your comment because I think it is harmful. In my understanding, you propose to add unnecessary complexity. This violates KISS principle, introduces YAGNI feature and will result in extra bugs and wasted development time. If a technology is newer, it doesn't mean you should use it in your program. If a technology is older, it doesn't mean you should avoid it. We still use TCP/IP today, right? How about wheel? Code does not rot, and the best idea will be to use the most suitable tool for the problem, even if the tool wasn't invented yesterday. (cont) – SigTerm Nov 21 '12 at 17:12
  • @StephanvandenHeuvel: ... Regarding OpenGL, shaders are not exactly trivial to understand, and in case of OpenGL 2.0 which you suggested, there's absolutely no gain compared fixed function pipeline for this particular task (skybox). – SigTerm Nov 21 '12 at 17:14
  • @SigTerm you have valid points. To be honest, it was mainly because I was hit with a wall of immediate mode functions in the code sample. If it was fixed function with vertex buffers, I probably would have not even mentioned it, so perhaps I was unclear. – Stephan van den Heuvel Nov 21 '12 at 18:07
  • Hey, this is out of the subject. But, don't load textures in display function. it will slow down your program. – shan Jan 07 '13 at 07:14

2 Answers2

2

Since you are specifying the texture coordinates manually, you should remove / disable the following automatic generation:

glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
glEnable(GL_TEXTURE_GEN_T);

In addition it looks suspicious that you are loading .bmp files as just raw RGB data.

msell
  • 2,168
  • 13
  • 30
1

The color would be turned back to normal if we replace GL_RGB with GL_BGR which is included in "glew.h"

Long
  • 11
  • 1