- //! Draws a shadow volume into the stencil buffer.\r
- void COpenGL3Driver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)\r
- {\r
- const u32 count=triangles.size();\r
- if (!StencilBuffer || !count)\r
- return;\r
-\r
- bool fog = Material.FogEnable;\r
- bool lighting = Material.Lighting;\r
- E_MATERIAL_TYPE materialType = Material.MaterialType;\r
-\r
- Material.FogEnable = false;\r
- Material.Lighting = false;\r
- Material.MaterialType = EMT_SOLID; // Dedicated material in future.\r
-\r
- setRenderStates3DMode();\r
-\r
- CacheHandler->setDepthTest(true);\r
- CacheHandler->setDepthFunc(GL_LESS);\r
- CacheHandler->setDepthMask(false);\r
-\r
- if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY)))\r
- {\r
- CacheHandler->setColorMask(ECP_NONE);\r
- glEnable(GL_STENCIL_TEST);\r
- }\r
-\r
- glEnableVertexAttribArray(EVA_POSITION);\r
- glVertexAttribPointer(EVA_POSITION, 3, GL_FLOAT, false, sizeof(core::vector3df), triangles.const_pointer());\r
-\r
- glStencilMask(~0);\r
- glStencilFunc(GL_ALWAYS, 0, ~0);\r
-\r
- GLenum decr = GL_DECR;\r
- GLenum incr = GL_INCR;\r
-\r
-#if defined(GL_OES_stencil_wrap)\r
- if (FeatureAvailable[IRR_OES_stencil_wrap])\r
- {\r
- decr = GL_DECR_WRAP_OES;\r
- incr = GL_INCR_WRAP_OES;\r
- }\r
-#endif\r
-\r
- CacheHandler->setCullFace(true);\r
-\r
- if (zfail)\r
- {\r
- CacheHandler->setCullFaceFunc(GL_FRONT);\r
- glStencilOp(GL_KEEP, incr, GL_KEEP);\r
- glDrawArrays(GL_TRIANGLES, 0, count);\r
-\r
- CacheHandler->setCullFaceFunc(GL_BACK);\r
- glStencilOp(GL_KEEP, decr, GL_KEEP);\r
- glDrawArrays(GL_TRIANGLES, 0, count);\r
- }\r
- else // zpass\r
- {\r
- CacheHandler->setCullFaceFunc(GL_BACK);\r
- glStencilOp(GL_KEEP, GL_KEEP, incr);\r
- glDrawArrays(GL_TRIANGLES, 0, count);\r
-\r
- CacheHandler->setCullFaceFunc(GL_FRONT);\r
- glStencilOp(GL_KEEP, GL_KEEP, decr);\r
- glDrawArrays(GL_TRIANGLES, 0, count);\r
- }\r
-\r
- glDisableVertexAttribArray(EVA_POSITION);\r
-\r
- glDisable(GL_STENCIL_TEST);\r
-\r
- Material.FogEnable = fog;\r
- Material.Lighting = lighting;\r
- Material.MaterialType = materialType;\r
- }\r
-\r
-\r
- void COpenGL3Driver::drawStencilShadow(bool clearStencilBuffer,\r
- video::SColor leftUpEdge, video::SColor rightUpEdge,\r
- video::SColor leftDownEdge, video::SColor rightDownEdge)\r
- {\r
- if (!StencilBuffer)\r
- return;\r
-\r
- chooseMaterial2D();\r
- setMaterialTexture(0, 0);\r
-\r
- setRenderStates2DMode(true, false, false);\r
-\r
- CacheHandler->setDepthMask(false);\r
- CacheHandler->setColorMask(ECP_ALL);\r
-\r
- CacheHandler->setBlend(true);\r
- CacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
-\r
- glEnable(GL_STENCIL_TEST);\r
- glStencilFunc(GL_NOTEQUAL, 0, ~0);\r
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);\r
-\r
- u16 indices[] = {0, 1, 2, 3};\r
- S3DVertex vertices[4];\r
- vertices[0] = S3DVertex(-1.f, 1.f, 0.9f, 0, 0, 1, leftDownEdge, 0, 0);\r
- vertices[1] = S3DVertex(1.f, 1.f, 0.9f, 0, 0, 1, leftUpEdge, 0, 0);\r
- vertices[2] = S3DVertex(1.f, -1.f, 0.9f, 0, 0, 1, rightUpEdge, 0, 0);\r
- vertices[3] = S3DVertex(-1.f, -1.f, 0.9f, 0, 0, 1, rightDownEdge, 0, 0);\r
-\r
- glEnableVertexAttribArray(EVA_POSITION);\r
- glEnableVertexAttribArray(EVA_COLOR);\r
- glVertexAttribPointer(EVA_POSITION, 3, GL_FLOAT, false, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Pos);\r
- glVertexAttribPointer(EVA_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(S3DVertex), &(static_cast<const S3DVertex*>(vertices))[0].Color);\r
- glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, indices);\r
- glDisableVertexAttribArray(EVA_COLOR);\r
- glDisableVertexAttribArray(EVA_POSITION);\r
-\r
- if (clearStencilBuffer)\r
- glClear(GL_STENCIL_BUFFER_BIT);\r
-\r
- glDisable(GL_STENCIL_TEST);\r
- }\r
-\r
-\r