diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Samples/SampleFramework/framework/src | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'PhysX_3.4/Samples/SampleFramework/framework/src')
16 files changed, 5071 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/ODBlock.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/ODBlock.cpp new file mode 100644 index 00000000..2e3bd040 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/ODBlock.cpp @@ -0,0 +1,530 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +/*-------------------------------------------------------------*\ +| | +| ODBlock class - object description script | +| | +| Copyright (C) 1999 Adam Moravanszky | +| | +| | +\*-------------------------------------------------------------*/ +/*-Revision----------------------\ +| At: 10/3/99 5:51:37 PM +| +| Changed vector container from +| storing val to refernce. +\-------------------------------*/ +/*-Revision----------------------\ +| At: 5/18/00 9:29:43 PM +| changed static sized indentifiers +| to arbitrary dynamic identifiers. +| +\-------------------------------*/ +/*-Revision----------------------\ +| At: 6/19/02 +| added multiline comments. +| +| +\-------------------------------*/ +/*-Revision----------------------\ +| At: 5/19/03 +| fixed commend bug with +| file > 0xffff chars. +| +\-------------------------------*/ +/*-Revision----------------------\ +| At: 19/10/09 +| removed encryption +| converted to FILE * usage. +| +\-------------------------------*/ +#include "ODBlock.h" +#include "PxTkFile.h" + +const char * ODBlock::lastError = NULL; + + +const char * ODBlock::ODSyntaxError::asString() +{ + static const char unex1[] = "Quote unexpected."; + static const char unex2[] = "Opening brace unexpected."; + static const char unex3[] = "Closing brace unexpected."; + static const char unex4[] = "Literal or semicolon unexpected."; + static const char unex5[] = "Unexpected end of file found."; + static const char encun[] = "Unknown encryption algo code."; + switch (err) + { + case ODSE_UNEX_QUOTE: + return unex1; + case ODSE_UNEX_OBRACE: + return unex2; + case ODSE_UNEX_CBRACE: + return unex3; + case ODSE_UNEX_LITERAL: + return unex4; + case ODSE_UNEX_EOF: + return unex5; + case ODSE_ENC_UNKNOWN: + return encun; + default: + return NULL; + } +} + +static inline bool isNewLine(char c) +{ + return c == '\n' || c == '\r'; +} + +bool ODBlock::loadScript(SampleFramework::File * fp) //loads block from script, including subbocks +{ + int c; + unsigned currindex = 0; + bool bQuote = false; //if we're inside a pair of quotes + identifier[0] = '\0'; + identSize = 0; + bTerminal = true; + termiter = NULL; + bool ignoreWhiteSpace = true; + + State state; + + state = WAIT_IDENT; + + + //0) read possible comments starting with # to end of line + //1) read our identifier. -->forget quotes for now. + + while(!feof(fp)) + { + do + { + c = fgetc(fp); + } + while (ignoreWhiteSpace && ((c == ' ') || (c == '\t') || isNewLine((char)c)) && !feof(fp)); + + if (c == '"') + { + if (state == BLOCK) + { + bTerminal = false; + ungetc(c, fp); + ODBlock * child = new ODBlock(); + addStatement(*child); + if (!child->loadScript(fp)) + return false; + } + else + { + if (state != WAIT_IDENT && state != IDENT) + { + lastError = ODSyntaxError(ODSyntaxError::ODSE_UNEX_QUOTE).asString(); + return false; + } + ignoreWhiteSpace = bQuote; + bQuote = !bQuote; + state = IDENT; + } + } + else + { + if (bQuote) + { + PX_ASSERT(state == IDENT); + //if (currindex >= identSize) + // { + // identSize = 2*currindex + 4; + // char * newi = new char [identSize+1]; + // if (identifier) + // strcpy(newi,identifier); + // delete [] identifier; + // identifier = newi; + // } + identifier[currindex] = (char) c; + identifier[currindex+1] = 0; + currindex++; + } + else + { + switch (c) + { + case '#': + while(!isNewLine((char)fgetc(fp))) ; //read and discard line + break; + case '/': + while(fgetc(fp) != '/') ; //read and discard comment + break; + case '{': + if (state != WAIT_BLOCK && state != IDENT) + { + lastError = ODSyntaxError(ODSyntaxError::ODSE_UNEX_OBRACE).asString();//identifier can be followed by block w/o whitespace inbetween + return false; + } + state = BLOCK; + break; + case '}': + if (state != BLOCK) + { + lastError = ODSyntaxError(ODSyntaxError::ODSE_UNEX_CBRACE).asString(); + return false; + } + return true; + default: + //text + //our identifier? + if (state == BLOCK) + { + bTerminal = false; + ungetc(c, fp); + ODBlock * child = new ODBlock(); + addStatement(*child); + if (!child->loadScript(fp)) + return false; + } + else + { + if (state != WAIT_IDENT && state != IDENT) + { + lastError = ODSyntaxError(ODSyntaxError::ODSE_UNEX_LITERAL).asString(); + return false; + } + if (state == IDENT && c == ';') //terminal ended + return true; + state = IDENT; + //if (currindex >= identSize) + // { + // identSize = 2*currindex + 4; + // char * newi = new char [identSize+1]; + // if (identifier) + // strcpy(newi,identifier); + // delete [] identifier; + // identifier = newi; + // } + identifier[currindex] = (char)c; + identifier[currindex+1] = 0; + currindex++; + } + } + } + } + } + //eof and block didn't close + lastError = ODSyntaxError(ODSyntaxError::ODSE_UNEX_EOF).asString(); + return false; +} + +ODBlock::ODBlock() +{ + //create empty block + identifier[0] = '\0'; + identSize = 0; + bTerminal = true; + termiter = NULL; + subBlocks.reserve(32); +} + +ODBlock::~ODBlock() +{ + //free the contents + ODBlockList::Iterator i; + for (i = subBlocks.begin(); i != subBlocks.end(); ++i) + delete (*i); + //free the pointers + subBlocks.clear(); + + //delete [] identifier; + identifier[0] = '\0'; + identSize = 0; +} + + +bool ODBlock::saveScript(SampleFramework::File * fp,bool bQuote) +{ + static int tablevel = 1; + static int retVal = 0; + int j; + //save the script in said file should be stream!! + for (j=0; j<tablevel-1; j++) + retVal = fprintf(fp,"\t"); + if (bQuote) + retVal = fprintf(fp,"\""); + if (identifier) + retVal = fprintf(fp, "%s", identifier); + else + retVal = fprintf(fp,"_noname"); + if (bQuote) + retVal = fprintf(fp,"\""); + if (!bTerminal) + { + retVal =fprintf(fp,"\n"); + for (j=0; j<tablevel; j++) + retVal = fprintf(fp,"\t"); + retVal = fprintf(fp,"{\n"); + tablevel ++; + for (physx::PxU32 i = 0; i < subBlocks.size(); ++i) + (subBlocks[i])->saveScript(fp,bQuote); + tablevel --; + for (j=0; j<tablevel; j++) + retVal = fprintf(fp,"\t"); + retVal = fprintf(fp,"}\n"); + } + else + retVal = fprintf(fp,";\n"); + + PX_ASSERT( retVal >= 0 ); + // added this return to make this compile on snc & release + return retVal >= 0; +} + + +const char * ODBlock::ident() +{ + static char noname[] = "_noname"; + if (identifier) + return identifier; + else + return noname; +} + + +bool ODBlock::isTerminal() +{ + return bTerminal; +} + + +void ODBlock::ident(const char * i) +{ + if (!i) return; + strcpy(identifier,i); +} + + +void ODBlock::addStatement(ODBlock &b) +{ + bTerminal = false; + subBlocks.pushBack(&b); +} + +void ODBlock::reset() //prepares to get first immediate terminal child of current block +{ + termiter = subBlocks.begin(); +} + +bool ODBlock::moreTerminals() //returns true if more terminals are available +{ + //skip any nonterminals + while ( (termiter != subBlocks.end()) && !(*termiter)->bTerminal) + ++termiter; + return termiter != subBlocks.end(); //return true if not the end yet +} + +char * ODBlock::nextTerminal() //returns a pointer to the next terminal string. +{ + char * s = (*termiter)->identifier; + ++termiter; + + static char noname[] = "_noname"; + if (s) + return s; + else + return noname; +} + +bool ODBlock::moreSubBlocks() //returns true if more sub blocks are available +{ + return termiter != subBlocks.end(); //return true if not the end yet +} +ODBlock * ODBlock::nextSubBlock() //returns a pointer to the next sub block. +{ + ODBlock * b = (*termiter); + ++termiter; + return b; +} + + +ODBlock * ODBlock::getBlock(const char * ident,bool bRecursiveSearch) //returns block with given identifier, or NULL. +{ + ODBlock * b; + if (identifier && ident && strncmp(identifier,ident,OD_MAXID) == 0) + return this; + else + { + if (bTerminal) + return NULL; + else + { + ODBlockList::Iterator i; + for (i = subBlocks.begin(); i != subBlocks.end(); ++i) + if (bRecursiveSearch) + { + b = (*i)->getBlock(ident,true); + if (b) + return b; + } + else + { + if ((*i)->identifier && ident && strncmp((*i)->identifier,ident,OD_MAXID) == 0) + return (*i); + } + return NULL; + } + } + +} + +// hig level macro functs, return true on success: +bool ODBlock::getBlockInt(const char * ident, int* p, unsigned count) //reads blocks of form: ident{ 123; 123; ... } +{ + ODBlock* temp = getBlock(ident); + if (temp) + { + temp->reset(); + for(; count && temp->moreTerminals(); --count) + if(p) + sscanf(temp->nextTerminal(),"%d", p++); + + return !count; + } + return false; +} + +// hig level macro functs, return true on success: +bool ODBlock::getBlockU32(const char * ident, physx::PxU32* p, unsigned count) //reads blocks of form: ident{ 123;} +{ + ODBlock* temp = getBlock(ident); + if (temp) + { + temp->reset(); + for(; count && temp->moreTerminals(); --count) + if(p) + sscanf(temp->nextTerminal(),"%u", p++); + + return !count; + } + return false; +} + +bool ODBlock::getBlockString(const char * ident, const char ** p) //of form: ident{abcdef;} +{ + ODBlock * temp = getBlock(ident); + if (temp) + { + temp->reset(); + if (temp->moreTerminals()) + { + *p = temp->nextTerminal(); + return true; + } + } + return false; +} +bool ODBlock::getBlockStrings(const char * ident, const char ** p, unsigned numStrings) //of form: ident{abcdef; abcdef;...} +{ + ODBlock * temp= getBlock(ident); + if (temp) + { + temp->reset(); + for (unsigned int n=0; n<numStrings; n++) + { + if (temp->moreTerminals()) + { + p[n] = temp->nextTerminal(); + } + } + } + return false; +} +bool ODBlock::getBlockFloat(const char * ident, float *p) //of form: ident{123.456;} +{ + ODBlock * temp = getBlock(ident); + if (temp) + { + temp->reset(); + if (temp->moreTerminals()) + { + if(p) sscanf(temp->nextTerminal(),"%f",p); + return true; + } + } + return false; +} +bool ODBlock::getBlockFloats(const char * ident, float *p, unsigned numfloats)//form: ident{12.3; 12.3; 12.3; ... }; +{ + ODBlock * temp = getBlock(ident); + if (temp) + { + temp->reset(); + for (unsigned int n=0; n<numfloats; n++) + if (temp->moreTerminals()) sscanf(temp->nextTerminal(),"%f",&(p[n])); + + return true; + } + return false; +} + +bool ODBlock::addBlockFloats(const char * ident, float *f, unsigned numfloats) +{ + char buf[32]; + ODBlock & newBlock = *new ODBlock(); + + addStatement(newBlock); + newBlock.ident(ident); + + for (unsigned i = 0; i < numfloats; i++) + { + ODBlock & floatBlock = *new ODBlock(); + newBlock.addStatement(floatBlock); + + //_gcvt_s(buf, 32, f[i],5); //gcc doesn't support this + sprintf(buf, "%.5f", f[i]); + + floatBlock.ident(buf); + } + return true; +} + +bool ODBlock::addBlockInts(const char * ident, int *f, unsigned numInts) +{ + char buf[32]; + ODBlock & newBlock = *new ODBlock(); + + addStatement(newBlock); + newBlock.ident(ident); + + for (unsigned i = 0; i < numInts; i++) + { + ODBlock & floatBlock = *new ODBlock(); + newBlock.addStatement(floatBlock); + //_itoa_s(f[i], buf, 32, 10); //gcc doesn't support this + sprintf(buf, "%d", f[i]); + floatBlock.ident(buf); + } + return true; +} + diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleApplication.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleApplication.cpp new file mode 100644 index 00000000..bb188f4b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleApplication.cpp @@ -0,0 +1,487 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <PsUtilities.h> +#include <SampleApplication.h> +#include <SampleCommandLine.h> +#include <SampleAssetManager.h> +#include <Renderer.h> +#include <RendererMemoryMacros.h> +#include <SamplePlatform.h> +#include "SampleFrameworkInputEventIds.h" + +#include "PsString.h" +#include "PsFoundation.h" +#include "PsUtilities.h" + +namespace Ps = physx::shdfnd; + +//#define RENDERER_USE_OPENGL_ON_WINDONWS 1 + +#if defined(SMOOTH_CAM) +const float g_smoothCamBaseVel = 6.0f; +const float g_smoothCamFastMul = 4.0f; +const float g_smoothCamPosLerp = 0.4f; + +const float g_smoothCamRotSpeed = 0.005f; +const float g_smoothCamRotLerp = 0.4f; +#endif + +#include "FrameworkFoundation.h" + +using namespace SampleFramework; + +static PxMat44 EulerToMat33(const PxVec3& e) +{ + const float c1 = cosf(e.z); + const float s1 = sinf(e.z); + const float c2 = cosf(e.y); + const float s2 = sinf(e.y); + const float c3 = cosf(e.x); + const float s3 = sinf(e.x); + PxMat44 m; + m.column0 = PxVec4(c1*c2, -s1*c2, s2, 0.0f); + m.column1 = PxVec4((s1*c3)+(c1*s2*s3), (c1*c3)-(s1*s2*s3),-c2*s3, 0.0f); + m.column2 = PxVec4((s1*s3)-(c1*s2*c3), (c1*s3)+(s1*s2*c3), c2*c3, 0.0f); + m.column3 = PxVec4(0,0,0,1); + return m; +} + +static PxVec3 Mat33ToEuler(const PxMat44& m) +{ + const PxF32 epsilon = 0.99999f; + PxVec3 e, x, y, z; + + x = PxVec3(m.column0.x, m.column1.x, m.column2.x); + y = PxVec3(m.column0.y, m.column1.y, m.column2.y); + z = PxVec3(m.column0.z, m.column1.z, m.column2.z); + + if(x.z > epsilon) + { + e.x = PxAtan2(z.y, y.y); + e.y = PxPi * 0.5f; + e.z = 0; + } + else if(x.z < -epsilon) + { + e.x = PxAtan2(z.y, y.y); + e.y = -PxPi * 0.5f; + e.z = 0; + } + else + { + e.x = PxAtan2(-y.z, z.z); + e.y = PxAsin(x.z); + e.z = PxAtan2(-x.y, x.x); + } + return e; +} + +SampleApplication::SampleApplication(const SampleCommandLine &cmdline, const char *assetPathPrefix, PxI32 camMoveButton) : + m_cmdline(cmdline) +, m_disableRendering(false) +, m_rotationSpeedScale(200.0f) +, m_moveSpeedScale(40.0f) +, m_rightStickRotate(false) +, m_rewriteBuffers(false) +{ + m_platform->setCWDToEXE(); + + if (assetPathPrefix) + { + if (!searchForPath(assetPathPrefix, m_assetPathPrefix, PX_ARRAY_SIZE(m_assetPathPrefix), true, 20)) + { + RENDERER_ASSERT(false, "assetPathPrefix could not be found in any of the parent directories!"); + m_assetPathPrefix[0] = 0; + } + } + else + { + RENDERER_ASSERT(assetPathPrefix, "assetPathPrefix must not be NULL (try \"media\" instead)"); + m_assetPathPrefix[0] = 0; + } + + m_renderer = 0; + m_sceneSize = 1.0f; + m_assetManager = 0; + m_timeCounter = 0; + m_camMoveButton = camMoveButton; + +} + +SampleApplication::~SampleApplication(void) +{ + RENDERER_ASSERT(!m_renderer, "Renderer was not released prior to window closure."); + RENDERER_ASSERT(!m_assetManager, "Asset Manager was not released prior to window closure."); + + DELETESINGLE(m_platform); + + clearSearchPaths(); +} + +void SampleApplication::setEyeTransform(const PxMat44& eyeTransform) +{ + m_worldToView.setInverseTransform(eyeTransform); + m_eyeRot = Mat33ToEuler(eyeTransform); +#if defined(SMOOTH_CAM) + m_targetEyePos = m_worldToView.getInverseTransform().getPosition(); + m_targetEyeRot = m_eyeRot; +#endif +} + +void SampleApplication::setEyeTransform(const PxVec3& pos, const PxVec3& rot) +{ + PxMat44 eye; + m_eyeRot = rot; + eye = EulerToMat33(m_eyeRot); + eye.setPosition(pos); +#if defined(SMOOTH_CAM) + m_targetEyePos = pos; + m_targetEyeRot = m_eyeRot; +#endif + + m_worldToView.setInverseTransform(eye); +} + +void SampleApplication::setViewTransform(const PxMat44 &viewTransform) +{ + m_worldToView.setForwardTransform(viewTransform); + m_eyeRot = Mat33ToEuler( m_worldToView.getInverseTransform() ); +#if defined(SMOOTH_CAM) + m_targetEyePos = m_worldToView.getInverseTransform().getPosition(); + m_targetEyeRot = m_eyeRot; +#endif +} + +const PxMat44& SampleApplication::getViewTransform() const +{ + return m_worldToView.getForwardTransform(); +} + +void SampleApplication::onOpen(void) +{ + m_platform->preRendererSetup(); + + char assetDir[1024]; + Ps::strlcpy(assetDir, sizeof(assetDir), m_assetPathPrefix); + Ps::strlcat(assetDir, sizeof(assetDir), "/SampleRenderer/4/"); + + m_eyeRot = PxVec3(0,0,0); + PxMat44 eye = PxMat44(PxIdentity); + const PxVec3 pos = PxVec3(0.0f, 2.0f, 16.0f); + eye.setPosition(pos); + m_worldToView.setInverseTransform(eye); +#if defined(SMOOTH_CAM) + m_targetEyePos = pos; + m_targetEyeRot = m_eyeRot; +#endif + + // default renderer drivers for various platforms... + SampleRenderer::RendererDesc renDesc; + setupRendererDescription(renDesc); +#if defined RENDERER_USE_OPENGL_ON_WINDONWS + renDesc.driver = SampleRenderer::Renderer::DRIVER_OPENGL; +#endif + + // check to see if the user wants to override the renderer driver... + if(m_cmdline.hasSwitch("ogl")) renDesc.driver = SampleRenderer::Renderer::DRIVER_OPENGL; + else if(m_cmdline.hasSwitch("gles2")) renDesc.driver = SampleRenderer::Renderer::DRIVER_GLES2; + else if(m_cmdline.hasSwitch("d3d9")) renDesc.driver = SampleRenderer::Renderer::DRIVER_DIRECT3D9; + else if(m_cmdline.hasSwitch("d3d11")) renDesc.driver = SampleRenderer::Renderer::DRIVER_DIRECT3D11; + else if(m_cmdline.hasSwitch("gcm")) renDesc.driver = SampleRenderer::Renderer::DRIVER_LIBGCM; + else if(m_cmdline.hasSwitch("null")) renDesc.driver = SampleRenderer::Renderer::DRIVER_NULL; + +#if defined(RENDERER_ANDROID) + renDesc.windowHandle = (physx::PxU64)android_window_ptr; +#endif + + m_renderer = SampleRenderer::Renderer::createRenderer(renDesc, assetDir); + m_platform->postRendererSetup(m_renderer); + + m_timeCounter = m_time.getCurrentCounterValue(); + + m_assetManager = new SampleAssetManager(*m_renderer); + addSearchPath(m_assetPathPrefix); + addSearchPath(assetDir); + onInit(); + + // make sure the resize method is called once + if (m_renderer) + { + PxU32 width,height; + m_renderer->getWindowSize(width, height); + onResize(width, height); + } +} + +bool SampleApplication::onClose(void) +{ + onShutdown(); + DELETESINGLE(m_assetManager); + + SAFE_RELEASE(m_renderer); + m_platform->postRendererRelease(); + + return true; +} + +inline float SmoothStepPolynomial( float s ) +{ + if( s <= 0 ) return 0; + if( s >= 1 ) return 1; + return s*s*(3-2*s); +} + +template <typename T> +T SmoothStep( const T& start, const T& end, float s ) +{ + float ss = SmoothStepPolynomial( s ); + return ss * (end - start) + start; +} + +void SampleApplication::onDraw(void) +{ + + if (!getRenderer()) + { + return; + } + + PX_PROFILE_ZONE("OnDraw", 0); + + physx::PxU64 qpc = m_time.getCurrentCounterValue(); + static float sToSeconds = float(m_time.getBootCounterFrequency().mNumerator) / float(m_time.getBootCounterFrequency().mDenominator * m_time.sNumTensOfNanoSecondsInASecond); + float dtime = float(qpc - m_timeCounter) * sToSeconds; + m_lastDTime = dtime; + m_timeCounter = qpc; + PX_ASSERT(dtime > 0); + if(dtime > 0) + { + dtime = tweakElapsedTime(dtime); + + { + PX_PROFILE_ZONE("PreRender", 0); + onTickPreRender(dtime); + } + if(m_renderer) + { + PX_PROFILE_ZONE("onRender", 0); + if(!m_disableRendering) + { + onRender(); + } + } + { + PX_PROFILE_ZONE("onPostRender", 0); + onTickPostRender(dtime); + } + + if(m_renderer && !m_disableRendering) + { + m_rewriteBuffers = m_renderer->swapBuffers(); + } + + // update scene... + + PxMat44 tmp = m_worldToView.getInverseTransform(); + PxMat44 eye = EulerToMat33(m_eyeRot); + eye.column3 = tmp.column3; + + PxVec3* targetParam; +#if defined(SMOOTH_CAM) + const float eyeSpeed = m_sceneSize * g_smoothCamBaseVel * dtime * (getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_SHIFT_SPEED) ? g_smoothCamFastMul : 1.0f); + targetParam = &m_targetEyePos; +#else + const float eyeSpeed = m_sceneSize * 4.0f * dtime * (getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_SHIFT_SPEED) ? 4.0f : 1.0f); + targetParam = &eye.t; +#endif + + const PxVec3 column2 = eye.getBasis(2); + const PxVec3 column0 = eye.getBasis(0); + const PxVec3 column1 = eye.getBasis(1); + + if(getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_MOVE_FORWARD)) + *targetParam -= column2 * eyeSpeed; + if(getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_MOVE_LEFT)) + *targetParam -= column0 * eyeSpeed; + if(getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_MOVE_BACKWARD)) + *targetParam += column2 * eyeSpeed; + if(getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_MOVE_RIGHT)) + *targetParam += column0 * eyeSpeed; + if(getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_MOVE_UP)) + *targetParam += column1 * eyeSpeed; + if(getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_MOVE_DOWN)) + *targetParam -= column1 * eyeSpeed; + + // move forward from gamepad + *targetParam -= column2 * eyeSpeed * getPlatform()->getSampleUserInput()->getAnalogInputEventState(CAMERA_GAMEPAD_MOVE_FORWARD_BACK) * m_moveSpeedScale * dtime; + // strafe from gamepad + *targetParam += column0 * eyeSpeed * getPlatform()->getSampleUserInput()->getAnalogInputEventState(CAMERA_GAMEPAD_MOVE_LEFT_RIGHT) * m_moveSpeedScale* dtime; + +#if defined(SMOOTH_CAM) + PxVec3 eye_t = eye.getPosition(); + eye_t = eye_t + (m_targetEyePos - eye_t) * g_smoothCamPosLerp; + eye.setPosition(eye_t); +#endif + + // rotate from gamepad + { + const PxF32 rotationSpeed = m_rotationSpeedScale * dtime; + PxF32 dx = getPlatform()->getSampleUserInput()->getAnalogInputEventState(CAMERA_GAMEPAD_ROTATE_LEFT_RIGHT) * rotationSpeed; + PxF32 dy = getPlatform()->getSampleUserInput()->getAnalogInputEventState(CAMERA_GAMEPAD_ROTATE_UP_DOWN) * rotationSpeed; + rotateCamera(dx, dy); + } + + m_worldToView.setInverseTransform(eye); + } +} + +// When holding down the mouse button and dragging across the edge of the window, +// the input provider will spit out nonsensical delta values... so threshold appropriately +void thresholdCameraRotate(physx::PxReal& dx, physx::PxReal& dy) +{ + static const physx::PxReal invalidDelta = 1000.f; + if ( physx::PxAbs(dx) > invalidDelta ) + dx = physx::PxSign(dx); + if ( physx::PxAbs(dy) > invalidDelta ) + dy = physx::PxSign(dy); +} + +void SampleApplication::onPointerInputEvent(const InputEvent& ie, physx::PxU32 x, physx::PxU32 y, physx::PxReal dx, physx::PxReal dy, bool val) +{ + switch (ie.m_Id) + { + case CAMERA_MOUSE_LOOK: + { + if(getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_MOVE_BUTTON)) + { + thresholdCameraRotate(dx, dy); + rotateCamera(dx, dy); + } + } + break; + } +} + +void SampleApplication::onDigitalInputEvent(const InputEvent& , bool val) +{ +} + +void SampleApplication::moveCamera(PxF32 dx, PxF32 dy) +{ + PxMat44 tmp = m_worldToView.getInverseTransform(); + PxMat44 eye = EulerToMat33(m_eyeRot); + eye.column3 = tmp.column3; + + PxVec3* targetParam; +#if defined(SMOOTH_CAM) + const float eyeSpeed = m_sceneSize * g_smoothCamBaseVel * m_lastDTime * (getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_SHIFT_SPEED) ? g_smoothCamFastMul : 1.0f); + targetParam = &m_targetEyePos; +#else + const float eyeSpeed = m_sceneSize * 4.0f * m_lastDTime * (getPlatform()->getSampleUserInput()->getDigitalInputEventState(CAMERA_SHIFT_SPEED) ? 4.0f : 1.0f); + targetParam = &eye.t; +#endif + + const PxVec3 column2 = eye.getBasis(2); + const PxVec3 column0 = eye.getBasis(0); + + // strafe from gamepad + *targetParam += column0 * eyeSpeed * dx * m_moveSpeedScale* m_lastDTime; + // move forward from gamepad + *targetParam -= column2 * eyeSpeed * dy * m_moveSpeedScale * m_lastDTime; + +#if defined(SMOOTH_CAM) + PxVec3 eye_t = eye.getPosition(); + eye_t = eye_t + (m_targetEyePos - eye_t) * g_smoothCamPosLerp; + eye.setPosition(eye_t); +#endif + + m_worldToView.setInverseTransform(eye); +} + +void SampleApplication::onAnalogInputEvent(const InputEvent& ie, float val) +{ + switch (ie.m_Id) + { + case CAMERA_GAMEPAD_ROTATE_LEFT_RIGHT: + { + rotateCamera((PxF32)val, (PxF32)0.0); + } + break; + case CAMERA_GAMEPAD_ROTATE_UP_DOWN: + { + rotateCamera((PxF32)0.0, (PxF32)val); + } + break; + case CAMERA_GAMEPAD_MOVE_LEFT_RIGHT: + { + moveCamera((PxF32)val, (PxF32)0.0); + } + break; + case CAMERA_GAMEPAD_MOVE_FORWARD_BACK: + { + moveCamera((PxF32)0.0, (PxF32)val); + } + break; + } +} + +void SampleApplication::rotateCamera(PxF32 dx, PxF32 dy) +{ + const float eyeCap = 1.5f; +#if defined(SMOOTH_CAM) + m_targetEyeRot.x -= dy * g_smoothCamRotSpeed; + m_targetEyeRot.y += dx * g_smoothCamRotSpeed; + if(m_targetEyeRot.x > eyeCap) m_targetEyeRot.x = eyeCap; + if(m_targetEyeRot.x < -eyeCap) m_targetEyeRot.x = -eyeCap; + + m_eyeRot= m_eyeRot + (m_targetEyeRot - m_eyeRot) * g_smoothCamRotLerp; +#else + const float eyeRotSpeed = 0.005f; + m_eyeRot.x -= dy * eyeRotSpeed; + m_eyeRot.y += dx * eyeRotSpeed; + if(m_eyeRot.x > eyeCap) m_eyeRot.x = eyeCap; + if(m_eyeRot.x < -eyeCap) m_eyeRot.x = -eyeCap; +#endif +} + +void SampleApplication::fatalError(const char * msg) +{ +shdfnd::printFormatted("Fatal Error in SampleApplication: %s\n", msg); +close(); +exit(1); +} + +void SampleApplication::doInput() +{ + m_platform->doInput(); +} + +void SampleApplication::setupRendererDescription(SampleRenderer::RendererDesc& renDesc) +{ + m_platform->setupRendererDescription(renDesc); +} + diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleAsset.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleAsset.cpp new file mode 100644 index 00000000..dd7db24b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleAsset.cpp @@ -0,0 +1,44 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SampleAsset.h> +#include "PsString.h" + +using namespace SampleFramework; + +SampleAsset::SampleAsset(Type type, const char *path) : + m_type(type) +{ + size_t len = strlen(path)+1; + m_path = new char[len]; + physx::shdfnd::strlcpy(m_path, len, path); + m_numUsers = 0; +} + +SampleAsset::~SampleAsset(void) +{ + if(m_path) delete [] m_path; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleAssetManager.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleAssetManager.cpp new file mode 100644 index 00000000..c1e19c4d --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleAssetManager.cpp @@ -0,0 +1,436 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SampleAssetManager.h> +#include <SampleAsset.h> +#include <SampleMaterialAsset.h> +#include <SampleTextureAsset.h> +#include <SampleInputAsset.h> + +#include <Renderer.h> + +#include <stdio.h> +#include "SamplePlatform.h" +#include "ODBlock.h" + +// for PsString.h +#include <PsString.h> +#include <PxTkFile.h> + +namespace Ps = physx::shdfnd; + +#include "SampleXml.h" +#include "extensions/PxDefaultStreams.h" + +using namespace SampleFramework; + +/////////////////////////////////////////////////////////////////////////////// + +static std::vector<char*>* gSearchPaths = NULL; + +void SampleFramework::addSearchPath(const char* path) +{ + if(!path) + return; + + const PxU32 len = *path ? (PxU32)strlen(path) : 0; + if(!len) + return; + + const PxU32 len2 = len+2; + char* searchPath = new char[len2]; + Ps::strlcpy(searchPath, len2, path); + if(path[len-1] != '/' && path[len-1] != '\\') + { + Ps::strlcat(searchPath, len2, "/"); + } + if(!gSearchPaths) + gSearchPaths = new std::vector<char*>; + gSearchPaths->push_back(searchPath); +} + +void SampleFramework::clearSearchPaths() +{ + if(!gSearchPaths) + return; + const PxU32 numSearchPaths = (PxU32)gSearchPaths->size(); + for(PxU32 i=0; i<numSearchPaths; i++) + { + delete [] (*gSearchPaths)[i]; + } + delete gSearchPaths; + gSearchPaths = NULL; +} + +static void FixSeparators(char* path) +{ + for (unsigned i = 0; i < strlen(path); ++i) + if (path[i] == '\\' || path[i] == '/') + path[i] = SampleFramework::SamplePlatform::platform()->getPathSeparator()[0]; +} + +File* SampleFramework::findFile(const char* path, bool binary) +{ + if(!gSearchPaths) + return NULL; + + File* file = NULL; + const PxU32 numSearchPaths = (PxU32)gSearchPaths->size(); + for(PxU32 i=0; i<numSearchPaths; i++) + { + const char* prefix = (*gSearchPaths)[i]; + + char fullPath[512]; + Ps::strlcpy(fullPath, 512, prefix); + Ps::strlcat(fullPath, 512, path); + FixSeparators(fullPath); + if(binary) + PxToolkit::fopen_s(&file, fullPath, "rb"); + else + { + // text files open also for write + PxToolkit::fopen_s(&file, fullPath, "r+"); + } + if(file) break; + } + return file; +} + +const char* SampleFramework::findPath(const char* path) +{ + if(!gSearchPaths) + return path; + + static char fullPath[512]; + + File* file = NULL; + const PxU32 numSearchPaths = (PxU32)gSearchPaths->size(); + for(PxU32 i=0; i<numSearchPaths; i++) + { + const char* prefix = (*gSearchPaths)[i]; + Ps::strlcpy(fullPath, 512, prefix); + Ps::strlcat(fullPath, 512, path); + FixSeparators(fullPath); + PxToolkit::fopen_s(&file, fullPath, "rb"); + if(file) break; + } + if(file) + { + fclose(file); + return fullPath; + } + else + return path; +} + + +/////////////////////////////////////////////////////////////////////////////// + +SampleAssetManager::SampleAssetManager(SampleRenderer::Renderer& renderer, + SampleAssetCreator* fallbackAssetCreator) : + m_renderer(renderer), + m_fallbackAssetCreator(fallbackAssetCreator) +{ +} + +SampleAssetManager::~SampleAssetManager(void) +{ + PX_ASSERT(m_assets.size() == 0); +} + +SampleAsset* SampleAssetManager::getAsset(const char* path, SampleAsset::Type type) +{ + SampleAsset* asset = findAsset(path); + if(!asset) + { + asset = loadAsset(path, type); + } + if(asset && asset->getType() != type) + { + releaseAsset(*asset); + asset = 0; + } + if(asset) + { + addAssetUser(*asset); + } + return asset; +} + +void SampleAssetManager::returnAsset(SampleAsset& asset) +{ + PX_ASSERT(asset.m_numUsers > 0); + if(asset.m_numUsers > 0) + { + asset.m_numUsers--; + } + if(asset.m_numUsers == 0) + { + releaseAsset(asset); + } +} + +SampleAsset* SampleAssetManager::findAsset(const char* path) +{ + SampleAsset* asset = NULL; + PxU32 numAssets = (PxU32)m_assets.size(); + for(PxU32 i=0; i<numAssets; i++) + { + if(!strcmp(m_assets[i]->getPath(), path)) + { + asset = m_assets[i]; + break; + } + } + return asset; +} + +static const char* strext(const char* str) +{ + const char* ext = str; + while(str) + { + str = strchr(str, '.'); + if(str) + { + str++; + ext = str; + } + } + return ext; +} + +class FileExtensions +{ +public: + explicit FileExtensions(const char** extensions, PxU32 numExtensions) + : mExtensions(extensions), mNumExtensions(numExtensions) { } + + template<typename EnumType> + EnumType typeOf(const char* extension) + { + PxU32 type = 0; + while (type < mNumExtensions && (Ps::stricmp(extension, mExtensions[type]) != 0)) ++type; + return static_cast<EnumType>(type); + } + +protected: + const char** mExtensions; + PxU32 mNumExtensions; +}; + +enum FileType { TYPE_XML = 0, TYPE_DDS, TYPE_TGA, TYPE_ODS, TYPE_PVR, TYPE_BMP, NUM_TYPES, TYPE_NOT_SUPPORTED = NUM_TYPES }; +static const char* sSupportedExtensions[NUM_TYPES] = {"xml", "dds", "tga", "ods", "pvr", "bmp"}; +static FileExtensions sFileExtensions(sSupportedExtensions, NUM_TYPES); + +#if defined(RENDERER_ENABLE_PVR_SUPPORT) +static FILE* findFileExchangeExtension(const char* path, bool binary, const char* origEnding, const char* newEnding) +{ + char pathPVR[512]; + strcpy(pathPVR, path); + char* endStr = strstr(pathPVR, origEnding); + strcpy(endStr, newEnding); + return findFile(pathPVR, binary); +} +#endif + +SampleAsset* SampleAssetManager::loadAsset(const char* path, SampleAsset::Type type) +{ + SampleAsset* asset = NULL; + const char* extension = strext(path); + if(extension && *extension) + { + FileType fileType = sFileExtensions.typeOf<FileType>(extension); + if (TYPE_NOT_SUPPORTED != fileType ) + { + File* file = NULL; +#if defined(RENDERER_ENABLE_PVR_SUPPORT) + if(fileType == TYPE_DDS) + { + file = findFileExchangeExtension(path, true, ".dds", ".pvr"); + fileType = TYPE_PVR; + } +#endif + if(!file) + file = findFile(path, fileType != TYPE_ODS); + + if(!file) + PxToolkit::fopen_s(&file, path, fileType != TYPE_ODS ? "rb" : "r+"); + + if(file) + { + switch(fileType) + { + case TYPE_XML: + asset = loadXMLAsset(*file, path); + break; + case TYPE_DDS: + asset = loadTextureAsset(*file, path, SampleTextureAsset::DDS); + break; + case TYPE_PVR: + asset = loadTextureAsset(*file, path, SampleTextureAsset::PVR); + break; + case TYPE_BMP: + asset = loadTextureAsset(*file, path, SampleTextureAsset::BMP); + break; + case TYPE_TGA: + asset = loadTextureAsset(*file, path, SampleTextureAsset::TGA); + break; + case TYPE_ODS: + asset = loadODSAsset(*file, path); + break; + case TYPE_NOT_SUPPORTED: + default: + PX_ALWAYS_ASSERT(); + }; + fclose(file); + } + } + + if (NULL == asset) + { + if (m_fallbackAssetCreator) + { + asset = m_fallbackAssetCreator->create(path, type); + } + if (NULL == asset) + { + +#define SAM_DEFAULT_MATERIAL "materials/simple_lit.xml" + +#if defined(RENDERER_ENABLE_PVR_SUPPORT) +# define SAM_DEFAULT_TEXTURE "textures/test.pvr" +#else +# define SAM_DEFAULT_TEXTURE "textures/test.dds" +#endif + + // report the missing asset + char msg[1024]; + + if (type == SampleAsset::ASSET_MATERIAL && strcmp(path, SAM_DEFAULT_MATERIAL) ) // Avoid infinite recursion + { + Ps::snprintf(msg, sizeof(msg), "Could not find material: %s, loading default material: %s", + path, SAM_DEFAULT_MATERIAL); + RENDERER_OUTPUT_MESSAGE(&m_renderer, msg); + + return loadAsset(SAM_DEFAULT_MATERIAL, type); // Try to use the default asset + } + else if (type == SampleAsset::ASSET_TEXTURE) + { + Ps::snprintf(msg, sizeof(msg), "Could not find texture: %s, loading default texture: %s", + path, SAM_DEFAULT_TEXTURE); + RENDERER_OUTPUT_MESSAGE(&m_renderer, msg); + + return loadAsset(SAM_DEFAULT_TEXTURE, type); // Try to use the default asset + } + else if (fileType == TYPE_ODS) + { + Ps::snprintf(msg, sizeof(msg), "Could not find input definition: %s", path); + RENDERER_OUTPUT_MESSAGE(&m_renderer, msg); + } + } + } + } + //PX_ASSERT(asset && asset->isOk()); + if(asset && !asset->isOk()) + { + deleteAsset(asset); + asset = 0; + } + if(asset) + { + addAsset(asset); + } + return asset; +} + +void SampleAssetManager::releaseAsset(SampleAsset& asset) +{ + PxU32 numAssets = (PxU32)m_assets.size(); + PxU32 found = numAssets; + for(PxU32 i=0; i<numAssets; i++) + { + if(&asset == m_assets[i]) + { + found = i; + break; + } + } + PX_ASSERT(found < numAssets); + if(found < numAssets) + { + m_assets[found] = m_assets.back(); + m_assets.pop_back(); + deleteAsset(&asset); + } +} + +void SampleAssetManager::addAssetUser(SampleAsset& asset) +{ + asset.m_numUsers++; +} + +void SampleAssetManager::addAsset(SampleAsset* asset) +{ + if (asset) + m_assets.push_back(asset); +} + +void SampleAssetManager::deleteAsset(SampleAsset* asset) +{ + if (asset) + asset->release(); +} + +SampleAsset* SampleAssetManager::loadXMLAsset(File& file, const char* path) +{ + SampleAsset* asset = NULL; + + PxDefaultFileInputData theBuffer(findPath(path)); + FAST_XML::XmlBuilder builder; + physx::shdfnd::FastXml *xml = createFastXml(&builder); + xml->processXml(theBuffer, false); + FAST_XML::xml_node* rootnode = builder.rootnode(); + if(!strcmp(rootnode->name(), "material")) + { + asset = new SampleMaterialAsset(*this, *rootnode, path); + } + xml->release(); + + return asset; +} + +SampleAsset* SampleAssetManager::loadTextureAsset(File& file, const char* path, SampleTextureAsset::Type texType) +{ + SampleTextureAsset* asset = new SampleTextureAsset(getRenderer(), file, path, texType); + return asset; +} + +SampleAsset* SampleAssetManager::loadODSAsset(File& file, const char* path) +{ + SampleAsset* asset = new SampleInputAsset(&file, path); + return asset; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleCommandLine.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleCommandLine.cpp new file mode 100644 index 00000000..91d21840 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleCommandLine.cpp @@ -0,0 +1,426 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include "FrameworkFoundation.h" +#include <SampleCommandLine.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "PxTkFile.h" +#include "foundation/PxAssert.h" + +#ifdef WIN32 +#include <windows.h> +#elif defined(ANDROID) +typedef int errno_t; +#endif + +#include "PsString.h" + +using namespace SampleFramework; +namespace Ps = physx::shdfnd; + +static char **CommandLineToArgvA(const char *cmdLine, unsigned int &_argc) +{ + char **argv = 0; + char *_argv = 0; + unsigned int len = 0; + unsigned int argc = 0; + char a = 0; + unsigned int i = 0; + unsigned int j = 0; + bool in_QM = false; + bool in_TEXT = false; + bool in_SPACE = true; + + len = (unsigned int)strlen(cmdLine); + i = ((len+2)/2)*sizeof(char*) + sizeof(char*); + argv = (char **)malloc(i + (len+2)*sizeof(char)); + _argv = (char *)(((char *)argv)+i); + argv[0] = _argv; + + i = 0; + + a = cmdLine[i]; + while(a) + { + if(in_QM) + { + if(a == '\"') + { + in_QM = false; + } + else + { + _argv[j] = a; + j++; + } + } + else + { + switch(a) + { + case '\"': + in_QM = true; + in_TEXT = true; + if(in_SPACE) + { + argv[argc] = _argv+j; + argc++; + } + in_SPACE = false; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if(in_TEXT) + { + _argv[j] = '\0'; + j++; + } + in_TEXT = false; + in_SPACE = true; + break; + default: + in_TEXT = true; + if(in_SPACE) + { + argv[argc] = _argv+j; + argc++; + } + _argv[j] = a; + j++; + in_SPACE = false; + break; + } + } + i++; + a = cmdLine[i]; + } + _argv[j] = '\0'; + argv[argc] = 0; + _argc = argc; + return argv; +} + +static bool isSwitchChar(char c) +{ + return (c == '-' || c == '/'); +} + +namespace +{ +void operationOK(int e) +{ + PX_UNUSED(e); + PX_ASSERT(0 == e); +} + +const char * const * getCommandLineArgumentsFromFile(unsigned int & argc, const char * programName, const char * commandLineFilePath) +{ + const char * const * argv = NULL; + argc = 0; + PX_ASSERT(NULL != programName); + PX_ASSERT(NULL != commandLineFilePath); + if(NULL != programName && NULL != commandLineFilePath) + { + File* commandLineFile = NULL; + operationOK(PxToolkit::fopen_s(&commandLineFile, commandLineFilePath, "r")); + if(NULL != commandLineFile) + { + operationOK(fseek(commandLineFile, 0, SEEK_END)); + const unsigned int commandLineFileCount = static_cast<unsigned int>(ftell(commandLineFile)); + rewind(commandLineFile); + const unsigned int bufferCount = static_cast<unsigned int>(::strlen(programName)) + 1 + commandLineFileCount + 1; + if(bufferCount > 0) + { + char * argsOwn = static_cast<char*>(::malloc(bufferCount)); + Ps::strlcpy(argsOwn, bufferCount, programName); + Ps::strlcat(argsOwn, bufferCount, " "); + const unsigned int offset = static_cast<unsigned int>(::strlen(argsOwn)); + PX_ASSERT((bufferCount - offset - 1) == commandLineFileCount); + if(NULL != fgets(argsOwn + offset, bufferCount - offset, commandLineFile)) + { + argv = CommandLineToArgvA(argsOwn, argc); + } + ::free(argsOwn); + argsOwn = NULL; + } + operationOK(fclose(commandLineFile)); + commandLineFile = NULL; + } + } + return argv; +} +} //namespace nameless + +SampleCommandLine::SampleCommandLine(unsigned int argc, const char * const * argv, const char * commandLineFilePathFallback) + :m_argc(0) + ,m_argv(NULL) + ,m_freeme(NULL) + ,m_argUsed(NULL) +{ + //initially, set to use inherent command line arguments + PX_ASSERT((0 != argc) && (NULL != argv) && "This class assumes argument 0 is always the executable path!"); + m_argc = argc; + m_argv = argv; + + //finalize init + initCommon(commandLineFilePathFallback); +} + +SampleCommandLine::SampleCommandLine(const char * args, const char * commandLineFilePathFallback) + :m_argc(0) + ,m_argv(NULL) + ,m_freeme(NULL) + ,m_argUsed(NULL) +{ + //initially, set to use inherent command line arguments + unsigned int argc = 0; + const char * const * argvOwning = NULL; + argvOwning = CommandLineToArgvA(args, argc); + PX_ASSERT((0 != argc) && (NULL != argvOwning) && "This class assumes argument 0 is always the executable path!"); + m_argc = argc; + m_argv = argvOwning; + m_freeme = const_cast<void *>(static_cast<const void *>(argvOwning)); + argvOwning = NULL; + + //finalize init + initCommon(commandLineFilePathFallback); +} + +SampleCommandLine::~SampleCommandLine(void) +{ + if(m_freeme) + { + free(m_freeme); + m_freeme = NULL; + } + if(m_argUsed) + { + delete[] m_argUsed; + m_argUsed = NULL; + } +} + +void SampleCommandLine::initCommon(const char * commandLineFilePathFallback) +{ + //if available, set to use command line arguments from file + const bool tryUseCommandLineArgumentsFromFile = ((1 == m_argc) && (NULL != commandLineFilePathFallback)); + if(tryUseCommandLineArgumentsFromFile) + { + unsigned int argcFile = 0; + const char * const * argvFileOwn = NULL; + argvFileOwn = getCommandLineArgumentsFromFile(argcFile, m_argv[0], commandLineFilePathFallback); + if((0 != argcFile) && (NULL != argvFileOwn)) + { + if(NULL != m_freeme) + { + ::free(m_freeme); + m_freeme = NULL; + } + m_argc = argcFile; + m_argv = argvFileOwn; + m_freeme = const_cast<void *>(static_cast<const void *>(argvFileOwn)); + argvFileOwn = NULL; + } + } + + //for tracking use-status of arguments + if((0 != m_argc) && (NULL != m_argv)) + { + m_argUsed = new bool[m_argc]; + for(unsigned int i = 0; i < m_argc; i++) + { + m_argUsed[i] = false; + } + } +} + +unsigned int SampleCommandLine::getNumArgs(void) const +{ + return(m_argc); +} + +const char * SampleCommandLine::getProgramName(void) const +{ + return(m_argv[0]); +} + +unsigned int SampleCommandLine::unusedArgsBufSize(void) const +{ + unsigned int bufLen = 0; + for(unsigned int i = 1; i < m_argc; i++) + { + if((!m_argUsed[i]) && isSwitchChar(m_argv[i][0])) + { + bufLen += (unsigned int) strlen(m_argv[i]) + 1; // + 1 is for the space between unused args + } + } + if(bufLen != 0) + { + bufLen++; // if there are unused args add a space for the '\0' char. + } + return(bufLen); +} + +const char* SampleCommandLine::getUnusedArgs(char *buf, unsigned int bufSize) const +{ + if(bufSize != 0) + { + buf[0] = '\0'; + for(unsigned int i = 1; i < m_argc; i++) + { + if((!m_argUsed[i]) && isSwitchChar(m_argv[i][0])) + { + Ps::strlcat(buf, bufSize, m_argv[i]); + Ps::strlcat(buf, bufSize, " "); + } + } + } + return(buf); +} + +//! has a given command-line switch? +// e.g. s=="foo" checks for -foo +bool SampleCommandLine::hasSwitch(const char *s, unsigned int argNum) const +{ + bool has = false; + PX_ASSERT(*s); + if(*s) + { + unsigned int n = (unsigned int) strlen(s); + unsigned int firstArg; + unsigned int lastArg; + if(argNum != invalidArgNum) + { + firstArg = argNum; + lastArg = argNum; + } + else + { + firstArg = 1; + lastArg = (m_argc > 1) ? (m_argc - 1) : 0; + } + for(unsigned int i=firstArg; i<=lastArg; i++) + { + const char *arg = m_argv[i]; + // allow switches of '/', '-', and double character versions of both. + if( (isSwitchChar(*arg) && !Ps::strnicmp(arg+1, s, n) && ((arg[n+1]=='\0')||(arg[n+1]=='='))) || + (isSwitchChar(*(arg+1)) && !Ps::strnicmp(arg+2, s, n) && ((arg[n+2]=='\0')||(arg[n+2]=='='))) ) + { + m_argUsed[i] = true; + has = true; + break; + } + } + } + return has; +} + +//! gets the value of a switch... +// e.g. s="foo" returns "bar" if '-foo=bar' is in the commandline. +const char *SampleCommandLine::getValue(const char *s, unsigned int argNum) const +{ + const char *value = 0; + PX_ASSERT(*s); + if(*s) + { + unsigned int firstArg; + unsigned int lastArg; + if(argNum != invalidArgNum) + { + firstArg = argNum; + lastArg = argNum; + } + else + { + firstArg = 1; + lastArg = m_argc - 1; + } + for(unsigned int i=firstArg; i<=lastArg; i++) + { + const char *arg = m_argv[i]; + if(isSwitchChar(*arg)) + { + arg++; + if(isSwitchChar(*arg)) // is it a double dash arg? '--' + { + arg++; + } + const char *st=s; + for(; *st && *arg && toupper(*st)==toupper(*arg) && *arg!='='; st++,arg++) + { + } + if(!*st && *arg=='=') + { + m_argUsed[i] = true; + value = arg+1; + break; + } + if(!*st && !*arg && ((i+1)<m_argc) && (!isSwitchChar(*m_argv[i+1]))) + { + m_argUsed[i] = true; + value = m_argv[i+1]; + break; + } + } + } + } + return value; +} + +//! if the first argument is the given command. +bool SampleCommandLine::isCommand(const char *s) const +{ + bool has = false; + const char *command = getCommand(); + if(command && !Ps::stricmp(command, s)) + { + has = true; + } + return has; +} + +//! get the first argument assuming it isn't a switch. +// e.g. for the command-line "myapp.exe editor -foo" it will return "editor". +const char *SampleCommandLine::getCommand(void) const +{ + const char *command = 0; + if(m_argc > 1 && !isSwitchChar(*m_argv[1])) + { + command = m_argv[1]; + } + return command; +} + +//! whether or not an argument has been read already +bool SampleCommandLine::isUsed(unsigned int argNum) const +{ + return argNum < m_argc ? m_argUsed[argNum] : false; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleDirManager.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleDirManager.cpp new file mode 100644 index 00000000..12bd98d7 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleDirManager.cpp @@ -0,0 +1,121 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include "SampleDirManager.h" +#include "SampleAssetManager.h" +#include "SamplePlatform.h" +#include "PsUtilities.h" +#include "PxTkFile.h" +#include "PsString.h" + +using namespace SampleFramework; + +static void FixPathSeparator(char* pathBuffer) +{ + char separator = SampleFramework::SamplePlatform::platform()->getPathSeparator()[0]; + + const size_t length = strlen(pathBuffer); + for(size_t i=0; i<length ; ++i) + { + if ('/' == pathBuffer[i] || '\\' == pathBuffer[i]) + pathBuffer[i] = separator; + } +} + +SampleDirManager::SampleDirManager(const char* relativePathRoot, bool isReadOnly, int maxRecursion) : mIsReadOnly(isReadOnly) +{ + if(!relativePathRoot || !SampleFramework::searchForPath(relativePathRoot, mPathRoot, PX_ARRAY_SIZE(mPathRoot), isReadOnly, maxRecursion)) + { + shdfnd::printFormatted("path \"%s\" not found\n", relativePathRoot); + mPathRoot[0] = '\0'; + } +} + +#define MAX_PATH_LENGTH 256 + +const char* SampleDirManager::getFilePath(const char* relativeFilePath, char* pathBuffer, bool testFileValidity) +{ + PX_ASSERT(pathBuffer); + + bool flattenRelativeFilePaths = false; +#if defined (RENDERER_IOS) + //iOS doesn't allow to share files in folders... + flattenRelativeFilePaths = !mIsReadOnly; +#endif + + strcpy(pathBuffer, getPathRoot()); + strcat(pathBuffer, "/"); + + if (flattenRelativeFilePaths) + { + char flattendPath[MAX_PATH_LENGTH]; + strcpy(flattendPath, relativeFilePath); + for (size_t i = 0; i < strlen(flattendPath); ++i) + { + if ('/' == flattendPath[i] || '\\' == flattendPath[i]) + flattendPath[i] = '_'; + } + strcat(pathBuffer, flattendPath); + } + else + { + strcat(pathBuffer, relativeFilePath); + if (!mIsReadOnly) + { + FixPathSeparator(pathBuffer); + //strip file from path and make sure the output directory exists + const char* ptr = strrchr(pathBuffer, '/'); + if (!ptr) + ptr = strrchr(pathBuffer, '\\'); + + if (ptr) + { + char dir[MAX_PATH_LENGTH]; + assert(MAX_PATH_LENGTH >= strlen(pathBuffer)); + strcpy(dir, pathBuffer); + dir[ptr - pathBuffer] = '\0'; + FixPathSeparator(dir); + SampleFramework::SamplePlatform::platform()->makeSureDirectoryPathExists(dir); + } + } + } + + FixPathSeparator(pathBuffer); + + if(testFileValidity) + { + File* fp = NULL; + PxToolkit::fopen_s(&fp, pathBuffer, "rb"); + if(!fp) + { + // Kai: user can still get full path in the path buffer (side effect) + return NULL; + } + fclose(fp); + } + + return pathBuffer; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleInputAsset.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleInputAsset.cpp new file mode 100644 index 00000000..2de45556 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleInputAsset.cpp @@ -0,0 +1,100 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include "SampleInputAsset.h" +#include "ODBlock.h" +#include <PxTkFile.h> +#include <PsString.h> + +using namespace SampleFramework; + +SampleInputAsset::SampleInputAsset(File* file, const char *path) +: SampleAsset(SampleAsset::ASSET_INPUT, path) +, m_SettingsBlock(NULL) +, m_File(file) +{ + m_SampleInputData.reserve(128); + + PX_ASSERT(file); + + if (!m_Mapping.loadScript(file)) + { + shdfnd::printFormatted("ODS parse error: %s in file: %s\n", m_Mapping.lastError, path); + PX_ASSERT(0); + } + + m_SettingsBlock = m_Mapping.getBlock("InputMapping"); + if (!m_SettingsBlock) + { + shdfnd::printFormatted("No \"InputEventSettings\" block found!\n"); + PX_ASSERT(0); + } + else + { + LoadData(m_SettingsBlock); + } +} + +SampleInputAsset::~SampleInputAsset() +{ + if(m_File) + { + fclose(m_File); + } +} + +void SampleInputAsset::LoadData(ODBlock* odsSettings) +{ + odsSettings->reset(); + while (odsSettings->moreSubBlocks()) + { + ODBlock* subBlock = odsSettings->nextSubBlock(); + subBlock->reset(); + + SampleInputData inputData; + if (!strcmp(subBlock->ident(), "map")) + { + if (subBlock->moreTerminals()) + { + const char* p = subBlock->nextTerminal(); + strcpy(inputData.m_UserInputName, p); + } + if (subBlock->moreTerminals()) + { + const char* p = subBlock->nextTerminal(); + strcpy(inputData.m_InputEventName, p); + } + + m_SampleInputData.push_back(inputData); + } + } +} + +bool SampleInputAsset::isOk(void) const +{ + return true; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleLineDebugRender.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleLineDebugRender.cpp new file mode 100644 index 00000000..243d1671 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleLineDebugRender.cpp @@ -0,0 +1,215 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SampleLineDebugRender.h> +#include <Renderer.h> +#include <RendererVertexBuffer.h> +#include <RendererVertexBufferDesc.h> +#include <RendererMesh.h> +#include <RendererMeshDesc.h> +#include <SampleAssetManager.h> +#include <SampleMaterialAsset.h> +#include <RendererMemoryMacros.h> + +using namespace SampleFramework; + +SampleLineDebugRender::SampleLineDebugRender(SampleRenderer::Renderer &renderer, SampleAssetManager &assetmanager) : + m_renderer(renderer), + m_assetmanager(assetmanager) +{ + m_material = static_cast<SampleMaterialAsset*>(m_assetmanager.getAsset("materials/simple_unlit.xml", SampleAsset::ASSET_MATERIAL)); + PX_ASSERT(m_material); + PX_ASSERT(m_material->getNumVertexShaders() == 1); + m_meshContext.material = m_material ? m_material->getMaterial(0) : 0; + + m_maxVerts = 0; + m_numVerts = 0; + m_vertexbuffer = 0; + m_mesh = 0; + m_lockedPositions = 0; + m_positionStride = 0; + m_lockedColors = 0; + m_colorStride = 0; + + checkResizeLine(2048); +} + +SampleLineDebugRender::~SampleLineDebugRender(void) +{ + checkUnlock(); + SAFE_RELEASE(m_vertexbuffer); + SAFE_RELEASE(m_mesh); + if(m_material) + { + m_assetmanager.returnAsset(*m_material); + } +} + +void SampleLineDebugRender::addLine(const PxVec3 &p0, const PxVec3 &p1, const SampleRenderer::RendererColor &color) +{ + checkResizeLine(m_numVerts+2); + addVert(p0, color); + addVert(p1, color); +} + +void SampleLineDebugRender::queueForRenderLine(void) +{ + if(m_meshContext.mesh) + { + checkUnlock(); + m_mesh->setVertexBufferRange(0, m_numVerts); + m_renderer.queueMeshForRender(m_meshContext); + } +} + +void SampleLineDebugRender::clearLine(void) +{ + m_numVerts = 0; +} + +void SampleLineDebugRender::checkResizeLine(PxU32 maxVerts) +{ + if(maxVerts > m_maxVerts) + { + m_maxVerts = maxVerts + (PxU32)(maxVerts*0.2f); + + SampleRenderer::RendererVertexBufferDesc vbdesc; + vbdesc.hint = SampleRenderer::RendererVertexBuffer::HINT_DYNAMIC; + vbdesc.semanticFormats[SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION] = SampleRenderer::RendererVertexBuffer::FORMAT_FLOAT3; + vbdesc.semanticFormats[SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR] = SampleRenderer::RendererVertexBuffer::FORMAT_COLOR_NATIVE; // same as RendererColor + vbdesc.maxVertices = m_maxVerts; + SampleRenderer::RendererVertexBuffer *vertexbuffer = m_renderer.createVertexBuffer(vbdesc); + PX_ASSERT(vertexbuffer); + + if(vertexbuffer) + { + PxU32 positionStride = 0; + void *positions = vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION, positionStride); + + PxU32 colorStride = 0; + void *colors = vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR, colorStride); + + PX_ASSERT(positions && colors); + if(positions && colors) + { + if(m_numVerts > 0) + { + // if we have existing verts, copy them to the new VB... + PX_ASSERT(m_lockedPositions); + PX_ASSERT(m_lockedColors); + if(m_lockedPositions && m_lockedColors) + { + for(PxU32 i=0; i<m_numVerts; i++) + { + memcpy(((PxU8*)positions) + (positionStride*i), ((PxU8*)m_lockedPositions) + (m_positionStride*i), sizeof(PxVec3)); + memcpy(((PxU8*)colors) + (colorStride*i), ((PxU8*)m_lockedColors) + (m_colorStride*i), sizeof(SampleRenderer::RendererColor)); + } + } + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + } + } + vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + } + if(m_vertexbuffer) + { + m_vertexbuffer->release(); + m_vertexbuffer = 0; + m_lockedPositions = 0; + m_positionStride = 0; + m_lockedColors = 0; + m_colorStride = 0; + } + SAFE_RELEASE(m_mesh); + if(vertexbuffer) + { + m_vertexbuffer = vertexbuffer; + SampleRenderer::RendererMeshDesc meshdesc; + meshdesc.primitives = SampleRenderer::RendererMesh::PRIMITIVE_LINES; + meshdesc.vertexBuffers = &m_vertexbuffer; + meshdesc.numVertexBuffers = 1; + meshdesc.firstVertex = 0; + meshdesc.numVertices = m_numVerts; + m_mesh = m_renderer.createMesh(meshdesc); + PX_ASSERT(m_mesh); + } + m_meshContext.mesh = m_mesh; + } +} + +void SampleLineDebugRender::checkLock(void) +{ + if(m_vertexbuffer) + { + if(!m_lockedPositions) + { + m_lockedPositions = m_vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION, m_positionStride); + PX_ASSERT(m_lockedPositions); + } + if(!m_lockedColors) + { + m_lockedColors = m_vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR, m_colorStride); + PX_ASSERT(m_lockedColors); + } + } +} + +void SampleLineDebugRender::checkUnlock(void) +{ + if(m_vertexbuffer) + { + if(m_lockedPositions) + { + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + m_lockedPositions = 0; + } + if(m_lockedColors) + { + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + m_lockedColors = 0; + } + } +} + +void SampleLineDebugRender::addVert(const PxVec3 &p, const SampleRenderer::RendererColor &color) +{ + PX_ASSERT(m_maxVerts > m_numVerts); + { + checkLock(); + if(m_lockedPositions && m_lockedColors) + { + memcpy(((PxU8*)m_lockedPositions) + (m_positionStride*m_numVerts), &p, sizeof(PxVec3)); +#if defined(RENDERER_XBOX360) + PxU8 colors[4] = {color.a, color.r, color.g, color.b}; + memcpy(((PxU8*)m_lockedColors) + (m_colorStride*m_numVerts), colors, sizeof(PxU8) * 4); +#else + memcpy(((PxU8*)m_lockedColors) + (m_colorStride*m_numVerts), &color, sizeof(SampleRenderer::RendererColor)); +#endif + m_numVerts++; + } + } +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleMaterialAsset.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleMaterialAsset.cpp new file mode 100644 index 00000000..238217ee --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleMaterialAsset.cpp @@ -0,0 +1,308 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SampleMaterialAsset.h> + +#include <Renderer.h> +#include <RendererMaterial.h> +#include <RendererMaterialDesc.h> +#include <RendererMaterialInstance.h> + +#include <SampleAssetManager.h> +#include <SampleTextureAsset.h> + +#include "SampleXml.h" +#include <ctype.h> + +using namespace SampleFramework; + +static SampleRenderer::RendererMaterial::BlendFunc +getBlendFunc(const char* nodeValue, + SampleRenderer::RendererMaterial::BlendFunc defaultBlendFunc = SampleRenderer::RendererMaterial::BLEND_ONE) +{ + using SampleRenderer::RendererMaterial; + RendererMaterial::BlendFunc blendFunc = defaultBlendFunc; + if( !strcmp(nodeValue, "ZERO")) blendFunc = RendererMaterial::BLEND_ZERO; + else if(!strcmp(nodeValue, "ONE")) blendFunc = RendererMaterial::BLEND_ONE; + else if(!strcmp(nodeValue, "SRC_COLOR")) blendFunc = RendererMaterial::BLEND_SRC_COLOR; + else if(!strcmp(nodeValue, "ONE_MINUS_SRC_COLOR")) blendFunc = RendererMaterial::BLEND_ONE_MINUS_SRC_COLOR; + else if(!strcmp(nodeValue, "SRC_ALPHA")) blendFunc = RendererMaterial::BLEND_SRC_ALPHA; + else if(!strcmp(nodeValue, "ONE_MINUS_SRC_ALPHA")) blendFunc = RendererMaterial::BLEND_ONE_MINUS_SRC_ALPHA; + else if(!strcmp(nodeValue, "DST_COLOR")) blendFunc = RendererMaterial::BLEND_DST_COLOR; + else if(!strcmp(nodeValue, "ONE_MINUS_DST_COLOR")) blendFunc = RendererMaterial::BLEND_ONE_MINUS_DST_COLOR; + else if(!strcmp(nodeValue, "DST_ALPHA")) blendFunc = RendererMaterial::BLEND_DST_ALPHA; + else if(!strcmp(nodeValue, "ONE_MINUS_DST_ALPHA")) blendFunc = RendererMaterial::BLEND_ONE_MINUS_DST_ALPHA; + else if(!strcmp(nodeValue, "SRC_ALPHA_SATURATE")) blendFunc = RendererMaterial::BLEND_SRC_ALPHA_SATURATE; + else PX_ASSERT(0); // Unknown blend func! + + return blendFunc; +} + +static void readFloats(const char *str, float *floats, unsigned int numFloats) +{ + PxU32 fcount = 0; + while(*str && !((*str>='0'&&*str<='9') || *str=='.')) str++; + for(PxU32 i=0; i<numFloats; i++) + { + if(*str) + { + floats[i] = (float)atof(str); + while(*str && ((*str>='0'&&*str<='9') || *str=='.')) str++; + while(*str && !((*str>='0'&&*str<='9') || *str=='.')) str++; + fcount++; + } + } + PX_ASSERT(fcount==numFloats); +} + +SampleMaterialAsset::SampleMaterialAsset(SampleAssetManager &assetManager, FAST_XML::xml_node &xmlroot, const char *path) : +SampleAsset(ASSET_MATERIAL, path), + m_assetManager(assetManager) +{ + + std::vector<const char*> mVertexShaderPaths; + //m_material = 0; + //m_materialInstance = 0; + + SampleRenderer::Renderer &renderer = assetManager.getRenderer(); + + SampleRenderer::RendererMaterialDesc matdesc; + const char *materialTypeName = xmlroot.getXMLAttribute("type"); + if(materialTypeName && !strcmp(materialTypeName, "lit")) + { + matdesc.type = SampleRenderer::RendererMaterial::TYPE_LIT; + } + else if(materialTypeName && !strcmp(materialTypeName, "unlit")) + { + matdesc.type = SampleRenderer::RendererMaterial::TYPE_UNLIT; + } + for(FAST_XML::xml_node *child=xmlroot.first_node(); child; child=child->next_sibling()) + { + const char *nodeName = child->name(); + const char *nodeValue = child->value(); + const char *name = child->getXMLAttribute("name"); + if(nodeName && nodeValue) + { + while(isspace(*nodeValue)) nodeValue++; // skip leading spaces. + if(!strcmp(nodeName, "shader")) + { + if(name && !strcmp(name, "vertex")) + { + //matdesc.vertexShaderPath = nodeValue; + mVertexShaderPaths.push_back(nodeValue); + } + else if(name && !strcmp(name, "fragment")) + { + matdesc.fragmentShaderPath = nodeValue; + } + else if(name && !strcmp(name, "geometry")) + { + matdesc.geometryShaderPath = nodeValue; + } + else if(name && !strcmp(name, "hull")) + { + matdesc.hullShaderPath = nodeValue; + } + else if(name && !strcmp(name, "domain")) + { + matdesc.domainShaderPath = nodeValue; + } + } + else if(!strcmp(nodeName, "alphaTestFunc")) + { + if( !strcmp(nodeValue, "EQUAL")) matdesc.alphaTestFunc = SampleRenderer::RendererMaterial::ALPHA_TEST_EQUAL; + else if(!strcmp(nodeValue, "NOT_EQUAL")) matdesc.alphaTestFunc = SampleRenderer::RendererMaterial::ALPHA_TEST_NOT_EQUAL; + else if(!strcmp(nodeValue, "LESS")) matdesc.alphaTestFunc = SampleRenderer::RendererMaterial::ALPHA_TEST_LESS; + else if(!strcmp(nodeValue, "LESS_EQUAL")) matdesc.alphaTestFunc = SampleRenderer::RendererMaterial::ALPHA_TEST_LESS_EQUAL; + else if(!strcmp(nodeValue, "GREATER")) matdesc.alphaTestFunc = SampleRenderer::RendererMaterial::ALPHA_TEST_GREATER; + else if(!strcmp(nodeValue, "GREATER_EQUAL")) matdesc.alphaTestFunc = SampleRenderer::RendererMaterial::ALPHA_TEST_GREATER_EQUAL; + else PX_ASSERT(0); // Unknown alpha test func! + } + else if(!strcmp(nodeName, "alphaTestRef")) + { + matdesc.alphaTestRef = PxClamp((float)atof(nodeValue), 0.0f, 1.0f); + } + else if(!strcmp(nodeName, "blending") && strstr(nodeValue, "true")) + { + matdesc.blending = true; + + static const PxU32 numBlendFuncs = 2; + static const char* blendFuncNames[numBlendFuncs] = + { + "srcBlendFunc", + "dstBlendFunc" + }; + static const SampleRenderer::RendererMaterial::BlendFunc blendFuncDefaults[numBlendFuncs] = + { + SampleRenderer::RendererMaterial::BLEND_SRC_ALPHA, + SampleRenderer::RendererMaterial::BLEND_ONE_MINUS_SRC_ALPHA + }; + SampleRenderer::RendererMaterial::BlendFunc* blendFuncs[numBlendFuncs] = + { + &matdesc.srcBlendFunc, + &matdesc.dstBlendFunc + }; + + // Parse optional src/dst blend funcs + for (PxU32 i = 0; i < numBlendFuncs; ++i) + { + FAST_XML::xml_node *blendNode = child->first_node(blendFuncNames[i]); + if (blendNode && blendNode->value()) + *blendFuncs[i] = getBlendFunc(blendNode->value(), blendFuncDefaults[i]); + else + *blendFuncs[i] = blendFuncDefaults[i]; + } + } + } + } + + for (size_t materialIndex = 0; materialIndex < mVertexShaderPaths.size(); materialIndex++) + { + MaterialStruct materialStruct; + + matdesc.vertexShaderPath = mVertexShaderPaths[materialIndex]; + materialStruct.m_material = NULL; + materialStruct.m_materialInstance = NULL; + materialStruct.m_maxBones = 0; + if (strstr(mVertexShaderPaths[materialIndex], "skeletalmesh") != NULL) + materialStruct.m_maxBones = RENDERER_MAX_BONES; + + materialStruct.m_material = renderer.createMaterial(matdesc); + PX_ASSERT(materialStruct.m_material); + if(materialStruct.m_material) + { + FAST_XML::xml_node *varsnode = xmlroot.first_node("variables"); + if(varsnode) + { + materialStruct.m_materialInstance = new SampleRenderer::RendererMaterialInstance(*materialStruct.m_material); + for(FAST_XML::xml_node *child=varsnode->first_node(); child; child=child->next_sibling()) + { + const char *nodename = child->name(); + const char *varname = child->getXMLAttribute("name"); + const char *value = child->value(); + + if(!strcmp(nodename, "float")) + { + float f = (float)atof(value); + const SampleRenderer::RendererMaterial::Variable *var = materialStruct.m_materialInstance->findVariable(varname, SampleRenderer::RendererMaterial::VARIABLE_FLOAT); + //PX_ASSERT(var); + if(var) materialStruct.m_materialInstance->writeData(*var, &f); + } + else if(!strcmp(nodename, "float2")) + { + float f[2]; + readFloats(value, f, 2); + const SampleRenderer::RendererMaterial::Variable *var = materialStruct.m_materialInstance->findVariable(varname, SampleRenderer::RendererMaterial::VARIABLE_FLOAT2); + //PX_ASSERT(var); + if(var) materialStruct.m_materialInstance->writeData(*var, f); + } + else if(!strcmp(nodename, "float3")) + { + float f[3]; + readFloats(value, f, 3); + const SampleRenderer::RendererMaterial::Variable *var = materialStruct.m_materialInstance->findVariable(varname, SampleRenderer::RendererMaterial::VARIABLE_FLOAT3); + //PX_ASSERT(var); + if(var) materialStruct.m_materialInstance->writeData(*var, f); + } + else if(!strcmp(nodename, "float4")) + { + float f[4]; + readFloats(value, f, 4); + const SampleRenderer::RendererMaterial::Variable *var = materialStruct.m_materialInstance->findVariable(varname, SampleRenderer::RendererMaterial::VARIABLE_FLOAT4); + //PX_ASSERT(var); + if(var) materialStruct.m_materialInstance->writeData(*var, f); + } + else if(!strcmp(nodename, "sampler2D") || !strcmp(nodename, "sampler3D")) + { + SampleTextureAsset *textureAsset = static_cast<SampleTextureAsset*>(assetManager.getAsset(value, ASSET_TEXTURE)); + PX_ASSERT(textureAsset); + if(textureAsset) + { + m_assets.push_back(textureAsset); + SampleRenderer::RendererMaterial::VariableType vartype = (0 == strcmp(nodename, "sampler2D")) ? SampleRenderer::RendererMaterial::VARIABLE_SAMPLER2D : SampleRenderer::RendererMaterial::VARIABLE_SAMPLER3D; + const SampleRenderer::RendererMaterial::Variable *var = materialStruct.m_materialInstance->findVariable(varname, vartype); + //PX_ASSERT(var); + if(var) + { + SampleRenderer::RendererTexture *texture = textureAsset->getTexture(); + materialStruct.m_materialInstance->writeData(*var, &texture); + } + } + } + + } + } + + m_vertexShaders.push_back(materialStruct); + } + } +} + +SampleFramework::SampleMaterialAsset::SampleMaterialAsset(SampleAssetManager &assetManager, Type type, const char *path) +: SampleAsset(type, path), + m_assetManager(assetManager) +{ + +} + +SampleMaterialAsset::~SampleMaterialAsset(void) +{ + PxU32 numAssets = (PxU32)m_assets.size(); + for(PxU32 i=0; i<numAssets; i++) + { + m_assetManager.returnAsset(*m_assets[i]); + } + for (size_t index = 0; index < m_vertexShaders.size(); index++) + { + if(m_vertexShaders[index].m_materialInstance) delete m_vertexShaders[index].m_materialInstance; + if(m_vertexShaders[index].m_material) m_vertexShaders[index].m_material->release(); + } +} + +size_t SampleMaterialAsset::getNumVertexShaders() const +{ + return m_vertexShaders.size(); +} + +SampleRenderer::RendererMaterial *SampleMaterialAsset::getMaterial(size_t vertexShaderIndex) +{ + return m_vertexShaders[vertexShaderIndex].m_material; +} + +SampleRenderer::RendererMaterialInstance *SampleMaterialAsset::getMaterialInstance(size_t vertexShaderIndex) +{ + return m_vertexShaders[vertexShaderIndex].m_materialInstance; +} + +bool SampleMaterialAsset::isOk(void) const +{ + return !m_vertexShaders.empty(); +} + +unsigned int SampleMaterialAsset::getMaxBones(size_t vertexShaderIndex) const +{ + return m_vertexShaders[vertexShaderIndex].m_maxBones; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SamplePointDebugRender.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SamplePointDebugRender.cpp new file mode 100644 index 00000000..65a6e5a4 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SamplePointDebugRender.cpp @@ -0,0 +1,207 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SamplePointDebugRender.h> +#include <Renderer.h> +#include <RendererVertexBuffer.h> +#include <RendererVertexBufferDesc.h> +#include <RendererMesh.h> +#include <RendererMeshDesc.h> +#include <SampleAssetManager.h> +#include <SampleMaterialAsset.h> +#include <RendererMemoryMacros.h> + +using namespace SampleFramework; + +SamplePointDebugRender::SamplePointDebugRender(SampleRenderer::Renderer &renderer, SampleAssetManager &assetmanager) : + m_renderer(renderer), + m_assetmanager(assetmanager) +{ + m_material = static_cast<SampleMaterialAsset*>(m_assetmanager.getAsset("materials/simple_unlit.xml", SampleAsset::ASSET_MATERIAL)); + PX_ASSERT(m_material); + PX_ASSERT(m_material->getNumVertexShaders() == 1); + m_meshContext.material = m_material ? m_material->getMaterial(0) : 0; + + m_maxVerts = 0; + m_numVerts = 0; + m_vertexbuffer = 0; + m_mesh = 0; + m_lockedPositions = 0; + m_positionStride = 0; + m_lockedColors = 0; + m_colorStride = 0; +} + +SamplePointDebugRender::~SamplePointDebugRender(void) +{ + checkUnlock(); + SAFE_RELEASE(m_vertexbuffer); + SAFE_RELEASE(m_mesh); + if(m_material) + { + m_assetmanager.returnAsset(*m_material); + } +} + +void SamplePointDebugRender::addPoint(const PxVec3 &p0, const SampleRenderer::RendererColor &color) +{ + checkResizePoint(m_numVerts+1); + addVert(p0, color); +} + +void SamplePointDebugRender::queueForRenderPoint(void) +{ + if(m_meshContext.mesh) + { + checkUnlock(); + m_mesh->setVertexBufferRange(0, m_numVerts); + m_renderer.queueMeshForRender(m_meshContext); + } +} + +void SamplePointDebugRender::clearPoint(void) +{ + m_numVerts = 0; +} + +void SamplePointDebugRender::checkResizePoint(PxU32 maxVerts) +{ + if(maxVerts > m_maxVerts) + { + m_maxVerts = maxVerts + (PxU32)(maxVerts*0.2f); + + SampleRenderer::RendererVertexBufferDesc vbdesc; + vbdesc.hint = SampleRenderer::RendererVertexBuffer::HINT_DYNAMIC; + vbdesc.semanticFormats[SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION] = SampleRenderer::RendererVertexBuffer::FORMAT_FLOAT3; + vbdesc.semanticFormats[SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR] = SampleRenderer::RendererVertexBuffer::FORMAT_COLOR_NATIVE; // same as RendererColor + vbdesc.maxVertices = m_maxVerts; + SampleRenderer::RendererVertexBuffer *vertexbuffer = m_renderer.createVertexBuffer(vbdesc); + PX_ASSERT(vertexbuffer); + + if(vertexbuffer) + { + PxU32 positionStride = 0; + void *positions = vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION, positionStride); + + PxU32 colorStride = 0; + void *colors = vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR, colorStride); + + PX_ASSERT(positions && colors); + if(positions && colors) + { + if(m_numVerts > 0) + { + // if we have existing verts, copy them to the new VB... + PX_ASSERT(m_lockedPositions); + PX_ASSERT(m_lockedColors); + if(m_lockedPositions && m_lockedColors) + { + for(PxU32 i=0; i<m_numVerts; i++) + { + memcpy(((PxU8*)positions) + (positionStride*i), ((PxU8*)m_lockedPositions) + (m_positionStride*i), sizeof(PxVec3)); + memcpy(((PxU8*)colors) + (colorStride*i), ((PxU8*)m_lockedColors) + (m_colorStride*i), sizeof(SampleRenderer::RendererColor)); + } + } + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + } + } + vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + } + if(m_vertexbuffer) + { + m_vertexbuffer->release(); + m_vertexbuffer = 0; + m_lockedPositions = 0; + m_positionStride = 0; + m_lockedColors = 0; + m_colorStride = 0; + } + SAFE_RELEASE(m_mesh); + if(vertexbuffer) + { + m_vertexbuffer = vertexbuffer; + SampleRenderer::RendererMeshDesc meshdesc; + meshdesc.primitives = SampleRenderer::RendererMesh::PRIMITIVE_POINTS; + meshdesc.vertexBuffers = &m_vertexbuffer; + meshdesc.numVertexBuffers = 1; + meshdesc.firstVertex = 0; + meshdesc.numVertices = m_numVerts; + m_mesh = m_renderer.createMesh(meshdesc); + PX_ASSERT(m_mesh); + } + m_meshContext.mesh = m_mesh; + } +} + +void SamplePointDebugRender::checkLock(void) +{ + if(m_vertexbuffer) + { + if(!m_lockedPositions) + { + m_lockedPositions = m_vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION, m_positionStride); + PX_ASSERT(m_lockedPositions); + } + if(!m_lockedColors) + { + m_lockedColors = m_vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR, m_colorStride); + PX_ASSERT(m_lockedColors); + } + } +} + +void SamplePointDebugRender::checkUnlock(void) +{ + if(m_vertexbuffer) + { + if(m_lockedPositions) + { + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + m_lockedPositions = 0; + } + if(m_lockedColors) + { + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + m_lockedColors = 0; + } + } +} + +void SamplePointDebugRender::addVert(const PxVec3 &p, const SampleRenderer::RendererColor &color) +{ + PX_ASSERT(m_maxVerts > m_numVerts); + { + checkLock(); + if(m_lockedPositions && m_lockedColors) + { + memcpy(((PxU8*)m_lockedPositions) + (m_positionStride*m_numVerts), &p, sizeof(PxVec3)); + memcpy(((PxU8*)m_lockedColors) + (m_colorStride*m_numVerts), &color, sizeof(SampleRenderer::RendererColor)); + m_numVerts++; + } + } +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTextureAsset.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTextureAsset.cpp new file mode 100644 index 00000000..c6302895 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTextureAsset.cpp @@ -0,0 +1,342 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SampleTextureAsset.h> + +#include <Renderer.h> +#include <RendererTexture2D.h> +#include <RendererTexture2DDesc.h> +#include <RendererMemoryMacros.h> +#include "PxTkBmpLoader.h" + +#include "nv_dds.h" +#include "PxTkFile.h" + +#ifdef RENDERER_ENABLE_TGA_SUPPORT +# include <targa.h> +#endif + +#ifdef RENDERER_ENABLE_PVR_SUPPORT +#include "pvrt.h" +#endif + +using namespace SampleFramework; + +SampleTextureAsset::SampleTextureAsset(SampleRenderer::Renderer &renderer, File &file, const char *path, Type texType) : + SampleAsset(ASSET_TEXTURE, path) +{ + m_texture = 0; + + switch(texType) + { + case DDS: loadDDS(renderer, file); break; + case TGA: loadTGA(renderer, file); break; + case PVR: loadPVR(renderer, file); break; + case BMP: loadBMP(renderer, file); break; + default: PX_ASSERT(0 && "Invalid texture type requested"); break; + } +} + +SampleTextureAsset::~SampleTextureAsset(void) +{ + SAFE_RELEASE(m_texture); +} + +void SampleTextureAsset::loadDDS(SampleRenderer::Renderer &renderer, File &file) +{ + nv_dds::CDDSImage ddsimage; + bool ok = ddsimage.load(&file, false); + PX_ASSERT(ok); + if(ok) + { + SampleRenderer::RendererTexture2DDesc tdesc; + nv_dds::TextureFormat ddsformat = ddsimage.get_format(); + switch(ddsformat) + { + case nv_dds::TextureBGRA: tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_B8G8R8A8; break; + case nv_dds::TextureDXT1: tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_DXT1; break; + case nv_dds::TextureDXT3: tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_DXT3; break; + case nv_dds::TextureDXT5: tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_DXT5; break; + default: break; + } + tdesc.width = ddsimage.get_width(); + tdesc.height = ddsimage.get_height(); + // if there is 1 mipmap, nv_dds reports 0 + tdesc.numLevels = ddsimage.get_num_mipmaps()+1; + PX_ASSERT(tdesc.isValid()); + m_texture = renderer.createTexture2D(tdesc); + PX_ASSERT(m_texture); + if(m_texture) + { + PxU32 pitch = 0; + void *buffer = m_texture->lockLevel(0, pitch); + PX_ASSERT(buffer); + if(buffer) + { + //PxU32 size = ddsimage.get_size(); + + PxU8 *levelDst = (PxU8*)buffer; + const PxU8 *levelSrc = (PxU8*)(unsigned char*)ddsimage; + const PxU32 levelWidth = m_texture->getWidthInBlocks(); + const PxU32 levelHeight = m_texture->getHeightInBlocks(); + const PxU32 rowSrcSize = levelWidth * m_texture->getBlockSize(); + PX_ASSERT(rowSrcSize <= pitch); // the pitch can't be less than the source row size. + for(PxU32 row=0; row<levelHeight; row++) + { + memcpy(levelDst, levelSrc, rowSrcSize); + levelDst += pitch; + levelSrc += rowSrcSize; + } + } + m_texture->unlockLevel(0); + + for(PxU32 i=1; i<tdesc.numLevels; i++) + { + void *buffer = m_texture->lockLevel(i, pitch); + PX_ASSERT(buffer); + if(buffer && pitch ) + { + const nv_dds::CSurface &surface = ddsimage.get_mipmap(i-1); + //PxU32 size = surface.get_size(); + + PxU8 *levelDst = (PxU8*)buffer; + const PxU8 *levelSrc = (PxU8*)(unsigned char*)surface; + const PxU32 levelWidth = SampleRenderer::RendererTexture2D::getFormatNumBlocks(surface.get_width(), m_texture->getFormat()); + const PxU32 levelHeight = SampleRenderer::RendererTexture2D::getFormatNumBlocks(surface.get_height(), m_texture->getFormat()); + const PxU32 rowSrcSize = levelWidth * m_texture->getBlockSize(); + PX_ASSERT(rowSrcSize <= pitch); // the pitch can't be less than the source row size. + for(PxU32 row=0; row<levelHeight; row++) + { + memcpy(levelDst, levelSrc, rowSrcSize); + levelDst += pitch; + levelSrc += rowSrcSize; + } + } + m_texture->unlockLevel(i); + } + } + } +} + +void SampleTextureAsset::loadPVR(SampleRenderer::Renderer& renderer, File& file) +{ +#ifdef RENDERER_ENABLE_PVR_SUPPORT + fseek(&file, 0, SEEK_END); + size_t size = ftell(&file); + fseek(&file, 0, SEEK_SET); + char* fileBuffer = new char[size+1]; + fread(fileBuffer, 1, size, &file); + fclose(&file); + fileBuffer[size] = '\0'; + + const PVRTextureInfo info(fileBuffer); + PX_ASSERT(info.data); + + SampleRenderer::RendererTexture2DDesc tdesc; + if (info.glFormat == GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG) + { + tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_PVR_4BPP; + } + else + { + tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_PVR_2BPP; + } + + tdesc.width = info.width; + tdesc.height = info.height; + tdesc.numLevels = info.mipCount + 1; + tdesc.data = NULL; + + PX_ASSERT(tdesc.isValid()); + m_texture = renderer.createTexture2D(tdesc); + PX_ASSERT(m_texture); + if (!info.data) + { + delete[] fileBuffer; + return; + } + + PxU32 pitch = 0; + PxU8* levelDst = (PxU8*)m_texture->lockLevel(0, pitch); + const PxU8* levelSrc = (PxU8*)info.data; + + PX_ASSERT(levelDst && levelSrc); + { + PxU32 levelWidth = tdesc.width; + PxU32 levelHeight = tdesc.height; + const PxU32 levelSize = m_texture->computeImageByteSize(levelWidth, levelHeight, 1, tdesc.format); + memcpy(levelDst, levelSrc, levelSize); + levelSrc += levelSize; + } + m_texture->unlockLevel(0); + + for(PxU32 i=1; i<tdesc.numLevels; i++) + { + PxU8* levelDst = (PxU8*)m_texture->lockLevel(i, pitch); + PX_ASSERT(levelDst); + { + const PxU32 levelWidth = m_texture->getLevelDimension(tdesc.width, i); + const PxU32 levelHeight = m_texture->getLevelDimension(tdesc.height, i); + const PxU32 levelSize = m_texture->computeImageByteSize(levelWidth, levelHeight, 1, tdesc.format); + memcpy(levelDst, levelSrc, levelSize); + levelSrc += levelSize; + } + m_texture->unlockLevel(i); + } + + delete[] fileBuffer; + +#endif +} + +void SampleTextureAsset::loadTGA(SampleRenderer::Renderer &renderer, File &file) +{ +#ifdef RENDERER_ENABLE_TGA_SUPPORT + tga_image* image = new tga_image(); + bool ok = (TGA_NOERR == tga_read_from_FILE( image, &file )); + + // flip it to make it look correct in the SampleFramework's renderer + tga_flip_vert( image ); + + PX_ASSERT(ok); + if( ok ) + { + SampleRenderer::RendererTexture2DDesc tdesc; + int componentCount = image->pixel_depth/8; + if( componentCount == 3 || componentCount == 4 ) + { + tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_B8G8R8A8; + + tdesc.width = image->width; + tdesc.height = image->height; + + tdesc.numLevels = 1; + PX_ASSERT(tdesc.isValid()); + m_texture = renderer.createTexture2D(tdesc); + PX_ASSERT(m_texture); + + if(m_texture) + { + PxU32 pitch = 0; + void *buffer = m_texture->lockLevel(0, pitch); + PX_ASSERT(buffer); + if(buffer) + { + PxU8 *levelDst = (PxU8*)buffer; + const PxU8 *levelSrc = (PxU8*)image->image_data; + const PxU32 levelWidth = m_texture->getWidthInBlocks(); + const PxU32 levelHeight = m_texture->getHeightInBlocks(); + const PxU32 rowSrcSize = levelWidth * m_texture->getBlockSize(); + PX_ASSERT(rowSrcSize <= pitch); // the pitch can't be less than the source row size. + for(PxU32 row=0; row<levelHeight; row++) + { + if( componentCount == 3 ) + { + // copy per pixel to handle RBG case, based on component count + for(PxU32 col=0; col<levelWidth; col++) + { + *levelDst++ = levelSrc[0]; + *levelDst++ = levelSrc[1]; + *levelDst++ = levelSrc[2]; + *levelDst++ = 0xFF; //alpha + levelSrc += componentCount; + } + } + else + { + memcpy(levelDst, levelSrc, rowSrcSize); + levelDst += pitch == 0xFFFFFFFF ? rowSrcSize : pitch; + levelSrc += rowSrcSize; + } + } + } + m_texture->unlockLevel(0); + } + } + } + tga_free_buffers(image); + delete image; + +#endif /* RENDERER_ENABLE_TGA_SUPPORT */ +} + +void SampleTextureAsset::loadBMP(SampleRenderer::Renderer &renderer, File &file) +{ + PxToolkit::BmpLoader loader; + bool ok = loader.loadBmp(&file); + PX_ASSERT(ok); + if(ok) + { + SampleRenderer::RendererTexture2DDesc tdesc; +#if !defined(RENDERER_PS3) + tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_B8G8R8A8; +#else + tdesc.format = SampleRenderer::RendererTexture2D::FORMAT_R8G8B8A8; +#endif + tdesc.width = loader.mWidth; + tdesc.height = loader.mHeight; + tdesc.numLevels = 1; + PX_ASSERT(tdesc.isValid()); + m_texture = renderer.createTexture2D(tdesc); + PX_ASSERT(m_texture); + if(m_texture) + { + PxU32 pitch = 0; + void *buffer = m_texture->lockLevel(0, pitch); + PX_ASSERT(buffer); + if(buffer) + { + const PxU32 levelWidth = m_texture->getWidthInBlocks(); + const PxU32 levelHeight = m_texture->getHeightInBlocks(); + SampleRenderer::RendererColor* levelDst = (SampleRenderer::RendererColor*)buffer + levelWidth * levelHeight; + const PxU8* levelSrc = (PxU8*)loader.mRGB; + for(PxU32 row=0; row<levelHeight; row++) + { + levelDst -= levelWidth; + // copy per pixel to handle RBG case + for(PxU32 col=0; col<levelWidth; col++) + { + levelDst[col].r = *levelSrc++; + levelDst[col].g = *levelSrc++; + levelDst[col].b = *levelSrc++; + levelDst[col].a = loader.mHasAlpha ? *levelSrc++ : 0xff; + } + } + } + m_texture->unlockLevel(0); + } + } +} + +SampleRenderer::RendererTexture2D *SampleTextureAsset::getTexture(void) +{ + return m_texture; +} + +bool SampleTextureAsset::isOk(void) const +{ + return m_texture ? true : false; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTree.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTree.cpp new file mode 100644 index 00000000..8d24e364 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTree.cpp @@ -0,0 +1,70 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +#include "SampleTree.h" + +using namespace SampleFramework; + +bool Tree::Node::appendChild(Node& node) +{ + if (!node.isRoot() || isOffspringOf(node)) + return false; + + node.mParent = this; + node.mPrev = mTail; + + if (NULL == mTail) + mHead = &node; + else + mTail->mNext = &node; + + mTail = &node; + + return true; +} + +bool Tree::Node::removeChild(Node& node) +{ + if (this != node.mParent) + return false; + + Node* prev = node.mPrev; + Node* next = node.mNext; + + if (NULL == prev) + mHead = next; + else + prev->mNext = next; + + if (NULL == next) + mTail = prev; + else + next->mPrev = prev; + + node.mParent = NULL; + return true; +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTriangleDebugRender.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTriangleDebugRender.cpp new file mode 100644 index 00000000..c596d6ab --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/SampleTriangleDebugRender.cpp @@ -0,0 +1,244 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SampleTriangleDebugRender.h> +#include <Renderer.h> +#include <RendererVertexBuffer.h> +#include <RendererVertexBufferDesc.h> +#include <RendererMesh.h> +#include <RendererMeshDesc.h> +#include <SampleAssetManager.h> +#include <SampleMaterialAsset.h> +#include <RendererMemoryMacros.h> + +using namespace SampleFramework; + +SampleTriangleDebugRender::SampleTriangleDebugRender(SampleRenderer::Renderer &renderer, SampleAssetManager &assetmanager) : + m_renderer(renderer), + m_assetmanager(assetmanager) +{ + m_material = static_cast<SampleMaterialAsset*>(m_assetmanager.getAsset("materials/simple_lit_color.xml", SampleAsset::ASSET_MATERIAL)); + PX_ASSERT(m_material); + PX_ASSERT(m_material->getNumVertexShaders() == 1); + m_meshContext.material = m_material ? m_material->getMaterial(0) : 0; + + m_maxVerts = 0; + m_numVerts = 0; + m_vertexbuffer = 0; + m_mesh = 0; + m_lockedPositions = 0; + m_positionStride = 0; + m_lockedNormals = 0; + m_normalStride = 0; + m_lockedColors = 0; + m_colorStride = 0; +} + +SampleTriangleDebugRender::~SampleTriangleDebugRender(void) +{ + checkUnlock(); + SAFE_RELEASE(m_vertexbuffer); + SAFE_RELEASE(m_mesh); + if(m_material) + { + m_assetmanager.returnAsset(*m_material); + } +} + +void SampleTriangleDebugRender::addTriangle(const PxVec3 &p0, const PxVec3 &p1, const PxVec3 &p2, const SampleRenderer::RendererColor &color) +{ + checkResizeTriangle(m_numVerts+3); + PxVec3 normal = (p1-p0).cross(p2-p0); + normal.normalize(); + addVert(p0, normal, color); + addVert(p1, normal, color); + addVert(p2, normal, color); +} + +void SampleTriangleDebugRender::addTriangle(const PxVec3 &p0, const PxVec3 &p1, const PxVec3 &p2, const PxVec3& n0, const PxVec3& n1, const PxVec3& n2, const SampleRenderer::RendererColor &color) +{ + checkResizeTriangle(m_numVerts+3); + addVert(p0, n0, color); + addVert(p1, n1, color); + addVert(p2, n2, color); +} + +void SampleTriangleDebugRender::queueForRenderTriangle(void) +{ + if(m_meshContext.mesh) + { + checkUnlock(); + m_mesh->setVertexBufferRange(0, m_numVerts); + m_renderer.queueMeshForRender(m_meshContext); + } +} + +void SampleTriangleDebugRender::clearTriangle(void) +{ + m_numVerts = 0; +} + +void SampleTriangleDebugRender::checkResizeTriangle(PxU32 maxVerts) +{ + if(maxVerts > m_maxVerts) + { + m_maxVerts = maxVerts + (PxU32)(maxVerts*0.2f); + + SampleRenderer::RendererVertexBufferDesc vbdesc; + vbdesc.hint = SampleRenderer::RendererVertexBuffer::HINT_DYNAMIC; + vbdesc.semanticFormats[SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION] = SampleRenderer::RendererVertexBuffer::FORMAT_FLOAT3; + vbdesc.semanticFormats[SampleRenderer::RendererVertexBuffer::SEMANTIC_NORMAL] = SampleRenderer::RendererVertexBuffer::FORMAT_FLOAT3; + vbdesc.semanticFormats[SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR] = SampleRenderer::RendererVertexBuffer::FORMAT_COLOR_NATIVE; // Same format as RendererColor + vbdesc.maxVertices = m_maxVerts; + SampleRenderer::RendererVertexBuffer *vertexbuffer = m_renderer.createVertexBuffer(vbdesc); + PX_ASSERT(vertexbuffer); + + if(vertexbuffer) + { + PxU32 positionStride = 0; + void *positions = vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION, positionStride); + + PxU32 normalStride = 0; + void *normals = vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_NORMAL, normalStride); + + PxU32 colorStride = 0; + void *colors = vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR, colorStride); + + PX_ASSERT(positions && colors); + if(positions && colors) + { + if(m_numVerts > 0) + { + // if we have existing verts, copy them to the new VB... + PX_ASSERT(m_lockedPositions); + PX_ASSERT(m_lockedNormals); + PX_ASSERT(m_lockedColors); + if(m_lockedPositions && m_lockedNormals && m_lockedColors) + { + for(PxU32 i=0; i<m_numVerts; i++) + { + memcpy(((PxU8*)positions) + (positionStride*i), ((PxU8*)m_lockedPositions) + (m_positionStride*i), sizeof(PxVec3)); + memcpy(((PxU8*)normals) + (normalStride*i), ((PxU8*)m_lockedNormals) + (m_normalStride*i), sizeof(PxVec3)); + memcpy(((PxU8*)colors) + (colorStride*i), ((PxU8*)m_lockedColors) + (m_colorStride*i), sizeof(SampleRenderer::RendererColor)); + } + } + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_NORMAL); + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + } + } + vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_NORMAL); + vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + } + if(m_vertexbuffer) + { + m_vertexbuffer->release(); + m_vertexbuffer = 0; + m_lockedPositions = 0; + m_positionStride = 0; + m_lockedNormals = 0; + m_normalStride = 0; + m_lockedColors = 0; + m_colorStride = 0; + } + SAFE_RELEASE(m_mesh); + if(vertexbuffer) + { + m_vertexbuffer = vertexbuffer; + SampleRenderer::RendererMeshDesc meshdesc; + meshdesc.primitives = SampleRenderer::RendererMesh::PRIMITIVE_TRIANGLES; + meshdesc.vertexBuffers = &m_vertexbuffer; + meshdesc.numVertexBuffers = 1; + meshdesc.firstVertex = 0; + meshdesc.numVertices = m_numVerts; + m_mesh = m_renderer.createMesh(meshdesc); + PX_ASSERT(m_mesh); + } + m_meshContext.mesh = m_mesh; + m_meshContext.cullMode = SampleRenderer::RendererMeshContext::NONE; + } +} + +void SampleTriangleDebugRender::checkLock(void) +{ + if(m_vertexbuffer) + { + if(!m_lockedPositions) + { + m_lockedPositions = m_vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION, m_positionStride); + PX_ASSERT(m_lockedPositions); + } + if(!m_lockedNormals) + { + m_lockedNormals = m_vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_NORMAL, m_normalStride); + PX_ASSERT(m_lockedNormals); + } + if(!m_lockedColors) + { + m_lockedColors = m_vertexbuffer->lockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR, m_colorStride); + PX_ASSERT(m_lockedColors); + } + } +} + +void SampleTriangleDebugRender::checkUnlock(void) +{ + if(m_vertexbuffer) + { + if(m_lockedPositions) + { + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_POSITION); + m_lockedPositions = 0; + } + if (m_lockedNormals) + { + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_NORMAL); + m_lockedNormals = 0; + } + if(m_lockedColors) + { + m_vertexbuffer->unlockSemantic(SampleRenderer::RendererVertexBuffer::SEMANTIC_COLOR); + m_lockedColors = 0; + } + } +} + +void SampleTriangleDebugRender::addVert(const PxVec3 &p, const PxVec3 &n, const SampleRenderer::RendererColor &color) +{ + PX_ASSERT(m_maxVerts > m_numVerts); + { + checkLock(); + if(m_lockedPositions && m_lockedNormals && m_lockedColors) + { + *(PxVec3*)(((PxU8*)m_lockedPositions) + (m_positionStride*m_numVerts)) = p; + *(PxVec3*)(((PxU8*)m_lockedNormals) + (m_normalStride*m_numVerts)) = n; + *(SampleRenderer::RendererColor*)(((PxU8*)m_lockedColors) + (m_colorStride*m_numVerts)) = color; + + m_numVerts++; + } + } +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/nv_dds.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/nv_dds.cpp new file mode 100644 index 00000000..9bd9628a --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/nv_dds.cpp @@ -0,0 +1,1115 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// PHYSX-CHANGES: +// - Removed dependency on OpenGL. -jdolan +// - MACOS does not always equate to BIG_ENDIAN... fixed it for all platforms. -jdolan + +/////////////////////////////////////////////////////////////////////////////// +// +// Description: +// +// Loads DDS images (DXTC1, DXTC3, DXTC5, RGB (888, 888X), and RGBA (8888) are +// supported) for use in OpenGL. Image is flipped when its loaded as DX images +// are stored with different coordinate system. If file has mipmaps and/or +// cubemaps then these are loaded as well. Volume textures can be loaded as +// well but they must be uncompressed. +// +// When multiple textures are loaded (i.e a volume or cubemap texture), +// additional faces can be accessed using the array operator. +// +// The mipmaps for each face are also stored in a list and can be accessed like +// so: image.get_mipmap() (which accesses the first mipmap of the first +// image). To get the number of mipmaps call the get_num_mipmaps function for +// a given texture. +// +// Call the is_volume() or is_cubemap() function to check that a loaded image +// is a volume or cubemap texture respectively. If a volume texture is loaded +// then the get_depth() function should return a number greater than 1. +// Mipmapped volume textures and DXTC compressed volume textures are supported. +// +/////////////////////////////////////////////////////////////////////////////// +// +// Update: 9/15/2003 +// +// Added functions to create new image from a buffer of pixels. Added function +// to save current image to disk. +// +// Update: 6/11/2002 +// +// Added some convenience functions to handle uploading textures to OpenGL. The +// following functions have been added: +// +// bool upload_texture1D(); +// bool upload_texture2D(unsigned int imageIndex = 0, GLenum target = GL_TEXTURE_2D); +// bool upload_textureRectangle(); +// bool upload_texture3D(); +// bool upload_textureCubemap(); +// +// See function implementation below for instructions/comments on using each +// function. +// +// The open function has also been updated to take an optional second parameter +// specifying whether the image should be flipped on load. This defaults to +// true. +// +/////////////////////////////////////////////////////////////////////////////// +// Sample usage +/////////////////////////////////////////////////////////////////////////////// +// +// Loading a compressed texture: +// +// CDDSImage image; +// GLuint texobj; +// +// image.load("compressed.dds"); +// +// glGenTextures(1, &texobj); +// glEnable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, texobj); +// +// glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, image.get_format(), +// image.get_width(), image.get_height(), 0, image.get_size(), +// image); +// +// for (int i = 0; i < image.get_num_mipmaps(); i++) +// { +// CSurface mipmap = image.get_mipmap(i); +// +// glCompressedTexImage2DARB(GL_TEXTURE_2D, i+1, image.get_format(), +// mipmap.get_width(), mipmap.get_height(), 0, mipmap.get_size(), +// mipmap); +// } +/////////////////////////////////////////////////////////////////////////////// +// +// Loading an uncompressed texture: +// +// CDDSImage image; +// GLuint texobj; +// +// image.load("uncompressed.dds"); +// +// glGenTextures(1, &texobj); +// glEnable(GL_TEXTURE_2D); +// glBindTexture(GL_TEXTURE_2D, texobj); +// +// glTexImage2D(GL_TEXTURE_2D, 0, image.get_components(), image.get_width(), +// image.get_height(), 0, image.get_format(), GL_UNSIGNED_BYTE, image); +// +// for (int i = 0; i < image.get_num_mipmaps(); i++) +// { +// glTexImage2D(GL_TEXTURE_2D, i+1, image.get_components(), +// image.get_mipmap(i).get_width(), image.get_mipmap(i).get_height(), +// 0, image.get_format(), GL_UNSIGNED_BYTE, image.get_mipmap(i)); +// } +// +/////////////////////////////////////////////////////////////////////////////// +// +// Loading an uncompressed cubemap texture: +// +// CDDSImage image; +// GLuint texobj; +// GLenum target; +// +// image.load("cubemap.dds"); +// +// glGenTextures(1, &texobj); +// glEnable(GL_TEXTURE_CUBE_MAP_ARB); +// glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texobj); +// +// for (int n = 0; n < 6; n++) +// { +// target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB+n; +// +// glTexImage2D(target, 0, image.get_components(), image[n].get_width(), +// image[n].get_height(), 0, image.get_format(), GL_UNSIGNED_BYTE, +// image[n]); +// +// for (int i = 0; i < image[n].get_num_mipmaps(); i++) +// { +// glTexImage2D(target, i+1, image.get_components(), +// image[n].get_mipmap(i).get_width(), +// image[n].get_mipmap(i).get_height(), 0, +// image.get_format(), GL_UNSIGNED_BYTE, image[n].get_mipmap(i)); +// } +// } +// +/////////////////////////////////////////////////////////////////////////////// +// +// Loading a volume texture: +// +// CDDSImage image; +// GLuint texobj; +// +// image.load("volume.dds"); +// +// glGenTextures(1, &texobj); +// glEnable(GL_TEXTURE_3D); +// glBindTexture(GL_TEXTURE_3D, texobj); +// +// PFNGLTEXIMAGE3DPROC glTexImage3D; +// glTexImage3D(GL_TEXTURE_3D, 0, image.get_components(), image.get_width(), +// image.get_height(), image.get_depth(), 0, image.get_format(), +// GL_UNSIGNED_BYTE, image); +// +// for (int i = 0; i < image.get_num_mipmaps(); i++) +// { +// glTexImage3D(GL_TEXTURE_3D, i+1, image.get_components(), +// image[0].get_mipmap(i).get_width(), +// image[0].get_mipmap(i).get_height(), +// image[0].get_mipmap(i).get_depth(), 0, image.get_format(), +// GL_UNSIGNED_BYTE, image[0].get_mipmap(i)); +// } + +#include <stdio.h> +#include <assert.h> +#include "PxTkFile.h" +#include "nv_dds.h" + +using namespace std; +using namespace nv_dds; + +/////////////////////////////////////////////////////////////////////////////// +// CDDSImage public functions + +/////////////////////////////////////////////////////////////////////////////// +// default constructor +CDDSImage::CDDSImage() + : m_format(TextureUnknown), + m_components(0), + m_type(TextureNone), + m_valid(false) +{ +} + +CDDSImage::~CDDSImage() +{ +} + +void CDDSImage::create_textureFlat(TextureFormat format, unsigned int components, const CTexture &baseImage) +{ + assert(format != 0); + assert(components != 0); + assert(baseImage.get_depth() == 1); + + // remove any existing images + clear(); + + m_format = format; + m_components = components; + m_type = TextureFlat; + + m_images.push_back(baseImage); + + m_valid = true; +} + +void CDDSImage::create_texture3D(TextureFormat format, unsigned int components, const CTexture &baseImage) +{ + assert(format != 0); + assert(components != 0); + assert(baseImage.get_depth() > 1); + + // remove any existing images + clear(); + + m_format = format; + m_components = components; + m_type = Texture3D; + + m_images.push_back(baseImage); + + m_valid = true; +} + +inline bool same_size(const CTexture &a, const CTexture &b) +{ + if (a.get_width() != b.get_width()) + return false; + if (a.get_height() != b.get_height()) + return false; + if (a.get_depth() != b.get_depth()) + return false; + + return true; +} + +void CDDSImage::create_textureCubemap(TextureFormat format, unsigned int components, + const CTexture &positiveX, const CTexture &negativeX, + const CTexture &positiveY, const CTexture &negativeY, + const CTexture &positiveZ, const CTexture &negativeZ) +{ + assert(format != 0); + assert(components != 0); + assert(positiveX.get_depth() == 1); + + // verify that all dimensions are the same + assert(same_size(positiveX, negativeX)); + assert(same_size(positiveX, positiveY)); + assert(same_size(positiveX, negativeY)); + assert(same_size(positiveX, positiveZ)); + assert(same_size(positiveX, negativeZ)); + + // remove any existing images + clear(); + + m_format = format; + m_components = components; + m_type = TextureCubemap; + + m_images.push_back(positiveX); + m_images.push_back(negativeX); + m_images.push_back(positiveY); + m_images.push_back(negativeY); + m_images.push_back(positiveZ); + m_images.push_back(negativeZ); + + m_valid = true; +} + +/////////////////////////////////////////////////////////////////////////////// +// loads DDS image +// +// filename - fully qualified name of DDS image +// flipImage - specifies whether image is flipped on load, default is true +bool CDDSImage::load(string filename, bool flipImage) +{ + assert(filename.length() != 0); + + // clear any previously loaded images + clear(); + + // open file + SampleRenderer::File *fp = 0; + PxToolkit::fopen_s(&fp, filename.c_str(), "rb"); + if (fp == NULL) + return false; + + bool success = load(fp, flipImage); + + fclose(fp); + + return success; +} + +/////////////////////////////////////////////////////////////////////////////// +// loads DDS image from FILE stream +// +// filename - fully qualified name of DDS image +// flipImage - specifies whether image is flipped on load, default is true +bool CDDSImage::load(SampleRenderer::File* fp, bool flipImage) +{ + assert(fp != 0); + + // clear any previously loaded images + clear(); + + // read in file marker, make sure its a DDS file + char filecode[4]; + size_t numRead = fread(filecode, 1, 4, fp); + if(numRead != 4) { return false; } + + if (strncmp(filecode, "DDS ", 4) != 0) + { + return false; + } + + // read in DDS header + DDS_HEADER ddsh; + numRead = fread(&ddsh, 1, sizeof(DDS_HEADER), fp); + if(numRead != sizeof(DDS_HEADER)) { return false; } + + swap_endian(&ddsh.dwSize); + swap_endian(&ddsh.dwFlags); + swap_endian(&ddsh.dwHeight); + swap_endian(&ddsh.dwWidth); + swap_endian(&ddsh.dwPitchOrLinearSize); + swap_endian(&ddsh.dwMipMapCount); + swap_endian(&ddsh.ddspf.dwSize); + swap_endian(&ddsh.ddspf.dwFlags); + swap_endian(&ddsh.ddspf.dwFourCC); + swap_endian(&ddsh.ddspf.dwRGBBitCount); + swap_endian(&ddsh.dwCaps1); + swap_endian(&ddsh.dwCaps2); + + // default to flat texture type (1D, 2D, or rectangle) + m_type = TextureFlat; + + // check if image is a cubemap + if (ddsh.dwCaps2 & DDSF_CUBEMAP) + m_type = TextureCubemap; + + // check if image is a volume texture + if ((ddsh.dwCaps2 & DDSF_VOLUME) && (ddsh.dwDepth > 0)) + m_type = Texture3D; + + // figure out what the image format is + if (ddsh.ddspf.dwFlags & DDSF_FOURCC) + { + switch(ddsh.ddspf.dwFourCC) + { + case FOURCC_DXT1: + m_format = TextureDXT1; + m_components = 3; + break; + case FOURCC_DXT3: + m_format = TextureDXT3; + m_components = 4; + break; + case FOURCC_DXT5: + m_format = TextureDXT5; + m_components = 4; + break; + default: + return false; + } + } + else if (ddsh.ddspf.dwFlags == DDSF_RGBA && ddsh.ddspf.dwRGBBitCount == 32) + { + m_format = TextureBGRA; + m_components = 4; + } + else if (ddsh.ddspf.dwFlags == DDSF_RGB && ddsh.ddspf.dwRGBBitCount == 32) + { + m_format = TextureBGRA; + m_components = 4; + } + else if (ddsh.ddspf.dwFlags == DDSF_RGB && ddsh.ddspf.dwRGBBitCount == 24) + { + m_format = TextureBGR; + m_components = 3; + } + else if (ddsh.ddspf.dwRGBBitCount == 8) + { + m_format = TextureLuminance; + m_components = 1; + } + else + { + return false; + } + + // store primary surface width/height/depth + unsigned int width, height, depth; + width = ddsh.dwWidth; + height = ddsh.dwHeight; + depth = clamp_size(ddsh.dwDepth); // set to 1 if 0 + + // use correct size calculation function depending on whether image is + // compressed + unsigned int (CDDSImage::*sizefunc)(unsigned int, unsigned int); + sizefunc = (is_compressed() ? &CDDSImage::size_dxtc : &CDDSImage::size_rgb); + + // load all surfaces for the image (6 surfaces for cubemaps) + for (unsigned int n = 0; n < (unsigned int)(m_type == TextureCubemap ? 6 : 1); n++) + { + // add empty texture object + m_images.push_back(CTexture()); + + // get reference to newly added texture object + CTexture &img = m_images[n]; + + // calculate surface size + unsigned int size = (this->*sizefunc)(width, height)*depth; + + // load surface + unsigned char *pixels = new unsigned char[size]; + numRead = fread(pixels, 1, size, fp); + if(numRead != size) { delete [] pixels; return false; } + + img.create(width, height, depth, size, pixels); + + delete [] pixels; + + if (flipImage) flip(img); + + unsigned int w = clamp_size(width >> 1); + unsigned int h = clamp_size(height >> 1); + unsigned int d = clamp_size(depth >> 1); + + // store number of mipmaps + unsigned int numMipmaps = ddsh.dwMipMapCount; + + // number of mipmaps in file includes main surface so decrease count + // by one + if (numMipmaps != 0) + numMipmaps--; + + // load all mipmaps for current surface + for (unsigned int i = 0; i < numMipmaps && (w || h); i++) + { + // add empty surface + img.add_mipmap(CSurface()); + + // get reference to newly added mipmap + CSurface &mipmap = img.get_mipmap(i); + + // calculate mipmap size + size = (this->*sizefunc)(w, h)*d; + + unsigned char *pixels = new unsigned char[size]; + numRead = fread(pixels, 1, size, fp); + if(numRead != size) { delete [] pixels; return false; } + + mipmap.create(w, h, d, size, pixels); + + delete [] pixels; + + if (flipImage) flip(mipmap); + + // shrink to next power of 2 + w = clamp_size(w >> 1); + h = clamp_size(h >> 1); + d = clamp_size(d >> 1); + } + } + + // swap cubemaps on y axis (since image is flipped in OGL) + if (m_type == TextureCubemap && flipImage) + { + CTexture tmp; + tmp = m_images[3]; + m_images[3] = m_images[2]; + m_images[2] = tmp; + } + + m_valid = true; + + return true; +} + +void CDDSImage::write_texture(const CTexture &texture, SampleRenderer::File *fp) +{ + assert(get_num_mipmaps() == texture.get_num_mipmaps()); + + fwrite(texture, 1, texture.get_size(), fp); + + for (unsigned int i = 0; i < texture.get_num_mipmaps(); i++) + { + const CSurface &mipmap = texture.get_mipmap(i); + fwrite(mipmap, 1, mipmap.get_size(), fp); + } +} + +bool CDDSImage::save(std::string filename, bool flipImage) +{ + assert(m_valid); + assert(m_type != TextureNone); + + // open file + SampleRenderer::File* fp = 0; + PxToolkit::fopen_s(&fp, filename.c_str(), "wb"); + if (fp == NULL) + return false; + + bool result = save(fp, flipImage); + + fclose(fp); + + return result; +} + +bool CDDSImage::save(SampleRenderer::File* fp, bool flipImage) +{ + assert(m_valid); + assert(m_type != TextureNone); + assert(fp != 0); + + DDS_HEADER ddsh; + unsigned int headerSize = sizeof(DDS_HEADER); + memset(&ddsh, 0, headerSize); + ddsh.dwSize = headerSize; + ddsh.dwFlags = DDSF_CAPS | DDSF_WIDTH | DDSF_HEIGHT | DDSF_PIXELFORMAT; + ddsh.dwHeight = get_height(); + ddsh.dwWidth = get_width(); + + if (is_compressed()) + { + ddsh.dwFlags |= DDSF_LINEARSIZE; + ddsh.dwPitchOrLinearSize = get_size(); + } + else + { + ddsh.dwFlags |= DDSF_PITCH; + ddsh.dwPitchOrLinearSize = get_dword_aligned_linesize(get_width(), m_components * 8); + } + + if (m_type == Texture3D) + { + ddsh.dwFlags |= DDSF_DEPTH; + ddsh.dwDepth = get_depth(); + } + + if (get_num_mipmaps() > 0) + { + ddsh.dwFlags |= DDSF_MIPMAPCOUNT; + ddsh.dwMipMapCount = get_num_mipmaps() + 1; + } + + ddsh.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); + + if (is_compressed()) + { + ddsh.ddspf.dwFlags = DDSF_FOURCC; + + if (m_format == TextureDXT1) + ddsh.ddspf.dwFourCC = FOURCC_DXT1; + if (m_format == TextureDXT3) + ddsh.ddspf.dwFourCC = FOURCC_DXT3; + if (m_format == TextureDXT5) + ddsh.ddspf.dwFourCC = FOURCC_DXT5; + } + else + { + ddsh.ddspf.dwFlags = (m_components == 4) ? DDSF_RGBA : DDSF_RGB; + ddsh.ddspf.dwRGBBitCount = m_components * 8; + ddsh.ddspf.dwRBitMask = 0x00ff0000; + ddsh.ddspf.dwGBitMask = 0x0000ff00; + ddsh.ddspf.dwBBitMask = 0x000000ff; + + if (m_components == 4) + { + ddsh.ddspf.dwFlags |= DDSF_ALPHAPIXELS; + ddsh.ddspf.dwABitMask = 0xff000000; + } + } + + ddsh.dwCaps1 = DDSF_TEXTURE; + + if (m_type == TextureCubemap) + { + ddsh.dwCaps1 |= DDSF_COMPLEX; + ddsh.dwCaps2 = DDSF_CUBEMAP | DDSF_CUBEMAP_ALL_FACES; + } + + if (m_type == Texture3D) + { + ddsh.dwCaps1 |= DDSF_COMPLEX; + ddsh.dwCaps2 = DDSF_VOLUME; + } + + if (get_num_mipmaps() > 0) + ddsh.dwCaps1 |= DDSF_COMPLEX | DDSF_MIPMAP; + + // write file header + fwrite("DDS ", 1, 4, fp); + + // write dds header + fwrite(&ddsh, 1, sizeof(DDS_HEADER), fp); + + if (m_type != TextureCubemap) + { + CTexture tex = m_images[0]; + if (flipImage) flip_texture(tex); + write_texture(tex, fp); + } + else + { + assert(m_images.size() == 6); + + for (unsigned int i = 0; i < m_images.size(); i++) + { + CTexture cubeFace; + + if (i == 2) + cubeFace = m_images[3]; + else if (i == 3) + cubeFace = m_images[2]; + else + cubeFace = m_images[i]; + + if (flipImage) flip_texture(cubeFace); + write_texture(cubeFace, fp); + } + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// free image memory +void CDDSImage::clear() +{ + m_components = 0; + m_format = TextureUnknown; + m_type = TextureNone; + m_valid = false; + + m_images.clear(); +} + +/////////////////////////////////////////////////////////////////////////////// +// clamps input size to [1-size] +inline unsigned int CDDSImage::clamp_size(unsigned int size) +{ + if (size <= 0) + size = 1; + + return size; +} + +/////////////////////////////////////////////////////////////////////////////// +// CDDSImage private functions +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// calculates size of DXTC texture in bytes +inline unsigned int CDDSImage::size_dxtc(unsigned int width, unsigned int height) +{ + return ((width+3)/4)*((height+3)/4)* + (m_format == TextureDXT1 ? 8 : 16); +} + +/////////////////////////////////////////////////////////////////////////////// +// calculates size of uncompressed RGB texture in bytes +inline unsigned int CDDSImage::size_rgb(unsigned int width, unsigned int height) +{ + return width*height*m_components; +} + +/////////////////////////////////////////////////////////////////////////////// +// Swap the bytes in a 32 bit value +inline void CDDSImage::swap_endian(void *val) +{ +#if defined(NV_DDS_BIG_ENDIAN) + unsigned int *ival = (unsigned int *)val; + + *ival = ((*ival >> 24) & 0x000000ff) | + ((*ival >> 8) & 0x0000ff00) | + ((*ival << 8) & 0x00ff0000) | + ((*ival << 24) & 0xff000000); +#else + (void)val; +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +// flip image around X axis +void CDDSImage::flip(CSurface &surface) +{ + unsigned int linesize; + unsigned int offset; + + if (!is_compressed()) + { + assert(surface.get_depth() > 0); + + unsigned int imagesize = surface.get_size()/surface.get_depth(); + linesize = imagesize / surface.get_height(); + + for (unsigned int n = 0; n < surface.get_depth(); n++) + { + offset = imagesize*n; + unsigned char *top = (unsigned char*)surface + offset; + unsigned char *bottom = top + (imagesize-linesize); + + for (unsigned int i = 0; i < (surface.get_height() >> 1); i++) + { + swap(bottom, top, linesize); + + top += linesize; + bottom -= linesize; + } + } + } + else + { + void (CDDSImage::*flipblocks)(DXTColBlock*, unsigned int); + unsigned int xblocks = surface.get_width() / 4; + unsigned int yblocks = surface.get_height() / 4; + unsigned int blocksize; + + switch (m_format) + { + case TextureDXT1: + blocksize = 8; + flipblocks = &CDDSImage::flip_blocks_dxtc1; + break; + case TextureDXT3: + blocksize = 16; + flipblocks = &CDDSImage::flip_blocks_dxtc3; + break; + case TextureDXT5: + blocksize = 16; + flipblocks = &CDDSImage::flip_blocks_dxtc5; + break; + default: + return; + } + + linesize = xblocks * blocksize; + + DXTColBlock *top; + DXTColBlock *bottom; + + for (unsigned int j = 0; j < (yblocks >> 1); j++) + { + top = (DXTColBlock*)((unsigned char*)surface+ j * linesize); + bottom = (DXTColBlock*)((unsigned char*)surface + (((yblocks-j)-1) * linesize)); + + (this->*flipblocks)(top, xblocks); + (this->*flipblocks)(bottom, xblocks); + + swap(bottom, top, linesize); + } + } +} + +void CDDSImage::flip_texture(CTexture &texture) +{ + flip(texture); + + for (unsigned int i = 0; i < texture.get_num_mipmaps(); i++) + { + flip(texture.get_mipmap(i)); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// swap to sections of memory +void CDDSImage::swap(void *byte1, void *byte2, unsigned int size) +{ + unsigned char *tmp = new unsigned char[size]; + + memcpy(tmp, byte1, size); + memcpy(byte1, byte2, size); + memcpy(byte2, tmp, size); + + delete [] tmp; +} + +/////////////////////////////////////////////////////////////////////////////// +// flip a DXT1 color block +void CDDSImage::flip_blocks_dxtc1(DXTColBlock *line, unsigned int numBlocks) +{ + DXTColBlock *curblock = line; + + for (unsigned int i = 0; i < numBlocks; i++) + { + swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char)); + swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char)); + + curblock++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// flip a DXT3 color block +void CDDSImage::flip_blocks_dxtc3(DXTColBlock *line, unsigned int numBlocks) +{ + DXTColBlock *curblock = line; + DXT3AlphaBlock *alphablock; + + for (unsigned int i = 0; i < numBlocks; i++) + { + alphablock = (DXT3AlphaBlock*)curblock; + + swap(&alphablock->row[0], &alphablock->row[3], sizeof(unsigned short)); + swap(&alphablock->row[1], &alphablock->row[2], sizeof(unsigned short)); + + curblock++; + + swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char)); + swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char)); + + curblock++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// flip a DXT5 alpha block +void CDDSImage::flip_dxt5_alpha(DXT5AlphaBlock *block) +{ + unsigned char gBits[4][4]; + + const unsigned int mask = 0x00000007; // bits = 00 00 01 11 + unsigned int bits = 0; + memcpy(&bits, &block->row[0], sizeof(unsigned char) * 3); + + gBits[0][0] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[0][1] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[0][2] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[0][3] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[1][0] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[1][1] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[1][2] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[1][3] = (unsigned char)(bits & mask); + + bits = 0; + memcpy(&bits, &block->row[3], sizeof(unsigned char) * 3); + + gBits[2][0] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[2][1] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[2][2] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[2][3] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[3][0] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[3][1] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[3][2] = (unsigned char)(bits & mask); + bits >>= 3; + gBits[3][3] = (unsigned char)(bits & mask); + + unsigned int *pBits = ((unsigned int*) &(block->row[0])); + + *pBits = *pBits | (gBits[3][0] << 0); + *pBits = *pBits | (gBits[3][1] << 3); + *pBits = *pBits | (gBits[3][2] << 6); + *pBits = *pBits | (gBits[3][3] << 9); + + *pBits = *pBits | (gBits[2][0] << 12); + *pBits = *pBits | (gBits[2][1] << 15); + *pBits = *pBits | (gBits[2][2] << 18); + *pBits = *pBits | (gBits[2][3] << 21); + + pBits = ((unsigned int*) &(block->row[3])); + +#if defined(NV_DDS_BIG_ENDIAN) + *pBits &= 0x000000ff; +#else + *pBits &= 0xff000000; +#endif + + *pBits = *pBits | (gBits[1][0] << 0); + *pBits = *pBits | (gBits[1][1] << 3); + *pBits = *pBits | (gBits[1][2] << 6); + *pBits = *pBits | (gBits[1][3] << 9); + + *pBits = *pBits | (gBits[0][0] << 12); + *pBits = *pBits | (gBits[0][1] << 15); + *pBits = *pBits | (gBits[0][2] << 18); + *pBits = *pBits | (gBits[0][3] << 21); +} + +/////////////////////////////////////////////////////////////////////////////// +// flip a DXT5 color block +void CDDSImage::flip_blocks_dxtc5(DXTColBlock *line, unsigned int numBlocks) +{ + DXTColBlock *curblock = line; + DXT5AlphaBlock *alphablock; + + for (unsigned int i = 0; i < numBlocks; i++) + { + alphablock = (DXT5AlphaBlock*)curblock; + + flip_dxt5_alpha(alphablock); + + curblock++; + + swap(&curblock->row[0], &curblock->row[3], sizeof(unsigned char)); + swap(&curblock->row[1], &curblock->row[2], sizeof(unsigned char)); + + curblock++; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// CTexture implementation +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// default constructor +CTexture::CTexture() + : CSurface() // initialize base class part +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// creates an empty texture +CTexture::CTexture(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels) + : CSurface(w, h, d, imgsize, pixels) // initialize base class part +{ +} + +CTexture::~CTexture() +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// copy constructor +CTexture::CTexture(const CTexture ©) + : CSurface(copy) +{ + for (unsigned int i = 0; i < copy.get_num_mipmaps(); i++) + m_mipmaps.push_back(copy.get_mipmap(i)); +} + +/////////////////////////////////////////////////////////////////////////////// +// assignment operator +CTexture &CTexture::operator= (const CTexture &rhs) +{ + if (this != &rhs) + { + CSurface::operator = (rhs); + + m_mipmaps.clear(); + for (unsigned int i = 0; i < rhs.get_num_mipmaps(); i++) + m_mipmaps.push_back(rhs.get_mipmap(i)); + } + + return *this; +} + +void CTexture::create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels) +{ + CSurface::create(w, h, d, imgsize, pixels); + + m_mipmaps.clear(); +} + +void CTexture::clear() +{ + CSurface::clear(); + + m_mipmaps.clear(); +} + +/////////////////////////////////////////////////////////////////////////////// +// CSurface implementation +/////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// default constructor +CSurface::CSurface() + : m_width(0), + m_height(0), + m_depth(0), + m_size(0), + m_pixels(NULL) +{ +} + +/////////////////////////////////////////////////////////////////////////////// +// creates an empty image +CSurface::CSurface(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels) + : m_width(0), + m_height(0), + m_depth(0), + m_size(0), + m_pixels(NULL) +{ + create(w, h, d, imgsize, pixels); +} + +/////////////////////////////////////////////////////////////////////////////// +// copy constructor +CSurface::CSurface(const CSurface ©) + : m_width(0), + m_height(0), + m_depth(0), + m_size(0), + m_pixels(NULL) +{ + if (copy.get_size() != 0) + { + m_size = copy.get_size(); + m_width = copy.get_width(); + m_height = copy.get_height(); + m_depth = copy.get_depth(); + + m_pixels = new unsigned char[m_size]; + memcpy(m_pixels, copy, m_size); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// assignment operator +CSurface &CSurface::operator= (const CSurface &rhs) +{ + if (this != &rhs) + { + clear(); + + if (rhs.get_size()) + { + m_size = rhs.get_size(); + m_width = rhs.get_width(); + m_height = rhs.get_height(); + m_depth = rhs.get_depth(); + + m_pixels = new unsigned char[m_size]; + memcpy(m_pixels, rhs, m_size); + } + } + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// +// clean up image memory +CSurface::~CSurface() +{ + clear(); +} + +/////////////////////////////////////////////////////////////////////////////// +// returns a pointer to image +CSurface::operator unsigned char*() const +{ + return m_pixels; +} + +/////////////////////////////////////////////////////////////////////////////// +// creates an empty image +void CSurface::create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels) +{ + assert(w != 0); + assert(h != 0); + assert(d != 0); + assert(imgsize != 0); + assert(pixels); + + clear(); + + m_width = w; + m_height = h; + m_depth = d; + m_size = imgsize; + m_pixels = new unsigned char[imgsize]; + memcpy(m_pixels, pixels, imgsize); +} + +/////////////////////////////////////////////////////////////////////////////// +// free surface memory +void CSurface::clear() +{ + if (m_pixels != NULL) + { + delete [] m_pixels; + m_pixels = NULL; + } +} diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/nv_dds.h b/PhysX_3.4/Samples/SampleFramework/framework/src/nv_dds.h new file mode 100644 index 00000000..cafe65bc --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/nv_dds.h @@ -0,0 +1,378 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. + +// PHYSX-CHANGES: +// - Removed dependency on OpenGL. -jdolan +// - MACOS does not always equate to BIG_ENDIAN... fixed it for all platforms. -jdolan +// - 64 bit fix for unix based platforms (replaced unsigned long with unsigned int) -sschirm + +#ifndef NV_DDS_H +#define NV_DDS_H + +#include <string> +#include <deque> +#include <assert.h> +#include <stdio.h> + +#include <RendererConfig.h> + +#if defined(__APPLE__) + #if BYTE_ORDER == BIG_ENDIAN + #define NV_DDS_BIG_ENDIAN + #endif +#elif defined(RENDERER_XBOX360) && _XBOX_VER == 200 + #define NV_DDS_BIG_ENDIAN +#elif defined(RENDERER_PS3) + #define NV_DDS_BIG_ENDIAN +#elif defined(RENDERER_WIIU) + #define NV_DDS_BIG_ENDIAN +#endif + +namespace nv_dds +{ + // surface description flags + const unsigned int DDSF_CAPS = 0x00000001l; + const unsigned int DDSF_HEIGHT = 0x00000002l; + const unsigned int DDSF_WIDTH = 0x00000004l; + const unsigned int DDSF_PITCH = 0x00000008l; + const unsigned int DDSF_PIXELFORMAT = 0x00001000l; + const unsigned int DDSF_MIPMAPCOUNT = 0x00020000l; + const unsigned int DDSF_LINEARSIZE = 0x00080000l; + const unsigned int DDSF_DEPTH = 0x00800000l; + + // pixel format flags + const unsigned int DDSF_ALPHAPIXELS = 0x00000001l; + const unsigned int DDSF_FOURCC = 0x00000004l; + const unsigned int DDSF_RGB = 0x00000040l; + const unsigned int DDSF_RGBA = 0x00000041l; + + // dwCaps1 flags + const unsigned int DDSF_COMPLEX = 0x00000008l; + const unsigned int DDSF_TEXTURE = 0x00001000l; + const unsigned int DDSF_MIPMAP = 0x00400000l; + + // dwCaps2 flags + const unsigned int DDSF_CUBEMAP = 0x00000200l; + const unsigned int DDSF_CUBEMAP_POSITIVEX = 0x00000400l; + const unsigned int DDSF_CUBEMAP_NEGATIVEX = 0x00000800l; + const unsigned int DDSF_CUBEMAP_POSITIVEY = 0x00001000l; + const unsigned int DDSF_CUBEMAP_NEGATIVEY = 0x00002000l; + const unsigned int DDSF_CUBEMAP_POSITIVEZ = 0x00004000l; + const unsigned int DDSF_CUBEMAP_NEGATIVEZ = 0x00008000l; + const unsigned int DDSF_CUBEMAP_ALL_FACES = 0x0000FC00l; + const unsigned int DDSF_VOLUME = 0x00200000l; + + // compressed texture types + const unsigned int FOURCC_DXT1 = 0x31545844l; //(MAKEFOURCC('D','X','T','1')) + const unsigned int FOURCC_DXT3 = 0x33545844l; //(MAKEFOURCC('D','X','T','3')) + const unsigned int FOURCC_DXT5 = 0x35545844l; //(MAKEFOURCC('D','X','T','5')) + + struct DXTColBlock + { + unsigned short col0; + unsigned short col1; + + unsigned char row[4]; + }; + + struct DXT3AlphaBlock + { + unsigned short row[4]; + }; + + struct DXT5AlphaBlock + { + unsigned char alpha0; + unsigned char alpha1; + + unsigned char row[6]; + }; + + struct DDS_PIXELFORMAT + { + unsigned int dwSize; + unsigned int dwFlags; + unsigned int dwFourCC; + unsigned int dwRGBBitCount; + unsigned int dwRBitMask; + unsigned int dwGBitMask; + unsigned int dwBBitMask; + unsigned int dwABitMask; + }; + + struct DDS_HEADER + { + unsigned int dwSize; + unsigned int dwFlags; + unsigned int dwHeight; + unsigned int dwWidth; + unsigned int dwPitchOrLinearSize; + unsigned int dwDepth; + unsigned int dwMipMapCount; + unsigned int dwReserved1[11]; + DDS_PIXELFORMAT ddspf; + unsigned int dwCaps1; + unsigned int dwCaps2; + unsigned int dwReserved2[3]; + }; + + enum TextureType + { + TextureNone, + TextureFlat, // 1D, 2D, and rectangle textures + Texture3D, + TextureCubemap + }; + + enum TextureFormat + { + TextureUnknown=0, + TextureBGRA, + TextureBGR, + TextureLuminance, + TextureDXT1, + TextureDXT3, + TextureDXT5, + }; + + class CSurface + { + public: + CSurface(); + CSurface(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels); + CSurface(const CSurface ©); + CSurface &operator= (const CSurface &rhs); + virtual ~CSurface(); + + operator unsigned char*() const; + + virtual void create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels); + virtual void clear(); + + inline unsigned int get_width() const { return m_width; } + inline unsigned int get_height() const { return m_height; } + inline unsigned int get_depth() const { return m_depth; } + inline unsigned int get_size() const { return m_size; } + + private: + unsigned int m_width; + unsigned int m_height; + unsigned int m_depth; + unsigned int m_size; + + unsigned char *m_pixels; + }; + + class CTexture : public CSurface + { + friend class CDDSImage; + + public: + CTexture(); + CTexture(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels); + CTexture(const CTexture ©); + CTexture &operator= (const CTexture &rhs); + ~CTexture(); + + void create(unsigned int w, unsigned int h, unsigned int d, unsigned int imgsize, const unsigned char *pixels); + void clear(); + + inline const CSurface &get_mipmap(unsigned int index) const + { + assert(!m_mipmaps.empty()); + assert(index < m_mipmaps.size()); + + return m_mipmaps[index]; + } + + inline void add_mipmap(const CSurface &mipmap) + { + m_mipmaps.push_back(mipmap); + } + + inline unsigned int get_num_mipmaps() const { return (unsigned int)m_mipmaps.size(); } + + protected: + inline CSurface &get_mipmap(unsigned int index) + { + assert(!m_mipmaps.empty()); + assert(index < m_mipmaps.size()); + + return m_mipmaps[index]; + } + + private: + std::deque<CSurface> m_mipmaps; + }; + + class CDDSImage + { + public: + CDDSImage(); + ~CDDSImage(); + + void create_textureFlat(TextureFormat format, unsigned int components, const CTexture &baseImage); + void create_texture3D(TextureFormat format, unsigned int components, const CTexture &baseImage); + void create_textureCubemap(TextureFormat format, unsigned int components, + const CTexture &positiveX, const CTexture &negativeX, + const CTexture &positiveY, const CTexture &negativeY, + const CTexture &positiveZ, const CTexture &negativeZ); + + void clear(); + bool load(std::string filename, bool flipImage = true); + bool load(SampleRenderer::File* fp, bool flipImage = true); + bool save(std::string filename, bool flipImage = true); + bool save(SampleRenderer::File* fp, bool flipImage = true); + + inline operator unsigned char*() + { + assert(m_valid); + assert(!m_images.empty()); + + return m_images[0]; + } + + inline unsigned int get_width() + { + assert(m_valid); + assert(!m_images.empty()); + + return m_images[0].get_width(); + } + + inline unsigned int get_height() + { + assert(m_valid); + assert(!m_images.empty()); + + return m_images[0].get_height(); + } + + inline unsigned int get_depth() + { + assert(m_valid); + assert(!m_images.empty()); + + return m_images[0].get_depth(); + } + + inline unsigned int get_size() + { + assert(m_valid); + assert(!m_images.empty()); + + return m_images[0].get_size(); + } + + inline unsigned int get_num_mipmaps() + { + assert(m_valid); + assert(!m_images.empty()); + + return m_images[0].get_num_mipmaps(); + } + + inline const CSurface &get_mipmap(unsigned int index) const + { + assert(m_valid); + assert(!m_images.empty()); + assert(index < m_images[0].get_num_mipmaps()); + + return m_images[0].get_mipmap(index); + } + + inline const CTexture &get_cubemap_face(unsigned int face) const + { + assert(m_valid); + assert(!m_images.empty()); + assert(m_images.size() == 6); + assert(m_type == TextureCubemap); + assert(face < 6); + + return m_images[face]; + } + + inline unsigned int get_components() { return m_components; } + inline TextureFormat get_format() { return m_format; } + inline TextureType get_type() { return m_type; } + + inline bool is_compressed() + { + if ((m_format == TextureDXT1) || + (m_format == TextureDXT3) || + (m_format == TextureDXT5)) + return true; + else + return false; + } + + inline bool is_cubemap() { return (m_type == TextureCubemap); } + inline bool is_volume() { return (m_type == Texture3D); } + inline bool is_valid() { return m_valid; } + + inline bool is_dword_aligned() + { + assert(m_valid); + + int dwordLineSize = get_dword_aligned_linesize(get_width(), m_components*8); + int curLineSize = get_width() * m_components; + + return (dwordLineSize == curLineSize); + } + + private: + unsigned int clamp_size(unsigned int size); + unsigned int size_dxtc(unsigned int width, unsigned int height); + unsigned int size_rgb(unsigned int width, unsigned int height); + inline void swap_endian(void *val); + + // calculates 4-byte aligned width of image + inline unsigned int get_dword_aligned_linesize(unsigned int width, unsigned int bpp) + { + return ((width * bpp + 31) & (unsigned int)(-32)) >> 3; + } + + void flip(CSurface &surface); + void flip_texture(CTexture &texture); + + void swap(void *byte1, void *byte2, unsigned int size); + void flip_blocks_dxtc1(DXTColBlock *line, unsigned int numBlocks); + void flip_blocks_dxtc3(DXTColBlock *line, unsigned int numBlocks); + void flip_blocks_dxtc5(DXTColBlock *line, unsigned int numBlocks); + void flip_dxt5_alpha(DXT5AlphaBlock *block); + + void write_texture(const CTexture &texture, SampleRenderer::File *fp); + + TextureFormat m_format; + unsigned int m_components; + TextureType m_type; + bool m_valid; + + std::deque<CTexture> m_images; + }; +} +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/framework/src/windows/WindowsSampleAssetManager.cpp b/PhysX_3.4/Samples/SampleFramework/framework/src/windows/WindowsSampleAssetManager.cpp new file mode 100644 index 00000000..a2bfaa82 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/framework/src/windows/WindowsSampleAssetManager.cpp @@ -0,0 +1,48 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +#include <SampleAssetManager.h> + +#define NOMINMAX +#include <windows.h> + + +bool SampleFramework::searchForPath(const char* path, char* buffer, int bufferSize, bool isReadOnly, int maxRecursion) +{ + char* tmpBuffer = (char*)alloca(bufferSize); + strcpy_s(buffer, bufferSize, path); + for(int i = 0; i < maxRecursion; i++) + { + if(GetFileAttributes(buffer) == INVALID_FILE_ATTRIBUTES) + { + sprintf_s(tmpBuffer, bufferSize, "../%s", buffer); + strcpy_s(buffer, bufferSize, tmpBuffer); + } + else + return true; + } + return false; +} |