com.ardor3d.scene.state.lwjgl.LwjglMaterialStateUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.ardor3d.scene.state.lwjgl.LwjglMaterialStateUtil.java

Source

/**
 * Copyright (c) 2008-2012 Ardor Labs, Inc.
 *
 * This file is part of Ardor3D.
 *
 * Ardor3D is free software: you can redistribute it and/or modify it 
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or at <http://www.ardor3d.com/LICENSE>.
 */

package com.ardor3d.scene.state.lwjgl;

import org.lwjgl.opengl.GL11;

import com.ardor3d.math.type.ReadOnlyColorRGBA;
import com.ardor3d.renderer.ContextManager;
import com.ardor3d.renderer.RenderContext;
import com.ardor3d.renderer.state.MaterialState;
import com.ardor3d.renderer.state.MaterialState.ColorMaterial;
import com.ardor3d.renderer.state.MaterialState.MaterialFace;
import com.ardor3d.renderer.state.RenderState.StateType;
import com.ardor3d.renderer.state.record.MaterialStateRecord;

public abstract class LwjglMaterialStateUtil {

    public static void apply(final MaterialState state) {
        // ask for the current state record
        final RenderContext context = ContextManager.getCurrentContext();
        final MaterialStateRecord record = (MaterialStateRecord) context.getStateRecord(StateType.Material);
        context.setCurrentState(StateType.Material, state);

        if (state.isEnabled()) {
            // setup colormaterial, if changed.
            applyColorMaterial(state.getColorMaterial(), state.getColorMaterialFace(), record);

            // apply colors, if needed and not what is currently set.
            applyColor(ColorMaterial.Ambient, state.getAmbient(), state.getBackAmbient(), record);
            applyColor(ColorMaterial.Diffuse, state.getDiffuse(), state.getBackDiffuse(), record);
            applyColor(ColorMaterial.Emissive, state.getEmissive(), state.getBackEmissive(), record);
            applyColor(ColorMaterial.Specular, state.getSpecular(), state.getBackSpecular(), record);

            // set our shine
            applyShininess(state.getShininess(), state.getBackShininess(), record);
        } else {
            // apply defaults
            applyColorMaterial(MaterialState.DEFAULT_COLOR_MATERIAL, MaterialState.DEFAULT_COLOR_MATERIAL_FACE,
                    record);

            applyColor(ColorMaterial.Ambient, MaterialState.DEFAULT_AMBIENT, MaterialState.DEFAULT_AMBIENT, record);
            applyColor(ColorMaterial.Diffuse, MaterialState.DEFAULT_DIFFUSE, MaterialState.DEFAULT_DIFFUSE, record);
            applyColor(ColorMaterial.Emissive, MaterialState.DEFAULT_EMISSIVE, MaterialState.DEFAULT_EMISSIVE,
                    record);
            applyColor(ColorMaterial.Specular, MaterialState.DEFAULT_SPECULAR, MaterialState.DEFAULT_SPECULAR,
                    record);

            applyShininess(MaterialState.DEFAULT_SHININESS, MaterialState.DEFAULT_SHININESS, record);
        }

        if (!record.isValid()) {
            record.validate();
        }
    }

    private static void applyColor(final ColorMaterial glMatColor, final ReadOnlyColorRGBA frontColor,
            final ReadOnlyColorRGBA backColor, final MaterialStateRecord record) {
        final int glMat = getGLColorMaterial(glMatColor);
        if (frontColor.equals(backColor)) {
            // consolidate to one call
            if (!isVertexProvidedColor(MaterialFace.FrontAndBack, glMatColor, record)) {
                if (!record.isValid()
                        || !record.isSetColor(MaterialFace.FrontAndBack, glMatColor, frontColor, record)) {
                    record.tempColorBuff.clear();
                    record.tempColorBuff.put(frontColor.getRed()).put(frontColor.getGreen())
                            .put(frontColor.getBlue()).put(frontColor.getAlpha());
                    record.tempColorBuff.flip();
                    GL11.glMaterial(getGLMaterialFace(MaterialFace.FrontAndBack), glMat, record.tempColorBuff);
                    record.setColor(MaterialFace.FrontAndBack, glMatColor, frontColor);
                }
            }
        } else {
            if (!isVertexProvidedColor(MaterialFace.Front, glMatColor, record)) {
                if (!record.isValid() || !record.isSetColor(MaterialFace.Front, glMatColor, frontColor, record)) {
                    record.tempColorBuff.clear();
                    record.tempColorBuff.put(frontColor.getRed()).put(frontColor.getGreen())
                            .put(frontColor.getBlue()).put(frontColor.getAlpha());
                    record.tempColorBuff.flip();
                    GL11.glMaterial(getGLMaterialFace(MaterialFace.Front), glMat, record.tempColorBuff);
                    record.setColor(MaterialFace.Front, glMatColor, frontColor);
                }
            }

            if (!isVertexProvidedColor(MaterialFace.Back, glMatColor, record)) {
                if (!record.isValid() || !record.isSetColor(MaterialFace.Back, glMatColor, backColor, record)) {
                    record.tempColorBuff.clear();
                    record.tempColorBuff.put(backColor.getRed()).put(backColor.getGreen()).put(backColor.getBlue())
                            .put(backColor.getAlpha());
                    record.tempColorBuff.flip();
                    GL11.glMaterial(getGLMaterialFace(MaterialFace.Back), glMat, record.tempColorBuff);
                    record.setColor(MaterialFace.Back, glMatColor, backColor);
                }
            }
        }
    }

    private static boolean isVertexProvidedColor(final MaterialFace face, final ColorMaterial glMatColor,
            final MaterialStateRecord record) {
        if (face != record.colorMaterialFace) {
            return false;
        }
        switch (glMatColor) {
        case Ambient:
            return record.colorMaterial == ColorMaterial.Ambient
                    || record.colorMaterial == ColorMaterial.AmbientAndDiffuse;
        case Diffuse:
            return record.colorMaterial == ColorMaterial.Diffuse
                    || record.colorMaterial == ColorMaterial.AmbientAndDiffuse;
        case Specular:
            return record.colorMaterial == ColorMaterial.Specular;
        case Emissive:
            return record.colorMaterial == ColorMaterial.Emissive;
        }
        return false;
    }

    private static void applyColorMaterial(final ColorMaterial colorMaterial, final MaterialFace face,
            final MaterialStateRecord record) {
        if (!record.isValid() || face != record.colorMaterialFace || colorMaterial != record.colorMaterial) {
            if (colorMaterial == ColorMaterial.None) {
                GL11.glDisable(GL11.GL_COLOR_MATERIAL);
            } else {
                final int glMat = getGLColorMaterial(colorMaterial);
                final int glFace = getGLMaterialFace(face);

                GL11.glColorMaterial(glFace, glMat);
                GL11.glEnable(GL11.GL_COLOR_MATERIAL);
                record.resetColorsForCM(face, colorMaterial);
            }
            record.colorMaterial = colorMaterial;
            record.colorMaterialFace = face;
        }
    }

    private static void applyShininess(final float frontShininess, final float backShininess,
            final MaterialStateRecord record) {
        if (frontShininess == backShininess) {
            // consolidate to one call
            if (!record.isValid() || frontShininess != record.frontShininess
                    || record.backShininess != backShininess) {
                GL11.glMaterialf(getGLMaterialFace(MaterialFace.FrontAndBack), GL11.GL_SHININESS, frontShininess);
                record.backShininess = record.frontShininess = frontShininess;
            }
        } else {
            if (!record.isValid() || frontShininess != record.frontShininess) {
                GL11.glMaterialf(getGLMaterialFace(MaterialFace.Front), GL11.GL_SHININESS, frontShininess);
                record.frontShininess = frontShininess;
            }

            if (!record.isValid() || backShininess != record.backShininess) {
                GL11.glMaterialf(getGLMaterialFace(MaterialFace.Back), GL11.GL_SHININESS, backShininess);
                record.backShininess = backShininess;
            }
        }
    }

    /**
     * Converts the color material setting of this state to a GL constant.
     * 
     * @return the GL constant
     */
    private static int getGLColorMaterial(final ColorMaterial material) {
        switch (material) {
        case None:
            return GL11.GL_NONE;
        case Ambient:
            return GL11.GL_AMBIENT;
        case Diffuse:
            return GL11.GL_DIFFUSE;
        case AmbientAndDiffuse:
            return GL11.GL_AMBIENT_AND_DIFFUSE;
        case Emissive:
            return GL11.GL_EMISSION;
        case Specular:
            return GL11.GL_SPECULAR;
        }
        throw new IllegalArgumentException("invalid color material setting: " + material);
    }

    /**
     * Converts the material face setting of this state to a GL constant.
     * 
     * @return the GL constant
     */
    private static int getGLMaterialFace(final MaterialFace face) {
        switch (face) {
        case Front:
            return GL11.GL_FRONT;
        case Back:
            return GL11.GL_BACK;
        case FrontAndBack:
            return GL11.GL_FRONT_AND_BACK;
        }
        throw new IllegalArgumentException("invalid material face setting: " + face);
    }
}