Java tutorial
/* * Copyright (c) 2016. See AUTHORS file. * * 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 com.mbrlabs.mundus.commons.shaders; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g3d.Renderable; import com.badlogic.gdx.graphics.g3d.Shader; import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute; import com.badlogic.gdx.graphics.g3d.shaders.BaseShader; import com.badlogic.gdx.graphics.g3d.utils.RenderContext; import com.badlogic.gdx.graphics.glutils.ShaderProgram; import com.badlogic.gdx.utils.Array; import com.mbrlabs.mundus.commons.env.Fog; import com.mbrlabs.mundus.commons.env.MundusEnvironment; import com.mbrlabs.mundus.commons.env.lights.DirectionalLight; import com.mbrlabs.mundus.commons.env.lights.DirectionalLightsAttribute; import com.mbrlabs.mundus.commons.utils.ShaderUtils; /** * @author Marcus Brummer * @version 22-11-2015 */ public class EntityShader extends BaseShader { private static final String VERTEX_SHADER = "com/mbrlabs/mundus/commons/shaders/entity.vert.glsl"; private static final String FRAGMENT_SHADER = "com/mbrlabs/mundus/commons/shaders/entity.frag.glsl"; // ============================ MATERIALS ============================ protected final int UNIFORM_MATERIAL_DIFFUSE_TEXTURE = register(new Uniform("u_diffuseTexture")); protected final int UNIFORM_MATERIAL_DIFFUSE_COLOR = register(new Uniform("u_diffuseColor")); protected final int UNIFORM_MATERIAL_DIFFUSE_USE_TEXTURE = register(new Uniform("u_diffuseUseTexture")); // ============================ MATRICES & CAM POSITION // ============================ protected final int UNIFORM_PROJ_VIEW_MATRIX = register(new Uniform("u_projViewMatrix")); protected final int UNIFORM_TRANS_MATRIX = register(new Uniform("u_transMatrix")); protected final int UNIFORM_CAM_POS = register(new Uniform("u_camPos")); // ============================ LIGHTS ============================ protected final int UNIFORM_AMBIENT_LIGHT_COLOR = register(new Uniform("u_ambientLight.color")); protected final int UNIFORM_AMBIENT_LIGHT_INTENSITY = register(new Uniform("u_ambientLight.intensity")); protected final int UNIFORM_DIRECTIONAL_LIGHT_COLOR = register(new Uniform("u_directionalLight.color")); protected final int UNIFORM_DIRECTIONAL_LIGHT_DIR = register(new Uniform("u_directionalLight.direction")); protected final int UNIFORM_DIRECTIONAL_LIGHT_INTENSITY = register(new Uniform("u_directionalLight.intensity")); // ============================ FOG ============================ protected final int UNIFORM_FOG_DENSITY = register(new Uniform("u_fogDensity")); protected final int UNIFORM_FOG_GRADIENT = register(new Uniform("u_fogGradient")); protected final int UNIFORM_FOG_COLOR = register(new Uniform("u_fogColor")); private ShaderProgram program; public EntityShader() { super(); program = ShaderUtils.compile(VERTEX_SHADER, FRAGMENT_SHADER, true); } @Override public void init() { super.init(program, null); } @Override public int compareTo(Shader other) { return 0; } @Override public boolean canRender(Renderable instance) { return true; } @Override public void begin(Camera camera, RenderContext context) { this.context = context; context.begin(); this.context.setCullFace(GL20.GL_BACK); this.context.setDepthTest(GL20.GL_LEQUAL, 0f, 1f); this.context.setDepthMask(true); program.begin(); set(UNIFORM_PROJ_VIEW_MATRIX, camera.combined); set(UNIFORM_CAM_POS, camera.position); } @Override public void render(Renderable renderable) { final MundusEnvironment env = (MundusEnvironment) renderable.environment; setLights(env); set(UNIFORM_TRANS_MATRIX, renderable.worldTransform); // texture uniform TextureAttribute diffuseTexture = ((TextureAttribute) (renderable.material.get(TextureAttribute.Diffuse))); ColorAttribute diffuseColor = ((ColorAttribute) (renderable.material.get(ColorAttribute.Diffuse))); if (diffuseTexture != null) { set(UNIFORM_MATERIAL_DIFFUSE_TEXTURE, diffuseTexture.textureDescription.texture); set(UNIFORM_MATERIAL_DIFFUSE_USE_TEXTURE, 1); } else { set(UNIFORM_MATERIAL_DIFFUSE_COLOR, diffuseColor.color); set(UNIFORM_MATERIAL_DIFFUSE_USE_TEXTURE, 0); } // Fog final Fog fog = env.getFog(); if (fog == null) { set(UNIFORM_FOG_DENSITY, 0f); set(UNIFORM_FOG_GRADIENT, 0f); } else { set(UNIFORM_FOG_DENSITY, fog.density); set(UNIFORM_FOG_GRADIENT, fog.gradient); set(UNIFORM_FOG_COLOR, fog.color); } // bind attributes, bind mesh & render; then unbinds everything renderable.meshPart.render(program); } private void setLights(MundusEnvironment env) { // ambient set(UNIFORM_AMBIENT_LIGHT_COLOR, env.getAmbientLight().color); set(UNIFORM_AMBIENT_LIGHT_INTENSITY, env.getAmbientLight().intensity); // TODO light array for each light type // directional lights final DirectionalLightsAttribute dirLightAttribs = env.get(DirectionalLightsAttribute.class, DirectionalLightsAttribute.Type); final Array<DirectionalLight> dirLights = dirLightAttribs == null ? null : dirLightAttribs.lights; if (dirLights != null && dirLights.size > 0) { final DirectionalLight light = dirLights.first(); set(UNIFORM_DIRECTIONAL_LIGHT_COLOR, light.color); set(UNIFORM_DIRECTIONAL_LIGHT_DIR, light.direction); set(UNIFORM_DIRECTIONAL_LIGHT_INTENSITY, light.intensity); } // TODO point lights, spot lights } @Override public void end() { context.end(); program.end(); } @Override public void dispose() { program.dispose(); } }