org.terasology.rendering.assets.Material.java Source code

Java tutorial

Introduction

Here is the source code for org.terasology.rendering.assets.Material.java

Source

/*
 * Copyright 2012 Benjamin Glatzel <benjamin.glatzel@me.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.terasology.rendering.assets;

import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TObjectIntHashMap;

import java.nio.FloatBuffer;

import org.lwjgl.opengl.GL20;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.asset.Asset;
import org.terasology.asset.AssetUri;
import org.terasology.logic.manager.ShaderManager;
import org.terasology.rendering.assets.metadata.ParamMetadata;

/**
 * @author Immortius
 */
public class Material implements Asset {

    private static final Logger logger = LoggerFactory.getLogger(Material.class);

    private final AssetUri uri;

    private Shader shader;
    private int shaderProgram;
    private int textureIndex = 0;
    private TObjectIntMap<String> bindMap = new TObjectIntHashMap<String>();
    private TIntObjectMap<Texture> textureMap = new TIntObjectHashMap<Texture>();

    public Material(AssetUri uri, Shader shader) {
        this.uri = uri;
        this.shader = shader;
        shaderProgram = shader.generateShaderInstance();
    }

    public void dispose() {
        logger.debug("Disposing material {}.", uri);

        GL20.glDeleteShader(shaderProgram);
        shaderProgram = 0;
    }

    public boolean isDisposed() {
        return shaderProgram == 0;
    }

    public int getShaderId() {
        return shaderProgram;
    }

    public void enable() {
        if (isDisposed())
            return;

        Material activeMaterial = ShaderManager.getInstance().getActiveMaterial();
        if (activeMaterial != this) {
            ShaderManager.getInstance().enableMaterial(this);
        }
    }

    public void bindTextures() {
        if (isDisposed())
            return;

        enable();
        for (int slot : textureMap.keys()) {
            ShaderManager.getInstance().bindTexture(slot, textureMap.get(slot));
        }
    }

    public void setFloat(String desc, float f) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform1f(id, f);
        }
    }

    public void setFloat2(String desc, float f1, float f2) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform2f(id, f1, f2);
        }
    }

    public void setFloat3(String desc, float f1, float f2, float f3) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform3f(id, f1, f2, f3);
        }
    }

    public void setFloat4(String desc, float f1, float f2, float f3, float f4) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform4f(id, f1, f2, f3, f4);
        }
    }

    public void setInt(String desc, int i) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform1i(id, i);
        }
    }

    public void setFloat1(String desc, FloatBuffer buffer) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform1(id, buffer);
        }
    }

    public void setFloat2(String desc, FloatBuffer buffer) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform2(id, buffer);
        }
    }

    public void setFloat3(String desc, FloatBuffer buffer) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform3(id, buffer);
        }
    }

    public void setFloat4(String desc, FloatBuffer buffer) {
        if (isDisposed())
            return;

        enable();
        int id = GL20.glGetUniformLocation(shaderProgram, desc);
        if (id != -1) {
            GL20.glUniform4(id, buffer);
        }
    }

    public void setTexture(String desc, Texture texture) {
        if (isDisposed())
            return;

        int texId = -1;
        if (bindMap.containsKey(desc)) {
            texId = bindMap.get(desc);
        } else {
            // TODO: do this initially, and try and have similar textures in similar slots for all materials.
            ParamMetadata metadata = shader.getParameter(desc);
            if (metadata == null) {
                return;
            }
            enable();
            texId = textureIndex++;
            int id = GL20.glGetUniformLocation(shaderProgram, desc);
            GL20.glUniform1i(id, texId);
            bindMap.put(desc, texId);
        }

        textureMap.put(texId, texture);
    }

    @Override
    public AssetUri getURI() {
        return uri;
    }

}