Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package javax.media.j3d;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
/**
* The ShaderProgramRetained object is a component object of an AppearanceRetained
* object that defines the shader properties used when programmable shader is
* enabled. ShaderProgramRetained object is an abstract class. All shader program
* objects must be created as either a GLSLShaderProgramRetained object or a
* CgShaderProgramRetained object.
*/
abstract class ShaderProgramRetained extends NodeComponentRetained {
// Each element in the array corresponds to a unique renderer if shared
// context or a unique canvas otherwise.
protected ShaderProgramData shaderProgramData[];
// Flag indicating whether an UNSUPPORTED_LANGUAGE_ERROR has
// already been reported for this shader program object. It is
// set in verifyShaderProgram and cleared in setLive or clearLive.
// TODO KCR: Add code to clear this in setLive or clearLive
private boolean unsupportedErrorReported = false;
// Flag indicating whether a LINK_ERROR has occurred for this shader program
// object. It is set in updateNative to indicate that the linkShaderProgram
// operation failed. It is cleared in setLive or clearLive.
// TODO KCR: Add code to clear this in setLive or clearLive
private boolean linkErrorOccurred = false;
// an array of shaders used by this shader program
protected ShaderRetained[] shaders;
// an array of vertex attribute names
protected String[] vertexAttrNames;
// an array of (uniform) shader attribute names
protected String[] shaderAttrNames;
// Set of ShaderAttribute objects for which we have already reported an error
private HashSet shaderAttrErrorSet = null;
// need to synchronize access from multiple rendering threads
Object resourceLock = new Object();
// Package-scope default constructor
ShaderProgramRetained() {
}
/**
* Sets the vertex attribute names array for this ShaderProgram
* object. Each element in the array specifies the shader
* attribute name that is bound to the corresponding numbered
* vertex attribute within a GeometryArray object that uses this
* shader program. Array element 0 specifies the name of
* GeometryArray vertex attribute 0, array element 1 specifies the
* name of GeometryArray vertex attribute 1, and so forth.
* The array of names may be null or empty (0 length), but the
* elements of the array must be non-null.
*
* @param vertexAttrNames array of vertex attribute names for this
* shader program. A copy of this array is made.
*/
void setVertexAttrNames(String[] vertexAttrNames) {
if (vertexAttrNames == null) {
this.vertexAttrNames = null;
}
else {
this.vertexAttrNames = vertexAttrNames.clone();
}
}
/**
* Retrieves the vertex attribute names array from this
* ShaderProgram object.
*
* @return a copy of this ShaderProgram's array of vertex attribute names.
*/
String[] getVertexAttrNames() {
if (vertexAttrNames == null) {
return null;
}
return vertexAttrNames.clone();
}
/**
* Sets the shader attribute names array for this ShaderProgram
* object. Each element in the array specifies a shader
* attribute name that may be set via a ShaderAttribute object.
* Only those attributes whose names that appear in the shader
* attribute names array can be set for a given shader program.
* The array of names may be null or empty (0 length), but the
* elements of the array must be non-null.
*
* @param shaderAttrNames array of shader attribute names for this
* shader program. A copy of this array is made.
*/
void setShaderAttrNames(String[] shaderAttrNames) {
if (shaderAttrNames == null) {
this.shaderAttrNames = null;
}
else {
this.shaderAttrNames = shaderAttrNames.clone();
}
}
/**
* Retrieves the shader attribute names array from this
* ShaderProgram object.
*
* @return a copy of this ShaderProgram's array of shader attribute names.
*/
String[] getShaderAttrNames() {
if (shaderAttrNames == null) {
return null;
}
return shaderAttrNames.clone();
}
/**
* Copies the specified array of shaders into this shader
* program. This method makes a shallow copy of the array. The
* array of shaders may be null or empty (0 length), but the
* elements of the array must be non-null. The shading
* language of each shader in the array must match the
* subclass. Subclasses may impose additional restrictions.
*
* @param shaders array of Shader objects to be copied into this
* ShaderProgram
*
* @exception CapabilityNotSetException if appropriate capability is
* not set and this object is part of live or compiled scene graph
*
* @exception IllegalArgumentException if the shading language of
* any shader in the shaders array doesn't match the type of the
* subclass.
*/
void setShaders(Shader[] shaders) {
if (shaders == null) {
this.shaders = null;
return;
}
this.shaders = new ShaderRetained[shaders.length];
// Copy vertex and fragment shader
for (int i = 0; i < shaders.length; i++) {
this.shaders[i] = (ShaderRetained)shaders[i].retained;
}
}
/**
* Retrieves the array of shaders from this shader program. A
* shallow copy of the array is returned. The return value may
* be null.
*
* @return a copy of this ShaderProgram's array of Shader objects
*
*/
Shader[] getShaders() {
if (shaders == null) {
return null;
} else {
Shader shads[] =
new Shader[shaders.length];
for (int i = 0; i < shaders.length; i++) {
if (shaders[i] != null) {
shads[i] = (Shader) shaders[i].source;
} else {
shads[i] = null;
}
}
return shads;
}
}
/**
* Method to create the native shader.
*/
abstract ShaderError createShader(Context ctx, ShaderRetained shader, ShaderId[] shaderIdArr);
/**
* Method to destroy the native shader.
*/
abstract ShaderError destroyShader(Context ctx, ShaderId shaderId);
/**
* Method to compile the native shader.
*/
abstract ShaderError compileShader(Context ctx, ShaderId shaderId, String source);
/**
* Method to create the native shader program.
*/
abstract ShaderError createShaderProgram(Context ctx, ShaderProgramId[] shaderProgramIdArr);
/**
* Method to destroy the native shader program.
*/
abstract ShaderError destroyShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
/**
* Method to link the native shader program.
*/
abstract ShaderError linkShaderProgram(Context ctx, ShaderProgramId shaderProgramId, ShaderId[] shaderIds);
/**
* Method to bind a vertex attribute name to the specified index.
*/
abstract ShaderError bindVertexAttrName(Context ctx, ShaderProgramId shaderProgramId, String attrName, int attrIndex);
/**
* Method to lookup a list of (uniform) shader attribute names and return
* information about the attributes.
*/
abstract void lookupShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId, String[] attrNames, AttrNameInfo[] attrNameInfoArr);
/*
* Method to lookup a list of vertex attribute names.
*/
abstract void lookupVertexAttrNames(Context ctx, ShaderProgramId shaderProgramId, String[] attrNames, boolean[] errArr);
/**
* Method to use the native shader program.
*/
abstract ShaderError enableShaderProgram(Context ctx, ShaderProgramId shaderProgramId);
/**
* Method to disable the native shader program.
*/
abstract ShaderError disableShaderProgram(Context ctx);
// ShaderAttributeValue methods
abstract ShaderError setUniform1i(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int value);
abstract ShaderError setUniform1f(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
float value);
abstract ShaderError setUniform2i(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int[] value);
abstract ShaderError setUniform2f(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
float[] value);
abstract ShaderError setUniform3i(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int[] value);
abstract ShaderError setUniform3f(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
float[] value);
abstract ShaderError setUniform4i(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int[] value);
abstract ShaderError setUniform4f(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
float[] value);
abstract ShaderError setUniformMatrix3f(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
float[] value);
abstract ShaderError setUniformMatrix4f(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
float[] value);
// ShaderAttributeArray methods
abstract ShaderError setUniform1iArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
abstract ShaderError setUniform1fArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
abstract ShaderError setUniform2iArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
abstract ShaderError setUniform2fArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
abstract ShaderError setUniform3iArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
abstract ShaderError setUniform3fArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
abstract ShaderError setUniform4iArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
int[] value);
abstract ShaderError setUniform4fArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
abstract ShaderError setUniformMatrix3fArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
abstract ShaderError setUniformMatrix4fArray(Context ctx,
ShaderProgramId shaderProgramId,
ShaderAttrLoc uniformLocation,
int numElements,
float[] value);
/**
* Method to return a flag indicating whether this
* ShaderProgram is supported on the specified Canvas.
*/
abstract boolean isSupported(Canvas3D cv);
@Override
void setLive(boolean backgroundGroup, int refCount) {
// System.err.println("ShaderProgramRetained.setLive()");
if (shaders != null) {
for (int i = 0; i < shaders.length; i++){
shaders[i].setLive(backgroundGroup, refCount);
}
}
super.doSetLive(backgroundGroup, refCount);
super.markAsLive();
}
@Override
void clearLive(int refCount) {
// System.err.println("ShaderProgramRetained.clearLive()");
super.clearLive(refCount);
if (shaders != null) {
for (int i = 0; i < shaders.length; i++) {
shaders[i].clearLive(refCount);
}
}
}
/**
* Method to enable the native shader program.
*/
private ShaderError enableShaderProgram(Canvas3D cv, int cvRdrIndex) {
assert(cvRdrIndex >= 0);
synchronized(resourceLock) {
return enableShaderProgram(cv.ctx,
shaderProgramData[cvRdrIndex].getShaderProgramId());
}
}
/**
* Method to disable the native shader program.
*/
private ShaderError disableShaderProgram(Canvas3D cv) {
return disableShaderProgram(cv.ctx);
}
/**
* Initializes a mirror object.
*/
@Override
synchronized void initMirrorObject() {
// Create mirror copy of shaders
if (this.shaders == null) {
((ShaderProgramRetained)mirror).shaders = null;
}
else {
((ShaderProgramRetained)mirror).shaders = new ShaderRetained[this.shaders.length];
// Copy vertex and fragment shader
for (int i = 0; i < this.shaders.length; i++) {
((ShaderProgramRetained)mirror).shaders[i] =
(ShaderRetained)this.shaders[i].mirror;
}
}
((ShaderProgramRetained)mirror).shaderProgramData = null;
// Create mirror copy of vertex attribute names
if (this.vertexAttrNames == null) {
((ShaderProgramRetained)mirror).vertexAttrNames = null;
}
else {
((ShaderProgramRetained)mirror).vertexAttrNames = this.vertexAttrNames.clone();
}
// Create mirror copy of shader attribute names
if (this.shaderAttrNames == null) {
((ShaderProgramRetained)mirror).shaderAttrNames = null;
}
else {
((ShaderProgramRetained)mirror).shaderAttrNames = this.shaderAttrNames.clone();
}
// Clear shader attribute error set
((ShaderProgramRetained)mirror).shaderAttrErrorSet = null;
}
/**
* Update the "component" field of the mirror object with the given "value"
*/
@Override
synchronized void updateMirrorObject(int component, Object value) {
// ShaderProgram can't be modified once it is live.
assert(false);
System.err.println("ShaderProgramRetained : updateMirrorObject NOT IMPLEMENTED YET");
}
/**
* Method to create a ShaderProgramData object for the specified
* canvas/renderer if it doesn't already exist.
*
* Issue 378 : reset the ShaderProgramData object if the context
* has been recreated for the particular canvas / renderer.
*/
private void createShaderProgramData(int cvRdrIndex, long ctxTimeStamp) {
// Create shaderProgram resources if it has not been done.
synchronized(resourceLock) {
if(shaderProgramData == null) {
// We rely on Java to initial the array elements to null.
shaderProgramData = new ShaderProgramData[cvRdrIndex+1];
}
else if(shaderProgramData.length <= cvRdrIndex) {
// We rely on Java to initial the array elements to null.
ShaderProgramData[] tempSPData = new ShaderProgramData[cvRdrIndex+1];
System.arraycopy(shaderProgramData, 0,
tempSPData, 0,
shaderProgramData.length);
shaderProgramData = tempSPData;
}
if(shaderProgramData[cvRdrIndex] == null) {
shaderProgramData[cvRdrIndex] = new ShaderProgramData();
} else if (shaderProgramData[cvRdrIndex].getCtxTimeStamp() != ctxTimeStamp) {
// Issue 378 - reset the shader program data for this canvas / renderer
// if the context has been recreated
shaderProgramData[cvRdrIndex].reset();
}
shaderProgramData[cvRdrIndex].setCtxTimeStamp(ctxTimeStamp);
}
}
/**
* Method to create the native shader program. We must already have
* called createShaderProgramData for this cvRdrIndex.
*/
private ShaderError createShaderProgram(Canvas3D cv, int cvRdrIndex) {
// Create shaderProgram resources if it has not been done.
synchronized(resourceLock) {
assert shaderProgramData[cvRdrIndex].getShaderProgramId() == null;
ShaderProgramId[] spIdArr = new ShaderProgramId[1];
ShaderError err = createShaderProgram(cv.ctx, spIdArr);
if(err != null) {
return err;
}
shaderProgramData[cvRdrIndex].setShaderProgramId(spIdArr[0]);
}
return null;
}
/**
* Method to link the native shader program.
*/
private ShaderError linkShaderProgram(Canvas3D cv, int cvRdrIndex,
ShaderRetained[] shaders) {
synchronized(resourceLock) {
ShaderId[] shaderIds = new ShaderId[shaders.length];
for(int i=0; i cvRdrIndex &&
shaderProgramData[cvRdrIndex] != null);
// // Check whether an entry in the shaderProgramData array has been allocated
// if (shaderProgramData == null ||
// shaderProgramData.length <= cvRdrIndex ||
// shaderProgramData[cvRdrIndex] == null) {
// return;
// }
ShaderProgramId shaderProgramId = shaderProgramData[cvRdrIndex].getShaderProgramId();
// Nothing to do if the shaderProgramId is null
if (shaderProgramId == null) {
return;
}
// Destroy the native resource, set the ID to null for this canvas/renderer,
// and clear the bit in the resourceCreationMask
// Ignore any possible shader error, because there is no meaningful way to report it
destroyShaderProgram(cv.ctx, shaderProgramId);
// Reset this ShaderProgramData object.
shaderProgramData[cvRdrIndex].reset();
}
}
/**
* updateNative is called while traversing the RenderBin to
* update the shader program state
*/
void updateNative(Canvas3D cv, boolean enable) {
// System.err.println("ShaderProgramRetained.updateNative : ");
final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != null;
int cvRdrIndex;
long ctxTimeStamp;
if (useSharedCtx) {
cvRdrIndex = cv.screen.renderer.rendererId;
ctxTimeStamp = cv.screen.renderer.sharedCtxTimeStamp;
} else {
cvRdrIndex = cv.canvasId;
ctxTimeStamp = cv.ctxTimeStamp;
}
// Create ShaderProgramData object for this canvas/renderer if it doesn't already exist
createShaderProgramData(cvRdrIndex, ctxTimeStamp);
// Check whether this shader program type is supported for this canvas
if (!verifyShaderProgramSupported(cv)) {
return;
}
// Just disable shader program and return if enable parameter is set to false
if (!enable) {
// Given the current design, disableShaderProgram cannot return a non-null value,
// so no need to check it
disableShaderProgram(cv);
return;
}
// Just disable shader program and return if array of shaders is empty,
// or if a previous attempt to link resulted in an error
if (shaders == null || shaders.length == 0 || linkErrorOccurred) {
disableShaderProgram(cv);
return;
}
boolean loadShaderProgram = false; // flag indicating whether to reload all shaderProgram states
if (getShaderProgramData(cvRdrIndex).getShaderProgramId() == null) {
loadShaderProgram = true;
}
//System.err.println(".... loadShaderProgram = " + loadShaderProgram);
//System.err.println(".... resourceCreationMask= " + resourceCreationMask);
ShaderError err = null;
boolean errorOccurred = false;
if (loadShaderProgram) {
if (useSharedCtx) {
// TODO : Need to test useSharedCtx case. ** Untested case **
cv.makeCtxCurrent(cv.screen.renderer.sharedCtx);
}
// Create shader resources if not already done
for(int i=0; i < shaders.length; i++) {
// Create ShaderProgramData object for this canvas/renderer if it doesn't already exist
shaders[i].createShaderData(cvRdrIndex, ctxTimeStamp);
if (shaders[i].compileErrorOccurred) {
errorOccurred = true;
}
else {
err = createShader(cv, cvRdrIndex, shaders[i]);
if (err != null) {
err.setShaderProgram((ShaderProgram)this.source);
err.setShader((Shader)shaders[i].source);
err.setCanvas3D(cv);
notifyErrorListeners(cv, err);
errorOccurred = true;
}
else {
err = compileShader(cv, cvRdrIndex, shaders[i]);
if (err != null) {
err.setShaderProgram((ShaderProgram)this.source);
err.setShader((Shader)shaders[i].source);
err.setCanvas3D(cv);
notifyErrorListeners(cv, err);
destroyShader(cv, cvRdrIndex, shaders[i]);
shaders[i].compileErrorOccurred = true;
errorOccurred = true;
}
}
}
}
// Create shader program
if (!errorOccurred) {
err = createShaderProgram(cv, cvRdrIndex);
if (err != null) {
err.setShaderProgram((ShaderProgram)this.source);
err.setCanvas3D(cv);
notifyErrorListeners(cv, err);
errorOccurred = true;
}
}
boolean linked = getShaderProgramData(cvRdrIndex).isLinked();
if (!linked) {
// Bind vertex attribute names
if (!errorOccurred) {
if (vertexAttrNames != null) {
// System.err.println("vertexAttrNames.length = " + vertexAttrNames.length);
for (int i = 0; i < vertexAttrNames.length; i++) {
err = bindVertexAttrName(cv, cvRdrIndex, vertexAttrNames[i], i);
// Report non-fatal error, if one was detected
if (err != null) {
err.setShaderProgram((ShaderProgram)this.source);
err.setCanvas3D(cv);
notifyErrorListeners(cv, err);
}
}
}
}
// Link shader program
if (!errorOccurred) {
err = linkShaderProgram(cv, cvRdrIndex, shaders);
if (err != null) {
err.setShaderProgram((ShaderProgram)this.source);
err.setCanvas3D(cv);
notifyErrorListeners(cv, err);
destroyShaderProgram(cv, cvRdrIndex);
linkErrorOccurred = true;
errorOccurred = true;
}
}
// lookup vertex attribute names
if (!errorOccurred) {
if (vertexAttrNames != null) {
lookupVertexAttrNames(cv, cvRdrIndex, vertexAttrNames);
}
}
// Lookup shader attribute names
if (!errorOccurred) {
if (shaderAttrNames != null) {
// System.err.println("shaderAttrNames.length = " + shaderAttrNames.length);
lookupShaderAttrNames(cv, cvRdrIndex, shaderAttrNames);
}
}
}
// Restore current context if we changed it to the shareCtx
if (useSharedCtx) {
cv.makeCtxCurrent(cv.ctx);
}
// If compilation or link error occured, disable shader program and return
if (errorOccurred) {
disableShaderProgram(cv);
return;
}
}
// Now we can enable the shader program
enableShaderProgram(cv, cvRdrIndex);
}
/**
* Update native value for ShaderAttributeValue class
*/
ShaderError setUniformAttrValue(Context ctx, ShaderProgramId shaderProgramId,
ShaderAttrLoc loc, ShaderAttributeValueRetained sav) {
switch (sav.getClassType()) {
case ShaderAttributeObjectRetained.TYPE_INTEGER:
return setUniform1i(ctx, shaderProgramId, loc,
((int[])sav.attrWrapper.getRef())[0]);
case ShaderAttributeObjectRetained.TYPE_FLOAT:
return setUniform1f(ctx, shaderProgramId, loc,
((float[])sav.attrWrapper.getRef())[0]);
case ShaderAttributeObjectRetained.TYPE_TUPLE2I:
return setUniform2i(ctx, shaderProgramId, loc,
(int[])sav.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE2F:
return setUniform2f(ctx, shaderProgramId, loc,
(float[])sav.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE3I:
return setUniform3i(ctx, shaderProgramId, loc,
(int[])sav.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE3F:
return setUniform3f(ctx, shaderProgramId, loc,
(float[])sav.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE4I:
return setUniform4i(ctx, shaderProgramId, loc,
(int[])sav.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE4F:
return setUniform4f(ctx, shaderProgramId, loc,
(float[])sav.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_MATRIX3F:
return setUniformMatrix3f(ctx, shaderProgramId, loc,
(float[])sav.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_MATRIX4F:
return setUniformMatrix4f(ctx, shaderProgramId, loc,
(float[])sav.attrWrapper.getRef());
default:
// Should never get here
assert false : "Unrecognized ShaderAttributeValue classType";
return null;
}
}
/**
* Update native value for ShaderAttributeArray class
*/
ShaderError setUniformAttrArray(Context ctx, ShaderProgramId shaderProgramId,
ShaderAttrLoc loc, ShaderAttributeArrayRetained saa) {
switch (saa.getClassType()) {
case ShaderAttributeObjectRetained.TYPE_INTEGER:
return setUniform1iArray(ctx, shaderProgramId, loc, saa.length(),
((int[])saa.attrWrapper.getRef()));
case ShaderAttributeObjectRetained.TYPE_FLOAT:
return setUniform1fArray(ctx, shaderProgramId, loc, saa.length(),
((float[])saa.attrWrapper.getRef()));
case ShaderAttributeObjectRetained.TYPE_TUPLE2I:
return setUniform2iArray(ctx, shaderProgramId, loc, saa.length(),
(int[])saa.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE2F:
return setUniform2fArray(ctx, shaderProgramId, loc, saa.length(),
(float[])saa.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE3I:
return setUniform3iArray(ctx, shaderProgramId, loc, saa.length(),
(int[])saa.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE3F:
return setUniform3fArray(ctx, shaderProgramId, loc, saa.length(),
(float[])saa.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE4I:
return setUniform4iArray(ctx, shaderProgramId, loc, saa.length(),
(int[])saa.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_TUPLE4F:
return setUniform4fArray(ctx, shaderProgramId, loc, saa.length(),
(float[])saa.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_MATRIX3F:
return setUniformMatrix3fArray(ctx, shaderProgramId, loc, saa.length(),
(float[])saa.attrWrapper.getRef());
case ShaderAttributeObjectRetained.TYPE_MATRIX4F:
return setUniformMatrix4fArray(ctx, shaderProgramId, loc, saa.length(),
(float[])saa.attrWrapper.getRef());
default:
// Should never get here
assert false : "Unrecognized ShaderAttributeArray classType";
return null;
}
}
void setShaderAttributes(Canvas3D cv, ShaderAttributeSetRetained attributeSet) {
final boolean useSharedCtx = cv.useSharedCtx && cv.screen.renderer.sharedCtx != null;
final int cvRdrIndex = useSharedCtx ? cv.screen.renderer.rendererId : cv.canvasId;
ShaderProgramData spData = getShaderProgramData(cvRdrIndex);
// Just return if shader program wasn't linked successfully
if (!spData.isLinked()) {
return;
}
ShaderProgramId shaderProgramId = spData.getShaderProgramId();
Iterator attrs = attributeSet.getAttrs().values().iterator();
while (attrs.hasNext()) {
ShaderError err = null;
ShaderAttributeRetained saRetained = attrs.next();
// Lookup attribute info for the specified attrName; null means
// that the name does not appear in the ShaderProgram, so we will
// report an error.
AttrNameInfo attrNameInfo = spData.getAttrNameInfo(saRetained.getAttributeName());
if(attrNameInfo == null) {
// System.err.println("ShaderProgramRetained : attrLocation (" + saRetained.getAttributeName() + ") is null.");
String errMsg = "Attribute name not set in ShaderProgram: " + saRetained.getAttributeName(); // TODO: I18N
err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_NAME_NOT_SET_ERROR, errMsg);
} else {
ShaderAttrLoc loc = attrNameInfo.getLocation();
if (loc != null) {
if (saRetained instanceof ShaderAttributeValueRetained) {
ShaderAttributeValueRetained savRetained = (ShaderAttributeValueRetained)saRetained;
if (attrNameInfo.isArray() ||
(savRetained.getClassType() != attrNameInfo.getType())) {
String errMsg = "Attribute type mismatch: " + savRetained.getAttributeName(); // TODO: I18N
err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_TYPE_ERROR, errMsg);
}
else {
err = setUniformAttrValue(cv.ctx, shaderProgramId, loc, savRetained);
}
} else if (saRetained instanceof ShaderAttributeArrayRetained) {
ShaderAttributeArrayRetained saaRetained = (ShaderAttributeArrayRetained)saRetained;
if (!attrNameInfo.isArray() ||
(saaRetained.getClassType() != attrNameInfo.getType())) {
String errMsg = "Attribute type mismatch: " + saaRetained.getAttributeName(); // TODO: I18N
err = new ShaderError(ShaderError.SHADER_ATTRIBUTE_TYPE_ERROR, errMsg);
}
else {
err = setUniformAttrArray(cv.ctx, shaderProgramId, loc, saaRetained);
}
} else if (saRetained instanceof ShaderAttributeBindingRetained) {
assert false;
throw new RuntimeException("not implemented");
} else {
assert false;
}
}
}
if (err != null) {
// Before reporting the ShaderAttribute error, check
// whether it has already been reported for this ShaderProgram
if (shaderAttrErrorSet == null) {
shaderAttrErrorSet = new HashSet();
}
if (shaderAttrErrorSet.add((ShaderAttribute) saRetained.source)) {
err.setShaderProgram((ShaderProgram)this.source);
err.setShaderAttributeSet((ShaderAttributeSet)attributeSet.source);
err.setShaderAttribute((ShaderAttribute)saRetained.source);
err.setCanvas3D(cv);
notifyErrorListeners(cv, err);
}
}
}
}
class ShaderProgramData extends Object {
// issue 378 - time stamp of context creation for this Canvas
private long ctxTimeStamp;
// shaderProgramId use by native code.
private ShaderProgramId shaderProgramId = null;
// linked flag for native.
private boolean linked = false;
// A map of locations for ShaderAttributes.
private HashMap attrNameInfoMap = new HashMap();
/** ShaderProgramData Constructor */
ShaderProgramData() {
}
void reset() {
ctxTimeStamp = 0L;
shaderProgramId = null;
linked = false;
attrNameInfoMap.clear();
}
long getCtxTimeStamp() {
return ctxTimeStamp;
}
void setCtxTimeStamp(long ctxTimeStamp) {
this.ctxTimeStamp = ctxTimeStamp;
}
void setShaderProgramId(ShaderProgramId shaderProgramId) {
this.shaderProgramId = shaderProgramId;
}
ShaderProgramId getShaderProgramId() {
return this.shaderProgramId;
}
void setLinked(boolean linked) {
this.linked = linked;
}
boolean isLinked() {
return linked;
}
void setAttrNameInfo(String shaderAttribute, AttrNameInfo attrNameInfo) {
assert (shaderAttribute != null);
attrNameInfoMap.put(shaderAttribute, attrNameInfo);
}
AttrNameInfo getAttrNameInfo(String shaderAttribute) {
return attrNameInfoMap.get(shaderAttribute);
}
}
// Data associated with an attribute name
class AttrNameInfo {
void setLocation(ShaderAttrLoc loc) {
this.loc = loc;
}
ShaderAttrLoc getLocation() {
return loc;
}
void setType(int type) {
this.type = type;
}
int getType() {
return type;
}
boolean isArray() {
return isArray;
}
void setArray(boolean isArray) {
this.isArray = isArray;
}
// Location of attribute name in linked shader program
private ShaderAttrLoc loc;
// boolean indicating whether the attribute is an array
private boolean isArray;
// type of shader attribute
private int type;
}
}