com.badlogic.gdx.graphics.g3d.lights.LightManager.java Source code

Java tutorial

Introduction

Here is the source code for com.badlogic.gdx.graphics.g3d.lights.LightManager.java

Source

/*******************************************************************************
 * Copyright 2011 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.badlogic.gdx.graphics.g3d.lights;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;

public class LightManager {

    public enum LightQuality {
        VERTEX, FRAGMENT
    };

    public LightQuality quality;

    final public Array<PointLight> pointLights = new Array<PointLight>(false, 16);
    final private float[] positions;
    final private float[] colors;
    final private float[] intensities;

    public final int maxLightsPerModel;

    final public Color ambientLight = new Color();

    /** Only one for optimizing - at least at now */
    public DirectionalLight dirLight;

    public LightManager() {
        this(4, LightQuality.VERTEX);
    }

    public LightManager(int maxLightsPerModel, LightQuality lightQuality) {
        quality = lightQuality;
        this.maxLightsPerModel = maxLightsPerModel;

        colors = new float[3 * maxLightsPerModel];
        positions = new float[3 * maxLightsPerModel];
        intensities = new float[maxLightsPerModel];
    }

    public void addLigth(PointLight light) {
        pointLights.add(light);
    }

    public void clear() {
        pointLights.clear();
    }

    public void calculateAndApplyLightsToModel(Vector3 center, ShaderProgram shader) {
        this.calculateLights(center.x, center.y, center.z);
        this.applyLights(shader);
    }

    // TODO make it better if it slow
    // NAIVE but simple implementation of light choosing algorithm
    // currently calculate lights based on transformed center position of model
    // TODO one idea would be first cull lights that can't affect the scene with
    // frustum check.
    // TODO another idea would be first cut lights that are further from model
    // than x that would make sorted faster
    public void calculateLights(float x, float y, float z) {
        final int maxSize = pointLights.size;
        // solve what are lights that influence most
        if (maxSize > maxLightsPerModel) {

            for (int i = 0; i < maxSize; i++) {
                final PointLight light = pointLights.get(i);
                light.priority = (int) (PointLight.PRIORITY_DISCRETE_STEPS
                        * (light.intensity / light.position.dst(x, y, z)));
                // if just linear fallof
            }
            pointLights.sort();
        }

        // fill the light arrays
        final int size = maxLightsPerModel > maxSize ? maxSize : maxLightsPerModel;
        for (int i = 0; i < size; i++) {
            final PointLight light = pointLights.get(i);
            final Vector3 pos = light.position;
            positions[3 * i + 0] = pos.x;
            positions[3 * i + 1] = pos.y;
            positions[3 * i + 2] = pos.z;

            final Color col = light.color;
            colors[3 * i + 0] = col.r;
            colors[3 * i + 1] = col.g;
            colors[3 * i + 2] = col.b;

            intensities[i] = light.intensity;
        }

        // TODO might not be needed
        for (int i = size; i < maxLightsPerModel; i++) {
            intensities[i] = 0;
        }
    }

    /** Apply lights GLES1.0, call calculateLights before aplying */
    public void applyLights() {

    }

    /** Apply lights GLES2.0, call calculateLights before aplying */
    public void applyLights(ShaderProgram shader) {
        shader.setUniform3fv("lightsPos", positions, 0, maxLightsPerModel * 3);
        shader.setUniform3fv("lightsCol", colors, 0, maxLightsPerModel * 3);
        shader.setUniform1fv("lightsInt", intensities, 0, maxLightsPerModel);
    }

    public void applyGlobalLights() {
        // TODO fix me
    }

    public void applyGlobalLights(ShaderProgram shader) {
        shader.setUniformf("ambient", ambientLight.r, ambientLight.g, ambientLight.b);
        if (dirLight != null) {
            final Vector3 v = dirLight.direction;
            final Color c = dirLight.color;
            shader.setUniformf("dirLightDir", v.x, v.y, v.z);
            shader.setUniformf("dirLightCol", c.r, c.g, c.b);
        }
    }
}