LWJGL纹理渲染/索引 [英] LWJGL texture rendering/indexing

查看:39
本文介绍了LWJGL纹理渲染/索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在尝试通过单个顶点和片段着色器将两个纹理渲染到两个完全独立的对象上时遇到问题.问题似乎在于试图建立索引,并将两个纹理绑定到它们自己的对象上.在尝试索引和绑定纹理时,较小的索引将始终出现在两个对象上.

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)

主要:

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();
    }
}

渲染类:

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);
    }
}

片段着色器:

#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);
}

推荐答案

必须设置为纹理采样器统一的值是纹理单位的索引,而不是纹理单位常数(例如:为0GL13.GL_TEXTURE0 GL13.GL_TEXTURE1 的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是一个状态引擎.绑定VAO和/或纹理对象会更改全局状态.不可能一次绑定2个对象.仅说明绑定的最后一个对象.在绘制调用之前,您必须绑定顶点数组对象"和纹理对象:

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();
}

这篇关于LWJGL纹理渲染/索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆