Trouble with Textures and Quads and Powers of Two...

Started by Indignation211, August 23, 2011, 00:14:48

Previous topic - Next topic

Indignation211

Hi, im new to using OpenGL and Slick, and ive run into a problem. I load a image as a Texture, i do texture.bind(), then draw a GL11 quad. Problem is, the quad gets sized up to the next power of 2 and a bunch of black space is added, which i don't want. So after doing some research and playing with the settings I eventually get this code:

public void render(){
        texture.bind();
        GL11.glBegin(GL11.GL_QUADS);
			GL11.glTexCoord2f(0, 0);
			GL11.glVertex2f(x, y);
			GL11.glTexCoord2f(imagewidth/texturewidth, 0);
			GL11.glVertex2f(x+imagewidth, y);
			GL11.glTexCoord2f(imagewidth/texturewidth, imageheight/textureheight);
			GL11.glVertex2f(x+imagewidth,y+imageheight);
			GL11.glTexCoord2f(0, imageheight/textureheight);
			GL11.glVertex2f(x,y+imageheight);
		GL11.glEnd();
    }


Which makes everything the right size and eliminates the black space... except now the images are distorted horribly beyond recognition. An example: an image of blue-and-white clouds becomes a block of one solid color.

So basically my problem is this: I have a 300x100 png image that i want to put on the screen exactly as-is with no extra black space added. How can I do this?

Indignation211

Ok I tried to take the easy way out and just make the .png files 512x128, place the 300x100 image in the top left corner and just leave the remaining space as transparent pixels. After saving I confirmed that the rest of the file is indeed transparent. I also returned my render() method to its "normal" state:
public void render(){
        texture.bind();
        GL11.glBegin(GL11.GL_QUADS);
                        //Top-left corner
			GL11.glTexCoord2f(0.0f, 0.0f);
			GL11.glVertex2f(x, y);
                        //Top-right corner
			GL11.glTexCoord2f(1.0f, 0.0f);
			GL11.glVertex2f(x+texturewidth, y);
                        //Bottom-right corner
			GL11.glTexCoord2f(1.0f, 1.0f);
			GL11.glVertex2f(x+texturewidth,y+textureheight);
                        //Bottom-left corner
			GL11.glTexCoord2f(0.0f, 1.0f);
			GL11.glVertex2f(x,y+textureheight);
		GL11.glEnd();
    }


Except now, the program is drawing white pixels where its supposed to be transparent x.x. EDIT: To be specific: This image is supposed to be drawn ontop of a background image, and the background is getting covered up unecessarily by these white pixels.

EDIT 2: If there's a better way to draw 2D Images than the make-texture-and-stick-onto-quad method then please tell me D:

Mickelukas

1. Create an empty picture with the power of two in size
2. Put your graphic in the top left corner
3. Convert to texture
4. Draw the texture using a quad or triangle strip or triangles (I doubt you need to worry about the performance and memory differences at the moment).
5. Enjoy the result ;)

As far as I can see you have some problems with 3 and 4. What code do you use for reading in the picture and converting it to a texture? Slick? Seeing as you don't need to use transparency at the moment (right?) it doesn't matter that much but you either have some problems with that or you don't use blend/alpha func based upon your second post.

As for 4, the texture coordinates of your picture will be something like (0,0), (picture.width/texture.width,0), (picture.width/texture.width,picture.height/texture.height), (0,picture.height/texture.height), and the vertex coordinates something like (0,0), (1,0), (1,1), (1,0) (or however big you want the picture to be).

Mike

broumbroum

Quote from: Indignation211 on August 23, 2011, 18:06:50
Ok I tried to take the easy way out and just make the .png files 512x128, place the 300x100 image in the top left corner and just leave the remaining space as transparent pixels.
....
EDIT 2: If there's a better way to draw 2D Images than the make-texture-and-stick-onto-quad method then please tell me D:
You have got two choices :
1. scale all your png to a POT size with an AffineTransform, but make a copy of Image original Dimension ; then convert to the POT texture, render at original dimension.
2. enable EXT_texture_rectange GL extension(should be used as substitute to GL_TEXTURE_2D, see gl doc). and load any non-POT sizes as texture.
8)

Indignation211

Here is what im using to create the texture (using Slick's TextureLoader):
public void setTexture(String ref){
        try {
            texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(ref));
            imagewidth = texture.getImageWidth();
            texturewidth = texture.getTextureWidth();
            imageheight = texture.getImageHeight();
            textureheight = texture.getTextureHeight();
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
    }


And here's the rest of the GL11 stuff:
public static void init() throws LWJGLException {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.setTitle(GAME_TITLE);
        Display.setVSyncEnabled(true);
        Display.create();

        GL11.glEnable(GL11.GL_TEXTURE_2D);

		GL11.glClearColor(0, 0, 0, 0);

        	// enable alpha blending
        	GL11.glEnable(GL11.GL_BLEND);
        	GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);

        	GL11.glViewport(0,0,WIDTH,HEIGHT);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);

		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);

        Keyboard.create();
    }

broumbroum

well I don't use Slick for the choice (1.) explained previously
http://sourceforge.net/apps/phpbb/sf3jswing/viewtopic.php?f=4&t=8 is a link to my texture loading class for LWJGL. it will directly load a POT texture, as I 've detailed in (1.).

jediTofu

Just use alpha.  The region surrounding the image can be set to black or w/e, and then set the alpha for black to 0.
cool story, bro