diff --git a/examples/pxScene2d/src/pxResource.cpp b/examples/pxScene2d/src/pxResource.cpp index 55f7d542e3..bbc9f52fac 100644 --- a/examples/pxScene2d/src/pxResource.cpp +++ b/examples/pxScene2d/src/pxResource.cpp @@ -858,7 +858,7 @@ void pxResource::processDownloadedResource(rtFileDownloadRequest* fileDownloadRe setLoadStatus("httpStatusCode",(uint32_t)fileDownloadRequest->httpStatusCode()); if (gUIThreadQueue) { - gUIThreadQueue->addTask(pxResource::onDownloadCanceledUI, this, (void*)"reject"); + gUIThreadQueue->addTask(onDownloadCanceledUI, this, (void*)"reject"); } } else if (fileDownloadRequest->downloadStatusCode() == 0 && @@ -901,7 +901,7 @@ void pxResource::processDownloadedResource(rtFileDownloadRequest* fileDownloadRe // TODO review overall flow and organization if (gUIThreadQueue) { - gUIThreadQueue->addTask(pxResource::onDownloadCompleteUI, this, (void*)"reject"); + gUIThreadQueue->addTask(onDownloadCompleteUI, this, (void*)"reject"); } } else if (result == PX_RESOURCE_LOAD_SUCCESS) @@ -916,7 +916,7 @@ void pxResource::processDownloadedResource(rtFileDownloadRequest* fileDownloadRe // TODO review overall flow and organization if (gUIThreadQueue) { - gUIThreadQueue->addTask(pxResource::onDownloadCompleteUI, this, (void*)"resolve"); + gUIThreadQueue->addTask(onDownloadCompleteUI, this, (void*)"resolve"); } } } @@ -933,7 +933,7 @@ void pxResource::processDownloadedResource(rtFileDownloadRequest* fileDownloadRe // TODO review overall flow and organization if (gUIThreadQueue) { - gUIThreadQueue->addTask(pxResource::onDownloadCompleteUI, this, (void*)"reject"); + gUIThreadQueue->addTask(onDownloadCompleteUI, this, (void*)"reject"); } } } diff --git a/examples/pxScene2d/src/pxShaderResource.cpp b/examples/pxScene2d/src/pxShaderResource.cpp index d4033575a4..44c5ddb7da 100644 --- a/examples/pxScene2d/src/pxShaderResource.cpp +++ b/examples/pxScene2d/src/pxShaderResource.cpp @@ -63,7 +63,10 @@ pxShaderResource::~pxShaderResource() void pxShaderResource::onInit() { - postlink(); + if(mProgram != -1) + { + postlink(); + } if( mInitialized) return; @@ -94,18 +97,30 @@ void pxShaderResource::setupResource() const char* vtxCode = mVertexSrc.length() > 0 ? (const char*) mVertexSrc.data() : vShaderText; // or use "default" Vertex shader + // COMPILE SHADER PROGRAM + // COMPILE SHADER PROGRAM + // COMPILE SHADER PROGRAM + if(shaderProgram::initShader( vtxCode, (const char*) mFragmentSrc.data() ) != RT_OK) { rtLogError("FATAL: Shader error: %s \n", mCompilation.cString() ); setLoadStatus("glError", mCompilation.cString() ); + setLoadStatus("statusCode",PX_RESOURCE_STATUS_DECODE_FAILURE); - gUIThreadQueue->addTask(onDownloadCanceledUI, this, (void*)"reject"); + if (gUIThreadQueue) + { + AddRef(); // async + gUIThreadQueue->addTask(onDownloadCanceledUI, this, (void*)"reject"); + } - rtValue nullValue; - mReady.send("reject", nullValue ); + mReady.send("reject", this ); } + // COMPILE SHADER PROGRAM + // COMPILE SHADER PROGRAM + // COMPILE SHADER PROGRAM + double stopDecodeTime = pxMilliseconds(); setLoadStatus("decodeTimeMs", static_cast(stopDecodeTime-startDecodeTime)); } @@ -243,193 +258,208 @@ rtError pxShaderResource::setUniforms(rtObjectRef o) rtValue keyVal; if (keys->Get(i, &keyVal) == RT_OK && !keyVal.isEmpty()) { - setFunc_t setFunc = NULL; - UniformType_t typeEnum = UniformType_Unknown; - rtString name = keyVal.toString(); rtString type = o.get(name); - if(name == "u_time") - { - mIsRealTime = true; - } - else - if(type == "int") - { - setFunc = pxShaderResource::setUniform1i; - typeEnum = UniformType_Int; - } - else - if(type == "float") - { - setFunc = pxShaderResource::setUniform1f; - typeEnum = UniformType_Float; - } - else - if(type == "ivec2") - { - setFunc = pxShaderResource::setUniform2iv; - typeEnum = UniformType_iVec2; - } - else - if(type == "ivec3") - { - setFunc = pxShaderResource::setUniform3iv; - typeEnum = UniformType_iVec3; - } - else - if(type == "ivec4") - { - setFunc = pxShaderResource::setUniform4iv; - typeEnum = UniformType_iVec4; - } - else - if(type == "vec2") - { - setFunc = pxShaderResource::setUniform2fv; - typeEnum = UniformType_Vec2; - } - else - if(type == "vec3") - { - setFunc = pxShaderResource::setUniform3fv; - typeEnum = UniformType_Vec3; - } - else - if(type == "vec4") - { - setFunc = pxShaderResource::setUniform4fv; - typeEnum = UniformType_Vec4; - } - else - if(type == "sampler2D") - { - if(name == "s_texture") - { - mNeedsFbo = true; - } - setFunc = (mSamplerCount == 3) ? pxShaderResource::bindTexture3 : - (mSamplerCount == 4) ? pxShaderResource::bindTexture4 : - (mSamplerCount == 5) ? pxShaderResource::bindTexture5 : NULL; - - typeEnum = UniformType_Sampler2D; - - mSamplerCount++; - } - - mUniform_map[name] = { name, typeEnum, (GLint) -1, rtValue(), false, setFunc }; // ADD TO MAP + addUniform(name, type); // ADD UNIFORM } }//FOR return RT_OK; } -void pxShaderResource::loadResourceFromFile() +rtError pxShaderResource::addUniform(const rtString &name, const rtString &type) { - init(); + setFunc_t setFunc = NULL; + UniformType_t typeEnum = UniformType_Unknown; - rtError loadFrgShader = RT_FAIL; + if(name.isEmpty() || type.isEmpty()) + { + rtLogError("Bad args ... empty !"); + return RT_FAIL; + } - if(mVertexUrl.beginsWith("data:text/plain,")) + if(name == "u_time") { - mVertexSrc.init( (const uint8_t* ) mVertexUrl.substring(16).cString(), - mVertexUrl.byteLength() - 16); + mIsRealTime = true; } - if(mFragmentUrl.beginsWith("data:text/plain,")) + else + if(type == "int") { - mFragmentSrc.init( (const uint8_t* ) mFragmentUrl.substring(16).cString(), - mFragmentUrl.byteLength() - 16); + setFunc = pxShaderResource::setUniform1i; + typeEnum = UniformType_Int; } - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - do + else + if(type == "float") + { + setFunc = pxShaderResource::setUniform1f; + typeEnum = UniformType_Float; + } + else + if(type == "ivec2") + { + setFunc = pxShaderResource::setUniform2iv; + typeEnum = UniformType_iVec2; + } + else + if(type == "ivec3") + { + setFunc = pxShaderResource::setUniform3iv; + typeEnum = UniformType_iVec3; + } + else + if(type == "ivec4") + { + setFunc = pxShaderResource::setUniform4iv; + typeEnum = UniformType_iVec4; + } + else + if(type == "vec2") + { + setFunc = pxShaderResource::setUniform2fv; + typeEnum = UniformType_Vec2; + } + else + if(type == "vec3") + { + setFunc = pxShaderResource::setUniform3fv; + typeEnum = UniformType_Vec3; + } + else + if(type == "vec4") + { + setFunc = pxShaderResource::setUniform4fv; + typeEnum = UniformType_Vec4; + } + else + if(type == "sampler2D") { - if (mFragmentSrc.length() != 0) + if(name == "s_texture") { - // We have FRAGMENT SHADER source already... - loadFrgShader = RT_OK; - break; + mNeedsFbo = true; } + setFunc = (mSamplerCount == 3) ? pxShaderResource::bindTexture3 : + (mSamplerCount == 4) ? pxShaderResource::bindTexture4 : + (mSamplerCount == 5) ? pxShaderResource::bindTexture5 : NULL; - bool isFrgFILE = ( mFragmentUrl.beginsWith("file://") || mFragmentUrl.beginsWith("FILE://") ); - rtString pathFrg = mFragmentUrl; + typeEnum = UniformType_Sampler2D; - if(isFrgFILE) - { - pathFrg.init( (const char* ) mFragmentUrl.substring(7).cString(), - mFragmentUrl.byteLength() - 7); - } + mSamplerCount++; + } + else + { + return RT_FAIL; // unknown type + } - loadFrgShader = rtLoadFile( pathFrg, mFragmentSrc); - if (loadFrgShader == RT_OK) - break; + mUniform_map[name] = { name, typeEnum, (GLint) -1, rtValue(), false, setFunc }; // ADD TO MAP - if (rtIsPathAbsolute(pathFrg)) - break; + return RT_OK; +} - rtModuleDirs *dirs = rtModuleDirs::instance(); +rtError pxShaderResource::loadShaderSource(rtString url, rtData &source) +{ + if (url.length() == 0) + { + // Bad URL... + rtLogWarn("Bad URL for SHADER: zero length. "); + return RT_FAIL; + } - for (rtModuleDirs::iter it = dirs->iterator(); it.first != it.second; it.first++) - { - if (rtLoadFile(rtConcatenatePath(*it.first, pathFrg.cString()).c_str(), mFragmentSrc) == RT_OK) - { - loadFrgShader = RT_OK; - break; - } - } - } while(0); + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // Remove (optional) FILE:// protocol prefix... + // + bool isFILE = ( url.beginsWith("file://") || url.beginsWith("FILE://") ); + if (isFILE == false && url.beginsWith("/") == false) + { + rtLogError("SHADER url is NOT a local file."); + return RT_FAIL; + } + + rtString path = url; + if(isFILE) + { + path.init( (const char* ) url.substring(7).cString(), + url.byteLength() - 7); + } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // Load the Shader source code... + // + if (rtLoadFile( path, source) == RT_OK) + return RT_OK; - rtError loadVtxShader = RT_FAIL; + if (rtIsPathAbsolute(path)) + return RT_OK;; + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // Resolve path & Load the Shader source code... + // + rtModuleDirs *dirs = rtModuleDirs::instance(); - do + for (rtModuleDirs::iter it = dirs->iterator(); it.first != it.second; it.first++) { - if (mVertexSrc.length() != 0) + if (rtLoadFile(rtConcatenatePath(*it.first, path.cString()).c_str(), source) == RT_OK) { - // We have VERTEX SHADER source already... - loadVtxShader = RT_OK; - break; + return RT_OK;; } + } + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (mVertexSrc.length() == 0) - { - //Use the Default VERTEX SHADER source... - loadVtxShader = RT_OK; - break; - } + rtLogError("Failed to load SHADER: %s ", path.cString() ); + return RT_FAIL; +} - bool isVtxFILE = ( mVertexUrl.beginsWith("file://") || mVertexUrl.beginsWith("FILE://") ); +void pxShaderResource::loadResourceFromFile() +{ + init(); - rtString pathVtx = mVertexUrl; + rtError loadFrgShader = RT_FAIL; + rtError loadVtxShader = RT_FAIL; - if(isVtxFILE) - { - pathVtx.init( (const char* ) mVertexUrl.substring(7).cString(), - mVertexUrl.byteLength() - 7); - } + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // FRAGMENT SHADER + // + if(mFragmentUrl.beginsWith("data:text/plain,")) + { + mFragmentSrc.init( (const uint8_t* ) mFragmentUrl.substring(16).cString(), + mFragmentUrl.byteLength() - 16); - loadVtxShader = rtLoadFile(pathVtx, mVertexSrc); - if (loadVtxShader == RT_OK) - break; + loadFrgShader = RT_OK; // it's a DATA URL !!! + } + else + { + loadFrgShader = loadShaderSource(mFragmentUrl, mFragmentSrc); + } - if (rtIsPathAbsolute(pathVtx)) - break; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // + // VERTEX SHADER + // + if(mVertexUrl.beginsWith("data:text/plain,")) + { + mVertexSrc.init( (const uint8_t* ) mVertexUrl.substring(16).cString(), + mVertexUrl.byteLength() - 16); - rtModuleDirs *dirs = rtModuleDirs::instance(); + loadVtxShader = RT_OK; // it's a DATA URL !!! + } + else + { + loadVtxShader = loadShaderSource(mVertexUrl, mVertexSrc); - for (rtModuleDirs::iter it = dirs->iterator(); it.first != it.second; it.first++) + if(mVertexSrc.length() == 0) { - if (rtLoadFile(rtConcatenatePath(*it.first, pathVtx.cString()).c_str(), mVertexSrc) == RT_OK) - { - loadVtxShader = RT_OK; - break; - } + loadVtxShader = RT_OK; // use Default VERTEX SHADER source... } - } while(0); + } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + setLoadStatus("statusCode",0); + // CREATE SHADER PROGRAMS if (loadFrgShader == RT_OK && loadVtxShader == RT_OK) @@ -439,7 +469,7 @@ void pxShaderResource::loadResourceFromFile() else { loadFrgShader = RT_RESOURCE_NOT_FOUND; - rtLogError("Could not load FRAGMENT shader file %s.", mFragmentUrl.cString()); + //rtLogError("Could not load FRAGMENT shader file %s.", mFragmentUrl.cString()); } if ( loadFrgShader != RT_OK) { @@ -464,8 +494,6 @@ void pxShaderResource::loadResourceFromFile() mFragmentSrc.term(); // Dump the source data... mVertexSrc.term(); // Dump the source data... - setLoadStatus("statusCode",0); - if (gUIThreadQueue) { AddRef(); // async @@ -589,14 +617,13 @@ void pxShaderResource::loadResource(rtObjectRef archive, bool reloading) mArchive = arc; } - bool isFrgURL = (mFragmentUrl.beginsWith("http:") || mFragmentUrl.beginsWith("https:") ); - bool isVtxURL = ( mVertexUrl.beginsWith("http:") || mVertexUrl.beginsWith("https:") ); - - bool isFrgDataURL = mFragmentUrl.beginsWith("data:text/plain,"); - //bool isVtxDataURL = mVertexUrl.beginsWith("data:text/plain,"); + bool isFrgURL = (mFragmentUrl.beginsWith("http:") || mFragmentUrl.beginsWith("https:") ); + bool isVtxURL = ( mVertexUrl.beginsWith("http:") || mVertexUrl.beginsWith("https:") ); + bool isFrgDataURL = isFrgURL ? false : mFragmentUrl.beginsWith("data:text/plain,"); + bool isVtxDataURL = isVtxURL ? false : mVertexUrl.beginsWith("data:text/plain,"); // FRAGMENT SHADER - if( isFrgURL && mFragmentSrc.length() == 0) + if( mFragmentSrc.length() == 0 && isFrgURL) { rtFileDownloadRequest* fragRequest; @@ -614,12 +641,10 @@ void pxShaderResource::loadResource(rtObjectRef archive, bool reloading) mDownloadInProgressMutex.unlock(); AddRef(); //ensure this object is not deleted while downloading rtFileDownloader::instance()->addToDownloadQueue(fragRequest); - - return; } // VERTEX SHADER - if (isVtxURL && mVertexSrc.length() == 0) + if (mVertexSrc.length() == 0 && isVtxURL) { rtFileDownloadRequest* vtxRequest; @@ -637,15 +662,15 @@ void pxShaderResource::loadResource(rtObjectRef archive, bool reloading) mDownloadInProgressMutex.unlock(); AddRef(); //ensure this object is not deleted while downloading rtFileDownloader::instance()->addToDownloadQueue(vtxRequest); - - return; } - else if (isFrgDataURL) + + // local FILES or DATA urls. + if( isFrgURL == false || isVtxURL == false ) // Need a download ? { - setLoadStatus("sourceType", "dataurl"); + setLoadStatus("sourceType", (isFrgDataURL || isVtxDataURL)? "dataurl" : "file"); double startResourceSetupTime = pxMilliseconds(); - loadResourceFromFile(); // Detect and Load shaders from URL directly + loadResourceFromFile(); // Local "/" or "FILE" or "DATA":" url's double stopResourceSetupTime = pxMilliseconds(); setLoadStatus("setupTimeMs", static_cast(stopResourceSetupTime-startResourceSetupTime)); @@ -658,22 +683,13 @@ void pxShaderResource::loadResource(rtObjectRef archive, bool reloading) double stopResourceSetupTime = pxMilliseconds(); setLoadStatus("setupTimeMs", static_cast(stopResourceSetupTime-startResourceSetupTime)); } - else - { - setLoadStatus("sourceType", "file"); - double startResourceSetupTime = pxMilliseconds(); - loadResourceFromFile(); - double stopResourceSetupTime = pxMilliseconds(); - setLoadStatus("setupTimeMs", static_cast(stopResourceSetupTime-startResourceSetupTime)); - } } uint32_t pxShaderResource::loadResourceData(rtFileDownloadRequest* fileDownloadRequest) { double startDecodeTime = pxMilliseconds(); - rtError decodeResult = RT_OK; // TODO: create shaderProgram //pxLoadImage(fileDownloadRequest->downloadedData(), - // fileDownloadRequest->downloadedDataSize(), - // imageOffscreen, init_w, init_h, init_sx, init_sy) + rtError decodeResult = RT_OK; + if(fileDownloadRequest->tag() == "frg") { mFragmentSrc.init( (const uint8_t*) fileDownloadRequest->downloadedData(), @@ -691,11 +707,7 @@ uint32_t pxShaderResource::loadResourceData(rtFileDownloadRequest* fileDownloadR { setLoadStatus("decodeTimeMs", static_cast(stopDecodeTime-startDecodeTime)); -#ifdef ENABLE_BACKGROUND_TEXTURE_CREATION - return PX_RESOURCE_LOAD_WAIT; -#else return PX_RESOURCE_LOAD_SUCCESS; -#endif //ENABLE_BACKGROUND_TEXTURE_CREATION } return PX_RESOURCE_LOAD_FAIL; diff --git a/examples/pxScene2d/src/pxShaderResource.h b/examples/pxScene2d/src/pxShaderResource.h index 49b2bbb2ca..05e7136f61 100644 --- a/examples/pxScene2d/src/pxShaderResource.h +++ b/examples/pxScene2d/src/pxShaderResource.h @@ -89,6 +89,8 @@ class pxShaderResource: public pxResource, public shaderProgram virtual void init(); virtual void onInit(); + rtError addUniform(const rtString &name, const rtString &type); + rtError uniforms(rtObjectRef& o) const; rtError setUniforms(rtObjectRef o); @@ -138,6 +140,8 @@ class pxShaderResource: public pxResource, public shaderProgram static rtError setUniformNfv(int N, const uniformLoc_t &p); // generic setter + rtError loadShaderSource(rtString url, rtData &source); + // Override to do uniform lookups virtual void prelink(); virtual void postlink(); @@ -151,9 +155,6 @@ class pxShaderResource: public pxResource, public shaderProgram int32_t mPasses; int32_t mSamplerCount; -// rtObjectRef mUniforms; -// rtObjectRef mAttributes; - rtString mVertexUrl; rtData mVertexSrc;