From d4468870031253ed6ce18f6031f1feb014743152 Mon Sep 17 00:00:00 2001 From: XProger Date: Thu, 9 Mar 2017 04:40:15 +0300 Subject: [PATCH] #23 shader cache load/save for binary shaders --- src/cache.h | 2 +- src/core.h | 26 ++++++- .../org.eclipse.cdt.codan.core.prefs | 72 ------------------- .../.settings/org.eclipse.jdt.core.prefs | 4 -- src/platform/android/AndroidManifest.xml | 12 ++-- src/platform/android/jni/main.cpp | 25 ++++--- .../org/xproger/openlara/MainActivity.java | 11 +-- src/platform/web/main.cpp | 5 ++ src/platform/win/main.cpp | 9 +++ src/shader.h | 65 +++++++++++++++-- src/utils.h | 45 +++++++++--- 11 files changed, 164 insertions(+), 112 deletions(-) delete mode 100644 src/platform/android/.settings/org.eclipse.cdt.codan.core.prefs delete mode 100644 src/platform/android/.settings/org.eclipse.jdt.core.prefs diff --git a/src/cache.h b/src/cache.h index f07ea92..99cbe78 100644 --- a/src/cache.h +++ b/src/cache.h @@ -91,7 +91,7 @@ struct ShaderCache { } Shader* compile(Core::Pass pass, Shader::Type type, bool caustics = false, bool alphaTest = false, bool clipPlane = false) { - char def[255], ext[255]; + char def[1024], ext[255]; ext[0] = 0; if (Core::support.shadowSampler) { #ifdef MOBILE diff --git a/src/core.h b/src/core.h index 50bc854..6679915 100644 --- a/src/core.h +++ b/src/core.h @@ -30,6 +30,13 @@ #define glGenVertexArrays glGenVertexArraysOES #define glDeleteVertexArrays glDeleteVertexArraysOES #define glBindVertexArray glBindVertexArrayOES + + #define PFNGLGETPROGRAMBINARYPROC PFNGLGETPROGRAMBINARYOESPROC + #define PFNGLPROGRAMBINARYPROC PFNGLPROGRAMBINARYOESPROC + #define glGetProgramBinary glGetProgramBinaryOES + #define glProgramBinary glProgramBinaryOES + + #define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES #elif __linux__ #define LINUX 1 #include @@ -59,6 +66,9 @@ #define GL_RGBA32F GL_RGBA #define GL_RGBA16F GL_RGBA #define GL_HALF_FLOAT GL_HALF_FLOAT_OES + + #define glGetProgramBinary(...) 0 + #define glProgramBinary(...) 0 #endif #include "utils.h" @@ -116,6 +126,7 @@ PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; + PFNGLGETPROGRAMIVPROC glGetProgramiv; // Render to texture PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; @@ -135,6 +146,8 @@ PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; PFNGLBINDVERTEXARRAYPROC glBindVertexArray; + PFNGLGETPROGRAMBINARYPROC glGetProgramBinary; + PFNGLPROGRAMBINARYPROC glProgramBinary; #endif #ifdef MOBILE @@ -215,6 +228,7 @@ namespace Core { bool texNPOT; bool texFloat, texFloatLinear; bool texHalf, texHalfLinear; + bool shaderBinary; } support; } @@ -270,6 +284,7 @@ namespace Core { GetProcOGL(glEnableVertexAttribArray); GetProcOGL(glDisableVertexAttribArray); GetProcOGL(glVertexAttribPointer); + GetProcOGL(glGetProgramiv); GetProcOGL(glGenFramebuffers); GetProcOGL(glBindFramebuffer); @@ -293,10 +308,14 @@ namespace Core { GetProcOGL(glGenVertexArrays); GetProcOGL(glDeleteVertexArrays); GetProcOGL(glBindVertexArray); + GetProcOGL(glGetProgramBinary); + GetProcOGL(glProgramBinary); #endif char *ext = (char*)glGetString(GL_EXTENSIONS); - //LOG("%s\n", ext); +// LOG("%s\n", ext); + + support.shaderBinary = extSupport(ext, "_program_binary"); support.VAO = extSupport(ext, "_vertex_array_object"); support.depthTexture = extSupport(ext, "_depth_texture"); support.shadowSampler = extSupport(ext, "_shadow_samplers") || extSupport(ext, "GL_ARB_shadow"); @@ -311,8 +330,9 @@ namespace Core { LOG("Vendor : %s\n", vendor); LOG("Renderer : %s\n", glGetString(GL_RENDERER)); LOG("Version : %s\n", glGetString(GL_VERSION)); - - LOG("supports:\n"); + LOG("cache : %s\n", Stream::cacheDir); + LOG("supports :\n"); + LOG(" binary shaders : %s\n", support.shaderBinary ? "true" : "false"); LOG(" vertex arrays : %s\n", support.VAO ? "true" : "false"); LOG(" depth texture : %s\n", support.depthTexture ? "true" : "false"); LOG(" shadow sampler : %s\n", support.shadowSampler ? "true" : "false"); diff --git a/src/platform/android/.settings/org.eclipse.cdt.codan.core.prefs b/src/platform/android/.settings/org.eclipse.cdt.codan.core.prefs deleted file mode 100644 index 4cc82b1..0000000 --- a/src/platform/android/.settings/org.eclipse.cdt.codan.core.prefs +++ /dev/null @@ -1,72 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.cdt.codan.checkers.errnoreturn=-Warning -org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} -org.eclipse.cdt.codan.checkers.errreturnvalue=-Error -org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.nocommentinside=-Error -org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.nolinecomment=-Error -org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.checkers.noreturn=-Error -org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false} -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error -org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error -org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=-Error -org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false} -org.eclipse.cdt.codan.internal.checkers.CatchByReference=-Warning -org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error -org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=-Warning -org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true} -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error -org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error -org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error -org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error -org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info -org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error -org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error -org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()} -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false} -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false} -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true} -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=-Warning -org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")} -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error -org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} -useParentScope=false diff --git a/src/platform/android/.settings/org.eclipse.jdt.core.prefs b/src/platform/android/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index b080d2d..0000000 --- a/src/platform/android/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.source=1.6 diff --git a/src/platform/android/AndroidManifest.xml b/src/platform/android/AndroidManifest.xml index 9061603..078e3ae 100644 --- a/src/platform/android/AndroidManifest.xml +++ b/src/platform/android/AndroidManifest.xml @@ -8,16 +8,20 @@ + - + + + android:label="@string/app_name"> diff --git a/src/platform/android/jni/main.cpp b/src/platform/android/jni/main.cpp index ab167fc..f2b1ed3 100644 --- a/src/platform/android/jni/main.cpp +++ b/src/platform/android/jni/main.cpp @@ -17,23 +17,30 @@ extern "C" { int lastTime, fpsTime, fps; -JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeInit(JNIEnv* env, jobject obj, jstring packName, jint levelOffset, jint musicOffset) { - LOG("native init"); - const char* pack = env->GetStringUTFChars(packName, NULL); - Stream *level = new Stream(pack); - Stream *music = new Stream(pack); +char Stream::cacheDir[255]; +char Stream::contentDir[255]; + +JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeInit(JNIEnv* env, jobject obj, jstring packName, jstring cacheDir, jint levelOffset, jint musicOffset) { + const char* str; + + Stream::contentDir[0] = Stream::cacheDir[0] = 0; + str = env->GetStringUTFChars(cacheDir, NULL); + strcat(Stream::cacheDir, str); + env->ReleaseStringUTFChars(cacheDir, str); + + str = env->GetStringUTFChars(packName, NULL); + Stream *level = new Stream(str); + Stream *music = new Stream(str); + env->ReleaseStringUTFChars(packName, str); + level->seek(levelOffset); music->seek(musicOffset); - env->ReleaseStringUTFChars(packName, pack); - LOG("game init"); Game::init(level, music); - LOG("done"); lastTime = getTime(); fpsTime = lastTime + 1000; fps = 0; - LOG("init"); } JNIEXPORT void JNICALL Java_org_xproger_openlara_Wrapper_nativeFree(JNIEnv* env) { diff --git a/src/platform/android/src/org/xproger/openlara/MainActivity.java b/src/platform/android/src/org/xproger/openlara/MainActivity.java index 29634a9..8ae0d7e 100644 --- a/src/platform/android/src/org/xproger/openlara/MainActivity.java +++ b/src/platform/android/src/org/xproger/openlara/MainActivity.java @@ -61,7 +61,7 @@ public class MainActivity extends Activity implements OnTouchListener, OnGeneric AssetFileDescriptor fLevel = this.getResources().openRawResourceFd(R.raw.level2); AssetFileDescriptor fMusic = this.getResources().openRawResourceFd(R.raw.music); - wrapper.onCreate(packName, (int)fLevel.getStartOffset(), (int)fMusic.getStartOffset()); + wrapper.onCreate(packName, getCacheDir().getAbsolutePath() + "/", (int)fLevel.getStartOffset(), (int)fMusic.getStartOffset()); } catch (Exception e) { e.printStackTrace(); finish(); @@ -165,6 +165,7 @@ public class MainActivity extends Activity implements OnTouchListener, OnGeneric static { System.loadLibrary("game"); +// System.load("/storage/emulated/0/libMGD.so"); } } @@ -232,7 +233,7 @@ class Touch { } class Wrapper implements Renderer { - public static native void nativeInit(String packName, int levelOffset, int musicOffset); + public static native void nativeInit(String packName, String cacheDir, int levelOffset, int musicOffset); public static native void nativeFree(); public static native void nativeReset(); public static native void nativeResize(int w, int h); @@ -243,13 +244,15 @@ class Wrapper implements Renderer { public Boolean ready = false; private String packName; + private String cacheDir; private int levelOffset; private int musicOffset; private ArrayList touch = new ArrayList(); private Sound sound; - public void onCreate(String packName, int levelOffset, int musicOffset) { + public void onCreate(String packName, String cacheDir, int levelOffset, int musicOffset) { this.packName = packName; + this.cacheDir = cacheDir; this.levelOffset = levelOffset; this.musicOffset = musicOffset; @@ -298,7 +301,7 @@ class Wrapper implements Renderer { @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { if (!ready) { - nativeInit(packName, levelOffset, musicOffset); + nativeInit(packName, cacheDir, levelOffset, musicOffset); sound.play(); ready = true; } diff --git a/src/platform/web/main.cpp b/src/platform/web/main.cpp index 61cf4a7..a924b53 100644 --- a/src/platform/web/main.cpp +++ b/src/platform/web/main.cpp @@ -265,7 +265,12 @@ EM_BOOL mouseCallback(int eventType, const EmscriptenMouseEvent *e, void *userDa return 1; } +char Stream::cacheDir[255]; +char Stream::contentDir[255]; + int main() { + Stream::contentDir[0] = Stream::cacheDir[0] = 0; + initGL(); emscripten_set_keydown_callback(0, 0, 1, keyCallback); diff --git a/src/platform/win/main.cpp b/src/platform/win/main.cpp index 8d0ad1f..532a500 100644 --- a/src/platform/win/main.cpp +++ b/src/platform/win/main.cpp @@ -312,6 +312,9 @@ void freeGL(HGLRC hRC) { wglDeleteContext(hRC); } +char Stream::cacheDir[255]; +char Stream::contentDir[255]; + #ifdef _DEBUG int main(int argc, char** argv) { _CrtMemState _ms; @@ -324,6 +327,12 @@ int main(int argc, char** argv) { //#else //int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { #endif + Stream::contentDir[0] = Stream::cacheDir[0] = 0; + + strcat(Stream::cacheDir, getenv("APPDATA")); + strcat(Stream::cacheDir, "\\OpenLara\\"); + CreateDirectory(Stream::cacheDir, NULL); + RECT r = { 0, 0, 1280, 720 }; AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false); diff --git a/src/shader.h b/src/shader.h index c7cf2a0..d1ebfab 100644 --- a/src/shader.h +++ b/src/shader.h @@ -23,7 +23,35 @@ struct Shader { MAX = 5 }; - Shader(const char *text, const char *defines = "") { + Shader(const char *source, const char *defines = "") { + char fileName[255]; + + // generate shader file path + if (Core::support.shaderBinary) { + uint32 hash = fnv32(defines, strlen(defines), fnv32(source, strlen(source))); + sprintf(fileName, "%s%08X.xsh", Stream::cacheDir, hash); + } + + ID = glCreateProgram(); + + if (!(Core::support.shaderBinary && linkBinary(fileName))) // try to load cached shader + if (linkSource(source, defines) && Core::support.shaderBinary) { // compile shader from source and dump it into cache + #ifndef __EMSCRIPTEN__ + GLenum format, size; + glGetProgramiv(ID, GL_PROGRAM_BINARY_LENGTH, (GLsizei*)&size); + char *data = new char[8 + size]; + glGetProgramBinary(ID, size, NULL, &format, &data[8]); + *(int*)(&data[0]) = format; + *(int*)(&data[4]) = size; + Stream::write(fileName, data, 8 + size); + delete[] data; + #endif + } + + init(); + } + + bool linkSource(const char *text, const char *defines = "") { #ifdef MOBILE #define GLSL_DEFINE "" #define GLSL_VERT "" @@ -42,7 +70,6 @@ struct Shader { GLchar info[256]; - ID = glCreateProgram(); for (int i = 0; i < 2; i++) { GLuint obj = glCreateShader(type[i]); glShaderSource(obj, 3, code[i], NULL); @@ -63,6 +90,36 @@ struct Shader { glGetProgramInfoLog(ID, sizeof(info), NULL, info); if (info[0]) LOG("! program: %s\n", info); + return checkLink(); + } + + bool linkBinary(const char *fileName) { + if (!Stream::fileExists(fileName)) + return false; + + GLenum size, format; + Stream stream(fileName); + stream.read(format); + stream.read(size); + char *data = new char[size]; + stream.raw(data, size); + glProgramBinary(ID, format, data, size); + delete[] data; + + return checkLink(); + } + + bool checkLink() { + GLint success; + glGetProgramiv(ID, GL_LINK_STATUS, &success); + return success != 0; + } + + virtual ~Shader() { + glDeleteProgram(ID); + } + + void init() { bind(); for (int st = 0; st < sMAX; st++) glUniform1iv(glGetUniformLocation(ID, (GLchar*)SamplerName[st]), 1, &st); @@ -71,10 +128,6 @@ struct Shader { uID[ut] = glGetUniformLocation(ID, (GLchar*)UniformName[ut]); } - virtual ~Shader() { - glDeleteProgram(ID); - } - void bind() { if (Core::active.shader != this) { Core::active.shader = this; diff --git a/src/utils.h b/src/utils.h index e78b62f..0172135 100644 --- a/src/utils.h +++ b/src/utils.h @@ -120,6 +120,12 @@ int nextPow2(uint32 x) { return x; } +uint32 fnv32(const char *data, int32 size, uint32 hash = 0x811c9dc5) { + for (int i = 0; i < size; i++) + hash = (hash ^ data[i]) * 0x01000193; + return hash; +} + struct vec2 { float x, y; vec2() {} @@ -717,6 +723,9 @@ struct Box { }; struct Stream { + static char cacheDir[255]; + static char contentDir[255]; + FILE *f; const char *data; int size, pos; @@ -724,16 +733,18 @@ struct Stream { Stream(const void *data, int size) : f(NULL), data((char*)data), size(size), pos(0) {} Stream(const char *name) : data(NULL), size(-1), pos(0) { - #ifdef __APPLE__ - extern char *contentPath; - int len = strlen(contentPath); - strcat(contentPath, name); - f = fopen(contentPath, "rb"); - contentPath[len] = '\0'; - #else - f = fopen(name, "rb"); - #endif + if (contentDir[0]) { + char path[255]; + path[0] = 0; + strcat(path, contentDir); + strcat(path, name); + f = fopen(path, "rb"); + } else + f = fopen(name, "rb"); + if (!f) LOG("error loading file \"%s\"\n", name); + ASSERT(f != NULL); + fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, 0, SEEK_SET); @@ -743,6 +754,22 @@ struct Stream { if (f) fclose(f); } + static bool fileExists(const char *name) { + FILE *f = fopen(name, "rb"); + if (!f) + return false; + else + fclose(f); + return true; + } + + static void write(const char *name, const void *data, int size) { + FILE *f = fopen(name, "wb"); + if (!f) return; + fwrite(data, size, 1, f); + fclose(f); + } + void setPos(int pos) { this->pos = pos; if (f) fseek(f, pos, SEEK_SET);