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/gles2 | |
| 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/gles2')
16 files changed, 3109 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2Renderer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2Renderer.cpp new file mode 100644 index 00000000..fb2aeb4f --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2Renderer.cpp @@ -0,0 +1,746 @@ +// 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 "GLES2Renderer.h" + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererDesc.h> + +#include <RendererVertexBufferDesc.h> +#include "GLES2RendererVertexBuffer.h" + +#include <RendererIndexBufferDesc.h> +#include "GLES2RendererIndexBuffer.h" + +#include <RendererInstanceBufferDesc.h> +#include "GLES2RendererInstanceBuffer.h" + +#include <RendererMeshDesc.h> +#include <RendererMeshContext.h> +#include "GLES2RendererMesh.h" + +#include <RendererMaterialDesc.h> +#include <RendererMaterialInstance.h> +#include "GLES2RendererMaterial.h" + +#include <RendererLightDesc.h> +#include <RendererDirectionalLightDesc.h> +#include "GLES2RendererDirectionalLight.h" + +#include <RendererTexture2DDesc.h> +#include "GLES2RendererTexture2D.h" + +#include <RendererProjection.h> + +#include <SamplePlatform.h> + +#include "foundation/PxMat44.h" + +#if defined(RENDERER_ANDROID) +PFNGLMAPBUFFEROESPROC glMapBufferOES = 0; +PFNGLUNMAPBUFFEROESPROC glUnmapBufferOES = 0; +#endif +bool GLEW_ARB_vertex_buffer_object = true; + +void SampleRenderer::PxToGL(GLfloat *gl44, const physx::PxMat44 &mat) +{ + PxMat44 mat44 = mat.getTranspose(); + memcpy(gl44, mat44.front(), 4 * 4 * sizeof (GLfloat)); +} + +void SampleRenderer::PxToGLColumnMajor(GLfloat *gl44, const physx::PxMat44 &mat44) +{ + memcpy(gl44, mat44.front(), 4 * 4 * sizeof (GLfloat)); +} + +void SampleRenderer::RenToGL(GLfloat *gl44, const RendererProjection &proj) +{ + proj.getRowMajor44(gl44); +} + +void SampleRenderer::RenToGLColumnMajor(GLfloat *gl44, const RendererProjection &proj) +{ + proj.getColumnMajor44(gl44); +} + +namespace SampleRenderer +{ + +GLES2Renderer::GLES2Renderer(const RendererDesc &desc, const char* assetDir) : + Renderer(DRIVER_GLES2, desc.errorCallback, assetDir), m_platform(SampleFramework::SamplePlatform::platform()) +{ + m_displayWidth = 0; + m_displayHeight = 0; + + m_viewMatrix = PxMat44(PxIdentity); + m_platform->initializeOGLDisplay(desc, m_displayWidth, m_displayHeight); + +#if defined RENDERER_ANDROID + glMapBufferOES = (PFNGLMAPBUFFEROESPROC) eglGetProcAddress("glMapBufferOES"); + glUnmapBufferOES = (PFNGLUNMAPBUFFEROESPROC) eglGetProcAddress("glUnmapBufferOES"); + + if (!glMapBufferOES || !glUnmapBufferOES) + { + GLEW_ARB_vertex_buffer_object = false; + } +#endif + + checkResize(); + + 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); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); +} + +RendererTexture3D* GLES2Renderer::createTexture3D(const RendererTexture3DDesc &desc) +{ + // TODO: Implement + return 0; +} + +void GLES2Renderer::setVsync(bool on) +{ + // TODO: Implement +} + +void GLES2Renderer::bindFogState(const RendererColor &fogColor, float fogDistance) +{ + m_fogColorAndDistance[0] = fogColor.r; + m_fogColorAndDistance[1] = fogColor.g; + m_fogColorAndDistance[2] = fogColor.b; + m_fogColorAndDistance[3] = fogDistance; +} + +GLES2Renderer::~GLES2Renderer(void) +{ + m_platform->freeDisplay(); +} + +bool GLES2Renderer::begin(void) +{ + return true; +} + +void GLES2Renderer::end(void) +{ + +} +void* GLES2Renderer::getDevice() +{ + /* @dduka, TODO: return something valid here */ + return NULL; +} + +bool GLES2Renderer::captureScreen(const char*) +{ + return false; +} + +bool GLES2Renderer::captureScreen(PxU32 &, PxU32&, PxU32&, const void*&) +{ + return false; +} + +void GLES2Renderer::getWindowSize(PxU32 &width, PxU32 &height) const +{ + RENDERER_ASSERT(m_displayHeight * m_displayWidth > 0, "variables not initialized properly"); + width = m_displayWidth; + height = m_displayHeight; +} + +PxU32 GLES2Renderer::convertColor(const RendererColor& color) const +{ + return GLES2RendererVertexBuffer::convertColor(color); +} + +void GLES2Renderer::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); + } +} + +void GLES2Renderer::finishRendering() +{ + glFinish(); + glFlush(); +} + +// clears the offscreen buffers. +void GLES2Renderer::clearBuffers(void) +{ + if(begin()) + { + glFinish(); + GLbitfield glbuf = GL_COLOR_BUFFER_BIT | GL_DEPTH_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. +bool GLES2Renderer::swapBuffers(void) +{ + if(begin()) + { + m_platform->swapBuffers(); + checkResize(); + } + end(); + return false; +} + +RendererVertexBuffer *GLES2Renderer::createVertexBuffer(const RendererVertexBufferDesc &desc) +{ + GLES2RendererVertexBuffer *vb = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Vertex Buffer Descriptor."); + if(desc.isValid()) + { + vb = new GLES2RendererVertexBuffer(desc); + } + return vb; +} + +RendererIndexBuffer *GLES2Renderer::createIndexBuffer(const RendererIndexBufferDesc &desc) +{ + GLES2RendererIndexBuffer *ib = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Index Buffer Descriptor."); + if(desc.isValid()) + { + ib = new GLES2RendererIndexBuffer(desc); + } + return ib; +} + +RendererInstanceBuffer *GLES2Renderer::createInstanceBuffer(const RendererInstanceBufferDesc &desc) +{ + GLES2RendererInstanceBuffer *ib = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Instance Buffer Descriptor."); + if(desc.isValid()) + { + ib = new GLES2RendererInstanceBuffer(desc); + } + return ib; +} + +RendererTexture2D *GLES2Renderer::createTexture2D(const RendererTexture2DDesc &desc) +{ + GLES2RendererTexture2D *texture = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Texture 2D Descriptor."); + if(desc.isValid()) + { + texture = new GLES2RendererTexture2D(desc); + } + return texture; +} + +RendererTarget *GLES2Renderer::createTarget(const RendererTargetDesc &desc) +{ + RENDERER_ASSERT(0, "Not Implemented."); + return 0; +} + +RendererMaterial *GLES2Renderer::createMaterial(const RendererMaterialDesc &desc) +{ + GLES2RendererMaterial *mat = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Material Descriptor."); + if(desc.isValid()) + { + mat = new GLES2RendererMaterial(*this, desc); + } + return mat; +} + +RendererMesh *GLES2Renderer::createMesh(const RendererMeshDesc &desc) +{ + GLES2RendererMesh *mesh = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Mesh Descriptor."); + if(desc.isValid()) + { + mesh = new GLES2RendererMesh(*this, desc); + } + return mesh; +} + +RendererLight *GLES2Renderer::createLight(const RendererLightDesc &desc) +{ + RendererLight *light = 0; + RENDERER_ASSERT(desc.isValid(), "Invalid Light Descriptor."); + if(desc.isValid()) + { + switch(desc.type) + { + case RendererLight::TYPE_DIRECTIONAL: + light = new GLES2RendererDirectionalLight(*static_cast<const RendererDirectionalLightDesc*>(&desc), *this, m_lightColor, m_intensity, m_lightDirection); + break; + default: + break; + } + } + return light; +} + + +void GLES2Renderer::bindViewProj(const physx::PxMat44 &eye, const RendererProjection &proj) +{ + physx::PxMat44 inveye = eye.inverseRT(); + + // load the projection matrix... + RenToGL(m_glProjectionMatrix, proj); + RenToGL(m_glProjectionMatrixC, proj); + + // load the view matrix... + m_viewMatrix = inveye; + + m_eyePosition = eye.getPosition(); + m_eyeDirection = -eye.getBasis(2); +} + +extern GLES2RendererMaterial* g_hackCurrentMat; +extern RendererMaterialInstance* g_hackCurrentMatInstance; + +void GLES2Renderer::bindAmbientState(const RendererColor &ambient) +{ + m_ambientColor[0] = ambient.r/255.0f; + m_ambientColor[1] = ambient.g/255.0f; + m_ambientColor[2] = ambient.b/255.0f; +} + +void GLES2Renderer::bindDeferredState(void) +{ + RENDERER_ASSERT(0, "Not implemented!"); +} + +void GLES2Renderer::setCommonRendererParameters() +{ + // if we use MojoShader + GLES2RendererMaterial::shaderProgram& program = g_hackCurrentMat->m_program[g_hackCurrentMat->m_currentPass]; + + if((program.vertexMojoResult || program.fragmentMojoResult) && (g_hackCurrentMatInstance != NULL)) + { + // eye position + const RendererMaterial::Variable* var = g_hackCurrentMat->findVariable("g_eyePosition", RendererMaterial::VARIABLE_FLOAT3); + if(var) g_hackCurrentMatInstance->writeData(*var, &m_eyePosition.x); + // eye direction + var = g_hackCurrentMat->findVariable("g_eyeDirection", RendererMaterial::VARIABLE_FLOAT3); + if(var) + { + g_hackCurrentMatInstance->writeData(*var, &m_eyeDirection.x); + } + // ambient color + var = g_hackCurrentMat->findVariable("g_ambientColor", RendererMaterial::VARIABLE_FLOAT3); + if(var) + { + g_hackCurrentMatInstance->writeData(*var, m_ambientColor); + } + // light color + m_lightColor[0] = .8f; + m_lightColor[1] = .8f; + m_lightColor[2] = .8f; + var = g_hackCurrentMat->findVariable("g_lightColor", RendererMaterial::VARIABLE_FLOAT3); + if(var) g_hackCurrentMatInstance->writeData(*var, m_lightColor); + // light intensity + var = g_hackCurrentMat->findVariable("g_lightIntensity", RendererMaterial::VARIABLE_FLOAT); + if(var) + { + g_hackCurrentMatInstance->writeData(*var, &m_intensity); + } + // light direction + var = g_hackCurrentMat->findVariable("g_lightDirection", RendererMaterial::VARIABLE_FLOAT3); + if(var) + { + g_hackCurrentMatInstance->writeData(*var, m_lightDirection); + } + // fog color and distance + var = g_hackCurrentMat->findVariable("g_fogColorAndDistance", RendererMaterial::VARIABLE_FLOAT3); + if(var) g_hackCurrentMatInstance->writeData(*var, m_fogColorAndDistance); + } +} + +void GLES2Renderer::bindMeshContext(const RendererMeshContext &context) +{ + physx::PxMat44 model = physx::PxMat44(PxIdentity); + physx::PxMat44 modelView; + + if(context.transform) model = *context.transform; + + GLfloat glmvp[16]; + GLfloat glmodel[16]; + GLfloat glview[16]; + GLfloat glmodelview[16]; + + GLES2RendererMaterial::shaderProgram& program = g_hackCurrentMat->m_program[g_hackCurrentMat->m_currentPass]; + + // if we don't use MojoShader + if (program.modelMatrixUniform != -1) + { + PxToGLColumnMajor(glmodel, model); + glUniformMatrix4fv(program.modelMatrixUniform, 1, GL_FALSE, glmodel); + } + if (program.viewMatrixUniform != -1) + { + PxToGLColumnMajor(glview, m_viewMatrix); + glUniformMatrix4fv(program.viewMatrixUniform, 1, GL_FALSE, glview); + } + if (program.projMatrixUniform != -1) + { + glUniformMatrix4fv(program.projMatrixUniform, 1, GL_FALSE, m_glProjectionMatrix); + } + if (program.modelViewMatrixUniform != -1) + { + modelView = m_viewMatrix * model; + PxToGLColumnMajor(glmodelview, modelView); + glUniformMatrix4fv(program.modelViewMatrixUniform, 1, GL_FALSE, glmodelview); + } + if (program.modelViewProjMatrixUniform != -1) + { + physx::PxMat44 MVP = physx::PxMat44(m_glProjectionMatrix); + modelView = m_viewMatrix * model; + PxToGL(glmodelview, modelView); + + MVP = modelView.getTranspose() * MVP; + memcpy(glmvp, MVP.front(), sizeof(MVP)); + + glUniformMatrix4fv(program.modelViewProjMatrixUniform, 1, GL_FALSE, glmvp); + } + + RENDERER_ASSERT(context.numBones <= RENDERER_MAX_BONES, "Too many bones."); + if(context.boneMatrices && context.numBones>0 && context.numBones <= RENDERER_MAX_BONES && + g_hackCurrentMat->m_program[g_hackCurrentMat->m_currentPass].boneMatricesUniform != -1) + { + GLfloat glbonematrix[16 * RENDERER_MAX_BONES]; + for(PxU32 i=0; i<context.numBones; i++) + { + PxToGL(glbonematrix+(16*i), context.boneMatrices[i]); + } + glUniformMatrix4fv(g_hackCurrentMat->m_program[g_hackCurrentMat->m_currentPass].boneMatricesUniform, context.numBones, GL_FALSE, glbonematrix); + } + + // if we use MojoShader + if(program.vertexMojoResult || program.fragmentMojoResult) + { + // view matrix + const RendererMaterial::Variable* var = g_hackCurrentMat->findVariable("g_viewMatrix", RendererMaterial::VARIABLE_FLOAT4x4); + if(var) + { + GLfloat glview[16]; + PxToGL(glview, m_viewMatrix); + g_hackCurrentMatInstance->writeData(*var, glview); + } + // projection matrix + var = g_hackCurrentMat->findVariable("g_projMatrix", RendererMaterial::VARIABLE_FLOAT4x4); + if(var) + { + g_hackCurrentMatInstance->writeData(*var, m_glProjectionMatrix); + } + // boneMatrices matrix + RENDERER_ASSERT(context.numBones <= RENDERER_MAX_BONES, "Too many bones."); // Not enough cash? CALL CASH BONE! + var = g_hackCurrentMat->findVariable("g_boneMatrices", RendererMaterial::VARIABLE_FLOAT4x4); + if(var) + { + GLfloat glbonematrices[16 * RENDERER_MAX_BONES]; + if(context.boneMatrices && context.numBones > 0 && context.numBones <= RENDERER_MAX_BONES) { + for(size_t i = 0; i < context.numBones; ++i) { + PxToGL(glbonematrices + 16 * i, context.boneMatrices[i]); + } + g_hackCurrentMat->bindVariable(g_hackCurrentMat->m_currentPass, *var, glbonematrices); + } + } + // model matrix + var = g_hackCurrentMat->findVariable("g_modelMatrix", RendererMaterial::VARIABLE_FLOAT4x4); + if(var) + { + PxToGL(glmodel, model); + g_hackCurrentMat->bindVariable(g_hackCurrentMat->m_currentPass, *var, glmodel); + } + // model-view matrix + var = g_hackCurrentMat->findVariable("g_modelViewMatrix", RendererMaterial::VARIABLE_FLOAT4x4); + if(var) + { + modelView = m_viewMatrix * model; + PxToGL(glmodelview, modelView); + g_hackCurrentMat->bindVariable(g_hackCurrentMat->m_currentPass, *var, glmodelview); + } + // model-view-projection matrix + var = g_hackCurrentMat->findVariable("g_MVP", RendererMaterial::VARIABLE_FLOAT4x4); + if(var) + { + physx::PxMat44 MVP = physx::PxMat44(m_glProjectionMatrix); + modelView = m_viewMatrix * model; + PxToGL(glmodelview, modelView); + + MVP = modelView.getTranspose() * MVP; + memcpy(glmvp, MVP.front(), sizeof(MVP)); + + g_hackCurrentMat->bindVariable(g_hackCurrentMat->m_currentPass, *var, glmvp); + } + } else LOGI("Couldn't bind uniform values! vr = %p, fr = %p, inst = %p, -- %p", g_hackCurrentMat->m_program[g_hackCurrentMat->m_currentPass].vertexMojoResult, + g_hackCurrentMat->m_program[g_hackCurrentMat->m_currentPass].fragmentMojoResult, g_hackCurrentMatInstance, g_hackCurrentMat); + + g_hackCurrentMat->submitUniforms(); + + switch(context.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"); + } +} + +void GLES2Renderer::beginMultiPass(void) +{ +} + +void GLES2Renderer::endMultiPass(void) +{ +} + +void GLES2Renderer::beginTransparentMultiPass(void) +{ +} + +void GLES2Renderer::endTransparentMultiPass(void) +{ +} + +void GLES2Renderer::renderDeferredLight(const RendererLight &/*light*/) +{ + RENDERER_ASSERT(0, "Not implemented!"); +} + +bool GLES2Renderer::isOk(void) const +{ + bool ok = true; + return ok; +} + +void GLES2Renderer::setupTextRenderStates() +{ + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(false); + glEnable(GL_TEXTURE_2D); +} + +void GLES2Renderer::resetTextRenderStates() +{ + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + glDisable(GL_TEXTURE_2D); +} + +bool GLES2Renderer::initTexter() +{ + Renderer::initTexter(); + + PxU32 width, height; + getWindowSize(width, height); + const PxU32 MIN_CHARACTER_WIDTH = 8; + const PxU32 TEXT_MAX_VERTICES = 4 * (width / MIN_CHARACTER_WIDTH); + const PxU32 TEXT_MAX_INDICES = TEXT_MAX_VERTICES * 1.5f; // we need 1.5 times more indices than vertices to describe text quads + + // Although text buffers (vertex and index buffers) are constantly updating, I received information that STATIC hint set on these buffers + // results in slightly better performance due to a bug (possibly) in GLES2 drivers on Android/Tegra. + // initialize vertex buffer -- will be used by all texts + RendererVertexBufferDesc vbdesc; + vbdesc.hint = RendererVertexBuffer::HINT_STATIC; + vbdesc.maxVertices = TEXT_MAX_VERTICES; + vbdesc.semanticFormats[RendererVertexBuffer::SEMANTIC_POSITION] = RendererVertexBuffer::FORMAT_FLOAT3; + vbdesc.semanticFormats[RendererVertexBuffer::SEMANTIC_TEXCOORD0] = RendererVertexBuffer::FORMAT_FLOAT2; + vbdesc.semanticFormats[RendererVertexBuffer::SEMANTIC_COLOR] = RendererVertexBuffer::FORMAT_COLOR_NATIVE; + m_textVertexBuffer = createVertexBuffer(vbdesc); + RENDERER_ASSERT(m_textVertexBuffer, "Failed to create Vertex Buffer."); + // initialize index buffer + RendererIndexBufferDesc inbdesc; + inbdesc.hint = RendererIndexBuffer::HINT_STATIC; + inbdesc.format = RendererIndexBuffer::FORMAT_UINT16; + inbdesc.maxIndices = TEXT_MAX_INDICES; + m_textIndexBuffer = createIndexBuffer(inbdesc); + RENDERER_ASSERT(m_textIndexBuffer, "Failed to create Instance Buffer."); + RendererMeshDesc meshdesc; + meshdesc.primitives = RendererMesh::PRIMITIVE_TRIANGLES; + meshdesc.vertexBuffers = &m_textVertexBuffer; + meshdesc.numVertexBuffers = 1; + meshdesc.firstVertex = 0; + meshdesc.numVertices = m_textVertexBuffer->getMaxVertices(); + meshdesc.indexBuffer = m_textIndexBuffer; + meshdesc.firstIndex = 0; + meshdesc.numIndices = m_textIndexBuffer->getMaxIndices(); + meshdesc.instanceBuffer = NULL; + meshdesc.firstInstance = 0; + meshdesc.numInstances = 0; + m_textMesh = createMesh(meshdesc); + RENDERER_ASSERT(m_textMesh, "Failed to create Mesh."); + + //m_textMaterial = NULL; + //m_textVertexBufferOffset = 0; + //m_textIndexBufferOffset = 0; + return true; +} + +void GLES2Renderer::renderTextBuffer(const void* verts, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, RendererMaterial* material) +{ + PxU32 positionStride = 0, colorStride = 0, texcoordStride = 0; + PxU8* locked_positions = static_cast<PxU8*>(m_textVertexBuffer->lockSemantic(RendererVertexBuffer::SEMANTIC_POSITION, positionStride)); + PxU8* locked_texcoords = static_cast<PxU8*>(m_textVertexBuffer->lockSemantic(RendererVertexBuffer::SEMANTIC_TEXCOORD0, texcoordStride)); + PxU8* locked_colors = static_cast<PxU8*>(m_textVertexBuffer->lockSemantic(RendererVertexBuffer::SEMANTIC_COLOR, colorStride)); + + // copy indices + PxU16* locked_indices = static_cast<PxU16*>(m_textIndexBuffer->lock()); + memcpy(locked_indices, indices, nbIndices * sizeof(PxU16)); + m_textIndexBuffer->unlock(); + + PxU32 windowWidth, windowHeight; + getWindowSize(windowWidth, windowHeight); + PxReal windowWidthHalf = windowWidth / 2.0f, + windowHeightHalf = windowHeight / 2.0f; + + TextVertex* tv = (TextVertex*)verts; + for(PxU32 i = 0; i < nbVerts; ++i, + locked_positions += positionStride, + locked_colors += colorStride, + locked_texcoords += texcoordStride, + tv += 1) + { + PxVec3 pos = PxVec3(tv->p.x / windowWidthHalf - 1.0f, 1.0f - tv->p.y / windowHeightHalf, 0.0f); + memcpy(locked_positions, &(pos), sizeof(tv->p)); + memcpy(locked_colors, &(tv->color), sizeof(tv->color)); + memcpy(locked_texcoords, &(tv->u), sizeof(PxReal)); + memcpy(locked_texcoords + sizeof(PxReal), &(tv->v), sizeof(PxReal)); + } + m_textVertexBuffer->unlockSemantic(RendererVertexBuffer::SEMANTIC_COLOR); + m_textVertexBuffer->unlockSemantic(RendererVertexBuffer::SEMANTIC_TEXCOORD0); + m_textVertexBuffer->unlockSemantic(RendererVertexBuffer::SEMANTIC_POSITION); + + // rendering goes here + m_textMesh->setVertexBufferRange(0, nbVerts); + m_textMesh->setIndexBufferRange(0, nbIndices); + m_textMesh->bind(); + m_textMesh->render(m_textMaterial); + m_textMesh->unbind(); +} + +void GLES2Renderer::renderLines2D(const void* vertices, PxU32 nbVerts) +{ + // @dduka, TODO: glEnableClientState is not available on GL ES 2.0 + /* + 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 GLES2Renderer::setupScreenquadRenderStates() +{ + //glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDepthMask(false); +} + +void GLES2Renderer::resetScreenquadRenderStates() +{ + //glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glDepthMask(true); +} + +} +#endif // #if defined(RENDERER_ENABLE_GLES2) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2Renderer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2Renderer.h new file mode 100644 index 00000000..60f3a586 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2Renderer.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 GLES2_RENDERER_H +#define GLES2_RENDERER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#if defined(RENDERER_ANDROID) +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <EGL/egl.h> + +extern PFNGLMAPBUFFEROESPROC glMapBufferOES; +extern PFNGLUNMAPBUFFEROESPROC glUnmapBufferOES; + +#elif defined(RENDERER_IOS) + +#include <OpenGLES/ES2/gl.h> +#include <OpenGLES/ES2/glext.h> + +#endif + +#define GL_TEXTURE0_ARB GL_TEXTURE0 +#define glBindBufferARB glBindBuffer +#define glBufferDataARB glBufferData +#define GL_ELEMENT_ARRAY_BUFFER_ARB GL_ELEMENT_ARRAY_BUFFER +#define GL_ARRAY_BUFFER_ARB GL_ARRAY_BUFFER +#define GL_STATIC_DRAW_ARB GL_STATIC_DRAW +#define GL_DYNAMIC_DRAW_ARB GL_DYNAMIC_DRAW +#define glGenBuffersARB glGenBuffers +#define glDeleteBuffersARB glDeleteBuffers +#define GL_CLAMP GL_CLAMP_TO_EDGE +#define GL_WRITE_ONLY GL_WRITE_ONLY_OES +#define GL_READ_WRITE GL_WRITE_ONLY_OES + +extern bool GLEW_ARB_vertex_buffer_object; + +#define glActiveTextureARB glActiveTexture +#define glClientActiveTextureARB(a) + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + +/* GL_EXT_texture_compression_s3tc */ +#ifndef GL_EXT_texture_compression_s3tc +/* GL_COMPRESSED_RGB_S3TC_DXT1_EXT defined in GL_EXT_texture_compression_dxt1 already. */ +/* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT defined in GL_EXT_texture_compression_dxt1 already. */ +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif + +#define GL_RGBA8 GL_RGBA +#define GL_BGRA8 GL_BGRA + +#include <Renderer.h> + +namespace SampleFramework { + class SamplePlatform; +} + +namespace SampleRenderer +{ + +class RendererVertexBuffer; +class RendererIndexBuffer; +class RendererMaterial; + +void PxToGL(GLfloat *gl44, const physx::PxMat44 &mat); +void PxToGLColumnMajor(GLfloat *gl44, const physx::PxMat44 &mat); +void RenToGL(GLfloat *gl44, const RendererProjection &proj); +void RenToGLColumnMajor(GLfloat *gl44, const RendererProjection &proj); + +class GLES2Renderer : public Renderer +{ + public: + GLES2Renderer(const RendererDesc &desc, const char* assetDir); + virtual ~GLES2Renderer(void); + + 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. + virtual bool swapBuffers(void); + // get the device pointer (void * abstraction) + virtual void *getDevice(); + + virtual bool captureScreen(const char*); + virtual bool captureScreen(PxU32 &width, PxU32& height, PxU32& sizeInBytes, const void*& screenshotData); + + // get the window size + void getWindowSize(PxU32 &width, PxU32 &height) const; + // copy common renderer variables to the material (like g_MVP, g_modelMatrix, etc) + virtual void setCommonRendererParameters(); + + 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); + + void finalizeTextRender(); + void finishRendering(); + virtual void setVsync(bool on); + private: + virtual void bindViewProj(const physx::PxMat44 &inveye, const RendererProjection &proj); + virtual void bindFogState(const RendererColor &fogColor, float fogDistance); + virtual void bindAmbientState(const RendererColor &ambientColor); + 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 bool initTexter(); + virtual void setupTextRenderStates(); + virtual void resetTextRenderStates(); + virtual void renderTextBuffer(const void* vertices, PxU32 nbVerts, const PxU16* indices, PxU32 nbIndices, SampleRenderer::RendererMaterial* material); + virtual void renderLines2D(const void* vertices, PxU32 nbVerts); + virtual void setupScreenquadRenderStates(); + virtual void resetScreenquadRenderStates(); + private: + SampleFramework::SamplePlatform* m_platform; + RendererVertexBuffer* m_textVertexBuffer; + RendererIndexBuffer* m_textIndexBuffer; + PxU32 m_textVertexBufferOffset; + PxU32 m_textIndexBufferOffset; + RendererMaterial* m_textMaterial; + RendererMesh* m_textMesh; + PxU32 m_displayWidth; + PxU32 m_displayHeight; + + physx::PxMat44 m_viewMatrix; + GLfloat m_glProjectionMatrix[16], m_glProjectionMatrixC[16]; + PxVec3 m_eyePosition; + PxVec3 m_eyeDirection; + GLfloat m_ambientColor[3]; + GLfloat m_lightColor[3]; + GLfloat m_intensity; + GLfloat m_lightDirection[3]; + GLfloat m_fogColorAndDistance[4]; +}; +} +#endif // #if defined(RENDERER_ENABLE_GLES2) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererDirectionalLight.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererDirectionalLight.cpp new file mode 100644 index 00000000..2f1fe5b9 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererDirectionalLight.cpp @@ -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. + + +#include "GLES2RendererDirectionalLight.h" +#include "GLES2RendererMaterial.h" +#include "GLES2Renderer.h" +#include "RendererMaterialInstance.h" + +#if defined(RENDERER_ENABLE_GLES2) +namespace SampleRenderer +{ + +GLES2RendererDirectionalLight::GLES2RendererDirectionalLight(const RendererDirectionalLightDesc &desc, + GLES2Renderer &renderer, GLfloat (&_lightColor)[3], + GLfloat& _lightIntensity, GLfloat (&_lightDirection)[3]) : + RendererDirectionalLight(desc), m_lightColor(_lightColor), m_lightIntensity(_lightIntensity), m_lightDirection(_lightDirection) +{ +} + +GLES2RendererDirectionalLight::~GLES2RendererDirectionalLight(void) +{ +} + +extern GLES2RendererMaterial* g_hackCurrentMat; +extern RendererMaterialInstance* g_hackCurrentMatInstance; + +void GLES2RendererDirectionalLight::bind(void) const +{ + m_lightColor[0] = m_color.r/255.0f; + m_lightColor[1] = m_color.g/255.0f; + m_lightColor[2] = m_color.b/255.0f; + m_lightIntensity = m_intensity; + m_lightDirection[0] = m_direction.x; + m_lightDirection[1] = m_direction.y; + m_lightDirection[2] = m_direction.z; +} + +} + +#endif // #if defined(RENDERER_ENABLE_GLES2) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererDirectionalLight.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererDirectionalLight.h new file mode 100644 index 00000000..d3b6dbe4 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererDirectionalLight.h @@ -0,0 +1,61 @@ +// 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 GLES2_RENDERER_DIRECTIONAL_LIGHT_H +#define GLES2_RENDERER_DIRECTIONAL_LIGHT_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererDirectionalLight.h> + +#include "GLES2Renderer.h" + +namespace SampleRenderer +{ +class RendererDirectionalLightDesc; + +class GLES2RendererDirectionalLight : public RendererDirectionalLight +{ + public: + GLES2RendererDirectionalLight(const RendererDirectionalLightDesc &desc, + GLES2Renderer &renderer, + GLfloat (&_lightColor)[3], GLfloat& _lightIntensity, GLfloat (&_lightDirection)[3]); + virtual ~GLES2RendererDirectionalLight(void); + + virtual void bind(void) const; + private: + GLfloat (&m_lightColor)[3]; + GLfloat& m_lightIntensity; + GLfloat (&m_lightDirection)[3]; +}; +} + +#endif // #if defined(RENDERER_ENABLE_GLES2) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererIndexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererIndexBuffer.cpp new file mode 100644 index 00000000..a12230c2 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererIndexBuffer.cpp @@ -0,0 +1,115 @@ +// 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 "GLES2RendererIndexBuffer.h" + +#if defined(RENDERER_ENABLE_GLES2) +#include <RendererIndexBufferDesc.h> + +namespace SampleRenderer +{ + +GLES2RendererIndexBuffer::GLES2RendererIndexBuffer(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 && desc.maxIndices > 0, "Cannot create zero size Index Buffer."); + if(desc.maxIndices > 0 && 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); + } + } + } +} + +GLES2RendererIndexBuffer::~GLES2RendererIndexBuffer(void) +{ + if(m_ibo) + { + glDeleteBuffersARB(1, &m_ibo); + } +} + +void *GLES2RendererIndexBuffer::lock(void) +{ + void *buffer = 0; + if(m_ibo) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_ibo); + buffer = glMapBufferOES(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } + return buffer; +} + +void GLES2RendererIndexBuffer::unlock(void) +{ + if(m_ibo) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_ibo); + glUnmapBufferOES(GL_ELEMENT_ARRAY_BUFFER_ARB); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } +} + +void GLES2RendererIndexBuffer::bind(void) const +{ + if(m_ibo) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_ibo); + } +} + +void GLES2RendererIndexBuffer::unbind(void) const +{ + if(m_ibo) + { + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } + } +} + +#endif // #if defined(RENDERER_ENABLE_GLES2) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererIndexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererIndexBuffer.h new file mode 100644 index 00000000..3f489a25 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererIndexBuffer.h @@ -0,0 +1,61 @@ +// 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 GLES2_RENDERER_INDEXBUFFER_H +#define GLES2_RENDERER_INDEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererIndexBuffer.h> +#include "GLES2Renderer.h" + +namespace SampleRenderer +{ +class GLES2RendererIndexBuffer : public RendererIndexBuffer +{ + public: + GLES2RendererIndexBuffer(const RendererIndexBufferDesc &desc); + virtual ~GLES2RendererIndexBuffer(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; +}; +} +#endif // #if defined(RENDERER_ENABLE_GLES2) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererInstanceBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererInstanceBuffer.cpp new file mode 100644 index 00000000..a78ddeac --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererInstanceBuffer.cpp @@ -0,0 +1,90 @@ +// 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_GLES2) + +#include "GLES2RendererInstanceBuffer.h" +#include <RendererInstanceBufferDesc.h> + +using namespace SampleRenderer; + +GLES2RendererInstanceBuffer::GLES2RendererInstanceBuffer(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; +} + +GLES2RendererInstanceBuffer::~GLES2RendererInstanceBuffer(void) +{ + if(m_buffer) free(m_buffer);//PX_FREE(m_buffer); +} + +physx::PxMat44 GLES2RendererInstanceBuffer::getModelMatrix(PxU32 index) const +{ + physx::PxMat44 model = PxMat44(PxIdentity); + if(index < m_maxInstances) + { + const void *instance = ((PxU8*)m_buffer)+(m_stride*index); + model = PxMat44(getInstanceColumn(instance, m_semanticDescs[SEMANTIC_NORMALX]), + getInstanceColumn(instance, m_semanticDescs[SEMANTIC_NORMALY]), + getInstanceColumn(instance, m_semanticDescs[SEMANTIC_NORMALZ]), + getInstanceColumn(instance, m_semanticDescs[SEMANTIC_POSITION])); + } + return model; +} + +PxVec3 GLES2RendererInstanceBuffer::getInstanceColumn(const void *instance, const GLES2RendererInstanceBuffer::SemanticDesc &sd) const +{ + PxVec3 col = *(PxVec3*)(((PxU8*)instance)+sd.offset); + return col; +} + +void *GLES2RendererInstanceBuffer::lock(void) +{ + return m_buffer; +} + +void GLES2RendererInstanceBuffer::unlock(void) +{ + +} + +void GLES2RendererInstanceBuffer::bind(PxU32 streamID, PxU32 firstInstance) const +{ + +} + +void GLES2RendererInstanceBuffer::unbind(PxU32 streamID) const +{ + +} + +#endif // #if defined(RENDERER_ENABLE_GLES2) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererInstanceBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererInstanceBuffer.h new file mode 100644 index 00000000..67c719cc --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererInstanceBuffer.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 GLES2_RENDERER_INSTANCEBUFFER_H +#define GLES2_RENDERER_INSTANCEBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererInstanceBuffer.h> +#include "GLES2Renderer.h" + +namespace SampleRenderer +{ + + class GLES2RendererInstanceBuffer : public RendererInstanceBuffer + { + public: + GLES2RendererInstanceBuffer(const RendererInstanceBufferDesc &desc); + virtual ~GLES2RendererInstanceBuffer(void); + + physx::PxMat44 getModelMatrix(PxU32 index) const; + + private: + PxVec3 getInstanceColumn(const void *instance, const GLES2RendererInstanceBuffer::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_GLES2) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMaterial.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMaterial.cpp new file mode 100644 index 00000000..252cc0c5 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMaterial.cpp @@ -0,0 +1,667 @@ +// 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 "GLES2RendererMaterial.h" + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererMaterialDesc.h> +#include <RendererMemoryMacros.h> + +#include "GLES2RendererTexture2D.h" + +#include <stdio.h> + +#include "mojoshader.h" + +namespace SampleRenderer +{ + +class GLESVariable : public RendererMaterial::Variable +{ +public: + GLESVariable(const char *name, RendererMaterial::VariableType type, PxU32 offset) + : Variable(name, type, offset) + { + } + + virtual ~GLESVariable(void) {} + + GLint m_location[RendererMaterial::NUM_PASSES]; + GLint m_sampler[RendererMaterial::NUM_PASSES]; +}; + +const std::string vertexUniformArrayName = "vs_uniforms_vec4"; +const std::string pixelUniformArrayName = "ps_uniforms_vec4"; + +std::string load_file(const char* file) +{ + LOG_INFO("GLES2RendererMaterial", "Opening: \"%s\"", file); + char file2[512]; + sprintf(file2, "/sdcard/media/SampleRenderer/4/shaders/%s", file); + FILE *f = fopen(file2, "rb"); + assert(f); + + fseek(f, 0, SEEK_END); + size_t size = ftell(f); + fseek(f, 0, SEEK_SET); + char *buffer = new char[size+1]; + fread(buffer, 1, size, f); + fclose(f); + buffer[size] = '\0'; + + std::string result(buffer); + delete[] buffer; + return result; +} + + +static int glsl_log(GLuint obj, GLenum check_compile) +{ + if (check_compile == GL_COMPILE_STATUS) + { + int len = 0; + glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &len); + if(len > 0) + { + char *str = (char *) malloc(len * sizeof(char)); + if (str) + { + glGetShaderInfoLog(obj, len, NULL, str); + LOG_INFO("nv_shader", "shader_debug: %s\n", str); + free(str); + } + } + } + else + { + int len = 0; + glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &len); + if(len > 0) + { + char *str = (char *)malloc(len * sizeof(char)); + if (str) + { + glGetProgramInfoLog(obj, len, NULL, str); + LOG_INFO("nv_shader", "shader_debug: %s\n", str); + free(str); + } + } + } + return 0; +} + +GLES2RendererMaterial::shaderProgram::shaderProgram() : + modelMatrixUniform(-1), + viewMatrixUniform(-1), + projMatrixUniform(-1), + modelViewMatrixUniform(-1), + boneMatricesUniform(-1), + modelViewProjMatrixUniform(-1), + positionAttr(-1), + colorAttr(-1), + normalAttr(-1), + tangentAttr(-1), + boneIndexAttr(-1), + boneWeightAttr(-1), + vsUniformsTotal(0), + psUniformsTotal(0), + vsUniformsVec4(NULL), + vsUniformsVec4Location(-1), + vsUniformsVec4Size(0), + psUniformsVec4(NULL), + psUniformsVec4Location(-1), + psUniformsVec4Size(0), + vertexMojoResult(NULL), + fragmentMojoResult(NULL) +{ +} + +GLES2RendererMaterial::shaderProgram::~shaderProgram() +{ + for(int i = 0; i < NUM_PASSES; ++i) + glDeleteProgram(program); + DELETESINGLE(vertexMojoResult); + DELETESINGLE(fragmentMojoResult); + DELETEARRAY(vsUniformsVec4); + DELETEARRAY(psUniformsVec4); +} + + +GLES2RendererMaterial::GLES2RendererMaterial(GLES2Renderer &renderer, const RendererMaterialDesc &desc) : + RendererMaterial(desc, false), + 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."); + } + + std::string vertexShaderPath(desc.vertexShaderPath); + std::string fragmentShaderPath(desc.fragmentShaderPath); + std::string vertexSource, fragmentSource; + + for(int i = 0; i < NUM_PASSES; ++i) + { + if(vertexShaderPath.substr(vertexShaderPath.size() - 3, 3) == ".cg") + { + m_program[i].vertexMojoResult = static_cast<mojoResult*>(SampleFramework::SamplePlatform::platform()-> + compileProgram(NULL, m_renderer.getAssetDir(), desc.vertexShaderPath, 0, getPassName(static_cast<Pass>(i)), "vmain", NULL)); + vertexSource = m_program[i].vertexMojoResult->parseResult.source; + LOGI("Vertex source is: \n %s \n", vertexSource.c_str()); + } + else + { + vertexSource = load_file(desc.vertexShaderPath); + } + if(fragmentShaderPath.substr(fragmentShaderPath.size() - 3, 3) == ".cg") + { + m_program[i].fragmentMojoResult = static_cast<mojoResult*>(SampleFramework::SamplePlatform::platform()-> + compileProgram(NULL, m_renderer.getAssetDir(), desc.fragmentShaderPath, 0, getPassName(static_cast<Pass>(i)), "fmain", NULL)); + fragmentSource = m_program[i].fragmentMojoResult->parseResult.source; + LOGI("Fragment source is: \n %s \n", fragmentSource.c_str()); + } + else + { + fragmentSource = load_file(desc.fragmentShaderPath); + } + + m_program[i].program = glCreateProgram(); + if(!m_program[i].program) + LOGI("GLES2RenderMaterial", "Failed to create program"); + m_program[i].vertexShader = glCreateShader(GL_VERTEX_SHADER); + if(!m_program[i].vertexShader) + LOGI("GLES2RenderMaterial", "Failed to create vertex shader"); + m_program[i].fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + if(!m_program[i].fragmentShader) + LOGI("GLES2RenderMaterial", "Failed to create vertex shader"); + + glAttachShader(m_program[i].program, m_program[i].vertexShader); + glAttachShader(m_program[i].program, m_program[i].fragmentShader); + + int size = (int)vertexSource.size(); + const char* vertexShaderCstr = vertexSource.c_str(); + glShaderSource(m_program[i].vertexShader, 1, &vertexShaderCstr, &size); + glCompileShader(m_program[i].vertexShader); + // __android_log_print(ANDROID_LOG_DEBUG, "GLES2RendererMaterial", "Compiling:\n_______________________________\n%s\n_______________________________\n", vertexSource.c_str()); + LOGI("Vertex shader compile status:"); + glsl_log(m_program[i].vertexShader, GL_COMPILE_STATUS); + + size = (int)fragmentSource.size(); + const char* fragmentShaderCstr = fragmentSource.c_str(); + glShaderSource(m_program[i].fragmentShader, 1, &fragmentShaderCstr, &size); + glCompileShader(m_program[i].fragmentShader); + // __android_log_print(ANDROID_LOG_DEBUG, "GLES2RendererMaterial", "Compiling:\n_______________________________\n%s\n_______________________________\n", fragmentSource.c_str()); + LOGI("Fragment shader compile status:"); + glsl_log(m_program[i].fragmentShader, GL_COMPILE_STATUS); + + glLinkProgram(m_program[i].program); + GLint link_status; + glsl_log(m_program[i].program, GL_LINK_STATUS); + glGetProgramiv(m_program[i].program, GL_LINK_STATUS, &link_status); + if(link_status == GL_FALSE) + { + LOGI("Failed to link program"); + GLint error = glGetError(); + if(error == GL_INVALID_VALUE) + LOGI("GL_INVALID_VALUE"); + else if(error == GL_INVALID_OPERATION) + LOGI("GL_INVALID_OPERATION"); + } + loadCustomConstants(static_cast<Pass>(i)); + } + LOGI(""); +} + +GLES2RendererMaterial::~GLES2RendererMaterial() +{ +} + +GLES2RendererMaterial *g_hackCurrentMat = NULL; +RendererMaterialInstance *g_hackCurrentMatInstance = NULL; + +void GLES2RendererMaterial::bind(RendererMaterial::Pass pass, RendererMaterialInstance *materialInstance, bool instanced) const +{ + g_hackCurrentMat = const_cast<GLES2RendererMaterial*>(this); + g_hackCurrentMatInstance = materialInstance; + m_currentPass = pass; + glUseProgram(m_program[m_currentPass].program); + m_renderer.setCommonRendererParameters(); + RendererMaterial::bind(m_currentPass, materialInstance, instanced); +} + +void GLES2RendererMaterial::bindMeshState(bool instanced) const +{ +} + +void GLES2RendererMaterial::unbind(void) const +{ +} + +static void bindSampler(const RendererMaterial::Variable &variable, const void *data, RendererMaterial::Pass pass) +{ + GLESVariable &var = (GLESVariable&) variable; + data = *(void**)data; + RENDERER_ASSERT(data, "NULL Sampler."); + if(data) + { + GLES2RendererTexture2D *tex = const_cast<GLES2RendererTexture2D*>(static_cast<const GLES2RendererTexture2D*>(data)); + glUniform1i(var.m_location[pass], var.m_sampler[pass]); + tex->bind(var.m_sampler[pass]); + } +} + +void GLES2RendererMaterial::submitUniforms() +{ + /* When all variables were fetched, we send this uniform array and clear collected variables. + At this point, if some variables will be binded after all variables already were supplied, + this will cause these variables not binded at all, until all other variables collected again. */ + Pass pass = g_hackCurrentMat->m_currentPass; + if(m_program[pass].vsUniformsTotal > 0 && m_program[pass].vsUniformsCollected.size() == m_program[pass].vsUniformsTotal) + { + const GLfloat* ptr = const_cast<const GLfloat*>(reinterpret_cast<GLfloat*>(m_program[pass].vsUniformsVec4)); + //LOGI("VERTEX: Setting uniform at %d of size %d from %x", m_program[pass].vsUniformsVec4Location, m_program[pass].vsUniformsVec4Size, ptr); + glUniform4fv(m_program[pass].vsUniformsVec4Location, (int)m_program[pass].vsUniformsVec4Size, ptr); + m_program[pass].vsUniformsCollected.clear(); + } + /* When all variables were fetched, we send this uniform array and clear collected variables. + At this point, if some variables will be binded after all variables already were supplied, + this will cause these variables not binded at all, until all other variables collected again. */ + if(m_program[pass].psUniformsTotal > 0 && m_program[pass].psUniformsCollected.size() == m_program[pass].psUniformsTotal) + { + const GLfloat* ptr = const_cast<const GLfloat*>(reinterpret_cast<GLfloat*>(m_program[pass].psUniformsVec4)); + // LOGI("FRAGMENT: Setting uniform at %d of size %d from %x", m_program[pass].psUniformsVec4Location, m_program[pass].psUniformsVec4Size, ptr); + glUniform4fv(m_program[pass].psUniformsVec4Location, (int)m_program[pass].psUniformsVec4Size, ptr); + m_program[pass].psUniformsCollected.clear(); + } +} + +void GLES2RendererMaterial::bindVariable(Pass pass, const Variable &variable, const void *data) const +{ + GLESVariable &var = (GLESVariable&) variable; + if(m_program[pass].vertexMojoResult || m_program[pass].fragmentMojoResult) + { + mojoResult::relocationType::iterator it = m_program[pass].vertexMojoResult->relocation.find(variable.getName()); + if(it != m_program[pass].vertexMojoResult->relocation.end()) + { + if(it->second.name == vertexUniformArrayName) + { + mojoResult::shaderUniformRelocation& relocation = it->second; + // Mojo could truncate unused parts of the original variable, so in the D3D assembly it'll have type which is bigger then needed in the translated shader. + // This is to prevent buffer overruns in such cases. + //relocation.size = (relocation.index + relocation.size) > m_program[pass].vsUniformsVec4SizeInBytes ? (m_program[pass].vsUniformsVec4SizeInBytes - relocation.index) : relocation.size; + //LOGI("Found variable '%s' for %s (%x)", variable.getName(), getPassName(pass), this); + //LOGI("VERTEX: Copying %d bytes from %x to %x+%d for %s (%s) -- %p", relocation.size, data, m_program[pass].vsUniformsVec4, relocation.index, variable.getName(), getPassName(pass), this); + memcpy(m_program[pass].vsUniformsVec4 + relocation.index, data, relocation.size); + m_program[pass].vsUniformsCollected.insert(variable.getName()); + } + else + { + bindSampler(variable, data, pass); + } + } + else if((it = m_program[pass].fragmentMojoResult->relocation.find(variable.getName())) != m_program[pass].fragmentMojoResult->relocation.end()) + { + if(it->second.name == pixelUniformArrayName) + { + mojoResult::shaderUniformRelocation& relocation = it->second; + // Mojo could truncate unused parts of the original variable, so in the D3D assembly it'll have type which is bigger then needed in the translated shader. + // This is to prevent buffer overruns in such cases. + //relocation.size = (relocation.index + relocation.size) > m_program[pass].psUniformsVec4SizeInBytes ? (m_program[pass].psUniformsVec4SizeInBytes - relocation.index) : relocation.size; + //LOGI("FRAGMENT: Copying %d bytes from %x to %x+%d for %s (%s) -- %p", relocation.size, data, m_program[pass].psUniformsVec4, relocation.index, variable.getName(), getPassName(pass), this); + memcpy(m_program[pass].psUniformsVec4 + relocation.index, data, relocation.size); + m_program[pass].psUniformsCollected.insert(variable.getName()); + } + else + { + bindSampler(variable, data, pass); + } + } + } + else + { + switch(var.getType()) + { + case VARIABLE_FLOAT: + { + float f = *(const float*)data; + //LOGI("GLES2RendererMaterial: VARIABLE_FLOAT"); + glUniform1f(var.m_location[pass], f); + break; + } + case VARIABLE_FLOAT2: + { + //LOGI("GLES2RendererMaterial: VARIABLE_FLOAT2"); + glUniform2fv(var.m_location[pass], 1, (const GLfloat*)data); + break; + } + case VARIABLE_FLOAT3: + { + //LOGI("GLES2RendererMaterial: VARIABLE_FLOAT3"); + glUniform3fv(var.m_location[pass], 1, (const GLfloat*)data); + break; + } + case VARIABLE_FLOAT4: + { + //LOGI("GLES2RendererMaterial: VARIABLE_FLOAT4"); + glUniform4fv(var.m_location[pass], 1, (const GLfloat*)data); + break; + } + case VARIABLE_FLOAT4x4: + { + //LOGI("GLES2RendererMaterial: VARIABLE_FLOAT4x4"); + glUniformMatrix4fv(var.m_location[pass], 1, GL_FALSE, (const GLfloat*)data); + break; + } + case VARIABLE_SAMPLER2D: + { + bindSampler(variable, data, pass); + break; + } + default: + break; + } + } +} + +RendererMaterial::VariableType GLES2RendererMaterial::GLTypetoVariableType(GLenum type) +{ + switch (type) + { + case GL_SAMPLER_2D: return VARIABLE_SAMPLER2D; + case GL_FLOAT: return VARIABLE_FLOAT; + case GL_FLOAT_VEC2: return VARIABLE_FLOAT2; + case GL_FLOAT_VEC3: return VARIABLE_FLOAT3; + case GL_FLOAT_VEC4: return VARIABLE_FLOAT4; + case GL_FLOAT_MAT4: return VARIABLE_FLOAT4x4; + default: return NUM_VARIABLE_TYPES; + } +} + +static std::string variableTypeToString(RendererMaterial::VariableType type) +{ + switch (type) + { + case RendererMaterial::VARIABLE_SAMPLER2D: return "VARIABLE_SAMPLER2D"; + case RendererMaterial::VARIABLE_FLOAT: return "VARIABLE_FLOAT"; + case RendererMaterial::VARIABLE_FLOAT2: return "VARIABLE_FLOAT2"; + case RendererMaterial::VARIABLE_FLOAT3: return "VARIABLE_FLOAT3"; + case RendererMaterial::VARIABLE_FLOAT4: return "VARIABLE_FLOAT4"; + case RendererMaterial::VARIABLE_FLOAT4x4: return "VARIABLE_FLOAT4x4"; + default: return "VARIABLE_UNKNOWN"; + } +} + +GLint GLES2RendererMaterial::getAttribLocation(size_t usage, size_t index, Pass pass) +{ + GLint result = -1; + if(m_program[pass].vertexMojoResult->parseResult.attributes.find(usage) != m_program[pass].vertexMojoResult->parseResult.attributes.end() && + m_program[pass].vertexMojoResult->parseResult.attributes[usage].size() > index) + return glGetAttribLocation(m_program[pass].program, m_program[pass].vertexMojoResult->parseResult.attributes[usage][index].c_str()); + return result; +} + +std::string GLES2RendererMaterial::mojoSampleNameToOriginal(Pass pass, const std::string& name) +{ + for(mojoResult::relocationType::const_iterator it = m_program[pass].vertexMojoResult->relocation.begin(); + it != m_program[pass].vertexMojoResult->relocation.end(); ++it) + { + if(it->second.name == name) return it->first; + } + for(mojoResult::relocationType::const_iterator it = m_program[pass].fragmentMojoResult->relocation.begin(); + it != m_program[pass].fragmentMojoResult->relocation.end(); ++it) + { + if(it->second.name == name) return it->first; + } + return std::string(); +} + +void GLES2RendererMaterial::loadCustomConstants(Pass pass) +{ + /* Find samplers locations */ + std::vector<std::string> uniformArrayName; + uniformArrayName.push_back("vs_uniforms_vec4"); + uniformArrayName.push_back("ps_uniforms_vec4"); + int sampler = 0; + GLint count; + glGetProgramiv(m_program[pass].program, GL_ACTIVE_UNIFORMS, &count); + + if (count == 0) + { + LOGI("No active uniforms!"); + } + + for (int i = 0; i < count; i++) + { + char name[512]; + GLsizei length; + GLint size; + GLenum type; + glGetActiveUniform(m_program[pass].program, i, 512, &length, &size, &type, name); + + assert(m_program[pass].vertexMojoResult && m_program[pass].fragmentMojoResult); + + RendererMaterial::VariableType vtype = GLTypetoVariableType(type); + if (strncmp(name, "g_", 2) && (vtype != NUM_VARIABLE_TYPES)) + { + if(m_program[pass].vertexMojoResult || m_program[pass].fragmentMojoResult) + { + if (vtype == VARIABLE_SAMPLER2D) + { + // find existing variable... + GLESVariable *var = NULL; + bool varFound = false; + const char* varName = mojoSampleNameToOriginal(pass, name).c_str(); + PxU32 numVariables = (PxU32)m_variables.size(); + for(PxU32 j=0; j<numVariables; j++) + { + if(!strcmp(m_variables[j]->getName(), varName)) + { + var = static_cast<GLESVariable*>(m_variables[j]); + varFound = true; + break; + } + } + + if(!varFound) + var = new GLESVariable(varName, vtype, m_variableBufferSize); + + var->m_location[pass] = glGetUniformLocation(m_program[pass].program, name); + var->m_sampler[pass] = sampler++; + if(!varFound) + { + m_variables.push_back(var); + m_variableBufferSize += var->getDataSize(); + LOGI("Uniform '%s' -> location %d, size %d", var->getName(), var->m_location[pass], var->getDataSize()); + } + else + { + LOGI("Uniform '%s' was updated -> location %d, m_sampler %d", var->getName(), var->m_location[pass], var->m_sampler[pass]); + } + } + else if(uniformArrayName[0].compare(0, uniformArrayName[0].size(), name, uniformArrayName[0].size()) == 0) + { + m_program[pass].vsUniformsVec4Size = size; + m_program[pass].vsUniformsVec4SizeInBytes = m_program[pass].vsUniformsVec4Size * sizeof(float) * 4; + m_program[pass].vsUniformsVec4 = new char[m_program[pass].vsUniformsVec4SizeInBytes]; + LOGI("Allocated %d bytes at %x for vsUniformsVec4", m_program[pass].vsUniformsVec4SizeInBytes, size_t(m_program[pass].vsUniformsVec4)); + m_program[pass].vsUniformsVec4Location = glGetUniformLocation(m_program[pass].program, name); + LOGI("Hidden uniform '%s' -> location %d, size %d x vec4", name, m_program[pass].vsUniformsVec4Location, m_program[pass].vsUniformsVec4Size); + } + else if(uniformArrayName[1].compare(0, uniformArrayName[1].size(), name, uniformArrayName[1].size()) == 0) + { + m_program[pass].psUniformsVec4Size = size; + m_program[pass].psUniformsVec4SizeInBytes = m_program[pass].psUniformsVec4Size * sizeof(float) * 4; + m_program[pass].psUniformsVec4 = new char[m_program[pass].psUniformsVec4SizeInBytes]; + LOGI("Allocated %d bytes at %x for psUniformsVec4", m_program[pass].psUniformsVec4SizeInBytes, size_t(m_program[pass].psUniformsVec4)); + m_program[pass].psUniformsVec4Location = glGetUniformLocation(m_program[pass].program, name); + LOGI("Hidden uniform '%s' -> location %d, size %d x vec4", name, m_program[pass].psUniformsVec4Location, m_program[pass].psUniformsVec4Size); + } + else + { + LOGI("Couldn't find uniform!"); + } + } + else + { + GLESVariable *var = new GLESVariable(name, vtype, m_variableBufferSize); + var->m_location[pass] = glGetUniformLocation(m_program[pass].program, name); + if (vtype == VARIABLE_SAMPLER2D) + var->m_sampler[pass] = sampler++; + LOGI("Uniform '%s' -> location %d, size %d", name, var->m_location[pass], var->getDataSize()); + m_variables.push_back(var); + m_variableBufferSize += var->getDataSize(); + } + } + } + /* Use attributes info received from the AndroidSamplePlatform layer */ + if(m_program[pass].vertexMojoResult || m_program[pass].fragmentMojoResult) + { + /* Find attributes locations */ + m_program[pass].positionAttr = getAttribLocation(MOJOSHADER_USAGE_POSITION, 0, pass); + m_program[pass].colorAttr = getAttribLocation(MOJOSHADER_USAGE_COLOR, 0, pass); + m_program[pass].normalAttr = getAttribLocation(MOJOSHADER_USAGE_NORMAL, 0, pass); + m_program[pass].tangentAttr = getAttribLocation(MOJOSHADER_USAGE_TANGENT, 0, pass); + m_program[pass].boneIndexAttr = -1; + m_program[pass].boneWeightAttr = -1; + memset(m_program[pass].texcoordAttr, -1, sizeof(m_program[pass].texcoordAttr)); + LOGI("Attributes:"); + if(m_program[pass].vertexMojoResult->parseResult.attributes.find(MOJOSHADER_USAGE_TEXCOORD) != m_program[pass].vertexMojoResult->parseResult.attributes.end()) + { + for(int i = 0; i < m_program[pass].vertexMojoResult->parseResult.attributes[MOJOSHADER_USAGE_TEXCOORD].size(); ++i) + { + m_program[pass].texcoordAttr[i] = glGetAttribLocation(m_program[pass].program, m_program[pass].vertexMojoResult->parseResult.attributes[MOJOSHADER_USAGE_TEXCOORD][i].c_str()); + LOGI("\t TEXCOORD%d: %d", i, m_program[pass].texcoordAttr[i]); + } + /* If shader contains more than 4 texture coords inputs, then next one/two should be: bone indices input, bone weights input */ + if(m_program[pass].vertexMojoResult->parseResult.attributes[MOJOSHADER_USAGE_TEXCOORD].size() > 4) + { + m_program[pass].boneIndexAttr = glGetAttribLocation(m_program[pass].program, m_program[pass].vertexMojoResult->parseResult.attributes[MOJOSHADER_USAGE_TEXCOORD][4].c_str()); + } + if(m_program[pass].vertexMojoResult->parseResult.attributes[MOJOSHADER_USAGE_TEXCOORD].size() > 5) + { + m_program[pass].boneWeightAttr = glGetAttribLocation(m_program[pass].program, m_program[pass].vertexMojoResult->parseResult.attributes[MOJOSHADER_USAGE_TEXCOORD][5].c_str()); + } + } + + LOGI("\t POSITION: %d", m_program[pass].positionAttr); + LOGI("\t COLOR: %d", m_program[pass].colorAttr); + LOGI("\t NORMAL: %d", m_program[pass].normalAttr); + LOGI("\t TANGENT: %d", m_program[pass].tangentAttr); + LOGI("\t BONE INDEX: %d", m_program[pass].boneIndexAttr); + LOGI("\t BONE WEIGHT: %d", m_program[pass].boneWeightAttr); + + /* Expose variables that were in the original shader, but are now inside one vec4 array */ + std::vector<mojoResult*> mojoResults; + mojoResults.push_back(m_program[pass].vertexMojoResult); + mojoResults.push_back(m_program[pass].fragmentMojoResult); + for(int i = 0; i < mojoResults.size(); ++i) + { + for(mojoResult::relocationType::const_iterator it = mojoResults[i]->relocation.begin(); + it != mojoResults[i]->relocation.end(); ++it) + { + if(it->second.name == uniformArrayName[i]) { + // find existing variable... + GLESVariable *var = NULL; + bool varFound = false; + PxU32 numVariables = (PxU32)m_variables.size(); + for(PxU32 j=0; j<numVariables; j++) + { + if(!strcmp(m_variables[j]->getName(), it->first.c_str())) + { + var = static_cast<GLESVariable*>(m_variables[j]); + varFound = true; + break; + } + } + if(!varFound) + var = new GLESVariable(it->first.c_str(), GLTypetoVariableType(it->second.type), m_variableBufferSize); + + var->setSize(it->second.size); + var->m_location[pass] = glGetAttribLocation(m_program[pass].program, it->second.name.c_str()); + + /* Count total variables inside an array */ + /* Inside vertex uniform array ... */ + if(i == 0) m_program[pass].vsUniformsTotal++; + /* or fragment uniform array */ + else m_program[pass].psUniformsTotal++; + + if(!varFound) + { + m_variables.push_back(var); + m_variableBufferSize += it->second.size; + } + if(varFound) + LOGI("Variable is found and updated with m_location for %s", getPassName(static_cast<Pass>(pass))); + LOGI("Uniform '%s' -> location %d, size %d of type %s", var->getName(), var->m_location[pass], it->second.size, variableTypeToString(var->getType()).c_str()); + } + } + } + LOGI("Variables inside vertex uniform array - %d", m_program[pass].vsUniformsTotal); + LOGI("Variables inside fragment uniform array - %d", m_program[pass].psUniformsTotal); + } + else + { + m_program[pass].modelViewProjMatrixUniform = glGetUniformLocation(m_program[pass].program, "g_MVP"); + m_program[pass].modelMatrixUniform = glGetUniformLocation(m_program[pass].program, "g_modelMatrix"); + m_program[pass].viewMatrixUniform = glGetUniformLocation(m_program[pass].program, "g_viewMatrix"); + m_program[pass].projMatrixUniform = glGetUniformLocation(m_program[pass].program, "g_projMatrix"); + m_program[pass].modelViewMatrixUniform = glGetUniformLocation(m_program[pass].program, "g_modelViewMatrix"); + m_program[pass].boneMatricesUniform = glGetUniformLocation(m_program[pass].program, "g_boneMatrices"); + + m_program[pass].positionAttr = glGetAttribLocation(m_program[pass].program, "position_attr"); + m_program[pass].colorAttr = glGetAttribLocation(m_program[pass].program, "color_attr"); + m_program[pass].normalAttr = glGetAttribLocation(m_program[pass].program, "normal_attr"); + m_program[pass].tangentAttr = glGetAttribLocation(m_program[pass].program, "tangent_attr"); + m_program[pass].boneIndexAttr = glGetAttribLocation(m_program[pass].program, "boneIndex_attr"); + m_program[pass].boneWeightAttr = glGetAttribLocation(m_program[pass].program, "boneWeight_attr"); + + for(PxU32 i=0; i<8; i++) + { + char attr[32]; + sprintf(attr, "texcoord%d_attr", i); + m_program[pass].texcoordAttr[i] = glGetAttribLocation(m_program[pass].program, attr); + } + } + + LOGI("That was %p", this); +} + +} +#endif // #if defined(RENDERER_ENABLE_GLES2) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMaterial.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMaterial.h new file mode 100644 index 00000000..b278f5e3 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMaterial.h @@ -0,0 +1,139 @@ +// 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 GLES2_RENDERER_MATERIAL_H +#define GLES2_RENDERER_MATERIAL_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererMaterial.h> +#include "GLES2Renderer.h" + +#if defined(RENDERER_ANDROID) +#include "android/AndroidSamplePlatform.h" +#elif defined(RENDERER_IOS) +#include "ios/IosSamplePlatform.h" +#endif + +#include <set> + +#include <set> + +namespace SampleRenderer +{ + +class GLES2RendererMaterial : public RendererMaterial +{ + public: + GLES2RendererMaterial(GLES2Renderer &renderer, const RendererMaterialDesc &desc); + virtual ~GLES2RendererMaterial(void); + virtual void setModelMatrix(const float *matrix) + { + PX_UNUSED(matrix); + PX_ALWAYS_ASSERT(); + } + virtual const Renderer& getRenderer() const { return m_renderer; } + + /* Actually executes glUniform* and submits data saved in the m_program[m_currentPass].vsUniformsVec4/psUniformsVec4 */ + void submitUniforms(); + + private: + 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; + + VariableType GLTypetoVariableType(GLenum type); + GLint getAttribLocation(size_t usage, size_t index, Pass pass); + std::string mojoSampleNameToOriginal(Pass pass, const std::string& name); + + private: + GLES2RendererMaterial &operator=(const GLES2RendererMaterial&) { return *this; } + + private: + void loadCustomConstants(Pass pass); + + friend class GLES2Renderer; + friend class GLES2RendererVertexBuffer; + friend class GLES2RendererDirectionalLight; + GLES2Renderer &m_renderer; + + GLenum m_glAlphaTestFunc; + + mutable struct shaderProgram { + GLuint vertexShader; + GLuint fragmentShader; + GLuint program; + + GLint modelMatrixUniform; + GLint viewMatrixUniform; + GLint projMatrixUniform; + GLint modelViewMatrixUniform; + GLint boneMatricesUniform; + GLint modelViewProjMatrixUniform; + + GLint positionAttr; + GLint colorAttr; + GLint normalAttr; + GLint tangentAttr; + GLint boneIndexAttr; + GLint boneWeightAttr; + + GLint texcoordAttr[8]; + + mutable std::set<std::string> vsUniformsCollected; + mutable std::set<std::string> psUniformsCollected; + + size_t vsUniformsTotal; + size_t psUniformsTotal; + + char* vsUniformsVec4; + GLuint vsUniformsVec4Location; + size_t vsUniformsVec4Size; + size_t vsUniformsVec4SizeInBytes; + char* psUniformsVec4; + GLuint psUniformsVec4Location; + size_t psUniformsVec4Size; + size_t psUniformsVec4SizeInBytes; + + mojoResult* vertexMojoResult; + mojoResult* fragmentMojoResult; + + shaderProgram(); + ~shaderProgram(); + } m_program[NUM_PASSES]; + + mutable Pass m_currentPass; +}; + +} + +#endif // #if defined(RENDERER_ENABLE_GLES2) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMesh.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMesh.cpp new file mode 100644 index 00000000..b5a0ff2c --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMesh.cpp @@ -0,0 +1,103 @@ +// 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 "GLES2RendererMesh.h" + +#if defined(RENDERER_ENABLE_GLES2) +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; +} + +GLES2RendererMesh::GLES2RendererMesh(GLES2Renderer& renderer, const RendererMeshDesc &desc) : + RendererMesh(desc), m_renderer(renderer) +{ + +} + +GLES2RendererMesh::~GLES2RendererMesh(void) +{ + +} + +void GLES2RendererMesh::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 GLES2RendererMesh::renderVertices(PxU32 numVertices, RendererMaterial *material) const +{ + RendererMesh::Primitive primitive = getPrimitives(); + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) glDepthMask(false); + glDrawArrays(getGLPrimitive(primitive), 0, numVertices); + if(primitive == RendererMesh::PRIMITIVE_POINT_SPRITES) glDepthMask(true); + } + +void GLES2RendererMesh::renderIndicesInstanced(PxU32 numVertices, PxU32 firstIndex, PxU32 numIndices, RendererIndexBuffer::Format indexFormat, RendererMaterial *material) const +{ + RENDERER_ASSERT(0, "TODO") +} + +void GLES2RendererMesh::renderVerticesInstanced(PxU32 numVertices, RendererMaterial *material) const +{ + RENDERER_ASSERT(0, "TODO") +} + +} +#endif // #if defined(RENDERER_ENABLE_GLES2) + diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMesh.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMesh.h new file mode 100644 index 00000000..b24dd778 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererMesh.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 GLES2_RENDERER_MESH_H +#define GLES2_RENDERER_MESH_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererMesh.h> + +#include "GLES2Renderer.h" + +namespace SampleRenderer +{ +class GLES2RendererMesh : public RendererMesh +{ + public: + GLES2RendererMesh(GLES2Renderer& renderer, const RendererMeshDesc &desc); + virtual ~GLES2RendererMesh(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: + Renderer& renderer() { return m_renderer; } + + GLES2Renderer& m_renderer; +}; +} +#endif // #if defined(RENDERER_ENABLE_OPENGL) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererTexture2D.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererTexture2D.cpp new file mode 100644 index 00000000..fab87c05 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererTexture2D.cpp @@ -0,0 +1,273 @@ +// 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 "GLES2RendererTexture2D.h" + +#if defined(RENDERER_ENABLE_GLES2) + +namespace SampleRenderer +{ + +static GLuint getGLPixelFormat(RendererTexture2D::Format format) +{ + GLuint glformat = 0; + switch(format) + { +#if !defined(RENDERER_IOS) + case RendererTexture2D::FORMAT_B8G8R8A8: glformat = GL_RGBA8; break; +#else + case RendererTexture2D::FORMAT_B8G8R8A8: glformat = GL_BGRA8; break; +#endif + 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: break; + } + return glformat; +} + +static GLuint getGLPixelInternalFormat(RendererTexture2D::Format format) +{ + GLuint glinternalformat = 0; + switch(format) + { + case RendererTexture2D::FORMAT_B8G8R8A8: + //apparently APPLE's current GLES2 implementation doesn't really support BGRA as an internal texture format + glinternalformat = GL_RGBA8; + break; + 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; + case RendererTexture2D::FORMAT_PVR_2BPP: + glinternalformat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + break; + case RendererTexture2D::FORMAT_PVR_4BPP: + glinternalformat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + break; + default: + 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: + 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: + 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; +} + +GLES2RendererTexture2D::GLES2RendererTexture2D(const RendererTextureDesc &desc) : + RendererTexture2D(desc) +{ + 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(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); + 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); + } +} + +GLES2RendererTexture2D::~GLES2RendererTexture2D(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 *GLES2RendererTexture2D::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 GLES2RendererTexture2D::select(PxU32 stageIndex) +{ + bind(stageIndex); +} + +void GLES2RendererTexture2D::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()); + 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 GLES2RendererTexture2D::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_GLES2) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererTexture2D.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererTexture2D.h new file mode 100644 index 00000000..9c9a2010 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererTexture2D.h @@ -0,0 +1,72 @@ +// 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 GLES2_RENDERER_TEXTURE_2D_H +#define GLES2_RENDERER_TEXTURE_2D_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererTexture2D.h> +#include <RendererTexture2DDesc.h> +#include "GLES2Renderer.h" + +namespace SampleRenderer +{ +class RendererTextureDesc; + +class GLES2RendererTexture2D : public RendererTexture2D +{ + public: + GLES2RendererTexture2D(const RendererTextureDesc &desc); + virtual ~GLES2RendererTexture2D(void); + + public: + virtual void *lockLevel(PxU32 level, PxU32 &pitch); + virtual void unlockLevel(PxU32 level); + + void bind(PxU32 textureUnit); + void select(PxU32 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; +}; +} +#endif // #if defined(RENDERER_ENABLE_GLES2) +#endif diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererVertexBuffer.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererVertexBuffer.cpp new file mode 100644 index 00000000..e9a0ec75 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererVertexBuffer.cpp @@ -0,0 +1,332 @@ +// 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 "GLES2RendererVertexBuffer.h" +#include "GLES2RendererMaterial.h" + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererVertexBufferDesc.h> + +namespace SampleRenderer +{ + +extern GLES2RendererMaterial *g_hackCurrentMat; + +GLES2RendererVertexBuffer::GLES2RendererVertexBuffer(const RendererVertexBufferDesc &desc) : + RendererVertexBuffer(desc) +{ + m_vbo = 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; + if(getHint() == HINT_DYNAMIC) + { + usage = GL_DYNAMIC_DRAW_ARB; + } + + 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); + } + } +} + +GLES2RendererVertexBuffer::~GLES2RendererVertexBuffer(void) +{ + if(m_vbo) + { + glDeleteBuffersARB(1, &m_vbo); + } +} + +void GLES2RendererVertexBuffer::swizzleColor(void *colors, PxU32 stride, PxU32 numColors, RendererVertexBuffer::Format inFormat) +{ + if (inFormat == RendererVertexBuffer::FORMAT_COLOR_RGBA) + { + const void *end = ((PxU8*)colors)+(stride*numColors); + for(PxU8* iterator = (PxU8*)colors; iterator < end; iterator+=stride) + { + std::swap(((PxU8*)iterator)[0], ((PxU8*)iterator)[2]); + } + } +} + +PxU32 GLES2RendererVertexBuffer::convertColor(const RendererColor& color) +{ + return color.a << 24 | color.b << 16 | color.g << 8 | color.r; +} + +void *GLES2RendererVertexBuffer::lock(void) +{ + void *buffer = 0; + if(m_vbo) + { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vbo); + buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + return buffer; +} + +void GLES2RendererVertexBuffer::unlock(void) +{ + if(m_vbo) + { + /* TODO: print out if format is USHORT4 */ + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vbo); + glUnmapBufferOES(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; +} + +#if !defined(RENDERER_ANDROID) && !defined(RENDERER_IOS) +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_TEXCOORD3: + case RendererVertexBuffer::SEMANTIC_BONEINDEX: + case RendererVertexBuffer::SEMANTIC_BONEWEIGHT: + glsemantic = GL_TEXTURE_COORD_ARRAY; + break; + } + RENDERER_ASSERT(glsemantic, "Unable to compute the GL Semantic for Vertex Buffer Semantic."); + return glsemantic; +} +#endif + +void GLES2RendererVertexBuffer::bindGL(GLint position, const SemanticDesc &sm, PxU8 *buffer) +{ + if (position == -1) + return; + + glEnableVertexAttribArray(position); + GLenum type = getGLFormatType(sm.format); + glVertexAttribPointer(position, getGLFormatSize(sm.format), type, type == GL_UNSIGNED_BYTE, m_stride, buffer+sm.offset); +} + +void GLES2RendererVertexBuffer::unbindGL(GLint pos) +{ + if (pos != -1) + glDisableVertexAttribArray(pos); +} + +void GLES2RendererVertexBuffer::bind(PxU32 streamID, PxU32 firstVertex) +{ + prepareForRender(); + GLES2RendererMaterial *mat = g_hackCurrentMat; + 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) + { + bindGL(mat->m_program[mat->m_currentPass].positionAttr, sm, buffer); + } + break; + case SEMANTIC_COLOR: + RENDERER_ASSERT(sm.format == FORMAT_COLOR_BGRA || sm.format == FORMAT_COLOR_RGBA || sm.format == FORMAT_COLOR_NATIVE || sm.format == FORMAT_FLOAT4, "Unsupported Vertex Buffer Format for COLOR semantic."); + if(sm.format == FORMAT_COLOR_BGRA || sm.format == FORMAT_COLOR_RGBA || sm.format == FORMAT_COLOR_NATIVE || sm.format == FORMAT_FLOAT4) + { + bindGL(mat->m_program[mat->m_currentPass].colorAttr, sm, buffer); + } + 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) + { + bindGL(mat->m_program[mat->m_currentPass].normalAttr, sm, buffer); + } + 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) + { + bindGL(mat->m_program[mat->m_currentPass].tangentAttr, sm, buffer); + } + 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)); + + bindGL(mat->m_program[mat->m_currentPass].texcoordAttr[channel], sm, buffer); + + break; + } + case SEMANTIC_BONEINDEX: + { + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + RENDERER_BONEINDEX_CHANNEL)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + RENDERER_BONEINDEX_CHANNEL)); + bindGL(mat->m_program[mat->m_currentPass].boneIndexAttr, sm, buffer); + break; + } + case SEMANTIC_BONEWEIGHT: + { + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + RENDERER_BONEWEIGHT_CHANNEL)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + RENDERER_BONEWEIGHT_CHANNEL)); + bindGL(mat->m_program[mat->m_currentPass].boneWeightAttr, sm, buffer); + break; + } + default: + /* + __android_log_print(ANDROID_LOG_DEBUG, "GLES2RendererVertexBuffer", "semantic: %d", i); + RENDERER_ASSERT(0, "Unable to bind Vertex Buffer Semantic."); + */ + break; + } + } + } + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + +void GLES2RendererVertexBuffer::unbind(PxU32 streamID) +{ + GLES2RendererMaterial *mat = g_hackCurrentMat; + + 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: unbindGL(mat->m_program[mat->m_currentPass].positionAttr); break; + case SEMANTIC_COLOR: unbindGL(mat->m_program[mat->m_currentPass].positionAttr); break; + case SEMANTIC_NORMAL: unbindGL(mat->m_program[mat->m_currentPass].normalAttr); break; + case SEMANTIC_TANGENT: unbindGL(mat->m_program[mat->m_currentPass].tangentAttr); break; + case SEMANTIC_BONEINDEX: unbindGL(mat->m_program[mat->m_currentPass].boneIndexAttr); break; + case SEMANTIC_BONEWEIGHT: unbindGL(mat->m_program[mat->m_currentPass].boneWeightAttr); break; + default: + /* + __android_log_print(ANDROID_LOG_DEBUG, "GLES2RendererVertexBuffer", "semantic: %d", i); + RENDERER_ASSERT(0, "Unable to unbind Vertex Buffer Semantic."); + */ + break; + } + } + } + for(PxU32 i=0; i<8; i++) + { + glActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + i)); + glClientActiveTextureARB((GLenum)(GL_TEXTURE0_ARB + i)); + + unbindGL(mat->m_program[mat->m_currentPass].texcoordAttr[i]); + } +} + +} +#endif // #if defined(RENDERER_ENABLE_GLES2) diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererVertexBuffer.h b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererVertexBuffer.h new file mode 100644 index 00000000..29009f90 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/gles2/GLES2RendererVertexBuffer.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 GLES2_RENDERER_VERTEXBUFFER_H +#define GLES2_RENDERER_VERTEXBUFFER_H + +#include <RendererConfig.h> + +#if defined(RENDERER_ENABLE_GLES2) + +#include <RendererVertexBuffer.h> +#include "GLES2Renderer.h" + +namespace SampleRenderer +{ + +class GLES2RendererVertexBuffer : public RendererVertexBuffer +{ + public: + GLES2RendererVertexBuffer(const RendererVertexBufferDesc &desc); + virtual ~GLES2RendererVertexBuffer(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); + + virtual void bindGL(GLint position, const SemanticDesc &sm, PxU8 *buffer); + virtual void unbindGL(GLint attr); + private: + + GLuint m_vbo; +}; + +} + +#endif // #if defined(RENDERER_ENABLE_GLES2) +#endif |