Stas Jaro
Stas Jaro

Reputation: 4885

opengl textures not rendering correctly

The problem i am encountering is that i cannot get my texture to render in the correct proportions and for some reason the texture is also repeating itself with a space inbetween.

this is the texture im using(i am trzing to fill the screen with this texture):

Texture

When rendered it looks like this(red outline is the entire screen and texture is rendered with a 1 px border):

screenshot

and here is the code:

package game;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Timer;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.opengl.TextureLoader;

public class WarZone {

private boolean done = false;
private String windowTitle = "War Zone";
private DisplayMode displayMode;
private Timer timer;
private float dt;

public static void main(String[] args) {
    new WarZone().run(false);
}

public void run(boolean fullscreen) {
    try {
        init();
        switchToOrtho();
        while (!done) {
            timer.tick();
            update();
            render();
            Display.update();
        }
        cleanup();
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(0);
    }
}

private void update() {
    // Exit if Escape is pressed or window is closed
    if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) || Display.isCloseRequested()) {
        done = true;
        return;
    }
}

private boolean render() {
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);  // Clear the screen and the depth buffer
    GL11.glLoadIdentity();                                              // Reset the current modelview matrix

    int w = displayMode.getWidth();
    int h = displayMode.getHeight();

    GL11.glColor3f(1, 0, 0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glVertex2i(0, 0);
        GL11.glVertex2i(w, 0);
        GL11.glVertex2i(w, h);
        GL11.glVertex2i(0, h);
    GL11.glEnd();
    //if(true)return false;
    GL11.glColor3f(0, 1, 1);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, 1);
    GL11.glBegin(GL11.GL_QUADS);
        GL11.glTexCoord2f(0, 0);
        GL11.glVertex2i(1, 1);
        GL11.glTexCoord2f(1, 0);
        GL11.glVertex2i(w - 1, 1);
        GL11.glTexCoord2f(1, 1);
        GL11.glVertex2i(w - 1, h - 1);
        GL11.glTexCoord2f(0, 1);
        GL11.glVertex2i(1, h - 1);
    GL11.glEnd();

    return true;                                                        // Rendered correctly
}

public static void switchToOrtho() {
    GL11.glDisable(GL11.GL_DEPTH_TEST);
    GL11.glDisable(GL11.GL_LIGHTING);
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glPushMatrix();
    GL11.glLoadIdentity();
    GL11.glOrtho(0, Display.getDisplayMode().getWidth(), 0, Display.getDisplayMode().getHeight(), -1, 1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
}

public static void switchToFrustum() {
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glPopMatrix();
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
}

private void init() throws Exception {
    createWindow();
    initGL();
    load();
}

private void load() throws FileNotFoundException, IOException {
    TextureLoader.getTexture("BMP", new FileInputStream("res/temp/Main_Menu_Play_Button.bmp"), true).getTextureID();
}

private void createWindow() throws Exception {
    DisplayMode availibleDisplayModes[] = Display.getAvailableDisplayModes();
    for (DisplayMode d:availibleDisplayModes) {
        if (d.getWidth() == 640 && d.getHeight() == 480 && d.getBitsPerPixel() == 32) {
            displayMode = d;
            break;
        }
    }
    Display.setDisplayMode(displayMode);
    Display.setTitle(windowTitle);
    Display.create();
}

private void initGL() {
    GL11.glEnable(GL11.GL_TEXTURE_2D);          // Enable texture mapping
    GL11.glShadeModel(GL11.GL_SMOOTH);          // Enable smooth shading
    GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  // Black background
    GL11.glClearDepth(1.0f);                    // Depth buffer setup
    GL11.glEnable(GL11.GL_DEPTH_TEST);          // Enables depth testing
    GL11.glDepthFunc(GL11.GL_LEQUAL);           // Type of depth testing

    GL11.glMatrixMode(GL11.GL_PROJECTION);      // Select projection matrix
    GL11.glLoadIdentity();                      // Reset the projection matrix

    // Calculate the aspect ratio of the window
    GLU.gluPerspective(45.0f, (float)displayMode.getWidth() / (float)displayMode.getHeight(), 0.1f, 100.0f);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);// Select the modelview matrix
    GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);// Most precise perspective calculations
}

public void requestFinish() {
    done = true;
}

private void cleanup() {
    Display.destroy();
}

}

I would reallz appreciate it if someone could tell me what i had done wrong.

Upvotes: 0

Views: 2088

Answers (2)

Nicol Bolas
Nicol Bolas

Reputation: 473427

First, I don't know what TextureLoader or newdawn.slick.opengl are, so there is only limited information I can give about this.

However, it is very possible that your texture loading code does not know how to handle non-power-of-two textures. Which means it is likely padding the texture's size out to the nearest power of two.

More importantly is this:

GL11.glColor3f(0, 1, 1);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 1);
GL11.glBegin(GL11.GL_QUADS);
    GL11.glTexCoord2f(0, 0);
    GL11.glVertex2i(1, 1);
    GL11.glTexCoord2f(1, 0);
    GL11.glVertex2i(w - 1, 1);
    GL11.glTexCoord2f(1, 1);
    GL11.glVertex2i(w - 1, h - 1);
    GL11.glTexCoord2f(0, 1);
    GL11.glVertex2i(1, h - 1);
GL11.glEnd();

This will draw a screen-sized quad (assuming that w and h are screen sizes). This quad maps the entire area of the texture to this quad. OpenGL is only doing what you told it to do: take the texture and map it to the quad.

If you want to draw a texture with pixel accuracy (1:1 texel to pixel), then you need to provide a width and height to the vertex positions that is equal to the texture's size, not the screen size.

Also, you set the color to (0, 1, 1). The default texture environment will multiply the per-vertex color by the texel values fetched from the texture. So you should either set the color to white, or change the texture environment.

Upvotes: 5

Delete
Delete

Reputation: 922

OpenGL Doesn't like textures that are not powers of two if I recall. Is your texture a power of 2 for both height and width?

http://www.gamedev.net/topic/466904-opengl-textures-only-power-of-two/

Upvotes: 0

Related Questions