текстуры OpenGL не рендерится правильно - PullRequest
0 голосов
/ 12 августа 2011

Проблема, с которой я сталкиваюсь, заключается в том, что я не могу заставить мою текстуру рендериться в правильных пропорциях, и по какой-то причине текстура также повторяется с пробелом между ними.

это текстура, которую я использую (яЯ пытаюсь заполнить экран этой текстурой):

Texture

При визуализации это выглядит так (красный контур - весь экран, а текстура отображается с границей 1 px):

screenshot

и вот код:

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();
}

}

Я был бы очень признателен, если бы кто-то мог сказать мне, что я сделал неправильно.

Ответы [ 2 ]

5 голосов
/ 12 августа 2011

Во-первых, я не знаю, что такое TextureLoader или newdawn.slick.opengl, поэтому я могу дать только ограниченную информацию об этом.

Однако, вполне возможно, что ваш код загрузки текстуры делаетне знаю, как обращаться с текстурами не-степени двух.Это означает, что он, вероятно, дополняет размер текстуры до ближайшей степени двойки.

Более важно то, что это:

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();

Это нарисует квадра размером с экран (при условии, что w и h - размеры экрана).Этот четырехугольник отображает всю область текстуры для этого четырехугольника.OpenGL делает только то, что вы сказали: возьмите текстуру и сопоставьте ее с квадратом.

Если вы хотите нарисовать текстуру с точностью до пикселя (1: 1 от пикселя до пикселя), тогда вам нужноукажите ширину и высоту для позиций вершин, равных размеру текстуры, а не размеру экрана.

Кроме того, вы устанавливаете цвет на (0, 1, 1).Текстурная среда по умолчанию будет умножать цвет каждой вершины на тексельные значения, извлеченные из текстуры.Поэтому вы должны либо установить цвет на белый, либо изменить текстуру среды.

0 голосов
/ 12 августа 2011

OpenGL Не нравится текстуры, которые не имеют степени двойки, если я помню.Ваша текстура имеет степень 2 для высоты и ширины?

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

...