LWJGL texture rendering/indexing

三世轮回 提交于 2021-02-10 06:46:27

问题


I am currently having issues with trying to render two textures onto two totally separate objects through a single vertex, and fragment shader. The issue seems to lie in trying to index, and bind the two textures onto their own objects. In trying to index and bind the textures, the smaller index will always appear onto both objects.

Can someone help me, or at least push me into the right direction?

here is my code for the main class, the renderer, and the fragment shader. (feel free to request more code)

main:

import Engine.IO.Image;
import Engine.IO.Input;
import Engine.IO.Window;
import Engine.graphics.*;
import Engine.maths.Vector2f;
import Engine.maths.Vector3f;
import Engine.objects.Camera;
import Engine.objects.GameObject;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL13;

public class Main implements Runnable {
    public Thread game;
    public  Window window;
    public Renderer renderer;
    public Shader shader;
    public  final int WIDTH = 1280, HEIGHT = 720;
    private String[] textureImageNames = {"nice_dude.jpg", "color.jpg", "pepe.jpg"};

    public GameObject thing1 = new GameObject(new Vector3f(-1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1), new Mesh(new Vertex[]{
            new Vertex(new Vector3f(-0.5f, 0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(0.0f,0.0f)),
            new Vertex(new Vector3f(0.5f, 0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(1.0f,0.0f)),
            new Vertex(new Vector3f(0.5f, -0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(1.0f,1.0f)),
            new Vertex(new Vector3f(-0.5f, -0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(0.0f,1.0f))
    }, new int[]{
            0, 1, 2, 0, 3, 2
    }), new Material(textureImageNames[0]));

    public GameObject thing2 = new GameObject(new Vector3f(1, 0, 0), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1), new Mesh(new Vertex[]{
            new Vertex(new Vector3f(-0.5f, 0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(0.0f,0.0f)),
            new Vertex(new Vector3f(0.5f, 0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(1.0f,0.0f)),
            new Vertex(new Vector3f(0.5f, -0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(1.0f,1.0f)),
            new Vertex(new Vector3f(-0.5f, -0.5f, 0.0f), new Vector3f(0.0f, 0.0f, 1.0f), new Vector2f(0.0f,1.0f))
    }, new int[]{
            0, 1, 2, 0, 3, 2
    }), new Material(textureImageNames[2]));

    public Camera camera = new Camera(new Vector3f(0, 0, 1), new Vector3f(0, 0,0));

    public void start(){
        game = new Thread(this,"game");
        game.start();
    }

    public void init(){
        System.out.println("Initializing Game!");
        window = new Window(WIDTH, HEIGHT, "Game");
        shader = new Shader("/shaders/mainVertex.glsl", "/shaders/mainFragment.glsl");
        window.setBackgroundColor(0.0f, 0.5f, 0.0f);
        window.create();
        thing1.getMesh().create();
        thing2.getMesh().create();
        thing1.getMaterial().create(new Image());
        thing2.getMaterial().create(new Image());
        shader.create();
        renderer = new Renderer(window, shader);
        renderer.renderMesh();
        renderer.enableShaderProgram();
        renderer.bindVAO(thing1);
        renderer.bindVAO(thing2);
        renderer.setUniformIndex(thing1,"tex", GL13.GL_TEXTURE0);
        renderer.setUniformIndex(thing2,"tex2", GL13.GL_TEXTURE1);
    }

    public void run(){
        init();
        while(!window.shouldClose() && !Input.isKeyDown(GLFW.GLFW_KEY_ESCAPE)){
            update();
            render();
            if(Input.isKeyDown(GLFW.GLFW_KEY_F11)){window.setFullscreen(!window.isFullscreen());}
        }
        close();
    }

    private void update(){
        //System.out.println("updating Game!");
        window.update();
        camera.update();
    }

    private void render(){
        renderer.updateRenderer(thing1);
        renderer.updateRenderer(thing2);
        renderer.renderCamera(camera);
        window.swapBuffers();
    }

    private void close(){
        window.destroy();
        thing1.getMesh().destroy();
        thing1.destroyMaterial();
        thing2.getMesh().destroy();
        thing2.destroyMaterial();
        shader.destroy();
        renderer.destroyRenderer();
    }

    public static void main(String[] args){
        new Main().start();
    }
}

render class:

package Engine.graphics;

import Engine.IO.Window;
import Engine.maths.Matrix4f;
import Engine.objects.Camera;
import Engine.objects.GameObject;
import org.lwjgl.opengl.*;

public class Renderer {
    private Shader shader;
    private Window window;

    public Renderer(Window window, Shader shader){
        this.shader = shader;
        this.window = window;
    }

    public void renderMesh() {
        GL30.glEnableVertexAttribArray(0);
        GL30.glEnableVertexAttribArray(1);
        GL30.glEnableVertexAttribArray(2);
    }

    public void enableShaderProgram(){
        shader.bind();
    }

    public void bindVAO(GameObject object){
        GL30.glBindVertexArray(object.getMesh().getVAO());
    }

    public void setUniformIndex(GameObject object, String textureName, int index){
        GL13.glActiveTexture(index);
        shader.setUniform(textureName, index);
        GL13.glBindTexture(GL11.GL_TEXTURE_2D, object.getMaterial().getTextureID());
    }

    public void updateRenderer(GameObject object){
        GL11.glDrawElements(GL11.GL_TRIANGLES, object.getMesh().getIndices().length, GL11.GL_UNSIGNED_INT, 0);

        shader.setUniform("model", Matrix4f.transform(object.getPosition(), object.getRotation(), object.getScale()));
        shader.setUniform("projection", window.getProjectionMatrix());
    }

    public void renderCamera(Camera camera){
        shader.setUniform("view", Matrix4f.view(camera.getPosition(), camera.getRotation()));
    }

    public void destroyRenderer(){
        shader.unBind();
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
        GL30.glDisableVertexAttribArray(0);
        GL30.glDisableVertexAttribArray(1);
        GL30.glDisableVertexAttribArray(2);
        GL30.glBindVertexArray(0);
    }
}

fragment shader:

#version 460 core

in vec3 passColor;
in vec2 passTextureCoord;

out vec4 outColor;

uniform sampler2D tex;
uniform sampler2D tex2;

void main(){
    outColor = texture(tex, passTextureCoord);
    outColor = texture(tex2, passTextureCoord);
}

回答1:


The value which has to be set to the texture sampler uniform is the index of the texture unit rather then the texture unit constant (e.g.: 0 for GL13.GL_TEXTURE0 and 1 for GL13.GL_TEXTURE1):

public void setUniformIndex(GameObject object, String textureName, int unit, int index){
    shader.setUniform(textureName, index);
    GL13.glActiveTexture(unit);
    GL13.glBindTexture(GL11.GL_TEXTURE_2D, object.getMaterial().getTextureID());
}

OpenGL is a state engine. Binding a VAO and or a texture object changes a global state. It is not possible to bind 2 objects at once. Only the last object which was bound is stated. You have to bind the Vertex Array Object and the texture object before the draw call:

private void render(){
        
    renderer.bindVAO(thing1);
    renderer.setUniformIndex(thing1,"tex", GL13.GL_TEXTURE0, 0);
    renderer.updateRenderer(thing1);
    
    renderer.bindVAO(thing2);
    renderer.setUniformIndex(thing2,"tex2", GL13.GL_TEXTURE1, 1);
    renderer.updateRenderer(thing2);
    
    renderer.renderCamera(camera);
    window.swapBuffers();
}


来源:https://stackoverflow.com/questions/63643497/lwjgl-texture-rendering-indexing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!