简体   繁体   English

opengl 纹理未正确渲染

[英]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):这是我使用的纹理(我想用这个纹理填充屏幕):

质地

When rendered it looks like this(red outline is the entire screen and texture is rendered with a 1 px border):渲染时看起来像这样(红色轮廓是整个屏幕,纹理以 1 px 边框渲染):

截屏

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.如果有人能告诉我我做错了什么,我将不胜感激。

First, I don't know what TextureLoader or newdawn.slick.opengl are, so there is only limited information I can give about this.首先,我不知道TextureLoadernewdawn.slick.opengl是什么,所以我只能提供有限的信息。

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.这意味着它可能会将纹理的大小填充到最接近的 2 次方。

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).这将绘制一个屏幕大小的四边形(假设wh是屏幕大小)。 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. OpenGL 只是在做你告诉它做的事情:把纹理和 map 放到四边形。

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.如果要以像素精度(1:1 texel 到像素)绘制纹理,则需要为顶点位置提供等于纹理大小而不是屏幕大小的宽度和高度。

Also, you set the color to (0, 1, 1).此外,您将颜色设置为 (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.因此,您应该将颜色设置为白色,或者更改纹理环境。

OpenGL Doesn't like textures that are not powers of two if I recall. OpenGL 我记得不喜欢不是 2 次方的纹理。 Is your texture a power of 2 for both height and width?你的纹理是高度和宽度的 2 的幂吗?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM