diff --git a/.gitignore b/.gitignore index 8e58cce79f..0b2545d291 100644 --- a/.gitignore +++ b/.gitignore @@ -82,3 +82,11 @@ tools/point-cloud-octree/bin/ .settings tools/externals/poly2tri-java/bin/ + +# Android-Studio +*.iml +*.idea + +# Gradle +build +*/build diff --git a/Android/G3MAndroidSDK/AndroidManifest.xml b/Android/G3MAndroidSDK/AndroidManifest.xml index d3f5476488..a630b7eb77 100644 --- a/Android/G3MAndroidSDK/AndroidManifest.xml +++ b/Android/G3MAndroidSDK/AndroidManifest.xml @@ -6,18 +6,4 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/ES2Renderer.java b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/ES2Renderer.java index 01aa480640..04d779a47f 100644 --- a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/ES2Renderer.java +++ b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/ES2Renderer.java @@ -62,29 +62,28 @@ public void onDrawFrame(final GL10 glUnused) { final G3MWidget widget = _widgetAndroid.getG3MWidget(); widget.render(_width, _height); - // experimental FPS reduction - DGD - final long now = System.currentTimeMillis(); - final long timeElapsedInRender = now - _startTime; - final long timeLeftInMS = GOAL_MS_PER_FRAME - timeElapsedInRender; - if (timeLeftInMS > 0) { - // System.gc(); - // - // timeElapsedInRender = System.currentTimeMillis() - _startTime; - // timeLeftInMS = GOAL_MS_PER_FRAME - timeElapsedInRender; - // if (timeLeftInMS > 0) { - try { - //ILogger.instance().logInfo("**** sleeping OpenGL thread for " + timeLeftInMS + "ms"); - Thread.sleep(timeLeftInMS); + if (!_widgetAndroid.getNoFPSReduction()) { + // experimental FPS reduction - DGD + final long now = System.currentTimeMillis(); + final long timeElapsedInRender = now - _startTime; + final long timeLeftInMS = GOAL_MS_PER_FRAME - timeElapsedInRender; + if (timeLeftInMS > 0) { + // System.gc(); + // + // timeElapsedInRender = System.currentTimeMillis() - _startTime; + // timeLeftInMS = GOAL_MS_PER_FRAME - timeElapsedInRender; + // if (timeLeftInMS > 0) { + try { + //ILogger.instance().logInfo("**** sleeping OpenGL thread for " + timeLeftInMS + "ms"); + Thread.sleep(timeLeftInMS); + } catch (final InterruptedException e) { + } + // } + _startTime = System.currentTimeMillis(); + } else { + _startTime = now; } - catch (final InterruptedException e) { - } - // } - _startTime = System.currentTimeMillis(); - } - else { - _startTime = now; } - } diff --git a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MBuilder_Android.java b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MBuilder_Android.java index 0b37e865a0..d2e3d8a883 100644 --- a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MBuilder_Android.java +++ b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MBuilder_Android.java @@ -19,11 +19,10 @@ public class G3MBuilder_Android private final G3MWidget_Android _nativeWidget; - - public G3MBuilder_Android(final Context context) { + public G3MBuilder_Android(final Context context, final boolean noFPSReduction) { super(); - _nativeWidget = new G3MWidget_Android(context); + _nativeWidget = new G3MWidget_Android(context, noFPSReduction); } @@ -91,6 +90,4 @@ protected IDownloader createDefaultDownloader() { getStorage(), // saveInBackground); } - - } diff --git a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MWidget_Android.java b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MWidget_Android.java index 2adfed7374..2f20b36831 100644 --- a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MWidget_Android.java +++ b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/G3MWidget_Android.java @@ -61,7 +61,7 @@ public final class G3MWidget_Android private final OnDoubleTapListener _doubleTapListener; private final GestureDetector _gestureDetector; private Thread _openGLThread = null; - + private final boolean _noFPSReduction; public G3MWidget_Android(final android.content.Context context) { this(context, null); @@ -83,11 +83,22 @@ public final void checkOpenGLThread() { } } + public G3MWidget_Android(final android.content.Context context, + final boolean noFPSReduction) { + this(context, null, noFPSReduction); + } // Needed to create widget from XML layout public G3MWidget_Android(final android.content.Context context, - final AttributeSet attrs) { + final AttributeSet attrs) { + this(context, attrs, false); + } + + public G3MWidget_Android(final android.content.Context context, + final AttributeSet attrs, + final boolean noFPSReduction) { super(context, attrs); + _noFPSReduction = noFPSReduction; initSingletons(); @@ -453,5 +464,7 @@ public G3MContext getG3MContext() { return getG3MWidget().getG3MContext(); } - + public boolean getNoFPSReduction() { + return _noFPSReduction; + } } diff --git a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/SQLiteStorage_Android.java b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/SQLiteStorage_Android.java index 68d57b336c..08405c3dfe 100644 --- a/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/SQLiteStorage_Android.java +++ b/Android/G3MAndroidSDK/src/org/glob3/mobile/specific/SQLiteStorage_Android.java @@ -2,8 +2,13 @@ package org.glob3.mobile.specific; -import java.io.ByteArrayOutputStream; -import java.io.File; +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Log; import org.glob3.mobile.generated.G3MContext; import org.glob3.mobile.generated.GTask; @@ -16,19 +21,23 @@ import org.glob3.mobile.generated.TimeInterval; import org.glob3.mobile.generated.URL; -import android.content.ContentValues; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.util.Log; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.Charset; public final class SQLiteStorage_Android extends IStorage { + private static final long DB_RAW_DATA_EXTERNAL_THRESHOLD = 1024 * 1024; // 1 MiB + private static final String DB_EXTERNAL_TAG = "EXT:"; + private static final Charset UTF8 = Charset.forName("UTF-8"); + private static final String[] COLUMNS = new String[] { "contents", "expiration" }; private static final String SELECTION = "name = ?"; @@ -41,6 +50,7 @@ public final class SQLiteStorage_Android private final BitmapFactory.Options _options; private final byte[] _temp_storage = new byte[128 * 1024]; + private final String _documentsDirectory; private class MySQLiteOpenHelper @@ -81,13 +91,7 @@ public void onUpgrade(final SQLiteDatabase db, private String getPath() { - File f = _androidContext.getExternalCacheDir(); - if ((f == null) || !f.exists()) { - f = _androidContext.getCacheDir(); - } - final String documentsDirectory = f.getAbsolutePath(); - - final File f2 = new File(new File(documentsDirectory), _databaseName); + final File f2 = new File(new File(_documentsDirectory), _databaseName); final String path = f2.getAbsolutePath(); Log.d("SQLiteStorage_Android", "Creating DB in " + path); @@ -98,8 +102,14 @@ private String getPath() { public SQLiteStorage_Android(final String path, final android.content.Context context) { + _androidContext = context; + File f = _androidContext.getExternalCacheDir(); + if ((f == null) || !f.exists()) { + f = _androidContext.getCacheDir(); + } + _documentsDirectory = f.getAbsolutePath(); + _databaseName = path; - _androidContext = context; _dbHelper = new MySQLiteOpenHelper(context, getPath()); _writeDB = _dbHelper.getWritableDatabase(); @@ -135,14 +145,74 @@ public void run(final G3MContext context) { } } + private boolean writeFileToCacheFolder(final String fileName, final byte[] content) { + final File f2 = new File(new File(_documentsDirectory), fileName); + FileOutputStream fout = null; + try { + fout = new FileOutputStream(f2); + fout.write(content); + fout.flush(); + return true; + } catch (FileNotFoundException e) { + e.printStackTrace(); + return false; + } catch (IOException e) { + e.printStackTrace(); + return false; + } finally { + if (fout != null) { + try { + fout.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + } + + private byte[] readFileFromCacheFolder(final String fileName) { + final File f2 = new File(new File(_documentsDirectory), fileName); + FileInputStream fin = null; + try { + fin = new FileInputStream(f2); + final int avail = fin.available(); + if (avail == 0) { + return null; + } + final byte[] r = new byte[avail]; + if (fin.read(r) != avail) { + return null; + } + return r; + } catch (FileNotFoundException e) { + e.printStackTrace(); + return null; + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + if (fin != null) { + try { + fin.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + } + } private synchronized void rawSave(final String table, final String name, final byte[] contents, final TimeInterval timeToExpires) { + + final boolean external = contents.length >= DB_RAW_DATA_EXTERNAL_THRESHOLD; + final String externalFileName = external ? (table + name).hashCode() + ".raw_cache" : null; + final ContentValues values = new ContentValues(3); values.put("name", name); - values.put("contents", contents); + values.put("contents", + external ? (DB_EXTERNAL_TAG + externalFileName).getBytes(UTF8) : contents); final long expiration = System.currentTimeMillis() + timeToExpires.milliseconds(); values.put("expiration", Long.toString(expiration)); @@ -150,6 +220,13 @@ private synchronized void rawSave(final String table, ILogger.instance().logError("SQL: Can't write " + table + " in database \"%s\". _writeDB not available\n", _databaseName); } else { + if (external) { + if (!writeFileToCacheFolder(externalFileName, contents)) { + ILogger.instance().logError("SQL: Can't write external file for cache \"%s\"\n", name); + return; + } + } + final long rowID = _writeDB.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE); if (rowID == -1) { ILogger.instance().logError("SQL: Can't write " + table + " in database \"%s\"\n", _databaseName); @@ -165,7 +242,7 @@ public IByteBufferResult readBuffer(final URL url, boolean expired = false; final String name = url._path; - final Cursor cursor = _readDB.query( // + final Cursor cursor = _readDB.query( // "buffer2", // COLUMNS, // SELECTION, // @@ -180,7 +257,23 @@ public IByteBufferResult readBuffer(final URL url, expired = (expirationInterval <= System.currentTimeMillis()); if (!expired || readExpired) { - buffer = new ByteBuffer_Android(data); + if (data.length > DB_EXTERNAL_TAG.length()) { + final String extTag = new String(data, 0, DB_EXTERNAL_TAG.length(), UTF8); + if (!extTag.isEmpty() && DB_EXTERNAL_TAG.equalsIgnoreCase(extTag)) { + final byte[] cacheData = readFileFromCacheFolder( + new String(data, DB_EXTERNAL_TAG.length(), data.length - DB_EXTERNAL_TAG.length(), UTF8)); + if (cacheData == null || cacheData.length == 0) { + ILogger.instance() + .logError("SQL: Can't read external file for cache \"%s\"\n", name); + cursor.close(); + return new IByteBufferResult(null, expired); + } + buffer = new ByteBuffer_Android(cacheData); + } + } + if (buffer == null) { + buffer = new ByteBuffer_Android(data); + } } } cursor.close(); @@ -251,8 +344,27 @@ public IImageResult readImage(final URL url, expired = (expirationInterval <= System.currentTimeMillis()); if (!expired || readExpired) { + Bitmap bitmap = null; + + if (data.length > DB_EXTERNAL_TAG.length()) { + final String extTag = new String(data, 0, DB_EXTERNAL_TAG.length(), UTF8); + if (!extTag.isEmpty() && DB_EXTERNAL_TAG.equalsIgnoreCase(extTag)) { + final byte[] cacheData = readFileFromCacheFolder( + new String(data, DB_EXTERNAL_TAG.length(), data.length - DB_EXTERNAL_TAG.length(), UTF8)); + if (cacheData == null || cacheData.length == 0) { + ILogger.instance() + .logError("SQL: Can't read external file for cache \"%s\"\n", name); + cursor.close(); + return new IImageResult(null, expired); + } + bitmap = BitmapFactory.decodeByteArray(cacheData, 0, cacheData.length, _options); + } + } + // final long start = System.currentTimeMillis(); - final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, _options); + if (bitmap == null) { + bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, _options); + } // ILogger.instance().logInfo("CACHE: Bitmap parsed in " + (System.currentTimeMillis() - start) + "ms"); if (bitmap == null) { diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/CustomShaderGLFeature.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/CustomShaderGLFeature.java new file mode 100644 index 0000000000..ab9b6596e9 --- /dev/null +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/CustomShaderGLFeature.java @@ -0,0 +1,32 @@ +package org.glob3.mobile.generated; +public abstract class CustomShaderGLFeature extends GLFeature +{ + private boolean _initializedShader; + + public void dispose() + { + super.dispose(); + } + + protected abstract boolean onInitializeShader(GL gl, GLState state, GPUProgram linkedProgram); + protected abstract void onAfterApplyShaderOnGPU(GL gl, GLState state, GPUProgram linkedProgram); + + public CustomShaderGLFeature(String shaderName) + { + super(GLFeatureGroupName.NO_GROUP, GLFeatureID.GLF_CUSTOM_SHADER); + _initializedShader = false; + _values.setCustomShaderName(shaderName); + } + + public final void afterApplyOnGPU(GL gl, GLState state, GPUProgram linkedProgram) + { + if (!_initializedShader) + { + _initializedShader = onInitializeShader(gl, state, linkedProgram); + } + if (_initializedShader) + { + onAfterApplyShaderOnGPU(gl, state, linkedProgram); + } + } +} \ No newline at end of file diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLFeatureID.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLFeatureID.java index 8db3b31fcf..f0c9654471 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLFeatureID.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLFeatureID.java @@ -36,7 +36,8 @@ public enum GLFeatureID GLF_DIRECTION_LIGTH, GLF_VERTEX_NORMAL, GLF_MODEL_VIEW, - GLF_BLENDING_MODE; + GLF_BLENDING_MODE, + GLF_CUSTOM_SHADER; public int getValue() { diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLState.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLState.java index 5fbac1d5cb..fff0d86fae 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLState.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GLState.java @@ -172,10 +172,16 @@ public final void applyOnGPU(GL gl, GPUProgramManager progManager) GLFeatureGroup.applyToAllGroups(accumulatedFeatures, _valuesSet, _globalState); - final int uniformsCode = _valuesSet.getUniformsCode(); - final int attributesCode = _valuesSet.getAttributesCode(); - - _linkedProgram = progManager.getProgram(gl, uniformsCode, attributesCode); //GET RETAINED REFERENCE + if (_valuesSet.hasCustomShader()) + { + _linkedProgram = progManager.getProgram(gl, _valuesSet.getCustomShaderName()); + } + else + { + final int uniformsCode = _valuesSet.getUniformsCode(); + final int attributesCode = _valuesSet.getAttributesCode(); + _linkedProgram = progManager.getProgram(gl, uniformsCode, attributesCode); //GET RETAINED REFERENCE + } } if (_valuesSet == null || _globalState == null) @@ -193,6 +199,12 @@ public final void applyOnGPU(GL gl, GPUProgramManager progManager) _linkedProgram.applyChanges(gl); + CustomShaderGLFeature feature = (CustomShaderGLFeature) getGLFeatureIncludingAncestors(GLFeatureID.GLF_CUSTOM_SHADER); + if (feature != null) + { + feature.afterApplyOnGPU(gl, this, _linkedProgram); + } + //prog->onUnused(); //Uncomment to check that all GPUProgramStates are complete } else @@ -245,6 +257,24 @@ public final GLFeature getGLFeature(GLFeatureID id) return null; } + public final GLFeature getGLFeatureIncludingAncestors(GLFeatureID id) + { + final int size = _features.size(); + for (int i = 0; i < size; i++) + { + GLFeature f = _features.get(i); + if (f._id == id) + { + return f; + } + } + if (_parentGLState != null) + { + return _parentGLState.getGLFeatureIncludingAncestors(id); + } + + return null; + } public final GLFeatureSet getGLFeatures(GLFeatureID id) { diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttribute.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttribute.java index b56f623ded..db46348c1c 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttribute.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttribute.java @@ -96,6 +96,10 @@ public final void set(GPUAttributeValue v) public void applyChanges(GL gl) { + if (_key == GPUAttributeKey.UNRECOGNIZED_ATTRIBUTE) + { + return; + } if (_value == null) { if (_enabled) diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttributeValueUnrecognized.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttributeValueUnrecognized.java new file mode 100644 index 0000000000..d20f415b1e --- /dev/null +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttributeValueUnrecognized.java @@ -0,0 +1,53 @@ +package org.glob3.mobile.generated; +//////// + +/////////// +public class GPUAttributeValueUnrecognized extends GPUAttributeValue +{ + public void dispose() + { + super.dispose(); + } + + public GPUAttributeValueUnrecognized(int type) + { + super(type, 0, 0, 0, 0, false); + } + + public final void setAttribute(GL gl, int id) + { + } + + public final boolean isEquals(GPUAttributeValue v) + { + return (v._type == _type); + } + + public final GPUAttributeValue shallowCopy() + { + return new GPUAttributeValueUnrecognized(_type); + } + + public final String description() + { + return "Attribute Unrecognized."; + } + + public final GPUAttributeValue copyOrCreate(GPUAttributeValue oldAtt) + { + if (oldAtt == null) + { + return new GPUAttributeValueUnrecognized(_type); + } + if (oldAtt._enabled) + { + oldAtt._release(); + return new GPUAttributeValueUnrecognized(_type); + } + return oldAtt; + } + +} +//////// + + diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttributeVec4Float.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttributeVec4Float.java index 68cba07db6..56493ec855 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttributeVec4Float.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUAttributeVec4Float.java @@ -10,7 +10,4 @@ public GPUAttributeVec4Float(String name, int id) { super(name, id, GLType.glFloat(), 4); } -} -//////// - - +} \ No newline at end of file diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgram.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgram.java index 4ed37c94cf..662aee84ef 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgram.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgram.java @@ -20,6 +20,8 @@ public class GPUProgram private int _nReferences; //Number of items that reference this Program + private boolean _referencedByName; + private boolean compileShader(GL gl, int shader, String source) { boolean result = gl.compileShader(shader, source); @@ -83,10 +85,17 @@ private void getVariables(GL gl) GPUUniform u = gl.getActiveUniform(this, i); if (u != null) { - _uniforms[u.getIndex()] = u; - - final int code = GPUVariable.getUniformCode(u._key); - _uniformsCode = _uniformsCode | code; + if (u._key == GPUUniformKey.UNRECOGNIZED_UNIFORM) + { + u.set(new GPUUniformValueUnrecognized(u._type)); + } + else + { + _uniforms[u.getIndex()] = u; + + final int code = GPUVariable.getUniformCode(u._key); + _uniformsCode = _uniformsCode | code; + } } _createdUniforms[counter++] = u; //Adding to created uniforms array @@ -104,10 +113,17 @@ private void getVariables(GL gl) GPUAttribute a = gl.getActiveAttribute(this, i); if (a != null) { - _attributes[a.getIndex()] = a; - - final int code = GPUVariable.getAttributeCode(a._key); - _attributesCode = _attributesCode | code; + if (a._key == GPUAttributeKey.UNRECOGNIZED_ATTRIBUTE) + { + a.set(new GPUAttributeValueUnrecognized(a._type)); + } + else + { + _attributes[a.getIndex()] = a; + + final int code = GPUVariable.getAttributeCode(a._key); + _attributesCode = _attributesCode | code; + } } _createdAttributes[counter++] = a; @@ -163,7 +179,7 @@ public void dispose() } } - public static GPUProgram createProgram(GL gl, String name, String vertexSource, String fragmentSource) + public static GPUProgram createProgram(GL gl, String name, String vertexSource, String fragmentSource, boolean referencedByName) { GPUProgram p = new GPUProgram(); @@ -171,6 +187,7 @@ public static GPUProgram createProgram(GL gl, String name, String vertexSource, p._name = name; p._programID = gl.createProgram(); p._gl = gl; + p._referencedByName = referencedByName; // compile vertex shader int vertexShader = gl.createShader(ShaderType.VERTEX_SHADER); @@ -205,7 +222,7 @@ public static GPUProgram createProgram(GL gl, String name, String vertexSource, // link program if (!p.linkProgram(gl)) { - ILogger.instance().logError("GPUProgram: ERROR linking graphic program\n"); + ILogger.instance().logError("GPUProgram: ERROR linking graphic program: %s\n", name); p.deleteShader(gl, vertexShader); p.deleteShader(gl, fragmentShader); p.deleteProgram(gl, p); @@ -221,7 +238,7 @@ public static GPUProgram createProgram(GL gl, String name, String vertexSource, if (gl.getError() != GLError.noError()) { - ILogger.instance().logError("Error while compiling program"); + ILogger.instance().logError("Error while compiling program: %s\n", name); } return p; @@ -246,6 +263,11 @@ public final int getGPUUniformsNumber() return _nUniforms; } + public final boolean isReferencedByName() + { + return _referencedByName; + } + public final GPUUniform getGPUUniform(String name) { final int key = GPUVariable.getUniformKey(name).getValue(); diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgramManager.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgramManager.java index 6f83c6ac67..f5b495d703 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgramManager.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUProgramManager.java @@ -31,6 +31,11 @@ private GPUProgram getCompiledProgram(String name) } private GPUProgram compileProgramWithName(GL gl, String name) + { + return compileProgramWithName(gl, name, false); + } + + private GPUProgram compileProgramWithName(GL gl, String name, boolean referencedByName) { GPUProgram prog = getCompiledProgram(name); @@ -41,7 +46,7 @@ private GPUProgram compileProgramWithName(GL gl, String name) //Compile new Program if (ps != null) { - prog = GPUProgram.createProgram(gl, ps._name, ps._vertexSource, ps._fragmentSource); + prog = GPUProgram.createProgram(gl, ps._name, ps._vertexSource, ps._fragmentSource, referencedByName); ///#warning DETECT COLISSION WITH COLLECTION OF GPUPROGRAM if (prog == null) { @@ -166,7 +171,7 @@ private GPUProgram getNewProgram(GL gl, int uniformsCode, int attributesCode) private GPUProgram getCompiledProgram(int uniformsCode, int attributesCode) { for (final GPUProgram p : _programs.values()) { - if ((p.getUniformsCode() == uniformsCode) && (p.getAttributesCode() == attributesCode)) { + if ((p.getUniformsCode() == uniformsCode) && (p.getAttributesCode() == attributesCode) && !p.isReferencedByName()) { return p; } } @@ -207,6 +212,30 @@ public final GPUProgram getProgram(GL gl, int uniformsCode, int attributesCode) return p; } + public final GPUProgram getProgram(GL gl, String name) + { + GPUProgram p = getCompiledProgram(name); + if (p == null) + { + p = compileProgramWithName(gl, name, true); + if (p == null) + { + ILogger.instance().logError("Problem at compiling program."); + return null; + } + + if (!name.equals(p.getName())) + { + ///#warning GIVE MORE DETAIL + ILogger.instance().logError("New compiled program does not match GL state."); + } + } + + p.addReference(); + + return p; + } + public final void removeUnused() { final java.util.Iterator> iterator = _programs.entrySet().iterator(); diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUUniform.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUUniform.java index c038974471..04d8b9618c 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUUniform.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUUniform.java @@ -82,6 +82,10 @@ public final void set(GPUUniformValue v) public final void applyChanges(GL gl) { + if (_key == GPUUniformKey.UNRECOGNIZED_UNIFORM) + { + return; + } if (_dirty) { _value.setUniform(gl, _id); diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUUniformValueUnrecognized.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUUniformValueUnrecognized.java new file mode 100644 index 0000000000..0df4a73bc6 --- /dev/null +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUUniformValueUnrecognized.java @@ -0,0 +1,27 @@ +package org.glob3.mobile.generated; +public class GPUUniformValueUnrecognized extends GPUUniformValue +{ + public void dispose() + { + super.dispose(); + } + + public GPUUniformValueUnrecognized(int type) + { + super(type); + } + + public final void setUniform(GL gl, IGLUniformID id) + { + } + + public final boolean isEquals(GPUUniformValue v) + { + return getType() == v.getType(); + } + + public final String description() + { + return "Uniform Unrecognized"; + } +} \ No newline at end of file diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUVariableValueSet.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUVariableValueSet.java index 8a6ac7f355..6c36d512bb 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUVariableValueSet.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/GPUVariableValueSet.java @@ -26,6 +26,7 @@ public class GPUVariableValueSet private int _uniformsCode; private int _attributeCode; + private String _customShaderName; //C++ TO JAVA CONVERTER TODO TASK: The implementation of the following method could not be found: // GPUVariableValueSet(GPUVariableValueSet that); @@ -39,6 +40,7 @@ public GPUVariableValueSet() _highestUniformKey = 0; _uniformsCode = 0; _attributeCode = 0; + _customShaderName = ""; for (int i = 0; i < 32; i++) { _uniformValues[i] = null; @@ -166,6 +168,11 @@ public final void combineWith(GPUVariableValueSet vs) } } } + + if (vs.hasCustomShader()) + { + _customShaderName = vs.getCustomShaderName(); + } } public final void applyValuesToProgram(GPUProgram prog) @@ -219,4 +226,18 @@ public final int getAttributesCode() return _attributeCode; } + public final boolean hasCustomShader() + { + return (_customShaderName.length() != 0); + } + + public final void setCustomShaderName(String name) + { + _customShaderName = name; + } + + public final String getCustomShaderName() + { + return _customShaderName; + } } \ No newline at end of file diff --git a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/Vector2D.java b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/Vector2D.java index daf879eaf7..757e0cfd2c 100644 --- a/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/Vector2D.java +++ b/Commons/G3MSharedSDK/src/org/glob3/mobile/generated/Vector2D.java @@ -156,7 +156,7 @@ public String toString() { public static Vector2D intersectionOfTwoLines(Vector2D p1, Vector2D r1, Vector2D p2, Vector2D r2) { - //u = (p2 − p1) × r1 / (r1 × r2) + //u = (p2 - p1) × r1 / (r1 × r2) //out = p2 + u x r2 double u = ((p2.sub(p1)).dot(r1)) / r1.dot(r2); diff --git a/iOS/G3MiOSSDK/Commons/GL/GLFeature.hpp b/iOS/G3MiOSSDK/Commons/GL/GLFeature.hpp index 3779a1e433..d69375fd21 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GLFeature.hpp +++ b/iOS/G3MiOSSDK/Commons/GL/GLFeature.hpp @@ -33,7 +33,8 @@ enum GLFeatureID{ GLF_DIRECTION_LIGTH, GLF_VERTEX_NORMAL, GLF_MODEL_VIEW, - GLF_BLENDING_MODE + GLF_BLENDING_MODE, + GLF_CUSTOM_SHADER }; class GLFeature: public RCObject { @@ -578,5 +579,35 @@ class VertexNormalGLFeature: public GLFeature { void applyOnGlobalGLState(GLGlobalState* state) const {} }; +class CustomShaderGLFeature: public GLFeature { +private: + bool _initializedShader; + + ~CustomShaderGLFeature() { +#ifdef JAVA_CODE + super.dispose(); +#endif + } + +protected: + virtual bool onInitializeShader(const GL* gl, const GLState* state, const GPUProgram* linkedProgram)=0; + virtual void onAfterApplyShaderOnGPU(const GL* gl, const GLState* state, const GPUProgram* linkedProgram)=0; + +public: + CustomShaderGLFeature(const std::string shaderName) : + GLFeature(NO_GROUP, GLF_CUSTOM_SHADER), _initializedShader(false) + { + _values->setCustomShaderName(shaderName); + } + + void afterApplyOnGPU(const GL* gl, const GLState* state, const GPUProgram* linkedProgram) { + if (!_initializedShader) { + _initializedShader = onInitializeShader(gl, state, linkedProgram); + } + if (_initializedShader) { + onAfterApplyShaderOnGPU(gl, state, linkedProgram); + } + } +}; #endif diff --git a/iOS/G3MiOSSDK/Commons/GL/GLState.cpp b/iOS/G3MiOSSDK/Commons/GL/GLState.cpp index 6cc346172c..76c3a11124 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GLState.cpp +++ b/iOS/G3MiOSSDK/Commons/GL/GLState.cpp @@ -111,10 +111,13 @@ void GLState::applyOnGPU(GL* gl, GPUProgramManager& progManager) const { GLFeatureGroup::applyToAllGroups(*accumulatedFeatures, *_valuesSet, *_globalState); - const int uniformsCode = _valuesSet->getUniformsCode(); - const int attributesCode = _valuesSet->getAttributesCode(); - - _linkedProgram = progManager.getProgram(gl, uniformsCode, attributesCode); //GET RETAINED REFERENCE + if (_valuesSet->hasCustomShader()) { + _linkedProgram = progManager.getProgram(gl, _valuesSet->getCustomShaderName()); + } else { + const int uniformsCode = _valuesSet->getUniformsCode(); + const int attributesCode = _valuesSet->getAttributesCode(); + _linkedProgram = progManager.getProgram(gl, uniformsCode, attributesCode); //GET RETAINED REFERENCE + } } if (_valuesSet == NULL || _globalState == NULL) { @@ -130,6 +133,11 @@ void GLState::applyOnGPU(GL* gl, GPUProgramManager& progManager) const { _linkedProgram->applyChanges(gl); + CustomShaderGLFeature* feature = (CustomShaderGLFeature*) getGLFeatureIncludingAncestors(GLF_CUSTOM_SHADER); + if (feature) { + feature->afterApplyOnGPU(gl, this, _linkedProgram); + } + //prog->onUnused(); //Uncomment to check that all GPUProgramStates are complete } else { @@ -164,6 +172,21 @@ GLFeature* GLState::getGLFeature(GLFeatureID id) const { return NULL; } +GLFeature* GLState::getGLFeatureIncludingAncestors(GLFeatureID id) const { + const int size = _features->size(); + for (int i = 0; i < size; i++) { + GLFeature* f = _features->get(i); + if (f->_id == id) { + return f; + } + } + if (_parentGLState != NULL) { + return _parentGLState->getGLFeatureIncludingAncestors(id); + } + + return NULL; +} + GLFeatureSet* GLState::getGLFeatures(GLFeatureID id) const { GLFeatureSet* features = new GLFeatureSet(); const int size = _features->size(); diff --git a/iOS/G3MiOSSDK/Commons/GL/GLState.hpp b/iOS/G3MiOSSDK/Commons/GL/GLState.hpp index 7bed995fe9..4c113b300a 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GLState.hpp +++ b/iOS/G3MiOSSDK/Commons/GL/GLState.hpp @@ -81,7 +81,8 @@ class GLState: public RCObject { int getNumberOfGLFeatures() const; GLFeature* getGLFeature(GLFeatureID id) const; - + GLFeature* getGLFeatureIncludingAncestors(GLFeatureID id) const; + GLFeatureSet* getGLFeatures(GLFeatureID id) const; }; diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUAttribute.hpp b/iOS/G3MiOSSDK/Commons/GL/GPUAttribute.hpp index 641fae3ffe..aba0b05b36 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUAttribute.hpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUAttribute.hpp @@ -171,6 +171,9 @@ class GPUAttribute: public GPUVariable { virtual void applyChanges(GL* gl) { + if (_key == UNRECOGNIZED_ATTRIBUTE) { + return; + } if (_value == NULL) { if (_enabled) { ILogger::instance()->logError("Attribute " + _name + " was not set but it is enabled."); @@ -412,4 +415,46 @@ class GPUAttributeVec4Float: public GPUAttribute{ }; //////// +/////////// +class GPUAttributeValueUnrecognized : public GPUAttributeValue { +private: + ~GPUAttributeValueUnrecognized() { +#ifdef JAVA_CODE + super.dispose(); +#endif + } + +public: + GPUAttributeValueUnrecognized(const int type) : + GPUAttributeValue(type, 0, 0, 0, 0, false) {} + + void setAttribute(GL* gl, const int id) const { + } + + bool isEquals(const GPUAttributeValue* v) const { + return (v->_type == _type); + } + + GPUAttributeValue* shallowCopy() const { + return new GPUAttributeValueUnrecognized(_type); + } + + std::string description() const { + return "Attribute Unrecognized."; + } + + GPUAttributeValue* copyOrCreate(GPUAttributeValue* oldAtt) const { + if (oldAtt == NULL) { + return new GPUAttributeValueUnrecognized(_type); + } + if (oldAtt->_enabled) { + oldAtt->_release(); + return new GPUAttributeValueUnrecognized(_type); + } + return oldAtt; + } + +}; +//////// + #endif diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUProgram.cpp b/iOS/G3MiOSSDK/Commons/GL/GPUProgram.cpp index adda1a0326..b7852ff57d 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUProgram.cpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUProgram.cpp @@ -16,13 +16,15 @@ GPUProgram* GPUProgram::createProgram(GL* gl, const std::string& name, const std::string& vertexSource, - const std::string& fragmentSource) { + const std::string& fragmentSource, + const bool referencedByName) { GPUProgram* p = new GPUProgram(); p->_name = name; p->_programID = gl->createProgram(); p->_gl = gl; + p->_referencedByName = referencedByName; // compile vertex shader int vertexShader= gl->createShader(VERTEX_SHADER); @@ -54,7 +56,7 @@ GPUProgram* GPUProgram::createProgram(GL* gl, // link program if (!p->linkProgram(gl)) { - ILogger::instance()->logError("GPUProgram: ERROR linking graphic program\n"); + ILogger::instance()->logError("GPUProgram: ERROR linking graphic program: %s\n", name.c_str()); p->deleteShader(gl, vertexShader); p->deleteShader(gl, fragmentShader); p->deleteProgram(gl, p); @@ -69,7 +71,7 @@ GPUProgram* GPUProgram::createProgram(GL* gl, p->getVariables(gl); if (gl->getError() != GLError::noError()) { - ILogger::instance()->logError("Error while compiling program"); + ILogger::instance()->logError("Error while compiling program: %s\n", name.c_str()); } return p; @@ -154,10 +156,14 @@ void GPUProgram::getVariables(GL* gl) { for (int i = 0; i < _nUniforms; i++) { GPUUniform* u = gl->getActiveUniform(this, i); if (u != NULL) { - _uniforms[u->getIndex()] = u; - - const int code = GPUVariable::getUniformCode(u->_key); - _uniformsCode = _uniformsCode | code; + if (u->_key == UNRECOGNIZED_UNIFORM) { + u->set(new GPUUniformValueUnrecognized(u->_type)); + } else { + _uniforms[u->getIndex()] = u; + + const int code = GPUVariable::getUniformCode(u->_key); + _uniformsCode = _uniformsCode | code; + } } _createdUniforms[counter++] = u; //Adding to created uniforms array @@ -173,10 +179,14 @@ void GPUProgram::getVariables(GL* gl) { for (int i = 0; i < _nAttributes; i++) { GPUAttribute* a = gl->getActiveAttribute(this, i); if (a != NULL) { - _attributes[a->getIndex()] = a; - - const int code = GPUVariable::getAttributeCode(a->_key); - _attributesCode = _attributesCode | code; + if (a->_key == UNRECOGNIZED_ATTRIBUTE) { + a->set(new GPUAttributeValueUnrecognized(a->_type)); + } else { + _attributes[a->getIndex()] = a; + + const int code = GPUVariable::getAttributeCode(a->_key); + _attributesCode = _attributesCode | code; + } } _createdAttributes[counter++] = a; diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUProgram.hpp b/iOS/G3MiOSSDK/Commons/GL/GPUProgram.hpp index 0f47c0fe41..1349edc80e 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUProgram.hpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUProgram.hpp @@ -56,6 +56,8 @@ class GPUProgram{ int _nReferences; //Number of items that reference this Program + bool _referencedByName; + bool compileShader(GL* gl, int shader, const std::string& source) const; bool linkProgram(GL* gl) const; void deleteShader(GL* gl, int shader) const; @@ -85,7 +87,8 @@ class GPUProgram{ static GPUProgram* createProgram(GL* gl, const std::string& name, const std::string& vertexSource, - const std::string& fragmentSource); + const std::string& fragmentSource, + const bool referencedByName); std::string getName() const { return _name;} @@ -94,6 +97,8 @@ class GPUProgram{ int getGPUAttributesNumber() const { return _nAttributes;} int getGPUUniformsNumber() const { return _nUniforms;} + bool isReferencedByName() const { return _referencedByName; } + GPUUniform* getGPUUniform(const std::string& name) const; GPUAttribute* getGPUAttribute(const std::string& name) const; diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.cpp b/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.cpp index 8be5030184..72076c6872 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.cpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.cpp @@ -41,6 +41,26 @@ GPUProgram* GPUProgramManager::getProgram(GL* gl, int uniformsCode, int attribut return p; } +GPUProgram* GPUProgramManager::getProgram(GL* gl, const std::string& name) { + GPUProgram* p = getCompiledProgram(name); + if (p == NULL) { + p = compileProgramWithName(gl, name, true); + if (p == NULL) { + ILogger::instance()->logError("Problem at compiling program."); + return NULL; + } + + if (p->getName() != name) { + //#warning GIVE MORE DETAIL + ILogger::instance()->logError("New compiled program does not match GL state."); + } + } + + p->addReference(); + + return p; +} + GPUProgram* GPUProgramManager::getNewProgram(GL* gl, int uniformsCode, int attributesCode) { const bool texture = GPUVariable::hasAttribute(attributesCode, TEXTURE_COORDS); @@ -133,14 +153,14 @@ GPUProgram* GPUProgramManager::getCompiledProgram(int uniformsCode, int attribut for (std::map::iterator it = _programs.begin(); it != _programs.end(); ++it) { //#warning GPUProgram getUniformsCode avoid call GPUProgram* p = it->second; - if (p->getUniformsCode() == uniformsCode && p->getAttributesCode() == attributesCode) { + if (p->getUniformsCode() == uniformsCode && p->getAttributesCode() == attributesCode && !p->isReferencedByName()) { return p; } } #endif #ifdef JAVA_CODE for (final GPUProgram p : _programs.values()) { - if ((p.getUniformsCode() == uniformsCode) && (p.getAttributesCode() == attributesCode)) { + if ((p.getUniformsCode() == uniformsCode) && (p.getAttributesCode() == attributesCode) && !p.isReferencedByName()) { return p; } } @@ -150,6 +170,12 @@ GPUProgram* GPUProgramManager::getCompiledProgram(int uniformsCode, int attribut GPUProgram* GPUProgramManager::compileProgramWithName(GL* gl, const std::string& name) { + return compileProgramWithName(gl, name, false); +} + +GPUProgram* GPUProgramManager::compileProgramWithName(GL* gl, + const std::string& name, + bool referencedByName) { GPUProgram* prog = getCompiledProgram(name); if (prog == NULL) { @@ -160,7 +186,8 @@ GPUProgram* GPUProgramManager::compileProgramWithName(GL* gl, prog = GPUProgram::createProgram(gl, ps->_name, ps->_vertexSource, - ps->_fragmentSource); + ps->_fragmentSource, + referencedByName); //#warning DETECT COLISSION WITH COLLECTION OF GPUPROGRAM if (prog == NULL) { ILogger::instance()->logError("Problem at creating program named %s.", name.c_str()); diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.hpp b/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.hpp index 970350046c..01f06b92f7 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.hpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUProgramManager.hpp @@ -26,6 +26,8 @@ class GPUProgramManager { GPUProgram* compileProgramWithName(GL* gl, const std::string& name); + GPUProgram* compileProgramWithName(GL* gl, const std::string& name, bool referencedByName); + GPUProgram* getNewProgram(GL* gl, int uniformsCode, int attributesCode); GPUProgram* getCompiledProgram(int uniformsCode, int attributesCode); @@ -37,6 +39,8 @@ class GPUProgramManager { GPUProgram* getProgram(GL* gl, int uniformsCode, int attributesCode); + GPUProgram* getProgram(GL* gl, const std::string& name); + void removeUnused(); }; diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUUniform.cpp b/iOS/G3MiOSSDK/Commons/GL/GPUUniform.cpp index 775cafab28..fc8a584e09 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUUniform.cpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUUniform.cpp @@ -17,6 +17,9 @@ void GPUUniform::unset() { } void GPUUniform::applyChanges(GL* gl) { + if (_key == UNRECOGNIZED_UNIFORM) { + return; + } if (_dirty) { _value->setUniform(gl, _id); _dirty = false; diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUUniform.hpp b/iOS/G3MiOSSDK/Commons/GL/GPUUniform.hpp index 56013dd169..970d1659e3 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUUniform.hpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUUniform.hpp @@ -578,4 +578,27 @@ class GPUUniformValueInt : public GPUUniformValue { } }; +class GPUUniformValueUnrecognized : public GPUUniformValue { +private: + ~GPUUniformValueUnrecognized() { +#ifdef JAVA_CODE + super.dispose(); +#endif + } + +public: + GPUUniformValueUnrecognized(const int type):GPUUniformValue(type) {} + + void setUniform(GL* gl, const IGLUniformID* id) const { + } + + bool isEquals(const GPUUniformValue* v) const { + return getType() == v->getType(); + } + + std::string description() const { + return "Uniform Unrecognized"; + } +}; + #endif diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.cpp b/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.cpp index 07f8bd0913..300ade1319 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.cpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.cpp @@ -28,6 +28,10 @@ void GPUVariableValueSet::combineWith(const GPUVariableValueSet* vs) { } } } + + if (vs->hasCustomShader()) { + _customShaderName = vs->getCustomShaderName(); + } } void GPUVariableValueSet::applyValuesToProgram(GPUProgram* prog) const { diff --git a/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.hpp b/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.hpp index 5f52ff80de..c4e3f70a17 100644 --- a/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.hpp +++ b/iOS/G3MiOSSDK/Commons/GL/GPUVariableValueSet.hpp @@ -21,6 +21,7 @@ class GPUVariableValueSet { mutable int _uniformsCode; mutable int _attributeCode; + mutable std::string _customShaderName; GPUVariableValueSet(const GPUVariableValueSet& that); GPUVariableValueSet& operator=(const GPUVariableValueSet& that); @@ -31,7 +32,8 @@ class GPUVariableValueSet { _highestAttributeKey(0), _highestUniformKey(0), _uniformsCode(0), - _attributeCode(0) { + _attributeCode(0), + _customShaderName("") { for (int i = 0; i < 32; i++) { _uniformValues[i] = NULL; _attributeValues[i] = NULL; @@ -133,6 +135,17 @@ class GPUVariableValueSet { int getAttributesCode() const; + bool hasCustomShader() const { + return (_customShaderName.length() != 0); + } + + void setCustomShaderName(const std::string& name) { + _customShaderName = name; + } + + const std::string getCustomShaderName() const { + return _customShaderName; + } }; #endif diff --git a/iOS/G3MiOSSDK/Commons/Geometry/Vector2D.cpp b/iOS/G3MiOSSDK/Commons/Geometry/Vector2D.cpp index a41d1ce047..878409ac7f 100644 --- a/iOS/G3MiOSSDK/Commons/Geometry/Vector2D.cpp +++ b/iOS/G3MiOSSDK/Commons/Geometry/Vector2D.cpp @@ -32,7 +32,7 @@ const std::string Vector2D::description() const { Vector2D Vector2D::intersectionOfTwoLines(const Vector2D& p1, const Vector2D& r1, const Vector2D& p2, const Vector2D& r2) { - //u = (p2 − p1) × r1 / (r1 × r2) + //u = (p2 - p1) × r1 / (r1 × r2) //out = p2 + u x r2 double u = ((p2.sub(p1)).dot(r1)) / r1.dot(r2);