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/renderer/src/ogl | |
| 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/renderer/src/ogl')
18 files changed, 3302 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRenderer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRenderer.cpp new file mode 100644 index 00000000..0d536f1d --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRenderer.cpp @@ -0,0 +1,873 @@ +// 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 <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRenderer.h" + +#include <RendererDesc.h> + +#include <RendererVertexBufferDesc.h> +#include "OGLRendererVertexBuffer.h" + +#include <RendererIndexBufferDesc.h> +#include "OGLRendererIndexBuffer.h" + +#include <RendererInstanceBufferDesc.h> +#include "OGLRendererInstanceBuffer.h" + +#include <RendererMeshDesc.h> +#include <RendererMeshContext.h> +#include "OGLRendererMesh.h" + +#include <RendererMaterialDesc.h> +#include <RendererMaterialInstance.h> +#include "OGLRendererMaterial.h" + +#include <RendererLightDesc.h> +#include <RendererDirectionalLightDesc.h> +#include "OGLRendererDirectionalLight.h" +#include <RendererSpotLightDesc.h> +#include "OGLRendererSpotLight.h" + +#include <RendererTexture2DDesc.h> +#include "OGLRendererTexture2D.h" + +#include <RendererProjection.h> + +#include <SamplePlatform.h> + +#include "PxTkFile.h" +#include "PsString.h" + +namespace Ps = physx::shdfnd; + +using namespace SampleRenderer; + +#if defined(RENDERER_ENABLE_CG) + void SampleRenderer::setColorParameter(CGparameter param, const RendererColor &color) + { + const float inv255 = 1.0f / 255.0f; + const float fcolor[3] = { color.r*inv255, color.g*inv255, color.b*inv255 }; + cgSetParameter3fv(param, fcolor); + } + + void SampleRenderer::setFloat4Parameter(CGparameter param, float* values) + { + cgSetParameter4fv(param, values); + } + +#endif + +#if defined(RENDERER_ENABLE_CG) + +#if !defined(RENDERER_PS3) + static void CGENTRY onCgError(CGcontext cgContext, CGerror err, void * data) + { + const char *errstr = cgGetErrorString(err); + if(cgContext) + { + errstr = cgGetLastListing(cgContext); + } + static_cast<SampleFramework::SamplePlatform*>(data)->showMessage("Cg error", errstr); + } +#endif + + OGLRenderer::CGEnvironment::CGEnvironment(void) + { + memset(this, 0, sizeof(*this)); + } + + OGLRenderer::CGEnvironment::CGEnvironment(CGcontext cgContext) + { + modelMatrix = cgCreateParameter(cgContext, CG_FLOAT4x4); + viewMatrix = cgCreateParameter(cgContext, CG_FLOAT4x4); + projMatrix = cgCreateParameter(cgContext, CG_FLOAT4x4); + modelViewMatrix = cgCreateParameter(cgContext, CG_FLOAT4x4); + modelViewProjMatrix = cgCreateParameter(cgContext, CG_FLOAT4x4); + + boneMatrices = cgCreateParameterArray(cgContext, CG_FLOAT4x4, RENDERER_MAX_BONES); + + fogColorAndDistance = cgCreateParameter(cgContext, CG_FLOAT4); + + eyePosition = cgCreateParameter(cgContext, CG_FLOAT3); + eyeDirection = cgCreateParameter(cgContext, CG_FLOAT3); + + ambientColor = cgCreateParameter(cgContext, CG_FLOAT3); + + lightColor = cgCreateParameter(cgContext, CG_FLOAT3); + lightIntensity = cgCreateParameter(cgContext, CG_FLOAT); + lightDirection = cgCreateParameter(cgContext, CG_FLOAT3); + lightPosition = cgCreateParameter(cgContext, CG_FLOAT3); + lightInnerRadius = cgCreateParameter(cgContext, CG_FLOAT); + lightOuterRadius = cgCreateParameter(cgContext, CG_FLOAT); + lightInnerCone = cgCreateParameter(cgContext, CG_FLOAT); + lightOuterCone = cgCreateParameter(cgContext, CG_FLOAT); + } +#endif + + void SampleRenderer::PxToGL(GLfloat *gl44, const physx::PxMat44 &mat44) + { + memcpy(gl44, mat44.front(), 4 * 4 * sizeof (GLfloat)); + } + + void SampleRenderer::RenToGL(GLfloat *gl44, const RendererProjection &proj) + { + proj.getColumnMajor44(gl44); + } + + OGLRenderer::OGLRenderer(const RendererDesc &desc, const char* assetDir) : + Renderer(DRIVER_OPENGL, desc.errorCallback, assetDir), m_platform(SampleFramework::SamplePlatform::platform()) + { + m_useShadersForTextRendering = false; + m_displayWidth = 0; + m_displayHeight = 0; + m_currMaterial = 0; + m_viewMatrix = PxMat44(PxIdentity); + + m_platform->initializeOGLDisplay(desc, m_displayWidth, m_displayHeight); + m_platform->postInitializeOGLDisplay(); + + //added this to avoid garbage being displayed during initialization + RendererColor savedColor = getClearColor(); + setClearColor(RendererColor(0U)); + clearBuffers(); + swapBuffers(); + setClearColor(savedColor); + + checkResize(); + +#if defined(RENDERER_ENABLE_CG) + m_cgContext = cgCreateContext(); + RENDERER_ASSERT(m_cgContext, "Unable to obtain Cg Context."); + + m_platform->initializeCGRuntimeCompiler(); + + if(m_cgContext) + { + m_cgEnv = CGEnvironment(m_cgContext); + +#if !defined(RENDERER_PS3) + cgSetErrorHandler(onCgError, m_platform); + cgSetParameterSettingMode(m_cgContext, CG_DEFERRED_PARAMETER_SETTING); +#endif +#if defined(RENDERER_DEBUG) + cgGLSetDebugMode(CG_TRUE); +#else + cgGLSetDebugMode(CG_FALSE); +#endif + } +#endif + + Ps::strlcpy(m_deviceName, sizeof(m_deviceName), (const char*)glGetString(GL_RENDERER)); + for(char *c=m_deviceName; *c; c++) + { + if(*c == '/') + { + *c = 0; + break; + } + } + + RendererColor& clearColor = getClearColor(); + glClearColor(clearColor.r/255.0f, clearColor.g/255.0f, clearColor.b/255.0f, clearColor.a/255.0f); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CW); + glEnable(GL_DEPTH_TEST); + } + + OGLRenderer::~OGLRenderer(void) + { + // avoid displaying garbage on screen + setClearColor(RendererColor(0U)); + clearBuffers(); + swapBuffers(); + releaseAllMaterials(); + +#if defined(RENDERER_ENABLE_CG) + if(m_cgContext) + { + cgDestroyContext(m_cgContext); + } +#endif + + m_platform->freeDisplay(); + } + + bool OGLRenderer::begin(void) + { + bool ok = false; + ok = m_platform->makeContextCurrent(); + return ok; + } + + void OGLRenderer::end(void) + { + GLenum error = glGetError(); + //RENDERER_ASSERT(GL_NO_ERROR == error, "An OpenGL error has occured"); + + if (GL_NO_ERROR != error) + { + const char* errorString = "unknown"; + +#define CASE(MESSAGE) case MESSAGE: errorString = #MESSAGE; break; + switch(error) + { + CASE(GL_INVALID_ENUM) + CASE(GL_INVALID_VALUE) + CASE(GL_INVALID_OPERATION) + CASE(GL_STACK_OVERFLOW) + CASE(GL_STACK_UNDERFLOW) + CASE(GL_OUT_OF_MEMORY) +#if !defined(RENDERER_PS3) + CASE(GL_INVALID_FRAMEBUFFER_OPERATION) +#endif + + }; + +#undef CASE + + char buf[128]; + Ps::snprintf(buf, 128, "GL error %x occurred (%s)\n", error, errorString); + if (m_errorCallback) + m_errorCallback->reportError(PxErrorCode::eINTERNAL_ERROR, buf, __FILE__, __LINE__); + } + } + + void OGLRenderer::checkResize(void) + { + PxU32 width = m_displayWidth; + PxU32 height = m_displayHeight; + m_platform->getWindowSize(width, height); + if(width != m_displayWidth || height != m_displayHeight) + { + m_displayWidth = width; + m_displayHeight = height; + glViewport(0, 0, (GLsizei)m_displayWidth, (GLsizei)m_displayHeight); + glScissor( 0, 0, (GLsizei)m_displayWidth, (GLsizei)m_displayHeight); + } + } + + // clears the offscreen buffers. + void OGLRenderer::clearBuffers(void) + { + if(begin()) + { + GLbitfield glbuf = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + glDepthMask(1); + + RendererColor& clearColor = getClearColor(); + glClearColor(clearColor.r/255.0f, clearColor.g/255.0f, clearColor.b/255.0f, clearColor.a/255.0f); + glClear(glbuf); + } + end(); + } + + // presents the current color buffer to the screen. + // returns true on device reset and if buffers need to be rewritten. + bool OGLRenderer::swapBuffers(void) + { + PX_PROFILE_ZONE("OGLRendererSwapBuffers",0); + if(begin()) + { + m_platform->swapBuffers(); + checkResize(); + } + end(); + return false; + } + + void OGLRenderer::getWindowSize(PxU32 &width, PxU32 &height) const + { + RENDERER_ASSERT(m_displayHeight * m_displayWidth > 0, "variables not initialized properly"); + width = m_displayWidth; + height = m_displayHeight; + } + + RendererVertexBuffer *OGLRenderer::createVertexBuffer(const RendererVertexBufferDesc &desc) + { + PX_PROFILE_ZONE("OGLRenderer_createVertexBuffer",0); + OGLRendererVertexBuffer *vb = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Vertex Buffer Descriptor."); + if(desc.isValid()) + { + vb = new OGLRendererVertexBuffer(desc); + } + return vb; + } + + RendererIndexBuffer *OGLRenderer::createIndexBuffer(const RendererIndexBufferDesc &desc) + { + PX_PROFILE_ZONE("OGLRenderer_createIndexBuffer",0); + OGLRendererIndexBuffer *ib = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Index Buffer Descriptor."); + if(desc.isValid()) + { + ib = new OGLRendererIndexBuffer(desc); + } + return ib; + } + + RendererInstanceBuffer *OGLRenderer::createInstanceBuffer(const RendererInstanceBufferDesc &desc) + { + PX_PROFILE_ZONE("OGLRenderer_createInstanceBuffer",0); + OGLRendererInstanceBuffer *ib = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Instance Buffer Descriptor."); + if(desc.isValid()) + { + ib = new OGLRendererInstanceBuffer(desc); + } + return ib; + } + + RendererTexture2D *OGLRenderer::createTexture2D(const RendererTexture2DDesc &desc) + { + PX_PROFILE_ZONE("OGLRenderer_createTexture2D",0); + OGLRendererTexture2D *texture = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Texture 2D Descriptor."); + if(desc.isValid()) + { + texture = new OGLRendererTexture2D(desc); + } + return texture; + } + + RendererTexture3D *OGLRenderer::createTexture3D(const RendererTexture3DDesc &desc) + { + // TODO: Implement + return 0; + } + + RendererTarget *OGLRenderer::createTarget(const RendererTargetDesc &desc) + { + PX_PROFILE_ZONE("OGLRenderer_createTarget",0); + RENDERER_ASSERT(0, "Not Implemented."); + return 0; + } + + RendererMaterial *OGLRenderer::createMaterial(const RendererMaterialDesc &desc) + { + RendererMaterial *mat = hasMaterialAlready(desc); + RENDERER_ASSERT(desc.isValid(), "Invalid Material Descriptor."); + if(!mat && desc.isValid()) + { + PX_PROFILE_ZONE("OGLRenderer_createMaterial",0); + mat = new OGLRendererMaterial(*this, desc); + + registerMaterial(desc, mat); + } + return mat; + } + + RendererMesh *OGLRenderer::createMesh(const RendererMeshDesc &desc) + { + PX_PROFILE_ZONE("OGLRenderer_createMesh",0); + OGLRendererMesh *mesh = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Mesh Descriptor."); + if(desc.isValid()) + { + mesh = new OGLRendererMesh(*this, desc); + } + return mesh; + } + + RendererLight *OGLRenderer::createLight(const RendererLightDesc &desc) + { + PX_PROFILE_ZONE("OGLRenderer_createLight",0); + RendererLight *light = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Light Descriptor."); + if(desc.isValid()) + { + switch(desc.type) + { + case RendererLight::TYPE_DIRECTIONAL: + light = new OGLRendererDirectionalLight(*static_cast<const RendererDirectionalLightDesc*>(&desc), *this); + break; + case RendererLight::TYPE_SPOT: + light = new OGLRendererSpotLight(*static_cast<const RendererSpotLightDesc*>(&desc), *this); + break; + default: + RENDERER_ASSERT(0, "OGLRenderer does not support this light type"); + break; + } + } + return light; + } + + void OGLRenderer::setVsync(bool on) + { + m_platform->setOGLVsync(on); + } + + void OGLRenderer::bindViewProj(const physx::PxMat44 &eye, const RendererProjection &proj) + { + PxMat44 inveye = eye.inverseRT(); + + // load the projection matrix... + const GLfloat* glproj = &proj.getPxMat44().column0.x; + + // load the view matrix... + m_viewMatrix = inveye; + +#if defined(RENDERER_ENABLE_CG) + GLfloat glview[16]; + PxToGL(glview, inveye); + const PxVec3 &eyePosition = eye.getPosition(); + const PxVec3 eyeDirection = -eye.getBasis(2); + if(m_cgEnv.viewMatrix) cgGLSetMatrixParameterfc(m_cgEnv.viewMatrix, glview); + if(m_cgEnv.projMatrix) cgGLSetMatrixParameterfc(m_cgEnv.projMatrix, glproj); + if(m_cgEnv.eyePosition) cgGLSetParameter3fv( m_cgEnv.eyePosition, &eyePosition.x); + if(m_cgEnv.eyeDirection) cgGLSetParameter3fv( m_cgEnv.eyeDirection, &eyeDirection.x); +#endif + } + + void OGLRenderer::bindFogState(const RendererColor &fogColor, float fogDistance) + { +#if defined(RENDERER_ENABLE_CG) + const float inv255 = 1.0f / 255.0f; + + float values[4]; + values[0] = fogColor.r*inv255; + values[1] = fogColor.g*inv255; + values[2] = fogColor.b*inv255; + values[3] = fogDistance; + + setFloat4Parameter(m_cgEnv.fogColorAndDistance, values); +#endif + } + + void OGLRenderer::bindAmbientState(const RendererColor &ambientColor) + { +#if defined(RENDERER_ENABLE_CG) + setColorParameter(m_cgEnv.ambientColor, ambientColor); +#endif + } + + void OGLRenderer::bindDeferredState(void) + { + RENDERER_ASSERT(0, "Not implemented!"); + } + + void OGLRenderer::bindMeshContext(const RendererMeshContext &context) + { + PX_PROFILE_ZONE("OGLRendererBindMeshContext",0); + physx::PxMat44 model; + physx::PxMat44 modelView; + + if(context.transform) model = *context.transform; + else model = PxMat44(PxIdentity); + modelView = m_viewMatrix * model; + + GLfloat glmodelview[16]; + PxToGL(glmodelview, modelView); + glLoadMatrixf(glmodelview); + + RendererMeshContext::CullMode cullMode = context.cullMode; + if (!blendingCull() && NULL != context.material && context.material->getBlending()) + cullMode = RendererMeshContext::NONE; + + switch(cullMode) + { + case RendererMeshContext::CLOCKWISE: + glFrontFace( GL_CW ); + glCullFace( GL_BACK ); + glEnable( GL_CULL_FACE ); + break; + case RendererMeshContext::COUNTER_CLOCKWISE: + glFrontFace( GL_CCW ); + glCullFace( GL_BACK ); + glEnable( GL_CULL_FACE ); + break; + case RendererMeshContext::NONE: + glDisable( GL_CULL_FACE ); + break; + default: + RENDERER_ASSERT(0, "Invalid Cull Mode"); + } + + switch(context.fillMode) + { + case RendererMeshContext::SOLID: + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + case RendererMeshContext::LINE: + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + break; + case RendererMeshContext::POINT: + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + break; + } + + +#if defined(RENDERER_ENABLE_CG) + GLfloat glmodel[16]; + PxToGL(glmodel, model); + if(m_cgEnv.modelMatrix) cgGLSetMatrixParameterfc(m_cgEnv.modelMatrix, glmodel); + if(m_cgEnv.modelViewMatrix) cgGLSetMatrixParameterfc(m_cgEnv.modelViewMatrix, glmodelview); + + RENDERER_ASSERT(context.numBones <= RENDERER_MAX_BONES, "Too many bones."); + if(context.boneMatrices && context.numBones>0 && context.numBones <= RENDERER_MAX_BONES) + { +#if 0 + for(PxU32 i=0; i<context.numBones; i++) + { + GLfloat glbonematrix[16]; + PxToGL(glbonematrix, context.boneMatrices[i]); + cgSetMatrixParameterfc(cgGetArrayParameter(m_cgEnv.boneMatrices, i), glbonematrix); + } +#else + GLfloat glbonematrix[16*RENDERER_MAX_BONES]; + for(PxU32 i=0; i<context.numBones; i++) + { + PxToGL(glbonematrix+(16*i), context.boneMatrices[i]); + } + +#if defined(RENDERER_PS3) + OGLRendererMaterial* pMaterial = (OGLRendererMaterial*)context.material; + if( pMaterial ) + { + CGprogram program = pMaterial->GetVertexProgramPS3(); + cgGLSetMatrixParameterArrayfc(cgGetNamedParameter(program, "g_" "boneMatrices"), + 0, context.numBones, glbonematrix); + } +#else + { + PX_PROFILE_ZONE("cgGLSetMatrixParameter",0); + cgGLSetMatrixParameterArrayfc(m_cgEnv.boneMatrices, 0, context.numBones, glbonematrix); + } +#endif +#endif + } + +#endif + } + + void OGLRenderer::beginMultiPass(void) + { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glDepthFunc(GL_EQUAL); + } + + void OGLRenderer::endMultiPass(void) + { + glDisable(GL_BLEND); + glDepthFunc(GL_LESS); + } + + void OGLRenderer::beginTransparentMultiPass(void) + { + setEnableBlendingOverride(true); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDepthFunc(GL_LEQUAL); + glDepthMask(false); + } + + void OGLRenderer::endTransparentMultiPass(void) + { + setEnableBlendingOverride(false); + glDisable(GL_BLEND); + glDepthFunc(GL_LESS); + glDepthMask(true); + } + + void OGLRenderer::renderDeferredLight(const RendererLight &/*light*/) + { + RENDERER_ASSERT(0, "Not implemented!"); + } + + PxU32 OGLRenderer::convertColor(const RendererColor& color) const + { + return OGLRendererVertexBuffer::convertColor(color); + } + + + bool OGLRenderer::isOk(void) const + { + bool ok = true; + ok = m_platform->isContextValid(); + return ok; + } + + /////////////////////////////////////////////////////////////////////////////// + + /*static DWORD gCullMode; + static DWORD gAlphaBlendEnable; + static DWORD gSrcBlend; + static DWORD gDstBlend; + static DWORD gFillMode; + static DWORD gZWrite; + static DWORD gLighting; + */ + + void OGLRenderer::setupTextRenderStates() + { + /* // PT: save render states. Let's just hope this isn't a pure device, else the Get method won't work + m_d3dDevice->GetRenderState(D3DRS_CULLMODE, &gCullMode); + m_d3dDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &gAlphaBlendEnable); + m_d3dDevice->GetRenderState(D3DRS_SRCBLEND, &gSrcBlend); + m_d3dDevice->GetRenderState(D3DRS_DESTBLEND, &gDstBlend); + m_d3dDevice->GetRenderState(D3DRS_FILLMODE, &gFillMode); + m_d3dDevice->GetRenderState(D3DRS_ZWRITEENABLE, &gZWrite); + m_d3dDevice->GetRenderState(D3DRS_LIGHTING, &gLighting); + + // PT: setup render states for text rendering + m_d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + m_d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + m_d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + m_d3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + m_d3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + m_d3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);*/ + + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDepthMask(false); + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + } + + void OGLRenderer::resetTextRenderStates() + { + glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); + // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDepthMask(true); + glEnable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + } + + void OGLRenderer::renderTextBuffer(const void* verts, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, RendererMaterial* material) + { + const int stride = sizeof(TextVertex); + char* data = (char*)verts; + + glEnableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // pos + glVertexPointer(3, GL_FLOAT, stride, data); + data += 3*sizeof(float); + + // rhw + PxU32 width, height; + getWindowSize(width, height); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, width, height, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + data += sizeof(float); + + // Diffuse color + glColorPointer(4, GL_UNSIGNED_BYTE, stride, data); + data += sizeof(int); + + // Texture coordinates + glTexCoordPointer(2, GL_FLOAT, stride, data); + data += 2*sizeof(float); + + glDrawRangeElements(GL_TRIANGLES, 0, nbVerts, nbIndices, GL_UNSIGNED_SHORT, indices); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + void OGLRenderer::renderLines2D(const void* vertices, PxU32 nbVerts) + { + const int stride = sizeof(TextVertex); + char* data = (char*)vertices; + + glEnableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + // pos + glVertexPointer(3, GL_FLOAT, stride, data); + data += 3*sizeof(float); + + // rhw + PxU32 width, height; + getWindowSize(width, height); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, width, height, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + data += sizeof(float); + + // Diffuse color + glColorPointer(4, GL_UNSIGNED_BYTE, stride, data); + data += sizeof(int); + + // Texture coordinates + glTexCoordPointer(2, GL_FLOAT, stride, data); + data += 2*sizeof(float); + + glDrawArrays(GL_LINE_STRIP, 0, nbVerts); + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + void OGLRenderer::setupScreenquadRenderStates() + { + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDepthMask(false); + glDisable(GL_LIGHTING); + } + + void OGLRenderer::resetScreenquadRenderStates() + { + glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDepthMask(true); + glEnable(GL_LIGHTING); + } + +#pragma pack(push,2) + typedef struct + { + unsigned short bfType; + unsigned int bfSize; + unsigned short bfReserved1; + unsigned short bfReserved2; + unsigned int bfOffBits; + } PXT_BITMAPFILEHEADER; +#pragma pack(pop) + typedef struct _tagBITMAPINFO + { + struct + { + GLuint biSize; + GLuint biWidth; + GLuint biHeight; + GLushort biPlanes; + GLushort biBitCount; + GLuint biCompression; + GLuint biSizeImage; + GLuint biXPelsPerMeter; + GLuint biYPelsPerMeter; + GLuint biClrUsed; + GLuint biClrImportant; + } bmiHeader; + unsigned int bmiColors[1]; + } PXT_BITMAPINFO; + + static inline PxU32 screenshotDataOffset() + { + return sizeof(PXT_BITMAPFILEHEADER) + sizeof(PXT_BITMAPINFO); + } + static inline PxU32 screenshotSize(PxU32 width, PxU32 height) + { + return width * height * 4 *sizeof(GLubyte) + screenshotDataOffset(); + } + + bool OGLRenderer::captureScreen(PxU32 &width, PxU32& height, PxU32& sizeInBytes, const void*& screenshotData) + { + // Target buffer size + const PxU32 newBufferSize = screenshotSize(m_displayWidth, m_displayHeight); + + // Resize of necessary + if (newBufferSize != (PxU32)m_displayData.size()) + m_displayData.resize(newBufferSize); + + // Quit if resize failed + if (newBufferSize != (PxU32)m_displayData.size()) + return false; + + // Write the screen data into the buffer + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glReadPixels(0, 0, m_displayWidth, m_displayHeight, GL_RGBA, GL_UNSIGNED_BYTE, &m_displayData[screenshotDataOffset()]); + if (GL_NO_ERROR != glGetError()) + return false; + + // Write the header data into the buffer + PXT_BITMAPFILEHEADER bitmapFileHeader; + PXT_BITMAPINFO bitmapInfoHeader; + + bitmapFileHeader.bfType = 0x4D42; //"BM" + bitmapFileHeader.bfReserved1 = 0; + bitmapFileHeader.bfReserved2 = 0; + bitmapFileHeader.bfOffBits = sizeof(PXT_BITMAPFILEHEADER) + sizeof(bitmapInfoHeader.bmiHeader); + bitmapFileHeader.bfSize = m_displayWidth * m_displayHeight * 4 + bitmapFileHeader.bfOffBits; + + bitmapInfoHeader.bmiHeader.biSize = sizeof(bitmapInfoHeader.bmiHeader); + bitmapInfoHeader.bmiHeader.biWidth = m_displayWidth; + bitmapInfoHeader.bmiHeader.biHeight = m_displayHeight; + bitmapInfoHeader.bmiHeader.biPlanes = 1; + bitmapInfoHeader.bmiHeader.biBitCount = 32; + bitmapInfoHeader.bmiHeader.biCompression = 0 /*BI_RGB*/; + bitmapInfoHeader.bmiHeader.biSizeImage = 0; + bitmapInfoHeader.bmiHeader.biXPelsPerMeter = 0; + bitmapInfoHeader.bmiHeader.biYPelsPerMeter = 0; + bitmapInfoHeader.bmiHeader.biClrUsed = 0; + bitmapInfoHeader.bmiHeader.biClrImportant = 0; + + memcpy(&m_displayData[0], &bitmapFileHeader, sizeof(bitmapFileHeader)); + memcpy(&m_displayData[sizeof(bitmapFileHeader)], &bitmapInfoHeader.bmiHeader, sizeof(bitmapInfoHeader.bmiHeader)); + + // Output the result + getWindowSize(width, height); + sizeInBytes = (PxU32)m_displayData.size(); + screenshotData = &m_displayData[0]; + + return true; + } + +#endif // #if defined(RENDERER_ENABLE_OPENGL) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRenderer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRenderer.h new file mode 100644 index 00000000..afd18693 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRenderer.h @@ -0,0 +1,189 @@ +// 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. +#ifndef OGL_RENDERER_H +#define OGL_RENDERER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) +#include <GLIncludes.h> + +#if defined(RENDERER_ENABLE_CG) + #include <Cg/cg.h> + #include <Cg/cgGL.h> +#endif + +#include <Renderer.h> + +namespace SampleFramework { + class SamplePlatform; +} + +namespace SampleRenderer +{ + +#if defined(RENDERER_ENABLE_CG) + void setColorParameter(CGparameter param, const RendererColor &color); + void setFloat4Parameter(CGparameter param, float* values); +#endif + + class OGLRendererMaterial; + + + void PxToGL(GLfloat *gl44, const physx::PxMat44 &mat); + void RenToGL(GLfloat *gl44, const RendererProjection &proj); + + class OGLRenderer : public Renderer + { + public: + OGLRenderer(const RendererDesc &desc, const char* assetDir); + virtual ~OGLRenderer(void); + +#if defined(RENDERER_ENABLE_CG) + class CGEnvironment + { + public: + CGparameter modelMatrix; + CGparameter viewMatrix; + CGparameter projMatrix; + CGparameter modelViewMatrix; + CGparameter modelViewProjMatrix; + + CGparameter boneMatrices; + + CGparameter fogColorAndDistance; + + CGparameter eyePosition; + CGparameter eyeDirection; + + CGparameter ambientColor; + + CGparameter lightColor; + CGparameter lightIntensity; + CGparameter lightDirection; + CGparameter lightPosition; + CGparameter lightInnerRadius; + CGparameter lightOuterRadius; + CGparameter lightInnerCone; + CGparameter lightOuterCone; + + public: + CGEnvironment(void); + CGEnvironment(CGcontext cgContext); + }; + + CGcontext getCGContext(void) { return m_cgContext; } + CGEnvironment &getCGEnvironment(void) { return m_cgEnv; } + const CGEnvironment &getCGEnvironment(void) const { return m_cgEnv; } +#endif + + const physx::PxMat44 &getViewMatrix(void) const { return m_viewMatrix; } + + void setCurrentMaterial(const OGLRendererMaterial *cm) { m_currMaterial = cm; } + const OGLRendererMaterial *getCurrentMaterial(void) { return m_currMaterial; } + + private: + bool begin(void); + void end(void); + void checkResize(void); + + public: + // clears the offscreen buffers. + virtual void clearBuffers(void); + + // presents the current color buffer to the screen. + // returns true on device reset and if buffers need to be rewritten. + virtual bool swapBuffers(void); + + // get the device pointer (void * abstraction) + virtual void *getDevice() { return static_cast<void*>(getCGContext()); } + + virtual bool captureScreen(const char* ) { PX_ASSERT("not supported"); return false; } + + // gets a handle to the current frame's data, in bitmap format + // note: subsequent calls will invalidate any previously returned data + // return true on successful screenshot capture + virtual bool captureScreen(PxU32 &width, PxU32& height, PxU32& sizeInBytes, const void*& screenshotData); + + // get the window size + void getWindowSize(PxU32 &width, PxU32 &height) const; + + virtual RendererVertexBuffer *createVertexBuffer( const RendererVertexBufferDesc &desc); + virtual RendererIndexBuffer *createIndexBuffer( const RendererIndexBufferDesc &desc); + virtual RendererInstanceBuffer *createInstanceBuffer(const RendererInstanceBufferDesc &desc); + virtual RendererTexture2D *createTexture2D( const RendererTexture2DDesc &desc); + virtual RendererTexture3D *createTexture3D( const RendererTexture3DDesc &desc); + virtual RendererTarget *createTarget( const RendererTargetDesc &desc); + virtual RendererMaterial *createMaterial( const RendererMaterialDesc &desc); + virtual RendererMesh *createMesh( const RendererMeshDesc &desc); + virtual RendererLight *createLight( const RendererLightDesc &desc); + + virtual void setVsync(bool on); + + private: + virtual void bindViewProj(const physx::PxMat44 &inveye, const RendererProjection &proj); + virtual void bindAmbientState(const RendererColor &ambientColor); + virtual void bindFogState(const RendererColor &fogColor, float fogDistance); + virtual void bindDeferredState(void); + virtual void bindMeshContext(const RendererMeshContext &context); + virtual void beginMultiPass(void); + virtual void endMultiPass(void); + virtual void beginTransparentMultiPass(void); + virtual void endTransparentMultiPass(void); + virtual void renderDeferredLight(const RendererLight &light); + virtual PxU32 convertColor(const RendererColor& color) const; + + virtual bool isOk(void) const; + + virtual void setupTextRenderStates(); + virtual void resetTextRenderStates(); + virtual void renderTextBuffer(const void* vertices, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, RendererMaterial* material); + virtual void renderLines2D(const void* vertices, PxU32 nbVerts); + virtual void setupScreenquadRenderStates(); + virtual void resetScreenquadRenderStates(); + + private: + SampleFramework::SamplePlatform* m_platform; +#if defined(RENDERER_ENABLE_CG) + CGcontext m_cgContext; + CGEnvironment m_cgEnv; +#endif + + const OGLRendererMaterial *m_currMaterial; + + PxU32 m_displayWidth; + PxU32 m_displayHeight; + + std::vector<GLubyte> m_displayData; + + physx::PxMat44 m_viewMatrix; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererDirectionalLight.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererDirectionalLight.cpp new file mode 100644 index 00000000..4301033d --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererDirectionalLight.cpp @@ -0,0 +1,58 @@ +// 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 <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererDirectionalLight.h" + +using namespace SampleRenderer; + +OGLRendererDirectionalLight::OGLRendererDirectionalLight(const RendererDirectionalLightDesc &desc, OGLRenderer &renderer) +: RendererDirectionalLight(desc) +#if defined(RENDERER_ENABLE_CG) +, m_cgenv(renderer.getCGEnvironment()) +#endif + +{ +} + +OGLRendererDirectionalLight::~OGLRendererDirectionalLight(void) +{ +} + +void OGLRendererDirectionalLight::bind(void) const +{ +#if defined(RENDERER_ENABLE_CG) + setColorParameter(m_cgenv.lightColor, m_color); + cgSetParameter1f( m_cgenv.lightIntensity, m_intensity); + cgSetParameter3fv(m_cgenv.lightDirection, &m_direction.x); +#endif +} + +#endif // #if defined(RENDERER_ENABLE_OPENGL) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererDirectionalLight.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererDirectionalLight.h new file mode 100644 index 00000000..cefad68f --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererDirectionalLight.h @@ -0,0 +1,60 @@ +// 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. +#ifndef OGL_RENDERER_DIRECTIONAL_LIGHT_H +#define OGL_RENDERER_DIRECTIONAL_LIGHT_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererDirectionalLight.h> + +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class RendererDirectionalLightDesc; + + class OGLRendererDirectionalLight : public RendererDirectionalLight + { + public: + OGLRendererDirectionalLight(const RendererDirectionalLightDesc &desc, OGLRenderer &renderer); + virtual ~OGLRendererDirectionalLight(void); + + virtual void bind(void) const; + + private: +#if defined(RENDERER_ENABLE_CG) + const OGLRenderer::CGEnvironment &m_cgenv; +#endif + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererIndexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererIndexBuffer.cpp new file mode 100644 index 00000000..4dda7229 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererIndexBuffer.cpp @@ -0,0 +1,138 @@ +// 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 <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererIndexBuffer.h" +#include <RendererIndexBufferDesc.h> + +#if PX_WINDOWS +#include "cudamanager/PxCudaContextManager.h" +#endif + +using namespace SampleRenderer; + +OGLRendererIndexBuffer::OGLRendererIndexBuffer(const RendererIndexBufferDesc &desc) : + RendererIndexBuffer(desc) +{ + m_indexSize = getFormatByteSize(getFormat()); + + RENDERER_ASSERT(GLEW_ARB_vertex_buffer_object, "Vertex Buffer Objects not supported on this machine!"); + if(GLEW_ARB_vertex_buffer_object) + { + RENDERER_ASSERT(desc.maxIndices > 0, "Cannot create zero size Index Buffer."); + if(desc.maxIndices > 0) + { + GLenum usage = GL_STATIC_DRAW_ARB; + if(getHint() == HINT_DYNAMIC) + { + usage = GL_DYNAMIC_DRAW_ARB; + } + + glGenBuffersARB(1, &m_ibo); + RENDERER_ASSERT(m_ibo, "Failed to create Index Buffer."); + if(m_ibo) + { + m_maxIndices = desc.maxIndices; + const PxU32 bufferSize = m_indexSize * m_maxIndices; + + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_ibo); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferSize, 0, usage); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + +#if PX_WINDOWS + if(m_interopContext && m_mustBeRegisteredInCUDA) + { + m_registeredInCUDA = m_interopContext->registerResourceInCudaGL(m_InteropHandle, (PxU32) m_ibo); + } +#endif + } + } + } +} + +OGLRendererIndexBuffer::~OGLRendererIndexBuffer(void) +{ + if(m_ibo) + { +#if PX_WINDOWS + if(m_registeredInCUDA) + { + m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + glDeleteBuffersARB(1, &m_ibo); + } +} + +void *OGLRendererIndexBuffer::lock(void) +{ + void *buffer = 0; + if(m_ibo) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_ibo); + buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_READ_WRITE); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } + return buffer; +} + +void OGLRendererIndexBuffer::unlock(void) +{ + if(m_ibo) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_ibo); + glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } +} + +void OGLRendererIndexBuffer::bind(void) const +{ + if(m_ibo) + { +#if !defined(RENDERER_PS3) + glEnableClientState(GL_INDEX_ARRAY); +#endif + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_ibo); + } +} + +void OGLRendererIndexBuffer::unbind(void) const +{ + if(m_ibo) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); +#if !defined(RENDERER_PS3) + glDisableClientState(GL_INDEX_ARRAY); +#endif + } +} + +#endif // #if defined(RENDERER_ENABLE_OPENGL) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererIndexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererIndexBuffer.h new file mode 100644 index 00000000..84e24b15 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererIndexBuffer.h @@ -0,0 +1,62 @@ +// 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. +#ifndef OGL_RENDERER_INDEXBUFFER_H +#define OGL_RENDERER_INDEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererIndexBuffer.h> +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class OGLRendererIndexBuffer : public RendererIndexBuffer + { + public: + OGLRendererIndexBuffer(const RendererIndexBufferDesc &desc); + virtual ~OGLRendererIndexBuffer(void); + + public: + virtual void *lock(void); + virtual void unlock(void); + + private: + virtual void bind(void) const; + virtual void unbind(void) const; + + private: + GLuint m_ibo; + PxU32 m_indexSize; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererInstanceBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererInstanceBuffer.cpp new file mode 100644 index 00000000..738a439c --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererInstanceBuffer.cpp @@ -0,0 +1,92 @@ +// 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 <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererInstanceBuffer.h" +#include <RendererInstanceBufferDesc.h> + +using namespace SampleRenderer; + +OGLRendererInstanceBuffer::OGLRendererInstanceBuffer(const RendererInstanceBufferDesc &desc) : + RendererInstanceBuffer(desc) +{ + m_bufferSize = (PxU32)(desc.maxInstances * m_stride); + m_buffer = malloc(m_bufferSize);//PX_ALLOC(m_bufferSize); + m_maxInstances = desc.maxInstances; +} + +OGLRendererInstanceBuffer::~OGLRendererInstanceBuffer(void) +{ + if(m_buffer) free(m_buffer);//PX_FREE(m_buffer); +} + +physx::PxMat44 OGLRendererInstanceBuffer::getModelMatrix(PxU32 index) const +{ + physx::PxMat44 model = PxMat44(PxIdentity); + if(index < m_maxInstances) + { + const void *instance = ((PxU8*)m_buffer)+(m_stride*index); + PxVec3 column0 = getInstanceColumn(instance, m_semanticDescs[SEMANTIC_NORMALX]); + PxVec3 column1 = getInstanceColumn(instance, m_semanticDescs[SEMANTIC_NORMALY]); + PxVec3 column2 = getInstanceColumn(instance, m_semanticDescs[SEMANTIC_NORMALZ]); + PxVec3 column3 = getInstanceColumn(instance, m_semanticDescs[SEMANTIC_POSITION]); + + model = PxMat44(column0, column1, column2, column3); + } + return model; +} + +PxVec3 OGLRendererInstanceBuffer::getInstanceColumn(const void *instance, const OGLRendererInstanceBuffer::SemanticDesc &sd) const +{ + PxVec3 col = *(PxVec3*)(((PxU8*)instance)+sd.offset); + return col; +} + +void *OGLRendererInstanceBuffer::lock(void) +{ + return m_buffer; +} + +void OGLRendererInstanceBuffer::unlock(void) +{ + +} + +void OGLRendererInstanceBuffer::bind(PxU32 streamID, PxU32 firstInstance) const +{ + +} + +void OGLRendererInstanceBuffer::unbind(PxU32 streamID) const +{ + +} + +#endif // #if defined(RENDERER_ENABLE_OPENGL) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererInstanceBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererInstanceBuffer.h new file mode 100644 index 00000000..f6ac259b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererInstanceBuffer.h @@ -0,0 +1,67 @@ +// 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. +#ifndef OGL_RENDERER_INSTANCEBUFFER_H +#define OGL_RENDERER_INSTANCEBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererInstanceBuffer.h> +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class OGLRendererInstanceBuffer : public RendererInstanceBuffer + { + public: + OGLRendererInstanceBuffer(const RendererInstanceBufferDesc &desc); + virtual ~OGLRendererInstanceBuffer(void); + + physx::PxMat44 getModelMatrix(PxU32 index) const; + + private: + PxVec3 getInstanceColumn(const void *instance, const OGLRendererInstanceBuffer::SemanticDesc &sd) const; + + public: + + virtual void *lock(void); + virtual void unlock(void); + + virtual void bind(PxU32 streamID, PxU32 firstInstance) const; + virtual void unbind(PxU32 streamID) const; + + private: + PxU32 m_bufferSize; + void *m_buffer; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMaterial.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMaterial.cpp new file mode 100644 index 00000000..fa84492c --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMaterial.cpp @@ -0,0 +1,518 @@ +// 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 "RendererConfig.h" + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererMaterial.h" +#include "OGLRendererTexture2D.h" + +#include <RendererMaterialDesc.h> + +#include <SamplePlatform.h> + +#include <stdio.h> + +// for PsString.h +namespace physx +{ + namespace string + {} +} +#include <PsString.h> +#include <PxTkFile.h> +namespace Ps = physx::shdfnd; + +using namespace SampleRenderer; + +#if defined(RENDERER_ENABLE_CG) + +static RendererMaterial::VariableType getVariableType(CGtype cgt) +{ + RendererMaterial::VariableType vt = RendererMaterial::NUM_VARIABLE_TYPES; + switch(cgt) + { + case CG_INT: vt = RendererMaterial::VARIABLE_INT; break; + case CG_FLOAT: vt = RendererMaterial::VARIABLE_FLOAT; break; + case CG_FLOAT2: vt = RendererMaterial::VARIABLE_FLOAT2; break; + case CG_FLOAT3: vt = RendererMaterial::VARIABLE_FLOAT3; break; + case CG_FLOAT4: vt = RendererMaterial::VARIABLE_FLOAT4; break; + case CG_FLOAT4x4: vt = RendererMaterial::VARIABLE_FLOAT4x4; break; + case CG_SAMPLER2D: vt = RendererMaterial::VARIABLE_SAMPLER2D; break; + case CG_SAMPLER3D: vt = RendererMaterial::VARIABLE_SAMPLER3D; break; + default: break; + } + RENDERER_ASSERT(vt < RendererMaterial::NUM_VARIABLE_TYPES, "Unable to convert shader parameter type."); + return vt; +} + +static GLuint getGLBlendFunc(RendererMaterial::BlendFunc func) +{ + GLuint glfunc = 0; + switch(func) + { + case RendererMaterial::BLEND_ZERO: glfunc = GL_ZERO; break; + case RendererMaterial::BLEND_ONE: glfunc = GL_ONE; break; + case RendererMaterial::BLEND_SRC_COLOR: glfunc = GL_SRC_COLOR; break; + case RendererMaterial::BLEND_ONE_MINUS_SRC_COLOR: glfunc = GL_ONE_MINUS_SRC_COLOR; break; + case RendererMaterial::BLEND_SRC_ALPHA: glfunc = GL_SRC_ALPHA; break; + case RendererMaterial::BLEND_ONE_MINUS_SRC_ALPHA: glfunc = GL_ONE_MINUS_SRC_ALPHA; break; + case RendererMaterial::BLEND_DST_ALPHA: glfunc = GL_DST_COLOR; break; + case RendererMaterial::BLEND_ONE_MINUS_DST_ALPHA: glfunc = GL_ONE_MINUS_DST_ALPHA; break; + case RendererMaterial::BLEND_DST_COLOR: glfunc = GL_DST_COLOR; break; + case RendererMaterial::BLEND_ONE_MINUS_DST_COLOR: glfunc = GL_ONE_MINUS_DST_COLOR; break; + case RendererMaterial::BLEND_SRC_ALPHA_SATURATE: glfunc = GL_SRC_ALPHA_SATURATE; break; + default: break; + } + RENDERER_ASSERT(glfunc, "Unable to convert Material Blend Func."); + return glfunc; +} + +static void connectParameters(CGparameter from, CGparameter to) +{ + if(from && to) cgConnectParameter(from, to); +} + +static void connectEnvParameters(const OGLRenderer::CGEnvironment &cgEnv, CGprogram program) +{ + connectParameters(cgEnv.modelMatrix, cgGetNamedParameter(program, "g_" "modelMatrix")); + connectParameters(cgEnv.viewMatrix, cgGetNamedParameter(program, "g_" "viewMatrix")); + connectParameters(cgEnv.projMatrix, cgGetNamedParameter(program, "g_" "projMatrix")); + connectParameters(cgEnv.modelViewMatrix, cgGetNamedParameter(program, "g_" "modelViewMatrix")); + connectParameters(cgEnv.modelViewProjMatrix, cgGetNamedParameter(program, "g_" "modelViewProjMatrix")); + + +#if !defined(RENDERER_PS3) + connectParameters(cgEnv.boneMatrices, cgGetNamedParameter(program, "g_" "boneMatrices")); +#endif + connectParameters(cgEnv.eyePosition, cgGetNamedParameter(program, "g_" "eyePosition")); + connectParameters(cgEnv.eyeDirection, cgGetNamedParameter(program, "g_" "eyeDirection")); + + connectParameters(cgEnv.fogColorAndDistance, cgGetNamedParameter(program, "g_" "fogColorAndDistance")); + + connectParameters(cgEnv.ambientColor, cgGetNamedParameter(program, "g_" "ambientColor")); + + connectParameters(cgEnv.lightColor, cgGetNamedParameter(program, "g_" "lightColor")); + connectParameters(cgEnv.lightIntensity, cgGetNamedParameter(program, "g_" "lightIntensity")); + connectParameters(cgEnv.lightDirection, cgGetNamedParameter(program, "g_" "lightDirection")); + connectParameters(cgEnv.lightPosition, cgGetNamedParameter(program, "g_" "lightPosition")); + connectParameters(cgEnv.lightInnerRadius, cgGetNamedParameter(program, "g_" "lightInnerRadius")); + connectParameters(cgEnv.lightOuterRadius, cgGetNamedParameter(program, "g_" "lightOuterRadius")); + connectParameters(cgEnv.lightInnerCone, cgGetNamedParameter(program, "g_" "lightInnerCone")); + connectParameters(cgEnv.lightOuterCone, cgGetNamedParameter(program, "g_" "lightOuterCone")); +} + +OGLRendererMaterial::CGVariable::CGVariable(const char *name, VariableType type, PxU32 offset) : + Variable(name, type, offset) +{ + m_vertexHandle = 0; + memset(m_fragmentHandles, 0, sizeof(m_fragmentHandles)); +} + +OGLRendererMaterial::CGVariable::~CGVariable(void) +{ + +} + +void OGLRendererMaterial::CGVariable::addVertexHandle(CGparameter handle) +{ + m_vertexHandle = handle; +} + +void OGLRendererMaterial::CGVariable::addFragmentHandle(CGparameter handle, Pass pass) +{ + m_fragmentHandles[pass] = handle; +} + +#endif + +OGLRendererMaterial::OGLRendererMaterial(OGLRenderer &renderer, const RendererMaterialDesc &desc) : + RendererMaterial(desc, renderer.getEnableMaterialCaching()), + m_renderer(renderer) +{ + m_glAlphaTestFunc = GL_ALWAYS; + + AlphaTestFunc alphaTestFunc = getAlphaTestFunc(); + switch(alphaTestFunc) + { + case ALPHA_TEST_ALWAYS: m_glAlphaTestFunc = GL_ALWAYS; break; + case ALPHA_TEST_EQUAL: m_glAlphaTestFunc = GL_EQUAL; break; + case ALPHA_TEST_NOT_EQUAL: m_glAlphaTestFunc = GL_NOTEQUAL; break; + case ALPHA_TEST_LESS: m_glAlphaTestFunc = GL_LESS; break; + case ALPHA_TEST_LESS_EQUAL: m_glAlphaTestFunc = GL_LEQUAL; break; + case ALPHA_TEST_GREATER: m_glAlphaTestFunc = GL_GREATER; break; + case ALPHA_TEST_GREATER_EQUAL: m_glAlphaTestFunc = GL_GEQUAL; break; + default: + RENDERER_ASSERT(0, "Unknown Alpha Test Func."); + } + +#if defined(RENDERER_ENABLE_CG) + m_vertexProgram = 0; +#if defined(RENDERER_PS3) + m_vertexProfile = getVertexProfile(); + m_fragmentProfile = getFragmentProfile(); +#else +#define NO_SUPPORT_DDX_DDY +#if 0 + // JD: CG_PROFILE_GPU_VP FAILS SO BAD! + m_vertexProfile = CG_PROFILE_ARBVP1; + m_fragmentProfile = CG_PROFILE_ARBVP1; +#else + // PH: Seems to work fine nowadays + m_vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); + m_fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); +#endif +#endif + memset(m_fragmentPrograms, 0, sizeof(m_fragmentPrograms)); + + CGcontext cgContext = m_renderer.getCGContext(); + const OGLRenderer::CGEnvironment &cgEnv = m_renderer.getCGEnvironment(); + if(cgContext && m_vertexProfile && m_fragmentProfile) + { + char fullPath[1024] = "-I"; + Ps::strlcat(fullPath, 1024, m_renderer.getAssetDir()); + Ps::strlcat(fullPath, 1024, "shaders/include"); + const char *vertexEntry = "vmain"; + const char *vertexArgs[] = + { + fullPath, + "-DRENDERER_VERTEX", +#ifdef RENDERER_PS3 + "-DRENDERER_PS3", + "-melf", +#endif + 0, 0, + }; + + cgGLSetOptimalOptions(m_vertexProfile); + if(1) + { + PX_PROFILE_ZONE("OGLRendererMaterial_compile_vertexProgram",0); + m_vertexProgram = static_cast<CGprogram>(SampleFramework::SamplePlatform::platform()->compileProgram(cgContext, m_renderer.getAssetDir(), desc.vertexShaderPath, m_vertexProfile, 0, vertexEntry, vertexArgs)); + } + RENDERER_ASSERT(m_vertexProgram, "Failed to compile Vertex Shader."); + if(m_vertexProgram) + { + PX_PROFILE_ZONE("OGLRendererMaterial_load_vertexProgram",0); + connectEnvParameters(cgEnv, m_vertexProgram); + cgGLLoadProgram(m_vertexProgram); + loadCustomConstants(m_vertexProgram, NUM_PASSES); + } + else + { + char msg[1024]; + Ps::snprintf(msg, sizeof(msg), "Could not find shader file: <%s> in path: <%sshaders/>", desc.vertexShaderPath, m_renderer.getAssetDir()); + RENDERER_OUTPUT_MESSAGE(&m_renderer, msg); + } + + const char *fragmentEntry = "fmain"; + for(PxU32 i=0; i<NUM_PASSES; i++) + { + char passDefine[64] = {0}; + Ps::snprintf(passDefine, 63, "-D%s", getPassName((Pass)i)); + + char fvaceDefine[20] = "-DENABLE_VFACE=0"; +#if PX_WINDOWS + // Aparently the FACE semantic is only supported with fp40 + if (cgGLIsProfileSupported(CG_PROFILE_FP40)) + { + fvaceDefine[15] = '1'; + } +#endif + const char *fragmentArgs[] = + { + fullPath, + "-DRENDERER_FRAGMENT", + fvaceDefine, // used for double sided rendering (as done in D3D anyways) + "-DVFACE=FACE", // rename VFACE to FACE semantic, the first is only known to HLSL shaders... +#ifdef RENDERER_PS3 + "-DRENDERER_PS3", + "-melf", + "-DENABLE_VFACE", +#endif +#ifdef NO_SUPPORT_DDX_DDY + "-DNO_SUPPORT_DDX_DDY", +#endif + passDefine, + 0, 0, + }; + cgGLSetOptimalOptions(m_fragmentProfile); + CGprogram fp = 0; + if(1) + { + PX_PROFILE_ZONE("OGLRendererMaterial_compile_fragmentProgram",0); + fp = static_cast<CGprogram>(SampleFramework::SamplePlatform::platform()->compileProgram(cgContext, m_renderer.getAssetDir(), desc.fragmentShaderPath, m_fragmentProfile, getPassName((Pass)i), fragmentEntry, fragmentArgs)); + } + RENDERER_ASSERT(fp, "Failed to compile Fragment Shader."); + if(fp) + { + PX_PROFILE_ZONE("OGLRendererMaterial_load_fragmentProgram",0); + connectEnvParameters(cgEnv, fp); + cgGLLoadProgram(fp); + m_fragmentPrograms[i] = fp; + loadCustomConstants(fp, (Pass)i); + } + } + } +#endif +} + +OGLRendererMaterial::~OGLRendererMaterial(void) +{ +#if defined(RENDERER_ENABLE_CG) + if(m_vertexProgram) + { + cgDestroyProgram(m_vertexProgram); + } + for(PxU32 i=0; i<NUM_PASSES; i++) + { + CGprogram fp = m_fragmentPrograms[i]; + if(fp) + { + cgDestroyProgram(fp); + } + } +#endif +} + +void OGLRendererMaterial::bind(RendererMaterial::Pass pass, RendererMaterialInstance *materialInstance, bool instanced) const +{ + m_renderer.setCurrentMaterial(this); + + if(m_glAlphaTestFunc == GL_ALWAYS) + { + glDisable(GL_ALPHA_TEST); + } + else + { + glEnable(GL_ALPHA_TEST); + glAlphaFunc(m_glAlphaTestFunc, PxClamp(getAlphaTestRef(), 0.0f, 1.0f)); + } + + if(getBlending()) + { + glBlendFunc(getGLBlendFunc(getSrcBlendFunc()), getGLBlendFunc(getDstBlendFunc())); + glEnable(GL_BLEND); + glDepthMask(0); + } + +#if defined(RENDERER_ENABLE_CG) + if(m_vertexProgram) + { + cgGLEnableProfile(m_vertexProfile); + cgGLBindProgram(m_vertexProgram); +#if !defined(RENDERER_PS3) + cgUpdateProgramParameters(m_vertexProgram); +#endif + } + if(pass < NUM_PASSES && m_fragmentPrograms[pass]) + { + cgGLEnableProfile(m_fragmentProfile); + cgGLBindProgram(m_fragmentPrograms[pass]); + + RendererMaterial::bind(pass, materialInstance, instanced); + //this is a kludge to make the particles work. I see no way to set env's through this interface + glEnable(GL_POINT_SPRITE_ARB); + glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); + +#if !defined(RENDERER_PS3) + cgUpdateProgramParameters(m_fragmentPrograms[pass]); +#endif + } +#endif +} + +void OGLRendererMaterial::bindMeshState(bool instanced) const +{ +#if defined(RENDERER_ENABLE_CG) + if(m_vertexProgram) + { +#if defined(RENDERER_PS3) + cgGLBindProgram(m_vertexProgram); +#else + cgUpdateProgramParameters(m_vertexProgram); +#endif + } +#endif +} + +void OGLRendererMaterial::unbind(void) const +{ +#if defined(RENDERER_ENABLE_CG) + glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE); + glDisable(GL_POINT_SPRITE_ARB); + glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); + + if(m_vertexProfile) + { + cgGLUnbindProgram(m_vertexProfile); + cgGLDisableProfile(m_vertexProfile); + } + if(m_fragmentProfile) + { + cgGLUnbindProgram(m_fragmentProfile); + cgGLDisableProfile(m_fragmentProfile); + } +#endif + + if(getBlending()) + { + glDisable(GL_BLEND); + glDepthMask(1); + } + + m_renderer.setCurrentMaterial(0); +} + +#if defined(RENDERER_ENABLE_CG) +template<class TextureType> +static void bindSamplerVariable(CGparameter param, RendererTexture2D &texture) +{ + TextureType &tex = *static_cast<TextureType*>(&texture); + if(param) + { + CGresource resource = cgGetParameterResource(param); + RENDERER_ASSERT(resource >= CG_TEXUNIT0 && resource <= CG_TEXUNIT15, "Invalid Texture Resource Location."); + if(resource >= CG_TEXUNIT0 && resource <= CG_TEXUNIT15) + { + tex.bind(resource-CG_TEXUNIT0); + } + } +} +#endif + +void OGLRendererMaterial::bindVariable(Pass pass, const Variable &variable, const void *data) const +{ +#if defined(RENDERER_ENABLE_CG) + CGVariable &var = *(CGVariable*)&variable; + switch(var.getType()) + { + case VARIABLE_FLOAT: + { + float f = *(const float*)data; + if(var.m_vertexHandle) cgGLSetParameter1f(var.m_vertexHandle, f); + if(var.m_fragmentHandles[pass]) cgGLSetParameter1f(var.m_fragmentHandles[pass], f); + break; + } + case VARIABLE_FLOAT2: + { + const float *f = (const float*)data; + if(var.m_vertexHandle) cgGLSetParameter2fv(var.m_vertexHandle, f); + if(var.m_fragmentHandles[pass]) cgGLSetParameter2fv(var.m_fragmentHandles[pass], f); + break; + } + case VARIABLE_FLOAT3: + { + const float *f = (const float*)data; + if(var.m_vertexHandle) cgGLSetParameter3fv(var.m_vertexHandle, f); + if(var.m_fragmentHandles[pass]) cgGLSetParameter3fv(var.m_fragmentHandles[pass], f); + break; + } + case VARIABLE_FLOAT4: + { + const float *f = (const float*)data; + if(var.m_vertexHandle) cgGLSetParameter4fv(var.m_vertexHandle, f); + if(var.m_fragmentHandles[pass]) cgGLSetParameter4fv(var.m_fragmentHandles[pass], f); + break; + } + case VARIABLE_SAMPLER2D: + data = *(void**)data; + RENDERER_ASSERT(data, "NULL Sampler."); + if(data) + { + bindSamplerVariable<OGLRendererTexture2D>(var.m_vertexHandle, *(RendererTexture2D*)data); + bindSamplerVariable<OGLRendererTexture2D>(var.m_fragmentHandles[pass], *(RendererTexture2D*)data); + } + break; + case VARIABLE_SAMPLER3D: + RENDERER_ASSERT(0, "3D GL Textures Not Implemented."); + /* + data = *(void**)data; + RENDERER_ASSERT(data, "NULL Sampler."); + if(data) + { + bindSamplerVariable<OGLRendererTexture3D>(var.m_vertexHandle, *(RendererTexture2D*)data); + bindSamplerVariable<OGLRendererTexture3D>(var.m_fragmentHandles[pass], *(RendererTexture2D*)data); + } + */ + break; + default: + RENDERER_ASSERT(0, "Cannot bind variable of this type."); + break; + } +#endif +} + +#if defined(RENDERER_ENABLE_CG) +void OGLRendererMaterial::loadCustomConstants(CGprogram program, Pass pass) +{ + for(CGparameter param = cgGetFirstParameter(program, CG_GLOBAL); param; param=cgGetNextParameter(param)) + { + const char *name = cgGetParameterName(param); + CGtype cgtype = cgGetParameterType(param); + VariableType type = cgtype != CG_STRUCT && cgtype != CG_ARRAY ? getVariableType(cgtype) : NUM_VARIABLE_TYPES; + if(type < NUM_VARIABLE_TYPES && cgIsParameter(param) && cgIsParameterReferenced(param) && strncmp(name, "g_", 2)) + { + CGVariable *var = 0; + // find existing variable... + PxU32 numVariables = (PxU32)m_variables.size(); + for(PxU32 i=0; i<numVariables; i++) + { + if(!strcmp(m_variables[i]->getName(), name)) + { + var = static_cast<CGVariable*>(m_variables[i]); + break; + } + } + // check to see if the variable is of the same type. + if(var) + { + RENDERER_ASSERT(var->getType() == type, "Variable changes type!"); + } + // if the variable was not found, add it. + if(!var) + { + var = new CGVariable(name, type, m_variableBufferSize); + m_variables.push_back(var); + m_variableBufferSize += var->getDataSize(); + } + if(pass < NUM_PASSES) + { + var->addFragmentHandle(param, pass); + } + else + { + var->addVertexHandle(param); + } + } + } +} +#endif + +#endif // #if defined(RENDERER_ENABLE_OPENGL) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMaterial.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMaterial.h new file mode 100644 index 00000000..f415e3a6 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMaterial.h @@ -0,0 +1,106 @@ +// 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. +#ifndef OGL_RENDERER_MATERIAL_H +#define OGL_RENDERER_MATERIAL_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererMaterial.h> + +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class OGLRendererMaterial : public RendererMaterial + { + friend class OGLRendererMesh; + public: + OGLRendererMaterial(OGLRenderer &renderer, const RendererMaterialDesc &desc); + virtual ~OGLRendererMaterial(void); + virtual void setModelMatrix(const float *matrix) + { + PX_UNUSED(matrix); + PX_ALWAYS_ASSERT(); + } + + private: + virtual const Renderer& getRenderer() const { return m_renderer; } + virtual void bind(RendererMaterial::Pass pass, RendererMaterialInstance *materialInstance, bool instanced) const; + virtual void bindMeshState(bool instanced) const; + virtual void unbind(void) const; + virtual void bindVariable(Pass pass, const Variable &variable, const void *data) const; + +#if defined(RENDERER_ENABLE_CG) + void loadCustomConstants(CGprogram program, Pass pass); +#endif + + private: +#if defined(RENDERER_ENABLE_CG) + class CGVariable : public Variable + { + friend class OGLRendererMaterial; + public: + CGVariable(const char *name, VariableType type, PxU32 offset); + virtual ~CGVariable(void); + + void addVertexHandle(CGparameter handle); + void addFragmentHandle(CGparameter handle, Pass pass); + + private: + CGparameter m_vertexHandle; + CGparameter m_fragmentHandles[NUM_PASSES]; + }; +#endif + + private: + OGLRendererMaterial &operator=(const OGLRendererMaterial&) { return *this; } + + private: + OGLRenderer &m_renderer; + + GLenum m_glAlphaTestFunc; + +#if defined(RENDERER_ENABLE_CG) + CGprofile m_vertexProfile; + CGprogram m_vertexProgram; + + CGprofile m_fragmentProfile; + CGprogram m_fragmentPrograms[NUM_PASSES]; +#if defined(RENDERER_PS3) + public: + CGprogram GetVertexProgramPS3(){ return m_vertexProgram;} +#endif +#endif + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMesh.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMesh.cpp new file mode 100644 index 00000000..cd25df2b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMesh.cpp @@ -0,0 +1,171 @@ +// 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 <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererMesh.h" + +#include "OGLRendererInstanceBuffer.h" +#include "OGLRendererMaterial.h" + +using namespace SampleRenderer; + +static GLenum getGLPrimitive(RendererMesh::Primitive primitive) +{ + GLenum glprim = ~(GLenum)0; + switch(primitive) + { + case RendererMesh::PRIMITIVE_POINTS: glprim = GL_POINTS; break; + case RendererMesh::PRIMITIVE_LINES: glprim = GL_LINES; break; + case RendererMesh::PRIMITIVE_LINE_STRIP: glprim = GL_LINE_STRIP; break; + case RendererMesh::PRIMITIVE_TRIANGLES: glprim = GL_TRIANGLES; break; + case RendererMesh::PRIMITIVE_TRIANGLE_STRIP: glprim = GL_TRIANGLE_STRIP; break; + case RendererMesh::PRIMITIVE_POINT_SPRITES: glprim = GL_POINTS; break; + default: break; + } + RENDERER_ASSERT(glprim != ~(GLenum)0, "Unable to find GL Primitive type."); + return glprim; +} + +static GLenum getGLIndexType(RendererIndexBuffer::Format format) +{ + GLenum gltype = 0; + switch(format) + { + case RendererIndexBuffer::FORMAT_UINT16: gltype = GL_UNSIGNED_SHORT; break; + case RendererIndexBuffer::FORMAT_UINT32: gltype = GL_UNSIGNED_INT; break; + default: break; + } + RENDERER_ASSERT(gltype, "Unable to convert to GL Index Type."); + return gltype; +} + +OGLRendererMesh::OGLRendererMesh(OGLRenderer &renderer, const RendererMeshDesc &desc) +: RendererMesh(desc) +, m_renderer(renderer) +{ + +} + +OGLRendererMesh::~OGLRendererMesh(void) +{ + +} + +void OGLRendererMesh::renderIndices(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial *material) const +{ + const PxU32 indexSize = RendererIndexBuffer::getFormatByteSize(indexFormat); + void *buffer = ((PxU8*)0)+indexSize*firstIndex; + glDrawElements(getGLPrimitive(getPrimitives()), numIndices, getGLIndexType(indexFormat), buffer); +} + +void OGLRendererMesh::renderVertices(PxU32 numVertices, RendererMaterial *material) const +{ + RendererMesh::Primitive primitive = getPrimitives(); + glDrawArrays(getGLPrimitive(primitive), 0, numVertices); +} + +void OGLRendererMesh::renderIndicesInstanced(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial *material) const +{ + const OGLRendererInstanceBuffer *ib = static_cast<const OGLRendererInstanceBuffer*>(getInstanceBuffer()); + if(ib) + { + const PxU32 firstInstance = m_firstInstance; + const PxU32 numInstances = getNumInstances(); + + const OGLRendererMaterial *currentMaterial = m_renderer.getCurrentMaterial(); + + CGparameter modelMatrixParam = m_renderer.getCGEnvironment().modelMatrix; + CGparameter modelViewMatrixParam = m_renderer.getCGEnvironment().modelViewMatrix; + + if(currentMaterial && modelMatrixParam && modelViewMatrixParam) + { + for(PxU32 i=0; i<numInstances; i++) + { +#if defined(RENDERER_ENABLE_CG) + const physx::PxMat44 &model = ib->getModelMatrix(firstInstance+i); + GLfloat glmodel[16]; + PxToGL(glmodel, model); + + physx::PxMat44 modelView = m_renderer.getViewMatrix() * model; + GLfloat glmodelview[16]; + PxToGL(glmodelview, modelView); + + cgGLSetMatrixParameterfc(modelMatrixParam, glmodel); + cgGLSetMatrixParameterfc(modelViewMatrixParam, glmodelview); +#endif + + currentMaterial->bindMeshState(false); + + renderIndices(numVertices, firstIndex, numIndices, indexFormat, material); + } + } + } +} + +void OGLRendererMesh::renderVerticesInstanced(PxU32 numVertices, RendererMaterial *material) const +{ + const OGLRendererInstanceBuffer *ib = static_cast<const OGLRendererInstanceBuffer*>(getInstanceBuffer()); + if(ib) + { + const PxU32 firstInstance = m_firstInstance; + const PxU32 numInstances = getNumInstances(); + + const OGLRendererMaterial *currentMaterial = m_renderer.getCurrentMaterial(); + + CGparameter modelMatrixParam = m_renderer.getCGEnvironment().modelMatrix; + CGparameter modelViewMatrixParam = m_renderer.getCGEnvironment().modelViewMatrix; + + if(currentMaterial && modelMatrixParam && modelViewMatrixParam) + { + for(PxU32 i=0; i<numInstances; i++) + { +#if defined(RENDERER_ENABLE_CG) + const physx::PxMat44 &model = ib->getModelMatrix(firstInstance+i); + GLfloat glmodel[16]; + PxToGL(glmodel, model); + + physx::PxMat44 modelView = m_renderer.getViewMatrix() * model; + GLfloat glmodelview[16]; + PxToGL(glmodelview, modelView); + + cgGLSetMatrixParameterfc(modelMatrixParam, glmodel); + cgGLSetMatrixParameterfc(modelViewMatrixParam, glmodelview); +#endif + + currentMaterial->bindMeshState(false); + + renderVertices(numVertices, material); + } + } + } +} + +#endif // #if defined(RENDERER_ENABLE_OPENGL) + diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMesh.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMesh.h new file mode 100644 index 00000000..95281bbd --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererMesh.h @@ -0,0 +1,66 @@ +// 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. +#ifndef OGL_RENDERER_MESH_H +#define OGL_RENDERER_MESH_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererMesh.h> + +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class OGLRendererMesh : public RendererMesh + { + public: + OGLRendererMesh(OGLRenderer &renderer, const RendererMeshDesc &desc); + virtual ~OGLRendererMesh(void); + + public: + virtual void renderIndices(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat,RendererMaterial *material) const; + virtual void renderVertices(PxU32 numVertices,RendererMaterial *material) const; + + virtual void renderIndicesInstanced(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat,RendererMaterial *material) const; + virtual void renderVerticesInstanced(PxU32 numVertices,RendererMaterial *material) const; + + protected: + void operator=(const OGLRendererMesh &){} + + Renderer& renderer() { return m_renderer; } + + private: + OGLRenderer &m_renderer; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererSpotLight.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererSpotLight.cpp new file mode 100644 index 00000000..9a44b99d --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererSpotLight.cpp @@ -0,0 +1,63 @@ +// 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 <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererSpotLight.h" + +using namespace SampleRenderer; + +OGLRendererSpotLight::OGLRendererSpotLight(const RendererSpotLightDesc &desc, OGLRenderer &renderer) +: RendererSpotLight(desc) +#if defined(RENDERER_ENABLE_CG) +, m_cgenv(renderer.getCGEnvironment()) +#endif +{ + +} + +OGLRendererSpotLight::~OGLRendererSpotLight(void) +{ + +} + +void OGLRendererSpotLight::bind(void) const +{ +#if defined(RENDERER_ENABLE_CG) + setColorParameter(m_cgenv.lightColor, m_color); + cgSetParameter1f( m_cgenv.lightIntensity, m_intensity); + cgSetParameter3fv(m_cgenv.lightDirection, &m_direction.x); + cgSetParameter3fv(m_cgenv.lightPosition, &m_position.x); + cgSetParameter1f( m_cgenv.lightInnerRadius, m_innerRadius); + cgSetParameter1f( m_cgenv.lightOuterRadius, m_outerRadius); + cgSetParameter1f( m_cgenv.lightInnerCone, m_innerCone); + cgSetParameter1f( m_cgenv.lightOuterCone, m_outerCone); +#endif +} + +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererSpotLight.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererSpotLight.h new file mode 100644 index 00000000..c6828849 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererSpotLight.h @@ -0,0 +1,58 @@ +// 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. +#ifndef OGL_RENDERER_SPOT_LIGHT_H +#define OGL_RENDERER_SPOT_LIGHT_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererSpotLight.h> + +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class OGLRendererSpotLight : public RendererSpotLight + { + public: + OGLRendererSpotLight(const RendererSpotLightDesc &desc, OGLRenderer &renderer); + virtual ~OGLRendererSpotLight(void); + + virtual void bind(void) const; + + private: +#if defined(RENDERER_ENABLE_CG) + const OGLRenderer::CGEnvironment &m_cgenv; +#endif + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_DIRECT3D9) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererTexture2D.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererTexture2D.cpp new file mode 100644 index 00000000..a0d99b8b --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererTexture2D.cpp @@ -0,0 +1,299 @@ +// 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 <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererTexture2D.h" +#include <RendererTexture2DDesc.h> + +using namespace SampleRenderer; + +static GLuint getGLPixelFormat(RendererTexture2D::Format format) +{ + GLuint glformat = 0; + switch(format) + { + case RendererTexture2D::FORMAT_B8G8R8A8: glformat = GL_BGRA; break; + case RendererTexture2D::FORMAT_R8G8B8A8: glformat = GL_RGBA; break; + case RendererTexture2D::FORMAT_A8: glformat = GL_ALPHA; break; + case RendererTexture2D::FORMAT_R32F: glformat = GL_LUMINANCE; break; + case RendererTexture2D::FORMAT_D16: glformat = GL_DEPTH_COMPONENT; break; + case RendererTexture2D::FORMAT_D24S8: glformat = GL_DEPTH_COMPONENT; break; + default: + // The pixel type need not be defined (in the case of compressed formats) + break; + } + return glformat; +} + +static GLuint getGLPixelInternalFormat(RendererTexture2D::Format format) +{ + GLuint glinternalformat = 0; + switch(format) + { + case RendererTexture2D::FORMAT_B8G8R8A8: + glinternalformat = GL_RGBA8; + break; + case RendererTexture2D::FORMAT_R8G8B8A8: + glinternalformat = GL_RGBA8; + break; + case RendererTexture2D::FORMAT_A8: + glinternalformat = GL_ALPHA8; + break; +#if !defined(RENDERER_PS3) + case RendererTexture2D::FORMAT_R32F: + if(GLEW_ARB_texture_float) glinternalformat = GL_LUMINANCE32F_ARB; + else if(GLEW_ATI_texture_float) glinternalformat = GL_LUMINANCE_FLOAT32_ATI; + break; +#endif + case RendererTexture2D::FORMAT_DXT1: + glinternalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + break; + case RendererTexture2D::FORMAT_DXT3: + glinternalformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case RendererTexture2D::FORMAT_DXT5: + glinternalformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; +#if !defined(RENDERER_PS3) + case RendererTexture2D::FORMAT_D16: + glinternalformat = GL_DEPTH_COMPONENT16_ARB; + break; + case RendererTexture2D::FORMAT_D24S8: + glinternalformat = GL_DEPTH_COMPONENT24_ARB; + break; +#endif + default: RENDERER_ASSERT(0, "Unsupported GL pixel internal format."); break; + } + RENDERER_ASSERT(glinternalformat, "Unable to compute GL Internal Format."); + return glinternalformat; +} + +static GLuint getGLPixelType(RendererTexture2D::Format format) +{ + GLuint gltype = 0; + switch(format) + { + case RendererTexture2D::FORMAT_B8G8R8A8: + case RendererTexture2D::FORMAT_R8G8B8A8: + gltype = GL_UNSIGNED_BYTE; + break; + case RendererTexture2D::FORMAT_A8: + gltype = GL_UNSIGNED_BYTE; + break; + case RendererTexture2D::FORMAT_R32F: + gltype = GL_FLOAT; + break; + case RendererTexture2D::FORMAT_D16: + gltype = GL_UNSIGNED_SHORT; + break; + case RendererTexture2D::FORMAT_D24S8: + gltype = GL_UNSIGNED_INT; + break; + default: + // The pixel type need not be defined (in the case of compressed formats) + break; + } + return gltype; +} + +static GLint getGLTextureFilter(RendererTexture2D::Filter filter, bool mipmap) +{ + GLint glfilter = 0; + switch(filter) + { + case RendererTexture2D::FILTER_NEAREST: glfilter = mipmap ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; break; + case RendererTexture2D::FILTER_LINEAR: glfilter = mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; break; + case RendererTexture2D::FILTER_ANISOTROPIC: glfilter = mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; break; + default: break; + } + RENDERER_ASSERT(glfilter, "Unable to convert to OpenGL Filter mode."); + return glfilter; +} + +static GLint getGLTextureAddressing(RendererTexture2D::Addressing addressing) +{ + GLint glwrap = 0; + switch(addressing) + { + case RendererTexture2D::ADDRESSING_WRAP: glwrap = GL_REPEAT; break; + case RendererTexture2D::ADDRESSING_CLAMP: glwrap = GL_CLAMP; break; + case RendererTexture2D::ADDRESSING_MIRROR: glwrap = GL_MIRRORED_REPEAT; break; + default: break; + } + RENDERER_ASSERT(glwrap, "Unable to convert to OpenGL Addressing mode."); + return glwrap; +} + +OGLRendererTexture2D::OGLRendererTexture2D(const RendererTexture2DDesc &desc) : +RendererTexture2D(desc) +{ + RENDERER_ASSERT(desc.depth == 1, "Invalid depth for 3D Texture!"); + + m_textureid = 0; + m_glformat = 0; + m_glinternalformat = 0; + m_gltype = 0; + m_numLevels = 0; + m_data = 0; + + m_glformat = getGLPixelFormat(desc.format); + m_glinternalformat = getGLPixelInternalFormat(desc.format); + m_gltype = getGLPixelType(desc.format); + + glGenTextures(1, &m_textureid); + RENDERER_ASSERT(m_textureid, "Failed to create OpenGL Texture."); + if(m_textureid) + { + m_width = desc.width; + m_height = desc.height; + m_numLevels = desc.numLevels; + m_data = new PxU8*[m_numLevels]; + memset(m_data, 0, sizeof(PxU8*)*m_numLevels); + + glBindTexture(GL_TEXTURE_2D, m_textureid); + if(isDepthStencilFormat(desc.format)) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY); + } + if(isCompressedFormat(desc.format)) + { + for(PxU32 i=0; i<desc.numLevels; i++) + { + PxU32 w = getLevelDimension(m_width, i); + PxU32 h = getLevelDimension(m_height, i); + PxU32 levelSize = computeImageByteSize(w, h, 1, desc.format); + m_data[i] = new PxU8[levelSize]; + memset(m_data[i], 0, levelSize); + + // limit the maximum level used for mip mapping (we don't update levels < 4 pixels wide) + if (w >= 4 && h >= 4) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, float(i)); + + glCompressedTexImage2D(GL_TEXTURE_2D, (GLint)i, m_glinternalformat, w, h, 0, levelSize, m_data[i]); + } + } + else + { + RENDERER_ASSERT(m_glformat, "Unknown OpenGL Format!"); + for(PxU32 i=0; i<desc.numLevels; i++) + { + PxU32 w = getLevelDimension(m_width, i); + PxU32 h = getLevelDimension(m_height, i); + PxU32 levelSize = computeImageByteSize(w, h, 1, desc.format); + m_data[i] = new PxU8[levelSize]; + memset(m_data[i], 0, levelSize); + glTexImage2D(GL_TEXTURE_2D, (GLint)i, m_glinternalformat, w, h, 0, m_glformat, m_gltype, m_data[i]); + } + } + + + // set filtering mode... + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getGLTextureFilter(desc.filter, m_numLevels > 1)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getGLTextureFilter(desc.filter, false)); + if(desc.filter == FILTER_ANISOTROPIC) + { + GLfloat maxAnisotropy = 1.0f; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); + } + + // set addressing modes... + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getGLTextureAddressing(desc.addressingU)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getGLTextureAddressing(desc.addressingV)); + + glBindTexture(GL_TEXTURE_2D, 0); + } +} + +OGLRendererTexture2D::~OGLRendererTexture2D(void) +{ + if(m_textureid) + { + glDeleteTextures(1, &m_textureid); + } + if(m_data) + { + for(PxU32 i=0; i<m_numLevels; i++) + { + delete [] m_data[i]; + } + delete [] m_data; + } +} + +void *OGLRendererTexture2D::lockLevel(PxU32 level, PxU32 &pitch) +{ + void *buffer = 0; + RENDERER_ASSERT(level < m_numLevels, "Level out of range!"); + if(level < m_numLevels) + { + buffer = m_data[level]; + pitch = getFormatNumBlocks(getWidth()>>level, getFormat()) * getBlockSize(); + } + return buffer; +} + +void OGLRendererTexture2D::unlockLevel(PxU32 level) +{ + RENDERER_ASSERT(level < m_numLevels, "Level out of range!"); + if(m_textureid && level < m_numLevels) + { + PxU32 w = getLevelDimension(getWidth(), level); + PxU32 h = getLevelDimension(getHeight(), level); + glBindTexture(GL_TEXTURE_2D, m_textureid); + if(isCompressedFormat(getFormat())) + { + PxU32 levelSize = computeImageByteSize(w, h, 1, getFormat()); + + // Some platforms don't like smaller than 4x4 compressed textures + if (w >= 4 && h >= 4) + glCompressedTexSubImage2D(GL_TEXTURE_2D, (GLint)level, 0, 0, w, h, m_glinternalformat, levelSize, m_data[level]); + } + else + { + glTexImage2D(GL_TEXTURE_2D, (GLint)level, m_glinternalformat, w, h, 0, m_glformat, m_gltype, m_data[level]); + } + glBindTexture(GL_TEXTURE_2D, 0); + } +} + +void OGLRendererTexture2D::bind(PxU32 textureUnit) +{ + if(m_textureid) + { + glActiveTextureARB(GL_TEXTURE0_ARB + textureUnit); + glClientActiveTextureARB(GL_TEXTURE0_ARB + textureUnit); + glBindTexture(GL_TEXTURE_2D, m_textureid); + } +} + +#endif // #if defined(RENDERER_ENABLE_OPENGL) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererTexture2D.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererTexture2D.h new file mode 100644 index 00000000..de894347 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererTexture2D.h @@ -0,0 +1,75 @@ +// 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. +#ifndef OGL_RENDERER_TEXTURE_2D_H +#define OGL_RENDERER_TEXTURE_2D_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererTexture2D.h> +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class OGLRendererTexture2D : public RendererTexture2D + { + public: + OGLRendererTexture2D(const RendererTexture2DDesc &desc); + virtual ~OGLRendererTexture2D(void); + + public: + virtual void *lockLevel(PxU32 level, PxU32 &pitch); + virtual void unlockLevel(PxU32 level); + + void bind(PxU32 textureUnit); + + virtual void select(PxU32 stageIndex) + { + bind(stageIndex); + } + + private: + + GLuint m_textureid; + GLuint m_glformat; + GLuint m_glinternalformat; + GLuint m_gltype; + + PxU32 m_width; + PxU32 m_height; + + PxU32 m_numLevels; + + PxU8 **m_data; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererVertexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererVertexBuffer.cpp new file mode 100644 index 00000000..6ca1c52c --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererVertexBuffer.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 "RendererConfig.h" +#include <SamplePlatform.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include "OGLRendererVertexBuffer.h" + +#include <RendererVertexBufferDesc.h> + +#if PX_WINDOWS +#include "cudamanager/PxCudaContextManager.h" +#endif + +using namespace SampleRenderer; + +OGLRendererVertexBuffer::OGLRendererVertexBuffer(const RendererVertexBufferDesc &desc) : + RendererVertexBuffer(desc) +, m_vbo(0) +, m_access(0) +{ + RENDERER_ASSERT(GLEW_ARB_vertex_buffer_object, "Vertex Buffer Objects not supported on this machine!"); + if(GLEW_ARB_vertex_buffer_object) + { + GLenum usage = GL_STATIC_DRAW_ARB; + m_access = GL_READ_WRITE; + if(getHint() == HINT_DYNAMIC) + { + usage = GL_DYNAMIC_DRAW_ARB; + m_access = GL_WRITE_ONLY; + } + + RENDERER_ASSERT(m_stride && desc.maxVertices, "Unable to create Vertex Buffer of zero size."); + if(m_stride && desc.maxVertices) + { + glGenBuffersARB(1, &m_vbo); + RENDERER_ASSERT(m_vbo, "Failed to create Vertex Buffer Object."); + } + if(m_vbo) + { + m_maxVertices = desc.maxVertices; + PxU32 bufferSize = m_stride * m_maxVertices; + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vbo); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize, 0, usage); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + +#if PX_WINDOWS + if(m_interopContext && m_mustBeRegisteredInCUDA) + { + RENDERER_ASSERT(m_deferredUnlock == false, "Deferred VB Unlock must be disabled when CUDA Interop is in use.") + m_registeredInCUDA = m_interopContext->registerResourceInCudaGL(m_InteropHandle, (PxU32) m_vbo); + } +#endif + } + } +} + +OGLRendererVertexBuffer::~OGLRendererVertexBuffer(void) +{ + if(m_vbo) + { +#if PX_WINDOWS + if(m_registeredInCUDA) + { + m_interopContext->unregisterResourceInCuda(m_InteropHandle); + } +#endif + glDeleteBuffersARB(1, &m_vbo); + } +} + +PxU32 OGLRendererVertexBuffer::convertColor(const RendererColor& color) +{ +#if defined(RENDERER_WINDOWS) + return color.a << 24 | color.b << 16 | color.g << 8 | color.r; +#elif defined (RENDERER_PS3) + return (PxU32&)color; +#elif defined (RENDERER_MACOSX) + return color.a << 24 | color.b << 16 | color.g << 8 | color.r; // TODO: JPB: Check if this is the right order +#elif defined(RENDERER_LINUX) + return color.a << 24 | color.b << 16 | color.g << 8 | color.r; +#else + PX_ASSERT(!"Platform not implemented"); + return (PxU32&)color; +#endif +} + +void OGLRendererVertexBuffer::swizzleColor(void *colors, PxU32 stride, PxU32 numColors, RendererVertexBuffer::Format inFormat) +{ +#if !defined(RENDERER_PS3) + if (inFormat == RendererVertexBuffer::FORMAT_COLOR_BGRA) + { + const void *end = ((PxU8*)colors)+(stride*numColors); + for(PxU8* iterator = (PxU8*)colors; iterator < end; iterator+=stride) + { + // swizzle red and blue + std::swap(((PxU8*)iterator)[0], ((PxU8*)iterator)[2]); + } + } +#endif +} + +void *OGLRendererVertexBuffer::lock(void) +{ + PX_PROFILE_ZONE("OGLRendererVertexBufferLock",0); + void *buffer = 0; + if(m_vbo) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vbo); + buffer = glMapBuffer(GL_ARRAY_BUFFER, m_access); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + return buffer; +} + +void OGLRendererVertexBuffer::unlock(void) +{ + if(m_vbo) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vbo); + glUnmapBuffer(GL_ARRAY_BUFFER); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + +static GLuint getGLFormatSize(RendererVertexBuffer::Format format) +{ + PxU32 size = 0; + switch(format) + { + case RendererVertexBuffer::FORMAT_FLOAT1: size = 1; break; + case RendererVertexBuffer::FORMAT_FLOAT2: size = 2; break; + case RendererVertexBuffer::FORMAT_FLOAT3: size = 3; break; + case RendererVertexBuffer::FORMAT_FLOAT4: size = 4; break; + case RendererVertexBuffer::FORMAT_UBYTE4: size = 4; break; + case RendererVertexBuffer::FORMAT_USHORT4: size = 4; break; + case RendererVertexBuffer::FORMAT_COLOR_BGRA: size = 4; break; + case RendererVertexBuffer::FORMAT_COLOR_RGBA: size = 4; break; + case RendererVertexBuffer::FORMAT_COLOR_NATIVE: size = 4; break; + default: break; + } + RENDERER_ASSERT(size, "Unable to compute number of Vertex Buffer elements."); + return size; +} + +static GLenum getGLFormatType(RendererVertexBuffer::Format format) +{ + GLenum type = 0; + switch(format) + { + case RendererVertexBuffer::FORMAT_FLOAT1: + case RendererVertexBuffer::FORMAT_FLOAT2: + case RendererVertexBuffer::FORMAT_FLOAT3: + case RendererVertexBuffer::FORMAT_FLOAT4: + type = GL_FLOAT; + break; + case RendererVertexBuffer::FORMAT_UBYTE4: + type = GL_BYTE; + break; + case RendererVertexBuffer::FORMAT_USHORT4: + type = GL_SHORT; + break; + case RendererVertexBuffer::FORMAT_COLOR_BGRA: + case RendererVertexBuffer::FORMAT_COLOR_RGBA: + case RendererVertexBuffer::FORMAT_COLOR_NATIVE: + type = GL_UNSIGNED_BYTE; + break; + default: break; + } + RENDERER_ASSERT(type, "Unable to compute GLType for Vertex Buffer Format."); + return type; +} + +static GLenum getGLSemantic(RendererVertexBuffer::Semantic semantic) +{ + GLenum glsemantic = 0; + switch(semantic) + { + case RendererVertexBuffer::SEMANTIC_POSITION: glsemantic = GL_VERTEX_ARRAY; break; + case RendererVertexBuffer::SEMANTIC_COLOR: glsemantic = GL_COLOR_ARRAY; break; + case RendererVertexBuffer::SEMANTIC_NORMAL: glsemantic = GL_NORMAL_ARRAY; break; + case RendererVertexBuffer::SEMANTIC_TANGENT: glsemantic = GL_TEXTURE_COORD_ARRAY; break; + + case RendererVertexBuffer::SEMANTIC_TEXCOORD0: + case RendererVertexBuffer::SEMANTIC_TEXCOORD1: + case RendererVertexBuffer::SEMANTIC_TEXCOORD2: + case RendererVertexBuffer::SEMANTIC_TEXCOORD3: + case RendererVertexBuffer::SEMANTIC_BONEINDEX: + case RendererVertexBuffer::SEMANTIC_BONEWEIGHT: + glsemantic = GL_TEXTURE_COORD_ARRAY; + break; + default: + break; + } + // There is no reason why certain semantics can go unsupported by OpenGL + //RENDERER_ASSERT(glsemantic, "Unable to compute the GL Semantic for Vertex Buffer Semantic."); + return glsemantic; +} + +void OGLRendererVertexBuffer::bind(PxU32 streamID, PxU32 firstVertex) +{ + PX_PROFILE_ZONE("OGLRendererVertexBufferBind",0); + prepareForRender(); + const PxU8 *buffer = ((PxU8*)0) + firstVertex*m_stride; + if(m_vbo) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vbo); + for(PxU32 i=0; i<NUM_SEMANTICS; i++) + { + Semantic semantic = (Semantic)i; + const SemanticDesc &sm = m_semanticDescs[semantic]; + if(sm.format < NUM_FORMATS) + { + switch(semantic) + { + case SEMANTIC_POSITION: + RENDERER_ASSERT(sm.format >= FORMAT_FLOAT1 && sm.format <= FORMAT_FLOAT4, "Unsupported Vertex Buffer Format for POSITION semantic."); + if(sm.format >= FORMAT_FLOAT1 && sm.format <= FORMAT_FLOAT4) + { + glVertexPointer(getGLFormatSize(sm.format), getGLFormatType(sm.format), m_stride, buffer+sm.offset); + } + break; + case SEMANTIC_COLOR: + // swizzling was already handled in unlock() + RENDERER_ASSERT((sm.format == FORMAT_COLOR_BGRA || sm.format == FORMAT_COLOR_RGBA || sm.format == FORMAT_COLOR_NATIVE), "Unsupported Vertex Buffer Format for COLOR semantic."); + if(sm.format == FORMAT_COLOR_BGRA || sm.format == FORMAT_COLOR_RGBA || sm.format == FORMAT_COLOR_NATIVE) + { + glColorPointer(getGLFormatSize(sm.format), getGLFormatType(sm.format), m_stride, buffer+sm.offset); + } + break; + case SEMANTIC_NORMAL: + RENDERER_ASSERT((sm.format == FORMAT_FLOAT3 || sm.format == FORMAT_FLOAT4), "Unsupported Vertex Buffer Format for NORMAL semantic."); + if(sm.format == FORMAT_FLOAT3 || sm.format == FORMAT_FLOAT4) + { + glNormalPointer(getGLFormatType(sm.format), m_stride, buffer+sm.offset); + } + break; + case SEMANTIC_TANGENT: + RENDERER_ASSERT((sm.format == FORMAT_FLOAT3 || sm.format == FORMAT_FLOAT4), "Unsupported Vertex Buffer Format for TANGENT semantic."); + if(sm.format == FORMAT_FLOAT3 || sm.format == FORMAT_FLOAT4) + { + const PxU32 channel = RENDERER_TANGENT_CHANNEL; + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glTexCoordPointer(getGLFormatSize(sm.format), getGLFormatType(sm.format), m_stride, buffer+sm.offset); + } + break; + case SEMANTIC_TEXCOORD0: + case SEMANTIC_TEXCOORD1: + case SEMANTIC_TEXCOORD2: + case SEMANTIC_TEXCOORD3: + { + const PxU32 channel = semantic - SEMANTIC_TEXCOORD0; + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glTexCoordPointer(getGLFormatSize(sm.format), getGLFormatType(sm.format), m_stride, buffer+sm.offset); + break; + } + case SEMANTIC_BONEINDEX: + { + const PxU32 channel = RENDERER_BONEINDEX_CHANNEL; + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glTexCoordPointer(getGLFormatSize(sm.format), getGLFormatType(sm.format), m_stride, buffer+sm.offset); + break; + } + case SEMANTIC_BONEWEIGHT: + { + const PxU32 channel = RENDERER_BONEWEIGHT_CHANNEL; + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + channel)); + glTexCoordPointer(getGLFormatSize(sm.format), getGLFormatType(sm.format), m_stride, buffer+sm.offset); + break; + } + case SEMANTIC_DISPLACEMENT_TEXCOORD: + case SEMANTIC_DISPLACEMENT_FLAGS: + break; + default: + RENDERER_ASSERT(0, "Unable to bind Vertex Buffer Semantic."); + } + + GLenum glsemantic = getGLSemantic(semantic); + if(glsemantic) + { + glEnableClientState(getGLSemantic(semantic)); + } + } + } + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + +void OGLRendererVertexBuffer::unbind(PxU32 streamID) +{ + for(PxU32 i=0; i<NUM_SEMANTICS; i++) + { + Semantic semantic = (Semantic)i; + const SemanticDesc &sm = m_semanticDescs[semantic]; + if(sm.format < NUM_FORMATS) + { + GLenum glsemantic = getGLSemantic(semantic); + if(glsemantic != GL_TEXTURE_COORD_ARRAY) + { + glDisableClientState(glsemantic); + } + } + } + for(PxU32 i=0; i<8; i++) + { + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + i)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + i)); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } +} + +#endif // #if defined(RENDERER_ENABLE_OPENGL) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererVertexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererVertexBuffer.h new file mode 100644 index 00000000..bca28184 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/ogl/OGLRendererVertexBuffer.h @@ -0,0 +1,65 @@ +// 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. +#ifndef OGL_RENDERER_VERTEXBUFFER_H +#define OGL_RENDERER_VERTEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_OPENGL) + +#include <RendererVertexBuffer.h> +#include "OGLRenderer.h" + +namespace SampleRenderer +{ + + class OGLRendererVertexBuffer : public RendererVertexBuffer + { + public: + OGLRendererVertexBuffer(const RendererVertexBufferDesc &desc); + virtual ~OGLRendererVertexBuffer(void); + + static PxU32 convertColor(const RendererColor& color); + + protected: + virtual void swizzleColor(void *colors, PxU32 stride, PxU32 numColors, RendererVertexBuffer::Format inFormat); + + virtual void *lock(void); + virtual void unlock(void); + + virtual void bind(PxU32 streamID, PxU32 firstVertex); + virtual void unbind(PxU32 streamID); + + private: + GLuint m_vbo; + GLenum m_access; + }; + +} // namespace SampleRenderer + +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif |