diff options
Diffstat (limited to 'src/render/Renderer.cpp')
-rw-r--r-- | src/render/Renderer.cpp | 330 |
1 files changed, 11 insertions, 319 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 53971f95..131e77fe 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -416,314 +416,6 @@ SetStencilState(int state) } } -#ifdef RW_D3D9 -struct BuildingInst -{ - rw::RawMatrix combinedMat; - rw::d3d9::InstanceDataHeader *instHeader; - uint8 fadeAlpha; - bool lighting; -}; -static BuildingInst blendInsts[3][2000]; -static int numBlendInsts[3]; - -static void -SetMatrix(BuildingInst *building, rw::Matrix *worldMat) -{ - using namespace rw; - RawMatrix world, worldview; - Camera *cam = engine->currentCamera; - convMatrix(&world, worldMat); - RawMatrix::mult(&worldview, &world, &cam->devView); - RawMatrix::mult(&building->combinedMat, &worldview, &cam->devProj); -} - -static bool -IsTextureTransparent(RwTexture *tex) -{ - if(tex == nil || tex->raster == nil) - return false; - return PLUGINOFFSET(rw::d3d::D3dRaster, tex->raster, rw::d3d::nativeRasterOffset)->hasAlpha; -} - -// Render all opaque meshes and put atomics that needs blending -// into the deferred list. -static void -AtomicFirstPass(RpAtomic *atomic, int pass) -{ - using namespace rw; - using namespace rw::d3d; - using namespace rw::d3d9; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_D3D9); - building->fadeAlpha = 255; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - - bool setupDone = false; - bool defer = false; - SetMatrix(building, atomic->getFrame()->getLTM()); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){ - Material *m = inst->material; - - if(inst->vertexAlpha || m->color.alpha != 255 || - IsTextureTransparent(m->texture)){ - defer = true; - continue; - } - - // alright we're rendering this atomic - if(!setupDone){ - setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride); - setIndices(building->instHeader->indexBuffer); - setVertexDeclaration(building->instHeader->vertexDeclaration); - setVertexShader(default_amb_VS); - d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4); - if(building->lighting) - setAmbient(pAmbient->color); - else - setAmbient(black); - setupDone = true; - } - - setMaterial(m->color, m->surfaceProps); - - if(m->texture){ - d3d::setTexture(0, m->texture); - setPixelShader(default_tex_PS); - }else - setPixelShader(default_PS); - - drawInst(building->instHeader, inst); - } - if(defer) - numBlendInsts[pass]++; -} - -static void -AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha) -{ - using namespace rw; - using namespace rw::d3d; - using namespace rw::d3d9; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_D3D9); - building->fadeAlpha = fadeAlpha; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - SetMatrix(building, atomic->getFrame()->getLTM()); - numBlendInsts[pass]++; -} - -static void -RenderBlendPass(int pass) -{ - using namespace rw; - using namespace rw::d3d; - using namespace rw::d3d9; - - setVertexShader(default_amb_VS); - - int i; - for(i = 0; i < numBlendInsts[pass]; i++){ - BuildingInst *building = &blendInsts[pass][i]; - - setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride); - setIndices(building->instHeader->indexBuffer); - setVertexDeclaration(building->instHeader->vertexDeclaration); - d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4); - if(building->lighting) - setAmbient(pAmbient->color); - else - setAmbient(black); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){ - Material *m = inst->material; - if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255) - continue; // already done this one - - rw::RGBA color = m->color; - color.alpha = (color.alpha * building->fadeAlpha)/255; - setMaterial(color, m->surfaceProps); - - if(m->texture){ - d3d::setTexture(0, m->texture); - setPixelShader(default_tex_PS); - }else - setPixelShader(default_PS); - - drawInst(building->instHeader, inst); - } - } -} -#endif -#ifdef RW_GL3 -struct BuildingInst -{ - rw::Matrix matrix; - rw::gl3::InstanceDataHeader *instHeader; - uint8 fadeAlpha; - bool lighting; -}; -static BuildingInst blendInsts[3][2000]; -static int numBlendInsts[3]; - -static bool -IsTextureTransparent(RwTexture *tex) -{ - if(tex == nil || tex->raster == nil) - return false; - return PLUGINOFFSET(rw::gl3::Gl3Raster, tex->raster, rw::gl3::nativeRasterOffset)->hasAlpha; -} - -// Render all opaque meshes and put atomics that needs blending -// into the deferred list. -static void -AtomicFirstPass(RpAtomic *atomic, int pass) -{ - using namespace rw; - using namespace rw::gl3; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_GL3); - building->fadeAlpha = 255; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - - WorldLights lights; - lights.numAmbients = 1; - lights.numDirectionals = 0; - lights.numLocals = 0; - if(building->lighting) - lights.ambient = pAmbient->color; - else - lights.ambient = black; - - bool setupDone = false; - bool defer = false; - building->matrix = *atomic->getFrame()->getLTM(); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){ - Material *m = inst->material; - - if(inst->vertexAlpha || m->color.alpha != 255 || - IsTextureTransparent(m->texture)){ - defer = true; - continue; - } - - // alright we're rendering this atomic - if(!setupDone){ - defaultShader->use(); - setWorldMatrix(&building->matrix); -#ifdef RW_GL_USE_VAOS - glBindVertexArray(building->instHeader->vao); -#else - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo); - glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo); - setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - setLights(&lights); - setupDone = true; - } - - setMaterial(m->color, m->surfaceProps); - - setTexture(0, m->texture); - - drawInst(building->instHeader, inst); - } -#ifndef RW_GL_USE_VAOS - disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - if(defer) - numBlendInsts[pass]++; -} - -static void -AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha) -{ - using namespace rw; - using namespace rw::gl3; - - BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]]; - - atomic->getPipeline()->instance(atomic); - building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData; - assert(building->instHeader != nil); - assert(building->instHeader->platform == PLATFORM_GL3); - building->fadeAlpha = fadeAlpha; - building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT); - building->matrix = *atomic->getFrame()->getLTM(); - numBlendInsts[pass]++; -} - -static void -RenderBlendPass(int pass) -{ - using namespace rw; - using namespace rw::gl3; - - defaultShader->use(); - WorldLights lights; - lights.numAmbients = 1; - lights.numDirectionals = 0; - lights.numLocals = 0; - - int i; - for(i = 0; i < numBlendInsts[pass]; i++){ - BuildingInst *building = &blendInsts[pass][i]; - -#ifdef RW_GL_USE_VAOS - glBindVertexArray(building->instHeader->vao); -#else - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo); - glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo); - setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - setWorldMatrix(&building->matrix); - if(building->lighting) - lights.ambient = pAmbient->color; - else - lights.ambient = black; - setLights(&lights); - - InstanceData *inst = building->instHeader->inst; - for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){ - Material *m = inst->material; - if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255) - continue; // already done this one - - rw::RGBA color = m->color; - color.alpha = (color.alpha * building->fadeAlpha)/255; - setMaterial(color, m->surfaceProps); - - setTexture(0, m->texture); - - drawInst(building->instHeader, inst); - } -#ifndef RW_GL_USE_VAOS - disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs); -#endif - } -} -#endif - void CRenderer::RenderOneBuilding(CEntity *ent, float camdist) { @@ -754,16 +446,16 @@ CRenderer::RenderOneBuilding(CEntity *ent, float camdist) alpha = mi->m_alpha * fadefactor; if(alpha == 255) - AtomicFirstPass(atomic, pass); + WorldRender::AtomicFirstPass(atomic, pass); else{ // not quite sure what this is about, do we have to do that? RpGeometry *geo = RpAtomicGetGeometry(lodatm); if(geo != RpAtomicGetGeometry(atomic)) RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); - AtomicFullyTransparent(atomic, pass, alpha); + WorldRender::AtomicFullyTransparent(atomic, pass, alpha); } }else - AtomicFirstPass(atomic, pass); + WorldRender::AtomicFirstPass(atomic, pass); ent->bImBeingRendered = false; // TODO: this seems wrong, but do we even need it? } @@ -801,8 +493,8 @@ CRenderer::RenderWorld(int pass) // only very temporary, there are more rendering issues RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RenderBlendPass(PASS_BLEND); - numBlendInsts[PASS_BLEND] = 0; + WorldRender::RenderBlendPass(PASS_BLEND); + WorldRender::numBlendInsts[PASS_BLEND] = 0; break; case 1: // Opaque @@ -824,16 +516,16 @@ CRenderer::RenderWorld(int pass) RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); - RenderBlendPass(PASS_NOZ); + WorldRender::RenderBlendPass(PASS_NOZ); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); break; case 2: // Transparent RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RenderBlendPass(PASS_ADD); + WorldRender::RenderBlendPass(PASS_ADD); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RenderBlendPass(PASS_BLEND); + WorldRender::RenderBlendPass(PASS_BLEND); break; } } @@ -917,9 +609,9 @@ CRenderer::ClearForFrame(void) ms_nNoOfInVisibleEntities = 0; gSortedVehiclesAndPeds.Clear(); - numBlendInsts[PASS_NOZ] = 0; - numBlendInsts[PASS_ADD] = 0; - numBlendInsts[PASS_BLEND] = 0; + WorldRender::numBlendInsts[PASS_NOZ] = 0; + WorldRender::numBlendInsts[PASS_ADD] = 0; + WorldRender::numBlendInsts[PASS_BLEND] = 0; } #endif |