纹理不起作用

时间:2015-02-17 05:26:27

标签: java opengl textures lwjgl texture2d

好的。那个OpenGL状态机是骗我的!我是认真的!就在几天前,所有人都使用即时模式甚至是VBO模式,但今天不行!今天我看到一个白色四边形,因为我重写了80%的旧代码。这是一件很酷的事,你知道吗 所以。我需要你的帮助。这是我的GL调用跟踪器输出:

[17.02.2015 17:45:47] [--------GAME_STARTED--------]
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_COLOR_ARRAY) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_TEXTURE_2D) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_TEXTURE_COORD_ARRAY) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_VERTEX_ARRAY) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_INDEX_ARRAY) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_NORMAL_ARRAY) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_NORMALIZE) -> false
[17.02.2015 17:45:49] [GLTrace] glGetInteger(GL_MATRIX_MODE) -> GL_MODELVIEW
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_DEPTH_TEST) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_ALPHA_TEST) -> false
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_STENCIL_TEST) -> false
[17.02.2015 17:45:49] [GLTrace] glGetInteger(GL_DEPTH_FUNC) -> GL_LESS
[17.02.2015 17:45:49] [GLTrace] glGetInteger(GL_CULL_FACE_MODE) -> GL_BACK
[17.02.2015 17:45:49] [GLTrace] glGetBoolean(GL_BLEND) -> false
[17.02.2015 17:45:49] [GLTrace] glGetInteger(GL_ARRAY_BUFFER_BINDING) -> 0
[17.02.2015 17:45:49] [GLTrace] glGetInteger(GL_ELEMENT_ARRAY_BUFFER_BINDING) -> 0
[17.02.2015 17:45:49] [GLTrace] glGetInteger(GL_TEXTURE_BINDING_2D) -> GL_CURRENT_BIT
[17.02.2015 17:45:49] [GLTrace] glEnable(GL_DEPTH_TEST) -> DONE
[17.02.2015 17:45:49] [GLTrace] glDisable(GL_CULL_FACE) -> DONE
[17.02.2015 17:45:49] [GLTrace] glCullFace(Off) -> DONE
[17.02.2015 17:45:49] [GLTrace] glDepthFunc(LessOrEqual) -> DONE
[17.02.2015 17:45:49] [GLTrace] glBindBuffer(VertexArray, -1) -> DONE
[17.02.2015 17:45:49] [GLTrace] glBindBuffer(ElementArray, -1) -> DONE
[17.02.2015 17:45:49] [GLTrace] glBindTexture(Texture2D, -1) -> DONE
[17.02.2015 17:45:49] [GLTrace] glViewport(0, 0, 800, 600) -> DONE
[17.02.2015 17:45:49] [GLTrace] glGetInteger(GL_MAX_TEXTURE_SIZE, java.nio.DirectIntBufferU[pos=0 lim=16 cap=16]) -> DONE
[17.02.2015 17:45:49] [GLTrace] glGenTextures() -> 2
[17.02.2015 17:45:49] [GLTrace] glBindTexture(Texture2D, 2) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexParameteri(Texture2D, GL_TEXTURE_BASE_LEVEL, 0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexParameteri(Texture2D, GL_TEXTURE_MAX_LEVEL, 0) -> DONE
[17.02.2015 17:45:49] [GLTrace] [Setting wrap mode: Clamp]
[17.02.2015 17:45:49] [GLTrace] glTexParameteri(Texture2D, GL_TEXTURE_WRAP_S, GL_CLAMP) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexParameteri(Texture2D, GL_TEXTURE_WRAP_T, GL_CLAMP) -> DONE
[17.02.2015 17:45:49] [GLTrace]  -> DONE
[17.02.2015 17:45:49] [GLTrace] [Setting filter mode: Nearest]
[17.02.2015 17:45:49] [GLTrace] glTexParameteri(Texture2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexParameteri(Texture2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) -> DONE
[17.02.2015 17:45:49] [GLTrace]  -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexImage2D(Texture2D, 0, RGBA, 256, 256, 0, RGBA, UnsignedByte, java.nio.DirectByteBuffer[pos=0 lim=262144 cap=262144]) -> DONE
[17.02.2015 17:45:49] [GLTrace] glClear(ColorAndDepth) -> DONE
[17.02.2015 17:45:49] [GLTrace] glLoadIdentity() -> DONE
[17.02.2015 17:45:49] [GLTrace] glMatrixMode(Projection) -> DONE
[17.02.2015 17:45:49] [GLTrace] glLoadIdentity() -> DONE
[17.02.2015 17:45:49] [GLTrace] gluPerspective(70.0, 1.3333334, 0.001, 5000.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glMatrixMode(ModelView) -> DONE
[17.02.2015 17:45:49] [GLTrace] glPushMatrix() -> DONE
[17.02.2015 17:45:49] [GLTrace] glBegin(Quads) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexCoord2f(0.0, 0.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glVertex3f(0.0, 0.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexCoord2f(1.0, 0.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glVertex3f(1.0, 0.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexCoord2f(1.0, 1.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glVertex3f(1.0, 1.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTexCoord2f(0.0, 1.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glVertex3f(0.0, 1.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glEnd() -> DONE
[17.02.2015 17:45:49] [GLTrace] glPopMatrix() -> DONE
[17.02.2015 17:45:49] [GLTrace] glLoadIdentity() -> DONE
[17.02.2015 17:45:49] [GLTrace] glMatrixMode(Projection) -> DONE
[17.02.2015 17:45:49] [GLTrace] gluOrtho2D(0.0, 800.0, 600.0, 0.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glMatrixMode(ModelView) -> DONE
[17.02.2015 17:45:49] [GLTrace] glTranslatef(0.375, 0.375, 0.0) -> DONE
[17.02.2015 17:45:49] [GLTrace] glDisable(GL_DEPTH_TEST) -> DONE
[17.02.2015 17:45:49] [GLTrace] glBindTexture(Texture2D, -1) -> DONE
[17.02.2015 17:45:49] [---------GAME_ENDED---------]

这是我的即时模式四重渲染 - 全是白色的! 为什么会这样?我非常确定slick-util正确加载图像。图像有效(仅在两天前测试)。我可能会做一些更改(全局渲染系统重构:3)...我没有使用slick-util Texture和TextureImpl。我也没有使用mipmap。

这是我对该段代码的实现:

public class Texture
{

    protected int width, height, texWidth, texHeight, depth;
    protected boolean alpha;
    protected WrapMode wrapMode = WrapMode.Clamp;
    protected FilterMode filterMode = FilterMode.Nearest;
    protected TextureBuffer buffer;
    protected PixelFormat dstPixelFormat = PixelFormat.RGBA, srcPixelFormat;

    public Texture(LoadableImageData imageData, WrapMode wrapMode, FilterMode filterMode)
    {
        this.width = imageData.getWidth();
        this.height = imageData.getHeight();
        this.texWidth = imageData.getTexWidth();
        this.texHeight = imageData.getTexHeight();
        this.depth = imageData.getDepth();
        this.wrapMode = wrapMode;
        this.filterMode = filterMode;
        this.alpha = depth == 32;
        this.srcPixelFormat = alpha ? PixelFormat.RGBA : PixelFormat.RGB;

        buffer = (TextureBuffer) BufferManager.create(BufferType.Texture);
        BufferManager.setup(this, imageData.getImageBufferData(), srcPixelFormat.getSize());
    }

    public int getWidth()
    {
        return width;
    }

    public int getHeight()
    {
        return height;
    }

    public TextureBuffer getBuffer()
    {
        return buffer;
    }

    public WrapMode getWrapMode()
    {
        return wrapMode;
    }

    public FilterMode getFilterMode()
    {
        return filterMode;
    }

    public PixelFormat getDstPixelFormat()
    {
        return dstPixelFormat;
    }

    public PixelFormat getSrcPixelFormat()
    {
        return srcPixelFormat;
    }
}

这是重新设计的纹理加载器:

public class TextureLoader
{

    private static IntBuffer maxResolutionBuffer;

    public static LoadableImageData loadImage(String resourceName)
    {
        LoadableImageData imageData = ImageDataFactory.getImageDataFor(resourceName);
        ByteBuffer data = null;
        try {
            data = imageData.loadImage(new BufferedInputStream(new FileInputStream(new File("res", resourceName))),
                                       false, null);
        } catch (FileNotFoundException ex) {
            FaultManager.process("Can't find image!", ex, true);
        } catch (IOException ex) {
            FaultManager.process("Can't load image!", ex, true);
        }
        return imageData;
    }

    public static Texture getTexture(LoadableImageData imageData, WrapMode wrap, FilterMode filter) throws IOException
    {
        if (!checkTextureResolution(imageData.getTexWidth(), imageData.getTexHeight())) {
            throw new IOException("Attempt to allocate a texture too big for the current hardware");
        }
        return new Texture(imageData, wrap, filter);
    }

    public static boolean checkTextureResolution(int texWidth, int texHeight)
    {
        if (maxResolutionBuffer == null) {
            maxResolutionBuffer = BufferUtils.createIntBuffer(16);
            GLProxy.getProperty(GL11.GL_MAX_TEXTURE_SIZE, GLProxy.GLParamType.Integer, maxResolutionBuffer);
        }
        int max = maxResolutionBuffer.get(0);
        if ((texWidth > max) || (texHeight > max)) {
            return false;
        }
        return true;
    }
}

在我的游戏代码中,我只是使用:

        try {
            LoadableImageData imageData = TextureLoader.loadImage("test.png");
            texture = TextureLoader.getTexture(imageData, WrapMode.Clamp, FilterMode.Nearest);
        } catch (IOException ex) {
            FaultManager.process("Can't load texture test.png!", ex, true);
        }

所有其他类都实现了自己的东西,我很确定你可以在GLTrace中找到它。

1 个答案:

答案 0 :(得分:0)

确定。这可以用于立即模式渲染和缓冲对象。 这也像魔术一样。通过启用GL_TEXTURE_2D(自己责备)并禁用GL_VERTEX_ARRAY和GL_INDEX_ARRAY来修复立即模式渲染。我刚试过这次后修复了VBO。我认为这是我状态改变的bug,导致纹理和数组默认启用之前。所以我不确定这次我是如何修复VBO的,但我很自豪地说,#stackoverflow"仍然有一些新鲜的想法! Gratz来自@ Jean-SimonBrochu!

OpenGL的主要问题
它用于函数式编程或状态编程。这意味着OpenGL上下文(您使用Display创建)将在每次错过一个调用或传递错误数据时让您哭泣。首先 - 如果不是关键,即使没有设置错误状态也只能工作。第二个 - JVM将被本机代码(C ++ / Asm)崩溃导致JNI崩溃。

这是我如何处理这个问题的简短建议:

  1. 控制OOP中的所有内容(您应该实现控制与任何GL调用相对应的过程的类等)
  2. 控制GL状态(您应该实现一个数据/选项容器类,它将包含抽象或当前的OpenGL状态)
  3. 每次你不确定到底是什么时都要使用glGetError。您应该在可疑地调用OpenGL之后立即使用此功能。
  4. 始终建立可理解的系统。总是!即使你为自己做项目。这可能会花费时间来帮助您了解您的shitworks。
  5. 处理您自己可以访问的所有工作。努力实现这一点将向您展示整个系统的工作原理,并帮助您调整您对系统的看法。
  6. 纹理不工作?检查一下!

    1. 检查您是否启用了GL_TEXTURE_2D(或实际旧版本中的GL_TEXTURE)。你必须确保你以后不会再禁用它!
    2. 检查与您选择的一种渲染模式相对应的所有GL状态选项。我的意思是,如果您正在使用VBO,您还应该启用GL_VERTEX_ARRAY并使用。
    3. 检查纹理坐标(texCoords)是否已正确设置并启用纹理坐标数组选项。
    4. 检查是否生成了mipmap或者根本不使用它们。默认情况下,OpenGL状态设置为使用mipmap。您可以通过采用正确的纹理过滤模式(GL_NEAREST / GL_LINEAR或GL_NEAREST_MIPMAP_NEAREST / GL_LINEAR_MIPMAP_LINEAR)来切换它。
    5. 检查您的图像是否使用Alpha通道,设置GL_BLEND并通过GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA将混合模式设置为Alpha。
    6. 检查网格上的法线是否正确(如果使用它们)。
    7. 最后检查您的传入数据(图像)。这很难,但如果你按照上面的第5条建议 - 那应该相当容易。
    8. 感谢。试着'是有用的,并提出了更多的答案,而不是问题的缺点:)

      这是我在GLState课程中遇到的问题:

      -   public boolean depthTest = true;
      +   public boolean depthTest = false;
      -   public boolean vertexArray = true, indexArray = true, colorArray = false, textureArray = false, normalArray = false;
      +   public boolean vertexArray, indexArray, colorArray, textureArray, normalArray;
      
      static {
      +       DEFAULT_3D.depthTest = true;
      +       DEFAULT_3D.vertexArray = true;
      +       DEFAULT_3D.indexArray = true;
      +
      +       DEBUG_3D.depthTest = true;
      +       DEBUG_3D.vertexArray = true;
      +       DEBUG_3D.indexArray = true;
              DEBUG_3D.faceCullingMode = FaceCullingMode.Off;
      }
      

      P.S。 LWJGL 2.9.1的解释