jogamp.opengl.util.glsl.fixedfunc.FixedFuncPipeline Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jogl-all Show documentation
Show all versions of jogl-all Show documentation
Java™ Binding for the OpenGL® API
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package jogamp.opengl.util.glsl.fixedfunc;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLArrayData;
import javax.media.opengl.GLES2;
import javax.media.opengl.GLException;
import javax.media.opengl.GLRunnable2;
import javax.media.opengl.GLUniformData;
import javax.media.opengl.fixedfunc.GLLightingFunc;
import javax.media.opengl.fixedfunc.GLPointerFunc;
import javax.media.opengl.fixedfunc.GLPointerFuncUtil;
import jogamp.opengl.Debug;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.opengl.util.PMVMatrix;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderState;
import com.jogamp.opengl.util.glsl.fixedfunc.ShaderSelectionMode;
/**
*
*
* Note: Certain GL FFP state values (e.g.: alphaTestFunc and cullFace)
* are mapped to a lower number range so they can be stored in low precision storage,
* i.e. in a 'lowp int' (GL ES2).
*
*/
public class FixedFuncPipeline {
protected static final boolean DEBUG;
static {
Debug.initSingleton();
DEBUG = PropertyAccess.isPropertyDefined("jogl.debug.FixedFuncPipeline", true);
}
/** The maximum texture units which could be used, depending on {@link ShaderSelectionMode}. */
public static final int MAX_TEXTURE_UNITS = 8;
public static final int MAX_LIGHTS = 8;
public FixedFuncPipeline(final GL2ES2 gl, final ShaderSelectionMode mode, final PMVMatrix pmvMatrix) {
shaderRootClass = FixedFuncPipeline.class;
shaderSrcRoot = shaderSrcRootDef;
shaderBinRoot = shaderBinRootDef;
vertexColorFile = vertexColorFileDef;
vertexColorLightFile = vertexColorLightFileDef;
fragmentColorFile = fragmentColorFileDef;
fragmentColorTextureFile = fragmentColorTextureFileDef;
init(gl, mode, pmvMatrix);
}
public FixedFuncPipeline(final GL2ES2 gl, final ShaderSelectionMode mode, final PMVMatrix pmvMatrix,
final Class shaderRootClass, final String shaderSrcRoot,
final String shaderBinRoot,
final String vertexColorFile, final String vertexColorLightFile,
final String fragmentColorFile, final String fragmentColorTextureFile) {
this.shaderRootClass = shaderRootClass;
this.shaderSrcRoot = shaderSrcRoot;
this.shaderBinRoot = shaderBinRoot;
this.vertexColorFile = vertexColorFile;
this.vertexColorLightFile = vertexColorLightFile;
this.fragmentColorFile = fragmentColorFile;
this.fragmentColorTextureFile = fragmentColorTextureFile;
init(gl, mode, pmvMatrix);
}
public ShaderSelectionMode getShaderSelectionMode() { return requestedShaderSelectionMode; }
public void setShaderSelectionMode(final ShaderSelectionMode mode) { requestedShaderSelectionMode=mode; }
public ShaderSelectionMode getCurrentShaderSelectionMode() { return currentShaderSelectionMode; }
public boolean verbose() { return verbose; }
public void setVerbose(final boolean v) { verbose = DEBUG || v; }
public boolean isValid() {
return shaderState.linked();
}
public ShaderState getShaderState() {
return shaderState;
}
public int getActiveTextureUnit() {
return activeTextureUnit;
}
public void destroy(final GL2ES2 gl) {
if(null != shaderProgramColor) {
shaderProgramColor.release(gl, true);
}
if(null != shaderProgramColorLight) {
shaderProgramColorLight.release(gl, true);
}
if(null != shaderProgramColorTexture2) {
shaderProgramColorTexture2.release(gl, true);
}
if(null != shaderProgramColorTexture4) {
shaderProgramColorTexture4.release(gl, true);
}
if(null != shaderProgramColorTexture4) {
shaderProgramColorTexture4.release(gl, true);
}
if(null != shaderProgramColorTexture8Light) {
shaderProgramColorTexture8Light.release(gl, true);
}
shaderState.destroy(gl);
}
//
// Simple Globals
//
public void glColor4f(final GL2ES2 gl, final float red, final float green, final float blue, final float alpha) {
colorStatic.put(0, red);
colorStatic.put(1, green);
colorStatic.put(2, blue);
colorStatic.put(3, alpha);
shaderState.useProgram(gl, true);
final GLUniformData ud = shaderState.getUniform(mgl_ColorStatic);
if(null!=ud) {
// same data object ..
shaderState.uniform(gl, ud);
} else {
throw new GLException("Failed to update: mgl_ColorStatic");
}
}
//
// Arrays / States
//
public void glEnableClientState(final GL2ES2 gl, final int glArrayIndex) {
glToggleClientState(gl, glArrayIndex, true);
}
public void glDisableClientState(final GL2ES2 gl, final int glArrayIndex) {
glToggleClientState(gl, glArrayIndex, false);
}
private void glToggleClientState(final GL2ES2 gl, final int glArrayIndex, final boolean enable) {
final String arrayName = GLPointerFuncUtil.getPredefinedArrayIndexName(glArrayIndex, clientActiveTextureUnit);
if(null == arrayName) {
throw new GLException("arrayIndex "+toHexString(glArrayIndex)+" unknown");
}
shaderState.useProgram(gl, true);
if(enable) {
shaderState.enableVertexAttribArray(gl, arrayName );
} else {
shaderState.disableVertexAttribArray(gl, arrayName );
}
switch( glArrayIndex ) {
case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
final int enableV = enable ? 1 : 0;
// enable-bitwise: textureCoordsEnabled |= (1 << clientActiveTextureUnit);
// disable-bitwise: textureCoordsEnabled &= ~(1 << clientActiveTextureUnit);
if ( textureCoordEnabled.get(clientActiveTextureUnit) != enableV) {
textureCoordEnabled.put(clientActiveTextureUnit, enableV);
textureCoordEnabledDirty = true;
}
break;
case GLPointerFunc.GL_COLOR_ARRAY:
colorVAEnabledDirty = true;
break;
}
}
public void glVertexPointer(final GL2ES2 gl, final GLArrayData data) {
shaderState.useProgram(gl, true);
shaderState.vertexAttribPointer(gl, data);
}
public void glColorPointer(final GL2ES2 gl, final GLArrayData data) {
shaderState.useProgram(gl, true);
shaderState.vertexAttribPointer(gl, data);
}
public void glNormalPointer(final GL2ES2 gl, final GLArrayData data) {
shaderState.useProgram(gl, true);
shaderState.vertexAttribPointer(gl, data);
}
//
// MULTI-TEXTURE
//
/** Enables/Disables the named texture unit (if changed), returns previous state */
private boolean glEnableTexture(final boolean enable, final int unit) {
final boolean isEnabled = 0 != ( textureEnabledBits & ( 1 << activeTextureUnit ) );
if( isEnabled != enable ) {
if(enable) {
textureEnabledBits |= ( 1 << unit );
textureEnabled.put(unit, 1);
} else {
textureEnabledBits &= ~( 1 << unit );
textureEnabled.put(unit, 0);
}
textureEnabledDirty=true;
}
return isEnabled;
}
public void glClientActiveTexture(int textureUnit) {
textureUnit -= GL.GL_TEXTURE0;
if(0 <= textureUnit && textureUnit "+toHexString(ifmt));
}
} else {
System.err.println("FixedFuncPipeline: Unimplemented glTexImage2D: target "+toHexString(target)+", internalformat "+toHexString(internalformat));
}
}
/*
public void glTexImage2D(int target, int level, int internalformat, int width, int height, int border,
int format, int type, long pixels_buffer_offset) {
textureFormat.put(activeTextureUnit, internalformat);
textureFormatDirty = true;
}*/
public void glTexEnvi(final int target, final int pname, final int value) {
if(GL2ES1.GL_TEXTURE_ENV == target && GL2ES1.GL_TEXTURE_ENV_MODE == pname) {
final int mode;
switch( value ) {
case GL2ES1.GL_ADD:
mode = 1;
break;
case GL2ES1.GL_MODULATE:
mode = 2;
break;
case GL2ES1.GL_DECAL:
mode = 3;
break;
case GL.GL_BLEND:
mode = 4;
break;
case GL.GL_REPLACE:
mode = 5;
break;
case GL2ES1.GL_COMBINE:
mode = 2; // FIXME
System.err.println("FixedFuncPipeline: glTexEnv GL_TEXTURE_ENV_MODE: unimplemented mode: "+toHexString(value));
break;
default:
throw new GLException("glTexEnv GL_TEXTURE_ENV_MODE: invalid mode: "+toHexString(value));
}
setTextureEnvMode(mode);
} else if(verbose) {
System.err.println("FixedFuncPipeline: Unimplemented TexEnv: target "+toHexString(target)+", pname "+toHexString(pname)+", mode: "+toHexString(value));
}
}
private void setTextureEnvMode(final int value) {
if( value != textureEnvMode.get(activeTextureUnit) ) {
textureEnvMode.put(activeTextureUnit, value);
textureEnvModeDirty = true;
}
}
public void glGetTexEnviv(final int target, final int pname, final IntBuffer params) { // FIXME
System.err.println("FixedFuncPipeline: Unimplemented glGetTexEnviv: target "+toHexString(target)+", pname "+toHexString(pname));
}
public void glGetTexEnviv(final int target, final int pname, final int[] params, final int params_offset) { // FIXME
System.err.println("FixedFuncPipeline: Unimplemented glGetTexEnviv: target "+toHexString(target)+", pname "+toHexString(pname));
}
//
// Point Sprites
//
public void glPointSize(final float size) {
pointParams.put(0, size);
pointParamsDirty = true;
}
public void glPointParameterf(final int pname, final float param) {
switch(pname) {
case GL2ES1.GL_POINT_SIZE_MIN:
pointParams.put(2, param);
break;
case GL2ES1.GL_POINT_SIZE_MAX:
pointParams.put(3, param);
break;
case GL.GL_POINT_FADE_THRESHOLD_SIZE:
pointParams.put(4+3, param);
break;
}
pointParamsDirty = true;
}
public void glPointParameterfv(final int pname, final float[] params, final int params_offset) {
switch(pname) {
case GL2ES1.GL_POINT_DISTANCE_ATTENUATION:
pointParams.put(4+0, params[params_offset + 0]);
pointParams.put(4+1, params[params_offset + 1]);
pointParams.put(4+2, params[params_offset + 2]);
break;
}
pointParamsDirty = true;
}
public void glPointParameterfv(final int pname, final java.nio.FloatBuffer params) {
final int o = params.position();
switch(pname) {
case GL2ES1.GL_POINT_DISTANCE_ATTENUATION:
pointParams.put(4+0, params.get(o + 0));
pointParams.put(4+1, params.get(o + 1));
pointParams.put(4+2, params.get(o + 2));
break;
}
pointParamsDirty = true;
}
// private int[] pointTexObj = new int[] { 0 };
private void glDrawPoints(final GL2ES2 gl, final GLRunnable2