lwjgltexturestate.java

来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 1,400 行 · 第 1/5 页

JAVA
1,400
字号
/*
 * Copyright (c) 2003-2009 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jme.scene.state.lwjgl;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Stack;
import java.util.logging.Logger;

import org.lwjgl.opengl.ARBDepthTexture;
import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBMultitexture;
import org.lwjgl.opengl.ARBShadow;
import org.lwjgl.opengl.ARBTextureCompression;
import org.lwjgl.opengl.ARBTextureCubeMap;
import org.lwjgl.opengl.ARBTextureEnvCombine;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.EXTTextureFilterAnisotropic;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.opengl.SGISGenerateMipmap;
import org.lwjgl.opengl.Util;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.glu.MipMap;

import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.image.Texture1D;
import com.jme.image.Texture2D;
import com.jme.image.Texture3D;
import com.jme.image.TextureCubeMap;
import com.jme.image.Texture.ApplyMode;
import com.jme.image.Texture.CombinerFunctionAlpha;
import com.jme.image.Texture.CombinerFunctionRGB;
import com.jme.image.Texture.CombinerOperandAlpha;
import com.jme.image.Texture.CombinerOperandRGB;
import com.jme.image.Texture.CombinerSource;
import com.jme.image.Texture.Type;
import com.jme.image.Texture.WrapAxis;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.RenderContext;
import com.jme.scene.Spatial;
import com.jme.scene.Spatial.TextureCombineMode;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.StateRecord;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.lwjgl.records.RendererRecord;
import com.jme.scene.state.lwjgl.records.TextureRecord;
import com.jme.scene.state.lwjgl.records.TextureStateRecord;
import com.jme.scene.state.lwjgl.records.TextureUnitRecord;
import com.jme.system.DisplaySystem;
import com.jme.util.Debug;
import com.jme.util.TextureManager;
import com.jme.util.geom.BufferUtils;
import com.jme.util.stat.StatCollector;
import com.jme.util.stat.StatType;

/**
 * <code>LWJGLTextureState</code> subclasses the TextureState object using the
 * LWJGL API to access OpenGL for texture processing.
 * 
 * @author Mark Powell
 * @author Joshua Slack
 * @version $Id: LWJGLTextureState.java,v 1.99 2008/04/21 02:57:04 renanse Exp $
 */
public class LWJGLTextureState extends TextureState {
    private static final Logger logger = Logger
            .getLogger(LWJGLTextureState.class.getName());

    private static final long serialVersionUID = 1L;
    private static boolean inited = false;

    /**
     * Constructor instantiates a new <code>LWJGLTextureState</code> object.
     * The number of textures that can be combined is determined during
     * construction. This equates the number of texture units supported by the
     * graphics card.
     */
    public LWJGLTextureState() {
        super();

        // get our array of texture objects ready.
        texture = new ArrayList<Texture>();

        // See if we haven't already setup a texturestate before.
        if (!inited) {
            // Check for support of multitextures.
            supportsMultiTexture = supportsMultiTextureDetected = GLContext
                    .getCapabilities().GL_ARB_multitexture;

            // Check for support of fixed function dot3 environment settings
            supportsEnvDot3 = supportsEnvDot3Detected = GLContext
                    .getCapabilities().GL_ARB_texture_env_dot3;

            // Check for support of fixed function dot3 environment settings
            supportsEnvCombine = supportsEnvCombineDetected = GLContext
                    .getCapabilities().GL_ARB_texture_env_combine;

            // Check for support of automatic mipmap generation
            automaticMipMaps = automaticMipMapsDetected = GLContext
                    .getCapabilities().GL_SGIS_generate_mipmap;
            
            supportsDepthTexture = GLContext.getCapabilities().GL_ARB_depth_texture;
            supportsShadow = GLContext.getCapabilities().GL_ARB_shadow;
            
            // If we do support multitexturing, find out how many textures we
            // can handle.
            if (supportsMultiTexture) {
                IntBuffer buf = BufferUtils.createIntBuffer(16);
                GL11
                        .glGetInteger(ARBMultitexture.GL_MAX_TEXTURE_UNITS_ARB,
                                buf);
                numFixedTexUnits = buf.get(0);
            } else {
                numFixedTexUnits = 1;
            }

            // Go on to check number of texture units supported for vertex and
            // fragment shaders
            if (GLContext.getCapabilities().GL_ARB_shader_objects
                    && GLContext.getCapabilities().GL_ARB_vertex_shader
                    && GLContext.getCapabilities().GL_ARB_fragment_shader) {
                IntBuffer buf = BufferUtils.createIntBuffer(16);
                GL11.glGetInteger(
                        ARBVertexShader.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB,
                        buf);
                numVertexTexUnits = buf.get(0);
                GL11.glGetInteger(
                        ARBFragmentShader.GL_MAX_TEXTURE_IMAGE_UNITS_ARB, buf);
                numFragmentTexUnits = buf.get(0);
                GL11.glGetInteger(ARBFragmentShader.GL_MAX_TEXTURE_COORDS_ARB,
                        buf);
                numFragmentTexCoordUnits = buf.get(0);
            } else {
                // based on nvidia dev doc:
                // http://developer.nvidia.com/object/General_FAQ.html#t6
                // "For GPUs that do not support GL_ARB_fragment_program and
                // GL_NV_fragment_program, those two limits are set equal to
                // GL_MAX_TEXTURE_UNITS."
                numFragmentTexCoordUnits = numFixedTexUnits;
                numFragmentTexUnits = numFixedTexUnits;

                // We'll set this to 0 for now since we do not know:
                numVertexTexUnits = 0;
            }

            // Now determine the maximum number of supported texture units
            numTotalTexUnits = Math.max(numFragmentTexCoordUnits, Math.max(
                    numFixedTexUnits, Math.max(numFragmentTexUnits,
                            numVertexTexUnits)));

            // Check for S3 texture compression capability.
            supportsS3TCCompression = supportsS3TCCompressionDetected = GLContext
                    .getCapabilities().GL_EXT_texture_compression_s3tc;

            // Check for S3 texture compression capability.
            supportsTexture3D = supportsTexture3DDetected = GLContext
                    .getCapabilities().GL_EXT_texture_3d;

            // Check for S3 texture compression capability.
            supportsTextureCubeMap = supportsTextureCubeMapDetected = GLContext
                    .getCapabilities().GL_ARB_texture_cube_map;

            // See if we support anisotropic filtering
            supportsAniso = supportsAnisoDetected = GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic;

            if (supportsAniso) {
                // Due to LWJGL buffer check, you can't use smaller sized
                // buffers (min_size = 16 for glGetFloat()).
                FloatBuffer max_a = BufferUtils.createFloatBuffer(16);
                max_a.rewind();

                // Grab the maximum anisotropic filter.
                GL11
                        .glGetFloat(
                                EXTTextureFilterAnisotropic.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,
                                max_a);

                // set max.
                maxAnisotropic = max_a.get(0);
            }

            // See if we support textures that are not power of 2 in size.
            supportsNonPowerTwo = supportsNonPowerTwoDetected = GLContext
                    .getCapabilities().GL_ARB_texture_non_power_of_two;

            // See if we support textures that do not have width == height.
            supportsRectangular = supportsRectangularDetected = GLContext
                    .getCapabilities().GL_ARB_texture_rectangle;

            // Setup our default texture by adding it to our array and loading
            // it, then clearing our array.
            setTexture(defaultTexture);
            load(0);
            this.texture.clear();

            // We're done initing! Wee! :)
            inited = true;
        }
    }

    /**
     * override MipMap to access helper methods
     */
    protected static class LWJGLMipMap extends MipMap {
        /**
         * @see MipMap#glGetIntegerv(int)
         */
        protected static int glGetIntegerv(int what) {
            return org.lwjgl.util.glu.Util.glGetIntegerv(what);
        }

        /**
         * @see MipMap#nearestPower(int)
         */
        protected static int nearestPower(int value) {
            return org.lwjgl.util.glu.Util.nearestPower(value);
        }

        /**
         * @see MipMap#bytesPerPixel(int, int)
         */
        protected static int bytesPerPixel(int format, int type) {
            return org.lwjgl.util.glu.Util.bytesPerPixel(format, type);
        }
    }

    @Override
    public final void load(int unit) {
        Texture texture = getTexture(unit);
        if (texture == null) {
            return;
        }
        
        // our texture type:
        Texture.Type type = texture.getType();

        RenderContext<?> context = DisplaySystem.getDisplaySystem().getCurrentContext();
        TextureStateRecord record = null;
        if (context != null)
            record = (TextureStateRecord) context.getStateRecord(StateType.Texture);

        // Check we are in the right unit
        if (record != null)
            checkAndSetUnit(unit, record);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?