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; }
RendererMesh *GLES2Renderer::createMesh(const RendererMeshDesc &desc) { GLES2RendererMesh *mesh = 0; RENDERER_ASSERT(desc.isValid(), "Invalid Mesh Descriptor."); if(desc.isValid()) { mesh = new GLES2RendererMesh(desc); } return mesh; }
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; }
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; }
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; }
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; }
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; }
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 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; }
bool GLES2Renderer::initTexter() { Renderer::initTexter(); PxU32 width, height; getWindowSize(width, height); const PxU32 MIN_CHARACTER_WIDTH = 8; const PxU32 TEXT_MAX_VERTICES = 16 * (width / MIN_CHARACTER_WIDTH); const PxU32 TEXT_MAX_INDICES = TEXT_MAX_VERTICES * 1.5f; // 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; // create mesh for quad vbdesc.hint = RendererVertexBuffer::HINT_STATIC; vbdesc.maxVertices = 128; 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_quadVertexBuffer = createVertexBuffer(vbdesc); RENDERER_ASSERT(m_quadVertexBuffer, "Failed to create Vertex Buffer."); // initialize index buffer inbdesc.hint = RendererIndexBuffer::HINT_STATIC; inbdesc.format = RendererIndexBuffer::FORMAT_UINT16; inbdesc.maxIndices = 128; m_quadIndexBuffer = createIndexBuffer(inbdesc); RENDERER_ASSERT(m_quadIndexBuffer, "Failed to create Instance Buffer."); meshdesc.primitives = RendererMesh::PRIMITIVE_TRIANGLES; meshdesc.vertexBuffers = &m_quadVertexBuffer; meshdesc.numVertexBuffers = 1; meshdesc.firstVertex = 0; meshdesc.numVertices = m_quadVertexBuffer->getMaxVertices(); meshdesc.indexBuffer = m_quadIndexBuffer; meshdesc.firstIndex = 0; meshdesc.numIndices = m_quadIndexBuffer->getMaxIndices(); meshdesc.instanceBuffer = NULL; meshdesc.firstInstance = 0; meshdesc.numInstances = 0; m_quadMesh = createMesh(meshdesc); RENDERER_ASSERT(m_quadMesh, "Failed to create Mesh."); }
void GLES2Renderer::renderDeferredLight(const RendererLight &/*light*/) { RENDERER_ASSERT(0, "Not implemented!"); }
void GLES2Renderer::bindMeshContext(const RendererMeshContext &context) { physx::PxMat44 model = physx::PxMat44::createIdentity(); 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) { PxToGL(glmodel, model); glUniformMatrix4fv(program.modelMatrixUniform, 1, GL_FALSE, glmodel); } if (program.viewMatrixUniform != -1) { PxToGL(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; PxToGL(glmodelview, modelView); glUniformMatrix4fv(program.modelViewMatrixUniform, 1, GL_FALSE, glmodelview); } if (program.modelViewProjMatrixUniform != -1) { modelView = m_viewMatrix * model; physx::PxMat44 MVP = PxMat44(m_glProjectionMatrix).getTranspose(); MVP = MVP * modelView; PxToGLColumnMajor(glmvp, MVP); glUniformMatrix4fv(program.modelViewProjMatrixUniform, 1, GL_FALSE, glmvp); } // if we use MojoShader if(program.vertexMojoResult || program.fragmentMojoResult) { // model matrix { const RendererMaterial::Variable* var = g_hackCurrentMat->findVariable("g_modelMatrix", RendererMaterial::VARIABLE_FLOAT4x4); if(var) { if (context.shaderData) { memcpy(&glmodel, context.shaderData, 16 * sizeof(PxF32)); } else { PxToGL(glmodel, model); } g_hackCurrentMat->bindVariable(g_hackCurrentMat->m_currentPass, *var, glmodel); } } // model-view matrix { const RendererMaterial::Variable* 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-project matrix { const RendererMaterial::Variable* 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); physx::PxMat44 MV(glmodelview); MVP = MV * MVP; memcpy(glmvp, MVP.front(), sizeof(MVP)); g_hackCurrentMat->bindVariable(g_hackCurrentMat->m_currentPass, *var, glmvp); } } } 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"); } RENDERER_ASSERT(context.numBones <= RENDERER_MAX_BONES, "Too many bones."); if(context.boneMatrices && context.numBones>0 && context.numBones <= RENDERER_MAX_BONES && program.boneMatricesUniform != -1) { GLfloat glbonematrix[16*RENDERER_MAX_BONES]; for(PxU32 i=0; i<context.numBones; i++) { PxToGL(glbonematrix+(16*i), context.boneMatrices[i]); } glUniformMatrix4fv(program.boneMatricesUniform, context.numBones, GL_FALSE, glbonematrix); } }
void GLES2Renderer::bindDeferredState(void) { RENDERER_ASSERT(0, "Not implemented!"); }
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); } }
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); } }
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; }
RendererTarget *GLES2Renderer::createTarget(const RendererTargetDesc &desc) { RENDERER_ASSERT(0, "Not Implemented."); return 0; }