All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.gov.nasa.worldwind.render.BasicLightingModel Maven / Gradle / Ivy

Go to download

World Wind is a collection of components that interactively display 3D geographic information within Java applications or applets.

There is a newer version: 2.0.0-986
Show newest version
/*
 * Copyright (C) 2012 United States Government as represented by the Administrator of the
 * National Aeronautics and Space Administration.
 * All Rights Reserved.
 */

package gov.nasa.worldwind.render;

import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.util.*;

import javax.media.opengl.GL2;

/**
 * Provides a simple lighting model with one light. This model uses only OpenGL light 0.
 *
 * @author tag
 * @version $Id: BasicLightingModel.java 1171 2013-02-11 21:45:02Z dcollins $
 */
public class BasicLightingModel implements LightingModel
{
    protected OGLStackHandler lightingStackHandler = new OGLStackHandler();
    protected Vec4 lightDirection = new Vec4(1.0, 0.5, 1.0);
    protected Material lightMaterial = Material.WHITE;
    protected long frameID;

    public void beginLighting(DrawContext dc)
    {
        if (this.lightingStackHandler.isActive())
            return; // lighting is already enabled

        GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
        this.lightingStackHandler.pushAttrib(gl, GL2.GL_LIGHTING_BIT);

        this.apply(dc);
    }

    public void endLighting(DrawContext dc)
    {
        GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
        this.lightingStackHandler.pop(gl);
        this.lightingStackHandler.clear();
    }

    /**
     * Returns the model's light direction.
     *
     * @return the model's light direction.
     */
    public Vec4 getLightDirection()
    {
        return lightDirection;
    }

    /**
     * Specifies the model's light direction.
     *
     * @param lightDirection the model's light direction.
     *
     * @throws IllegalArgumentException if the light direction is null.
     */
    public void setLightDirection(Vec4 lightDirection)
    {
        if (lightDirection == null)
        {
            String message = Logging.getMessage("nullValue.LightDirectionIsNull");
            Logging.logger().severe(message);
            throw new IllegalStateException(message);
        }

        this.lightDirection = lightDirection;
    }

    /**
     * Returns the model's light material.
     *
     * @return the model's light material.
     */
    public Material getLightMaterial()
    {
        return lightMaterial;
    }

    /**
     * Specifies the model's light direction.
     *
     * @param lightMaterial the model's light material.
     *
     * @throws IllegalArgumentException if the light material is null.
     */
    public void setLightMaterial(Material lightMaterial)
    {
        if (lightMaterial == null)
        {
            String message = Logging.getMessage("nullValue.LightMaterialIsNull");
            Logging.logger().severe(message);
            throw new IllegalStateException(message);
        }

        this.lightMaterial = lightMaterial;
    }

    protected void apply(DrawContext dc)
    {
        GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.

        gl.glEnable(GL2.GL_LIGHTING);
        applyStandardLightModel(gl);
        applyStandardShadeModel(gl);

        gl.glEnable(GL2.GL_LIGHT0);
        applyStandardLightMaterial(gl, GL2.GL_LIGHT0, this.lightMaterial);
        applyStandardLightDirection(gl, GL2.GL_LIGHT0, this.lightDirection);
    }

    protected void applyStandardLightModel(GL2 gl)
    {
        float[] modelAmbient = new float[4];
        modelAmbient[0] = 1.0f;
        modelAmbient[1] = 1.0f;
        modelAmbient[2] = 1.0f;
        modelAmbient[3] = 0.0f;

        gl.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, modelAmbient, 0);
        gl.glLightModeli(GL2.GL_LIGHT_MODEL_LOCAL_VIEWER, GL2.GL_TRUE);
//        gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL2.GL_FALSE);
        gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL2.GL_TRUE);
    }

    protected void applyStandardShadeModel(GL2 gl)
    {
        gl.glShadeModel(GL2.GL_SMOOTH);
    }

    protected static void applyStandardLightMaterial(GL2 gl, int light, Material material)
    {
        // The alpha value at a vertex is taken only from the diffuse material's alpha channel, without any
        // lighting computations applied. Therefore we specify alpha=0 for all lighting ambient, specular and
        // emission values. This will have no effect on material alpha.

        float[] ambient = new float[4];
        float[] diffuse = new float[4];
        float[] specular = new float[4];
        material.getDiffuse().getRGBColorComponents(diffuse);
        material.getSpecular().getRGBColorComponents(specular);
        ambient[3] = diffuse[3] = specular[3] = 0.0f;

        gl.glLightfv(light, GL2.GL_AMBIENT, ambient, 0);
        gl.glLightfv(light, GL2.GL_DIFFUSE, diffuse, 0);
        gl.glLightfv(light, GL2.GL_SPECULAR, specular, 0);
    }

    protected void applyStandardLightDirection(GL2 gl, int light, Vec4 direction)
    {
        // Setup the light as a directional light coming from the viewpoint. This requires two state changes
        // (a) Set the light position as direction x, y, z, and set the w-component to 0, which tells OpenGL this is
        //     a directional light.
        // (b) Invoke the light position call with the identity matrix on the modelview stack. Since the position
        //     is transformed by the

        Vec4 vec = direction.normalize3();
        float[] params = new float[4];
        params[0] = (float) vec.x;
        params[1] = (float) vec.y;
        params[2] = (float) vec.z;
        params[3] = 0.0f;

        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glPushMatrix();
        gl.glLoadIdentity();

        gl.glLightfv(light, GL2.GL_POSITION, params, 0);

        gl.glPopMatrix();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy