【问题标题】:Textures not binding in OpenGL (LWJGL/Slick-util)OpenGL 中未绑定的纹理 (LWJGL/Slick-util)
【发布时间】:2013-01-02 13:53:54
【问题描述】:

我对似乎将纹理绑定到形状的东西有疑问。当我这样做时,我会得到一个尺寸正确的白色形状,这是Color.white.bind() 给它的颜色。

GraphicsManager.java

package com.jackwilsdon.spectrun;

import java.io.IOException;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.Color;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class GraphicsManager {

    final static int WIDTH = 800;
    final static int HEIGHT = 600;

    private static Texture cloudTexture = null;

    public static void initDisplay() throws LWJGLException
    {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.create();
    }

    public static void initOpenGL()
    {     
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public static void loadTextures()
    {
        Texture currentObject = null;
        try {
            currentObject = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("./resources/cloud.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Texture loaded: "+currentObject);
        System.out.println(">> Image width: "+currentObject.getImageWidth());
        System.out.println(">> Image height: "+currentObject.getImageHeight());
        System.out.println(">> Texture width: "+currentObject.getTextureWidth());
        System.out.println(">> Texture height: "+currentObject.getTextureHeight());
        System.out.println(">> Texture ID: "+currentObject.getTextureID());
        cloudTexture = currentObject;
    }

    public static void DrawRectangle(int x, int y, int width, int height)
    {
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x,y);
            GL11.glVertex2f(x+width,y);
            GL11.glVertex2f(x+width,y+height);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
    }

    public static void DrawRectangle(int x, int y, int width, int height, int red, int green, int blue)
    {
        GL11.glColor3ub((byte)red, (byte)green, (byte)blue);
        DrawRectangle(x, y, width, height);
    }

    public static Vector2f DrawCloud(int x, int y)
    {
        cloudTexture.bind();
        int width = cloudTexture.getImageWidth();
        int height = cloudTexture.getImageHeight();
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x,y);
            GL11.glVertex2f(x+width,y);
            GL11.glVertex2f(x+width,y+height);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
        return new Vector2f(cloudTexture.getImageWidth(), cloudTexture.getImageHeight());
    }
}

我怀疑这与我的 initOpenGL() 方法有关,就像我看过的一个示例 (http://ninjacave.com/slickutil1) 一样,他们的方法非常不同。只是将他们的复制到我的中会产生意想不到的结果(黑屏)。我的 initOpenGL() 方法中是否缺少某些内容?

编辑:loadTextures() 方法输出正确的图像尺寸,但纹理的尺寸不同,这是什么意思?

编辑 2:PNG 不是问题,我尝试了另外 2 个以找到相同的结果。


修复我的代码后,通过设置纹理坐标出现了一个新问题。 我现在得到一个奇怪的效果,像这样; i.imgur.com/5lr79.png。图像不再是全尺寸,并且在其左下角有一个黑框。

GraphicsManager.java

package com.jackwilsdon.spectrun;

import java.io.IOException;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
import org.newdawn.slick.Color;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class GraphicsManager {

    final static int WIDTH = 800;
    final static int HEIGHT = 600;

    private static Texture cloudTexture = null;

    public static void initDisplay() throws LWJGLException
    {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.create();
    }

    public static void initOpenGL()
    {    
        GL11.glEnable(GL11.GL_TEXTURE);  
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();
        GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
    }

    public static void loadTextures()
    {
        Texture currentObject = null;
        try {
            currentObject = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("./resources/cloud.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Texture loaded: "+currentObject);
        System.out.println(">> Image width: "+currentObject.getImageWidth());
        System.out.println(">> Image height: "+currentObject.getImageHeight());
        System.out.println(">> Texture width: "+currentObject.getTextureWidth());
        System.out.println(">> Texture height: "+currentObject.getTextureHeight());
        System.out.println(">> Texture ID: "+currentObject.getTextureID());
        cloudTexture = currentObject;
    }

    public static void DrawRectangle(int x, int y, int width, int height)
    {
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x,y);
            GL11.glVertex2f(x+width,y);
            GL11.glVertex2f(x+width,y+height);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
    }

    public static void DrawRectangle(int x, int y, int width, int height, int red, int green, int blue)
    {
        GL11.glColor3ub((byte)red, (byte)green, (byte)blue);
        DrawRectangle(x, y, width, height);
    }

    public static Vector2f DrawCloud(int x, int y)
    {
        cloudTexture.bind();
        int width = cloudTexture.getImageWidth();
        int height = cloudTexture.getImageHeight();
        GL11.glBegin(GL11.GL_QUADS);
            GL11.glTexCoord2f(1,1);
            GL11.glVertex2f(x,y);
            GL11.glTexCoord2f(0,1);
            GL11.glVertex2f(x+width,y);
            GL11.glTexCoord2f(0,0);
            GL11.glVertex2f(x+width,y+height);
            GL11.glTexCoord2f(1,0);
            GL11.glVertex2f(x,y+height);
        GL11.glEnd();
        return new Vector2f(cloudTexture.getImageWidth(), cloudTexture.getImageHeight());
    }
}

【问题讨论】:

    标签: java opengl lwjgl slick2d


    【解决方案1】:

    您没有调用 GL11.glEnable( GL11.GL_TEXTURE ) 并且您也没有设置任何纹理坐标,这无济于事。

    这两者都会影响你在四边形上看到纹理的能力......

    【讨论】:

    • 设置纹理坐标后,我现在得到一个奇怪的效果,像这样; i.imgur.com/5lr79.png。图像不再是全尺寸,并且在其左下角有一个黑框。
    • @jackwilsdon:看起来 lwjgl 正在将图像的大小重新调整为 2 的幂。最好使用轴上的 2 幂的纹理或将最大 tex-coord 设置为(actualWidth/pow2Width) 而不是 1。
    【解决方案2】:

    我确实相信对 bind() 的调用需要在您的 glBegin() 和 glEnd() 调用之间才能使其生效。尺寸问题有点奇怪——也许你的纹理尺寸不是 2 的幂,它是由驱动程序翻译的?

    【讨论】:

    • 抱歉,这不起作用。我还添加了GL11.glEnable(GL11.GL_TEXTURE_2D); 试图修复它,但这也不起作用。
    • 是的,我的 OpenGL 知识真的很生疏,否则我很快就会发现丢失的 texcoord 调用......我被 LibGDX 宠坏了。在本机编程上下文中而不是从 Java 角度研究 OpenGL 可能对您有所帮助。 LWJGL 只是 Java 和(本机)OpenGL API 之间的一个薄层,您确实需要深入研究 API 本身。有大量关于在 C/C++ 中使用 OpenGL 的书籍。也许你应该考虑读一读。
    • 谢谢,我会试试看 :) 对出现的新问题有什么想法吗?
    【解决方案3】:

    您首先没有启用 gl_TEXTURE_2D。其次,您需要在 glBegin() 和 glEnd() 中调用 .bind()。第三,您需要纹理坐标。因此,对于左上边缘,它将是 'glTexCoord(0, 0)',下一个是 '(1, 0)',然后是 '(1, 1)',最后是 '(0, 1)'

    【讨论】:

    • 看了你的绘制云方法后,我意识到你的纹理坐标是错误的。看看我的答案是否正确,它应该可以解决您的问题。
    • 我以这种方式制作了纹理坐标,否则图像看起来会垂直翻转。这是我当前的坐标代码(出现翻转的代码):gist.github.com/a3ef7d9bce9f0dfaa02a
    【解决方案4】:

    不要忘记在需要时调用 TextureImpl.unbind。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多