Enum problems

Some weird things have been happening when using enums for me. I'm trying to make a 2d RPG using opengl and C++. It was going well up to now. Basically my enum seems to be interfering with something.

This is where it returns the type of tile in tile.cpp
1
2
3
TILE Tile::GetType() {
    return type;
}


the enum is declared in main.h
1
2
3
enum TILE {
    T_GRASS
};



I call my tile->Draw function and set as the last parameter textures[tile->GetType()] (this happens in a loop)
tile->Draw((x * 32) - camOffsetX, (y * 32) - camOffsetY, textures[tile->GetType()]);

This is my tile draw function
1
2
3
4
5
6
7
8
9
10
void Tile::Draw(int x, int y, GLuint texture) {
    glBindTexture(GL_TEXTURE_2D, texture);

    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex2f(x, y);
        glTexCoord2f(0, 1); glVertex2f(x, y + 32);
        glTexCoord2f(1, 1); glVertex2f(x + 32, y + 32);
        glTexCoord2f(1, 0); glVertex2f(x + 32, y);
    glEnd();
}



If I call like this:
tile->Draw((x * 32) - camOffsetX, (y * 32) - camOffsetY, textures[T_GRASS]);

then the tiles get shown properly but if I call using tile->GetType() then they're white???? Also, T_GRASS's value is 0 when using cout and so is tile->GetType() so I don't get why it turns out white.

Even more confusing though, if I use textures[T_GRASS] but put a
cout << tile->GetType();
right before then it displays white!

It happens whenever I return an enum. Too confusing huh?

Thanks,
Matthew
This sounds like memory corruption. How, when, and where are you defining "textures"?
GLuint textures[256]; is declared in Game.h as private

All the tiles are initialized here in Game.cpp (this version sets the texture beforehand but still the exact same behavior)

1
2
3
4
5
6
for(int x = 0; x < level_w; x++) {
		for(int y = 0; y < level_h; y++) {
			Tile *tile = new Tile(T_GRASS, textures[T_GRASS]);
			level->AddTile(x, y, tile);
		}
	}


the constructor for tile is in Tile.cpp:

1
2
3
4
Tile::Tile(int type, GLuint tex) { //also tried GLuint &tex
	this->type = type;
	this->tex  = tex;
}


but whenever I call

tile->Draw((x * 32) - camOffsetX, (y * 32) - camOffsetY);

then it shows it as white and the app goes quite laggy

EDIT: Just realised that when ran in debug mode I get a segmentation fault :/ on this line:

glBindTexture(GL_TEXTURE_2D, tex);
Last edited on
I do have to wonder how you're calling Draw with two parameters when it takes three. Typo? It shouldn't even compile.
Oh sorry, I've modified some of it in the mean time for testing, hence "(this version sets the texture beforehand but still the exact same behavior)". So I've tried storing the GLuint within the class so when I call draw it takes it from there but also tried sending it directly through the Draw function but none work.
A few possibilities to try:

1) Try a smaller array.
2) Maybe try a standard library container, such as a list. Those are much harder to get away with memory corrupting operations.

If you would, give those a shot and report the results?
Okay so I changed to a vector
vector<GLuint> textures;

is used
textures.push_back(Load_Image("textures/tiles/grass.png"));

to load the texture but still no difference

To make it even more confusing when I remove the glBindTexture it works, I guess because the SOIL image loading library I use uses glBindTexture when loading in the image so it uses the latest texture I loaded.
Is the image square?
As in, are the dimensions square numbers?
Last edited on
Yes, 32x32 pixels
I used SOIL once for loading textures into an OpenGL engine I was writing, and I vaguely remember having this same problem. Give me a bit to dig through my old code.
I don't think this is to do with the image, it's the variable tex

In here it's fine

1
2
3
4
Tile::Tile(TILE type, GLuint tex) {
	this->type = type;
	this->tex  = tex;
}


But I get a segmentation fault here when binding it
1
2
3
4
5
6
7
8
9
10
void Tile::Draw(int x, int y) {
	glBindTexture(GL_TEXTURE_2D, tex);
	
	glBegin(GL_QUADS);
		glTexCoord2f(0, 0); glVertex2f(x, y);
		glTexCoord2f(0, 1); glVertex2f(x, y + 32);
		glTexCoord2f(1, 1); glVertex2f(x + 32, y + 32);
		glTexCoord2f(1, 0); glVertex2f(x + 32, y);
	glEnd();
}
Ok, here is some of what I wrote:
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
enum textures{
TEXTURE_CROSSHAIR,
TEXTURE_LOGO,
TEXTURE_DIRT,
TEXTURE_GRASS_SIDE,
TEXTURE_GRASS,
TEXTURE_STONE};
void client::loadTexts() {
 //First crosshair

    textureList[TEXTURE_CROSSHAIR] = SOIL_load_OGL_texture(
                                         "resource/art/UI/crosshair.tga",
                                         SOIL_LOAD_AUTO,
                                         SOIL_CREATE_NEW_ID,
                                         SOIL_FLAG_INVERT_Y | SOIL_FLAG_MULTIPLY_ALPHA
                                     );
    textureList[TEXTURE_LOGO] = SOIL_load_OGL_texture
                                (
                                    "resource/art/UI/logo.tga",
                                    SOIL_LOAD_AUTO,
                                    SOIL_CREATE_NEW_ID,
                                    SOIL_FLAG_INVERT_Y | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_POWER_OF_TWO
                                );
    textureList[TEXTURE_DIRT] = SOIL_load_OGL_texture
                                (
                                    "resource/art/blocks/terrain/dirt.tga",
                                    SOIL_LOAD_AUTO,
                                    SOIL_CREATE_NEW_ID,
                                    SOIL_FLAG_TEXTURE_REPEATS
                                );
    textureList[TEXTURE_GRASS_SIDE] = SOIL_load_OGL_texture
                                      (
                                          "resource/art/blocks/terrain/grassblockside.tga",
                                          SOIL_LOAD_AUTO,
                                          SOIL_CREATE_NEW_ID,
                                          SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_INVERT_Y
                                      );
    textureList[TEXTURE_GRASS] = SOIL_load_OGL_texture
                                 (
                                     "resource/art/blocks/terrain/grass.tga",
                                     SOIL_LOAD_AUTO,
                                     SOIL_CREATE_NEW_ID,
                                     SOIL_FLAG_TEXTURE_REPEATS
                                 );
    if(!textureList[TEXTURE_CROSSHAIR] || !textureList[TEXTURE_LOGO] || !textureList[TEXTURE_DIRT])
    {
        cout<<"TEXTURE LOAD FAILIURE: "<<SOIL_last_result()<<endl;
        system("PAUSE");
        exit(0);
    }

    cubeTexture = new cubeLayout;
    cubeTexture->UP = textureList[TEXTURE_GRASS];
    cubeTexture->DOWN = textureList[TEXTURE_DIRT];
    cubeTexture->LEFT = textureList[TEXTURE_GRASS_SIDE];
    cubeTexture->RIGHT = textureList[TEXTURE_GRASS_SIDE];
    cubeTexture->FRONT = textureList[TEXTURE_GRASS_SIDE];
    cubeTexture->BACK = textureList[TEXTURE_GRASS_SIDE];
}

Then I had a custom cubeLayout (cubeTexture) class for handling the texturing of the cube.
Are you using SOIL_load_OGL_texture()?


Last edited on
Yes I am:

1
2
3
GLuint Load_Image(const char *file) {
	return SOIL_load_OGL_texture(file, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);
}


i'm basically doing the same thing as you

textures.push_back(Load_Image("textures/tiles/grass.png"));

It's just the Draw function and the tex variable playing up and giving seg faults
Take off the SOIL_FLAG_MIPMAPS flag, if I remember correctly that had a lot to do with it.
No thats not the problem, doesn't make a difference.

Heres a brief overview of what I've found so far:

Tile *tile = new Tile(T_GRASS, textures.at(T_GRASS));
textures.at(T_GRASS); is perfectly fine when outputted the line before

in tile constructor

1
2
3
4
Tile::Tile(TILE type, GLuint tex) {
	this->type = type;
	this->tex  = tex;
}

GLuint tex gives seg fault when using cout when clearly it was fine just before

so when calling the draw function glBindTexture fails and gives segfault
Is GLunit meant to be copied? Currently it is copied as it is passed by value, but even if you passed it by reference you have explicitly called operator= with "this->tex = tex".

Have you tried this?
1
2
3
4
Tile::Tile(TILE type, GLuint &tex) : tex(tex)
{
	this->type = type;
}
Sorry doesn't work either, I'm using codeblocks and the debuggers playing up, it doesn't stop on any breakpoints.
Topic archived. No new replies allowed.