1

使用 slick 在 LWJGL 中显示我的 3D 盒子上的纹理时出现问题。早些时候我遇到了错误:

WARN:class org.newdawn.slick.opengl.PNGImageData failed to read the data
java.lang.UnsupportedOperationException: Unsupported format for this image

说它无法读取图像。所以我将图像转换为 24 位(也尝试了 8 位),现在我只得到:

INFO:Use Java PNG Loader = true

显示了我的 3D 立方体,但上面没有纹理。不知道该怎么做才能让它显示我的纹理。

纹理类:

    package com.base.engine;

import static org.lwjgl.opengl.GL11.*;

public class Texture {
    private int id;

    public Texture(int id) {
        this.id = id;
    }

    public void bind() {
        glBindTexture(GL_TEXTURE_2D, id);

    }

    public int getID() {
        return id;
    }
}

材质类

package com.base.engine;

public class Material
{
    private Texture texture;
    private Vector3f color;

    public Material(Texture texture)
    {
        this(texture, new Vector3f(1,1,1));
    }

    public Material(Texture texture, Vector3f color)
    {
        this.texture = texture;
        this.color = color;
    }

    public Texture getTexture()
    {
        return texture;
    }

    public void setTexture(Texture texture)
    {
        this.texture = texture;
    }

    public Vector3f getColor()
    {
        return color;
    }

    public void setColor(Vector3f color)
    {
        this.color = color;
    }
}

游戏类:

package com.base.engine;
import java.io.FileInputStream;
import java.io.InputStream;



public class Game 
{
    private Mesh mesh;
    private Shader shader;
    private Material material;
    private Transform transform;
    private Camera camera;



    public Game()
    {

        mesh = ResourceLoader.loadMesh("box.obj");
        material = new Material(ResourceLoader.loadTexture("test.png"), new Vector3f(0,1,1));


        shader = BasicShader.getInstance();
        camera = new Camera();

//      Vertex[] vertices = new Vertex[] {new Vertex(new Vector3f(-1,-1,0), new Vector2f(0,0)),
//                                    new Vertex(new Vector3f(0,1,0), new Vector2f(0.5f,0)),
//                                    new Vertex(new Vector3f(1,-1,0), new Vector2f(1.0f,0)),
//                                    new Vertex(new Vector3f(0,-1,1), new Vector2f(0.5f,1.0f))};
//      
//      int[] indices = new int[] {3,1,0,
//                                 2,1,3,
//                                 0,1,2,
//                                 0,2,3};
//      
//      mesh.addVertices(vertices, indices);

        Transform.setProjection(70f, Window.getWidth(), Window.getHeight(), 0.1f, 1000);
        Transform.setCamera(camera);
        transform = new Transform();
    }

    public void input()
    {
        camera.input();

//      if(Input.getKeyDown(Input.KEY_UP))
//          System.out.println("We've just pressed up!");
//      if(Input.getKeyUp(Input.KEY_UP))
//          System.out.println("We've just released up!");
//      
//      if(Input.getMouseDown(1))
//          System.out.println("We've just right clicked at " + Input.getMousePosition().toString());
//      if(Input.getMouseUp(1))
//          System.out.println("We've just released right mouse button!");
    }

    float temp = 0.0f;

    public void update()
    {
        temp += Time.getDelta();

        float sinTemp = (float)Math.sin(temp);

        transform.setTranslation(sinTemp, 0, 5);
        transform.setRotation(0, sinTemp * 180, 0);
        //transform.setScale(0.7f * sinTemp, 0.7f * sinTemp, 0.7f * sinTemp);
    }

    public void render()
    {
        RenderUtil.setClearColor(Transform.getCamera().getPos().div(2048f).abs());

        shader.bind();
        shader.updateUniforms(transform.getTransformation(), transform.getProjectedTransformation(), material);
        mesh.draw();
    }
}

RenderUtil 类:

package com.base.engine;

import static org.lwjgl.opengl.GL11.*;

public class RenderUtil
{
    public static void clearScreen()
    {
        //TODO: Stencil Buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }

    public static void setTextures(boolean enabled)
    {
        if(enabled)
            glEnable(GL_TEXTURE_2D);
        else
            glDisable(GL_TEXTURE_2D);
    }

    public static void unbindTextures()
    {
        glBindTexture(GL_TEXTURE_2D, 0);
    }

    public static void setClearColor(Vector3f color)
    {
        glClearColor(color.getX(), color.getY(), color.getZ(), 1.0f);
    }

    public static void initGraphics()
    {
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        glFrontFace(GL_CW);
        glCullFace(GL_BACK);
        glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);

        //TODO: Depth clamp for later

        glEnable(GL_TEXTURE_2D);
        glEnable(GL_FRAMEBUFFER_SRGB);
    }

    public static String getOpenGLVersion()
    {
        return glGetString(GL_VERSION);
    }
}

着色器类:

package com.base.engine;

import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL32.*;

import java.util.HashMap;

public class Shader
{
    private int program;
    private HashMap<String, Integer> uniforms;

    public Shader()
    {
        program = glCreateProgram();
        uniforms = new HashMap<String, Integer>();

        if(program == 0)
        {
            System.err.println("Shader creation failed: Could not find valid memory location in constructor");
            System.exit(1);
        }
    }

    public void bind()
    {
        glUseProgram(program);
    }

    public void updateUniforms(Matrix4f worldMatrix, Matrix4f projectedMatrix, Material material)
    {

    }

    public void addUniform(String uniform)
    {
        int uniformLocation = glGetUniformLocation(program, uniform);

        if(uniformLocation == 0xFFFFFFFF)
        {
            System.err.println("Error: Could not find uniform: " + uniform);
            new Exception().printStackTrace();
            System.exit(1);
        }

        uniforms.put(uniform, uniformLocation);
    }

    public void addVertexShader(String text)
    {
        addProgram(text, GL_VERTEX_SHADER);
    }

    public void addGeometryShader(String text)
    {
        addProgram(text, GL_GEOMETRY_SHADER);
    }

    public void addFragmentShader(String text)
    {
        addProgram(text, GL_FRAGMENT_SHADER);
    }

    public void compileShader()
    {
        glLinkProgram(program);

        if(glGetProgram(program, GL_LINK_STATUS) == 0)
        {
            System.err.println(glGetProgramInfoLog(program, 1024));
            System.exit(1);
        }

        glValidateProgram(program);

        if(glGetProgram(program, GL_VALIDATE_STATUS) == 0)
        {
            System.err.println(glGetProgramInfoLog(program, 1024));
            System.exit(1);
        }
    }

    private void addProgram(String text, int type)
    {
        int shader = glCreateShader(type);

        if(shader == 0)
        {
            System.err.println("Shader creation failed: Could not find valid memory location when adding shader");
            System.exit(1);
        }

        glShaderSource(shader, text);
        glCompileShader(shader);

        if(glGetShader(shader, GL_COMPILE_STATUS) == 0)
        {
            System.err.println(glGetShaderInfoLog(shader, 1024));
            System.exit(1);
        }

        glAttachShader(program, shader);
    }

    public void setUniformi(String uniformName, int value)
    {
        glUniform1i(uniforms.get(uniformName), value);
    }

    public void setUniformf(String uniformName, float value)
    {
        glUniform1f(uniforms.get(uniformName), value);
    }

    public void setUniform(String uniformName, Vector3f value)
    {
        glUniform3f(uniforms.get(uniformName), value.getX(), value.getY(), value.getZ());
    }

    public void setUniform(String uniformName, Matrix4f value)
    {
        glUniformMatrix4(uniforms.get(uniformName), true, Util.createFlippedBuffer(value));
    }
}

基本着色器类:

package com.base.engine;

public class BasicShader extends Shader
{
    private static final BasicShader instance = new BasicShader();

    public static BasicShader getInstance()
    {
        return instance;
    }

    private BasicShader()
    {
        super();

        addVertexShader(ResourceLoader.loadShader("basicVertex.vs"));
        addFragmentShader(ResourceLoader.loadShader("basicFragment.fs"));
        compileShader();

        addUniform("transform");
        addUniform("color");
    }

    public void updateUniforms(Matrix4f worldMatrix, Matrix4f projectedMatrix, Material material)
    {
        if(material.getTexture() != null)
            material.getTexture().bind();
        else
            RenderUtil.unbindTextures();

        setUniform("transform", projectedMatrix);
        setUniform("color", material.getColor());
    }
}

基本顶点.vs

#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;

out vec2 texCoord0;

uniform mat4 transform;

void main()
{
    gl_Position = transform * vec4(position, 1.0);
    texCoord0 = texCoord;
}

基本片段.fs

#version 330

in vec2 texCoord0;

out vec4 fragColor;

uniform vec3 color;
uniform sampler2D sampler;

void main()
{
    vec4 textureColor = texture(sampler, texCoord0.xy);

    if(textureColor == vec4(0,0,0,0))
        fragColor = vec4(color, 1);
    else
        fragColor = textureColor * vec4(color, 1);
}

谢谢您的帮助!

4

1 回答 1

1

根据您提供的代码,您实际上从未绑定过纹理。

我看到你已经导入org.lwjgl.opengl.GL11.*了,但是你在代码中绑定了一个叫做“着色器”的东西。您使用的是固定功能管道还是着色器?我问是因为如果你真的在你的软件中只使用 OpenGL 1.1,你还需要启用GL_TEXTURE_2D.

于 2013-09-16T21:36:02.707 回答