glBindTexture(GL_TEXTURE_2D, number); for numbers bigger than 1

Like in topic. Is it possible to use glBindTexture(GL_TEXTURE_2D, number) for numbers bigger than 1? Currently when I try to do this, I can see only untextured quads.

Here is my texture binding and usage code:
(TextureHolder is just class with texture and two int values)


public class Texture {
    
    public static void create(int number, TextureHolder tex) {
        glBindTexture(GL_TEXTURE_2D, number);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width, tex.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.texture);
    }
    
    public static void load(int number) {
        glBindTexture(GL_TEXTURE_2D, number);
    }
    
    public static void draw(TextureHolder tex, float x, float y, float angle) {
        glPushMatrix();
            glTranslated(x, y, 0);
            glRotated(angle/(Math.PI/180), 0, 0, 1);
            glBegin(GL_QUADS);
                glColor4f(1,1,1,1);
                glTexCoord2f(0,1); glVertex2f(-tex.height/2, -tex.width/2);
                glTexCoord2f(0,0); glVertex2f(-tex.height/2, tex.width/2);
                glTexCoord2f(1,0); glVertex2f(tex.height/2, tex.width/2);
                glTexCoord2f(1,1); glVertex2f(tex.height/2, -tex.width/2);
            glEnd();
        glPopMatrix();
    }
    
}

How I use it:


public void createTexture(String path) {
        textureLoader = Tools.TextureLoader.create(path);
        Texture.create(20, textureLoader);
    }

@Override public void Draw() {
        Texture.load(20);
        Texture.draw(textureLoader, x, y, angleRad);
    }

glGenTextures will give you a “name” (aka: ID) that you can use for that texture.

Here is a simple texture wrapper example.

Is it possible to “load” empty texture numbers into memory for later use? I am using enum for storing texture numbers to have better control of them.

I have tried this, but it does not work (I still can’t use texture numbers bigger than 1):


        int i = 1;
        int texAmount = 0;
        while (i<=30) {
            texAmount = glGenTextures();
            i++;
        } 

The problems is that enums are determined at compile time, while the values returned by glGenTextures cannot be assumed to have any pattern. Therefore trying to get texture IDs into enums is the wrong approach (by definition).

Why not simply make an int[], and store the texture IDs in them. Then use the enums to refer to a slot in the array.


int[] textureHandles = new int[30];
for(int i=0; i<textureHandles.length; i++) {
   textureHandles[i] = glGenTextures();
}

public enum TextureID {
   GROUND, WATER, ROCK, AIR
}

glBindTexture(GL_TEXTURE_2D, textureHandles[ROCK.ordinal()]);

Unfortunately, this approach does not work too.

It works just fine. Show us more of your code, so we can see what goes wrong there.

You should be using glGenTextures(); like this:


public static int create(TextureHolder tex) {
    int uniqueId = glGenTextures();
    glBindTextures(GL_TEXTURE_2D, uniqueId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width, tex.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.texture);
}

private int texId;
public void createTexture(String path) {
        textureLoader = Tools.TextureLoader.create(path);
        texId = Texture.create(textureLoader);
    }

@Override public void Draw() {
        Texture.load(texId);
        Texture.draw(textureLoader, x, y, angleRad);
    }

Results:

http://imageshack.us/a/img338/268/screenshot024e.png

http://imageshack.us/a/img84/290/screenshot025ho.png

I don’t know where the problem is, so there is my full code: https://dl.dropbox.com/u/67758055/src.zip

I will be very grateful if someone will tell me where the problem is. :wink:

hi,
if you want some help on an international forum like here, you absolutely have to take the habit to write your code in English. I was willing to help here but when I saw that your code was in a language I don’t understand, I just stopped trying as it would have been too painful … and I think it will be the same for most people of this forum.

Translated code and all resources, it is possible to run project in IDE: https://dl.dropbox.com/u/67758055/Silent_Space_English.zip

I hope that there will be no trouble understanding this code. :wink:

ok great :slight_smile:
I had a look, the problem here is the Texture class. The textureId that is generated by glGenTextures() is used as an index in the static array “textures” instead of being used directly :


    public static void load(int number) {
        glBindTexture(GL_TEXTURE_2D, textures[number]);
    }

“textures” is never modified in your code, meaning that it is initially filled with 0, so here you’re always binding texture id 0 which is quite the same as disabling textures :slight_smile:

just replacing the load method with :


    public static void load(int number) {
        glBindTexture(GL_TEXTURE_2D, number);
    }

should fix your issue as long as “number” is always generated by glGenTextures()

Hope this helps :wink:

EDIT :
something else, you have to add this when creating the texture (in the Texture class, after glTexImage2D(…)) :


	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Texture 0 is a perfectly valid texture id, and refers to the single texture unit from OpenGL 1.0. It’s just not usually a very good to use it. It’s most definitely not the same thing as disabling textures, only glDisable does that.

probably true, but srsly, are you really calling glDisable() everytime you want to disable texturing? You have to admit you are using glBindTexture(GL_TEXTURE_2D, 0); :stuck_out_tongue:

[quote]The first version of OpenGL, version 1.0, was released in January 1992 by Mark Segal and Kurt Akeley.
[/quote]
Seriously?

Matheus23: +1

You cannot count on texture 0 having any particular default data in it. Typically it’s white, but on some GPUs/drivers, people have told me it’s black. I don’t usually have much need to disable texturing. For times when I do need a solid color, I generate a white pixmap or I work a white square into the atlas, which is more so I can treat that solid block like any other tile. Otherwise it’s not that expensive to disable as long as you’re not doing it a zillion times per frame.

When do you really need to disable texturing in fixed function? Using a 1x1 white TextureRegion from your current sprite sheet has the same effect.

You shouldn’t need to use glDisable (which can lead to performance problems) or bind texture 0 (which might have unusual results on shitty drivers). Just bind your white texture region whenever you want a “solid” or “untextured” primitive. And as a bonus, you won’t even need to flush your sprite batch. :slight_smile:

You mean, exactly what sproingie was saying?