Help with textures

I'm trying to create a program that loads an image using SDL and converts it to an Opengl Texture then displays that texture on a square. It sounded simple enough but I find myself stuck. I have the program written but all I'm getting is a plain white square. I have all the libraries include from both opengl and SDL. I used code::blocks and created an SDL project then manually added the opengl libraries.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <SDL.h>
#include <GL/glut.h>

void drawScene();
void handleResize(int w,int h);

void initRendering() {
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_NORMALIZE);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_TEXTURE_2D);
}

int main(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(400, 400);

	glutCreateWindow("Textures - SLD & OpenGL");
	initRendering();

	glutDisplayFunc(drawScene);
	//glutKeyboardFunc(handleKeypress);
	glutReshapeFunc(handleResize);

	glutMainLoop();
	return 0;
}

void handleResize(int w,int h)
{
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluOrtho2D (0, (GLdouble) w, 0, (GLdouble) h);
}

void drawScene() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    GLuint TextureID = 0;

    SDL_Surface* Surface = SDL_LoadBMP("cb.bmp");

    glGenTextures(1, &TextureID);
    glBindTexture(GL_TEXTURE_2D, TextureID);

    int Mode = GL_RGB;

    if(Surface->format->BytesPerPixel == 4) {
        Mode = GL_RGBA;
    }

    glTexImage2D(GL_TEXTURE_2D, 0, Mode, Surface->w, Surface->h, 0, Mode, GL_UNSIGNED_BYTE, Surface->pixels);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // For Ortho mode, of course
    int X = 0;
    int Y = 0;
    int Width = 100;
    int Height = 100;

    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f(X, Y, 0);
        glTexCoord2f(1, 0); glVertex3f(X + Width, Y, 0);
        glTexCoord2f(1, 1); glVertex3f(X + Width, Y + Height, 0);
        glTexCoord2f(0, 1); glVertex3f(X, Y + Height, 0);
    glEnd();

	glutSwapBuffers();
}


What am I missing or doing wrong?
Be sure to set your clear color and be sure to set the current color before rendering the quad.

I suspect the problem is this though:

SDL_Surface* Surface = SDL_LoadBMP("cb.bmp");

Try using the fully qualified path to cb.bmp and see if that fixes the problem.
Well I set the clear color and used the full path for cb.bmp but I'm still getting the same problem. However, I did use glColor3f(1,1,1); before rendering the quad so that may be why I'm getting a plain white square. I wasn't sure how to set the color since I'm trying to display a texture on the square so I just used all 1's. Do you think that that could cause an issue?
I'm trying to display a texture on the square so I just used all 1's. Do you think that that could cause an issue?

No, that should be fine.

Are you setting the clear color to something besides white (like black)? And are you seeing the clear color background and the white square or just a white square taking up the whole window? If it's the latter, then it could be an issue with your projection matrix. If it's the former, then it narrows it down to being just a texturing issue.

One thing I would do is I would setup the viewport and projection matrix within the call to initRendering(). Right now you're only setting it up within handleResize(). I would also move the texture generation outside the rendering loop as you're now creating a texture every frame.

After that, I would try setting the other texture parameters (i.e. GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T).

If after that the code still isn't working, I would look at the SDL_Surface itself and I would also look at Surface->pixels for clues (i.e. is it null or garbage?) Hopefully it won't come to this but after that I would suggest calling glGetError() all over the place in hopes of finding a point of failure.
Last edited on
I tried doing your suggestions and nothings changed but I'm not sure how I would setup viewport in initrendering since I use the screen size and I don't know how to use glGetError() or the texture parameters that you gave. I have to goto bed soon so I'll be able to wake up in time for school so I didn't have time to google them. Anyways, heres the code so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <SDL.h>
#include <GL/glut.h>

void drawScene();
void handleResize(int w,int h);


GLuint TextureID = 0;

SDL_Surface* Surface = SDL_LoadBMP("C:/Documents and Settings/fachenjang/Desktop/Programming/C++/OpenGl/Textures/cb.bmp");

void initRendering() {
	glDisable(GL_DEPTH_TEST);
	glGetError();
	glEnable(GL_NORMALIZE);
	glGetError();
	glEnable(GL_COLOR_MATERIAL);
	glGetError();
	glEnable(GL_TEXTURE_2D);
	glGetError();
    glMatrixMode (GL_PROJECTION);
    glGetError();
    glLoadIdentity ();
    glGetError();

	glClearColor(0,0,0,1);
	glGetError();
}

void Texture()
{
    glGenTextures(1, &TextureID);
    glGetError();
    glBindTexture(GL_TEXTURE_2D, TextureID);
    glGetError();

    int Mode = GL_RGB;

    if(Surface->format->BytesPerPixel == 4) {
        Mode = GL_RGBA;
    }

    glGetError();
    glTexImage2D(GL_TEXTURE_2D, 0, Mode, Surface->w, Surface->h, 0, Mode, GL_UNSIGNED_BYTE, Surface->pixels);
    glGetError();
}

int main(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(400, 400);

	glutCreateWindow("Textures - SLD & OpenGL");
	initRendering();

	glutDisplayFunc(drawScene);
	//glutKeyboardFunc(handleKeypress);
	glutReshapeFunc(handleResize);

	glutMainLoop();
	return 0;
}

void handleResize(int w,int h)
{
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluOrtho2D (0, (GLdouble) w, 0, (GLdouble) h);
}

void drawScene() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glGetError();

	glMatrixMode(GL_MODELVIEW);
	glGetError();
    glLoadIdentity();
    glGetError();

    Texture();

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glGetError();
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glGetError();

    // For Ortho mode, of course
    int X = 0;
    int Y = 0;
    int Width = 100;
    int Height = 100;

    glBegin(GL_QUADS);
        glColor3f(1,1,1);
        glTexCoord2f(0, 0); glVertex3f(X, Y, 0);
        glTexCoord2f(1, 0); glVertex3f(X + Width, Y, 0);
        glTexCoord2f(1, 1); glVertex3f(X + Width, Y + Height, 0);
        glTexCoord2f(0, 1); glVertex3f(X, Y + Height, 0);
    glEnd();

	glutSwapBuffers();
}


Last thing, could someone try to compile the code themselves to see if the problem is with my IDE or compiler? cb.bmp is the image that comes with the creating of an SDL project on code::blocks. It's nothing but the code::blocks logo on a black background
I'm not sure how I would setup viewport in initrendering since I use the screen size

I was going to suggest using the size that you gave (400 x 400) but after doing some searching it seems the glutReshapeFunc is guaranteed to be called so your projection matrix is probably OK.

I don't know how to use glGetError()
glGetError() returns a GLenum that is one of the values indicated on the following page:

http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml

I would suggest writing a function that calls glGetError and does a switch on the result.

I don't know how to use ... the texture parameters that you gave


Try calling this after Texture():

1
2
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);


Other possible values for GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T are indicated on this page:

http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml

Also, you're still creating the texture within the main draw loop. I would suggest placing the calls to glTexParameteri within Texture() and move the call to Texture() to right after the call to initRendering().
I've tried your suggestions but am still having no luck at all. I thing I'm just gonna see if I can find someone's code online and see if I can use that because this has been going no where.

edit:
had no luck finding one that I could use but I have discovered that the program runs from code::blocks just fine (minus not displaying the image) but crashes before anything is displayed if it's run by double clicking the program in its file

Edit 2:
Fixed the problem. The image had the wrong dimensions (not powers of 2)
Last edited on
I'm having a new problem now. The images are being displayed (finally) but they all have some sort of discoloration. I've tried 4 different images. 2 gained a blue tint, 1 gained an orange tint, and the other was just fine. My code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <SDL_Image.h>
#include <GL/glut.h>

void drawScene();
void handleResize(int w,int h);

GLuint TextureID;

SDL_Surface *Image = IMG_Load("Cb.bmp");

void initRendering() {
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_TEXTURE_2D);
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();


	glClearColor(0,0,0,1);

}

void Texture(SDL_Surface *Surface)
{
    if (Surface != NULL){
    glGenTextures(1, &TextureID);

    glBindTexture(GL_TEXTURE_2D, TextureID);

    GLint Mode = GL_RGB;

    if(Surface->format->BytesPerPixel == 4) {
        Mode = GL_RGBA;
    }

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, Mode, Surface->w, Surface->h, 0, Mode, GL_UNSIGNED_BYTE, Surface->pixels);
    }
    else
    {
        exit(0);
    }

}

int main(int argc, char** argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(400, 400);

	glutCreateWindow("Textures - SLD & OpenGL");
	initRendering();
	Texture(Image);

	glutDisplayFunc(drawScene);
	//glutKeyboardFunc(handleKeypress);
	glutReshapeFunc(handleResize);

	glutMainLoop();
	return 0;
}

void handleResize(int w,int h)
{
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D (0, (GLdouble) w, 0, (GLdouble) h);
}

void drawScene() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


	glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();



    // For Ortho mode, of course
    int X = 50;
    int Y = 50;
    int Width = 300;
    int Height = 300;

    glEnable(GL_TEXTURE_2D);

    glBegin(GL_QUADS);
        glColor3f(1,1,1);
        glTexCoord2f(0, 1); glVertex2f(X, Y);
        glTexCoord2f(1, 1); glVertex2f(X + Width, Y);
        glTexCoord2f(1, 0); glVertex2f(X + Width, Y + Height);
        glTexCoord2f(0, 0); glVertex2f(X, Y + Height);
    glEnd();

	glutSwapBuffers();
}

/**********************************************************************************************
 *Note - glTexCoord2f uses coordinates where the topleft is (1,1) and the bottemright is (0,0)*
 **********************************************************************************************/
Topic archived. No new replies allowed.