void CNumbersAttribute::setColor(video::SColor color) { reset(); if (IsFloat) { if (Count > 0) ValueF[0] = (f32) color.getRed() / 255.0f; if (Count > 1) ValueF[1] = (f32) color.getGreen() / 255.0f; if (Count > 2) ValueF[2] = (f32) color.getBlue() / 255.0f; if (Count > 3) ValueF[3] = (f32) color.getAlpha() / 255.0f; } else { if (Count > 0) ValueI[0] = color.getRed(); if (Count > 1) ValueI[1] = color.getGreen(); if (Count > 2) ValueI[2] = color.getBlue(); if (Count > 3) ValueI[3] = color.getAlpha(); } }
void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix) { GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; const Track * const track = World::getWorld()->getTrack(); // This function is only called once per frame - thus no need for setters. const float fogmax = track->getFogMax(); const float startH = track->getFogStartHeight(); const float endH = track->getFogEndHeight(); const float start = track->getFogStart(); const float end = track->getFogEnd(); const video::SColor tmpcol = track->getFogColor(); core::vector3df col(tmpcol.getRed() / 255.0f, tmpcol.getGreen() / 255.0f, tmpcol.getBlue() / 255.0f); setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); glUseProgram(MeshShader::TransparentFogShader::Program); MeshShader::TransparentFogShader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, irr_driver->getInvProjMatrix(), fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0); glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); }
//! Default constructor for color list CNumbersAttribute::CNumbersAttribute(const c8* name, video::SColor value) : ValueI(), ValueF(), Count(4), IsFloat(false) { Name = name; ValueI.pushBack(value.getRed()); ValueI.pushBack(value.getGreen()); ValueI.pushBack(value.getBlue()); ValueI.pushBack(value.getAlpha()); }
void COBJMeshWriter::getColorAsStringLine(const video::SColor& color, const c8* const prefix, core::stringc& s) const { s = prefix; s += " "; s += core::stringc(color.getRed()/255.f); s += " "; s += core::stringc(color.getGreen()/255.f); s += " "; s += core::stringc(color.getBlue()/255.f); s += "\n"; }
void push_ARGB8(lua_State *L, video::SColor color) { lua_newtable(L); lua_pushnumber(L, color.getAlpha()); lua_setfield(L, -2, "a"); lua_pushnumber(L, color.getRed()); lua_setfield(L, -2, "r"); lua_pushnumber(L, color.getGreen()); lua_setfield(L, -2, "g"); lua_pushnumber(L, color.getBlue()); lua_setfield(L, -2, "b"); }
// Fill the editfields with the value for the given color void CColorControl::setEditsFromColor(video::SColor col) { DirtyFlag = true; if ( EditAlpha ) EditAlpha->setText( core::stringw(col.getAlpha()).c_str() ); if ( EditRed ) EditRed->setText( core::stringw(col.getRed()).c_str() ); if ( EditGreen ) EditGreen->setText( core::stringw(col.getGreen()).c_str() ); if ( EditBlue ) EditBlue->setText( core::stringw(col.getBlue()).c_str() ); if ( ColorStatic ) ColorStatic->setBackgroundColor(col); }
void IrrDriver::renderLightsScatter(unsigned pointlightcount) { getFBO(FBO_HALF1).Bind(); glClearColor(0., 0., 0., 0.); glClear(GL_COLOR_BUFFER_BIT); const Track * const track = World::getWorld()->getTrack(); // This function is only called once per frame - thus no need for setters. float start = track->getFogStart() + .001; const video::SColor tmpcol = track->getFogColor(); core::vector3df col(tmpcol.getRed() / 255.0f, tmpcol.getGreen() / 255.0f, tmpcol.getBlue() / 255.0f); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); FullScreenShader::FogShader::getInstance()->SetTextureUnits(irr_driver->getDepthStencilTexture()); DrawFullScreenEffect<FullScreenShader::FogShader>(1.f / (40.f * start), col); glEnable(GL_DEPTH_TEST); core::vector3df col2(1., 1., 1.); glUseProgram(LightShader::PointLightScatterShader::getInstance()->Program); glBindVertexArray(LightShader::PointLightScatterShader::getInstance()->vao); LightShader::PointLightScatterShader::getInstance()->SetTextureUnits(irr_driver->getDepthStencilTexture()); LightShader::PointLightScatterShader::getInstance()->setUniforms(1.f / (40.f * start), col2); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, MIN2(pointlightcount, MAXLIGHT)); glDisable(GL_BLEND); m_post_processing->renderGaussian6Blur(getFBO(FBO_HALF1), getFBO(FBO_HALF2), 5., 5.); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); getFBO(FBO_COLORS).Bind(); m_post_processing->renderPassThrough(getRenderTargetTexture(RTT_HALF1)); }
/** Compute spherical harmonics coefficients from ambient light */ void SphericalHarmonics::setAmbientLight(const video::SColor &ambient) { //do not recompute SH coefficients if we already use the same ambient light if((m_spherical_harmonics_textures.size() != 6) && (ambient == m_ambient)) return; m_spherical_harmonics_textures.clear(); m_ambient = ambient; unsigned char *sh_rgba[6]; unsigned sh_w = 16; unsigned sh_h = 16; for (unsigned i = 0; i < 6; i++) { sh_rgba[i] = new unsigned char[sh_w * sh_h * 4]; for (unsigned j = 0; j < sh_w * sh_h * 4; j += 4) { sh_rgba[i][j] = ambient.getBlue(); sh_rgba[i][j + 1] = ambient.getGreen(); sh_rgba[i][j + 2] = ambient.getRed(); sh_rgba[i][j + 3] = 255; } } Color *float_tex_cube[6]; convertToFloatTexture(sh_rgba, sh_w, sh_h, float_tex_cube); generateSphericalHarmonics(float_tex_cube, sh_w); for (unsigned i = 0; i < 6; i++) { delete[] sh_rgba[i]; delete[] float_tex_cube[i]; } // Diffuse env map is x 0.25, compensate for (unsigned i = 0; i < 9; i++) { m_blue_SH_coeff[i] *= 4; m_green_SH_coeff[i] *= 4; m_red_SH_coeff[i] *= 4; } } //setAmbientLight
void WieldMeshSceneNode::setColor(video::SColor c) { assert(!m_lighting); scene::IMesh *mesh = m_meshnode->getMesh(); if (!mesh) return; u8 red = c.getRed(); u8 green = c.getGreen(); u8 blue = c.getBlue(); u32 mc = mesh->getMeshBufferCount(); for (u32 j = 0; j < mc; j++) { video::SColor bc(m_base_color); if ((m_colors.size() > j) && (m_colors[j].override_base)) bc = m_colors[j].color; video::SColor buffercolor(255, bc.getRed() * red / 255, bc.getGreen() * green / 255, bc.getBlue() * blue / 255); scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); colorizeMeshBuffer(buf, &buffercolor); } }
static void applyFacesShading(video::SColor& color, float factor) { color.setRed(core::clamp(core::round32(color.getRed()*factor), 0, 255)); color.setGreen(core::clamp(core::round32(color.getGreen()*factor), 0, 255)); color.setBlue(core::clamp(core::round32(color.getBlue()*factor), 0, 255)); }
void STKMeshSceneNode::render() { irr::video::IVideoDriver* driver = irr_driver->getVideoDriver(); if (!Mesh || !driver) return; ++PassCount; updateNoGL(); updateGL(); bool isTransparent; for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (!mb) continue; video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType; video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type); isTransparent = rnd->isTransparent(); break; } if ((irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) && immediate_draw && !isTransparent) { core::matrix4 invmodel; AbsoluteTransformation.getInverse(invmodel); glDisable(GL_CULL_FACE); if (update_each_frame) updatevbo(); glUseProgram(MeshShader::ObjectPass1Shader::getInstance()->Program); // Only untextured for (unsigned i = 0; i < GLmeshes.size(); i++) { irr_driver->IncreaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; compressTexture(mesh.textures[0], true); if (UserConfigParams::m_azdo) { if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::ObjectPass1Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); } else MeshShader::ObjectPass1Shader::getInstance()->SetTextureUnits(std::vector < GLuint > { getTextureGLuint(mesh.textures[0]) }); MeshShader::ObjectPass1Shader::getInstance()->setUniforms(AbsoluteTransformation, invmodel); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } glEnable(GL_CULL_FACE); return; } if (irr_driver->getPhase() == SOLID_LIT_PASS && immediate_draw && !isTransparent) { core::matrix4 invmodel; AbsoluteTransformation.getInverse(invmodel); glDisable(GL_CULL_FACE); if (update_each_frame && !UserConfigParams::m_dynamic_lights) updatevbo(); glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program); // Only untextured for (unsigned i = 0; i < GLmeshes.size(); i++) { irr_driver->IncreaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; if (UserConfigParams::m_azdo) { GLuint64 DiffuseHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_DIFFUSE), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(DiffuseHandle)) glMakeTextureHandleResidentARB(DiffuseHandle); GLuint64 SpecularHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_SPECULAR), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[1]); if (!glIsTextureHandleResidentARB(SpecularHandle)) glMakeTextureHandleResidentARB(SpecularHandle); GLuint64 SSAOHandle = glGetTextureSamplerHandleARB(irr_driver->getRenderTargetTexture(RTT_HALF1_R), MeshShader::ObjectPass2Shader::getInstance()->SamplersId[2]); if (!glIsTextureHandleResidentARB(SSAOHandle)) glMakeTextureHandleResidentARB(SSAOHandle); if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0])); } else MeshShader::ObjectPass2Shader::getInstance()->SetTextureUnits(createVector<GLuint>( irr_driver->getRenderTargetTexture(RTT_DIFFUSE), irr_driver->getRenderTargetTexture(RTT_SPECULAR), irr_driver->getRenderTargetTexture(RTT_HALF1_R), getTextureGLuint(mesh.textures[0]))); MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } glEnable(GL_CULL_FACE); return; } if (irr_driver->getPhase() == GLOW_PASS) { glUseProgram(MeshShader::ColorizeShader::getInstance()->Program); for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); if (!mb) continue; if (irr_driver->hasARB_base_instance()) glBindVertexArray(VAOManager::getInstance()->getVAO(video::EVT_STANDARD)); else glBindVertexArray(GLmeshes[i].vao); drawGlow(GLmeshes[i]); } } if (irr_driver->getPhase() == TRANSPARENT_PASS && isTransparent) { ModelViewProjectionMatrix = computeMVP(AbsoluteTransformation); if (immediate_draw) { if (update_each_frame) updatevbo(); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); if (World::getWorld() && World::getWorld()->isFogEnabled()) { glUseProgram(MeshShader::TransparentFogShader::getInstance()->Program); for (unsigned i = 0; i < GLmeshes.size(); i++) { GLMesh &mesh = GLmeshes[i]; irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; const Track * const track = World::getWorld()->getTrack(); // This function is only called once per frame - thus no need for setters. const float fogmax = track->getFogMax(); const float startH = track->getFogStartHeight(); const float endH = track->getFogEndHeight(); const float start = track->getFogStart(); const float end = track->getFogEnd(); const video::SColor tmpcol = track->getFogColor(); video::SColorf col(tmpcol.getRed() / 255.0f, tmpcol.getGreen() / 255.0f, tmpcol.getBlue() / 255.0f); compressTexture(mesh.textures[0], true); if (UserConfigParams::m_azdo) { if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::TransparentFogShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); } else MeshShader::TransparentFogShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) }); MeshShader::TransparentFogShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } } else { glUseProgram(MeshShader::TransparentShader::getInstance()->Program); for (unsigned i = 0; i < GLmeshes.size(); i++) { irr_driver->IncreaseObjectCount(); GLMesh &mesh = GLmeshes[i]; GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; compressTexture(mesh.textures[0], true); if (UserConfigParams::m_azdo) { if (!mesh.TextureHandles[0]) mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentShader::getInstance()->SamplersId[0]); if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0])) glMakeTextureHandleResidentARB(mesh.TextureHandles[0]); MeshShader::TransparentShader::getInstance()->SetTextureHandles(createVector<uint64_t>(mesh.TextureHandles[0])); } else MeshShader::TransparentShader::getInstance()->SetTextureUnits(std::vector<GLuint>{ getTextureGLuint(mesh.textures[0]) }); MeshShader::TransparentShader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); glBindVertexArray(0); } } return; } } }
aiColor3D IrrToAssimpColor(video::SColor color) { return aiColor3D(color.getRed() / 255.f, color.getGreen() / 255.f, color.getBlue() / 255.f); }
// ---------------------------------------------------------------------------- void DrawCalls::handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *ImmediateDraw, const scene::ICameraSceneNode *cam, ShadowMatrices& shadow_matrices) { STKMeshCommon* node = dynamic_cast<STKMeshCommon*>(Node); if (!node) return; node->updateNoGL(); m_deferred_update.push_back(node); if (node->isImmediateDraw()) { ImmediateDraw->push_back(Node); return; } bool culled_for_cams[6] = { true, true, true, true, true, true }; culled_for_cams[0] = isCulledPrecise(cam, Node, irr_driver->getBoundingBoxesViz()); if (UserConfigParams::m_gi && !shadow_matrices.isRSMMapAvail()) { culled_for_cams[1] = isCulledPrecise(shadow_matrices.getSunCam(), Node); } if (CVS->isShadowEnabled()) { for (unsigned i = 0; i < 4; i++) { culled_for_cams[i + 2] = isCulledPrecise(shadow_matrices.getShadowCamNodes()[i], Node); } } // Transparent if (World::getWorld() && World::getWorld()->isFogEnabled()) { const Track * const track = World::getWorld()->getTrack(); // Todo : put everything in a ubo const float fogmax = track->getFogMax(); const float startH = track->getFogStartHeight(); const float endH = track->getFogEndHeight(); const float start = track->getFogStart(); const float end = track->getFogEnd(); const video::SColor tmpcol = track->getFogColor(); video::SColorf col(tmpcol.getRed() / 255.0f, tmpcol.getGreen() / 255.0f, tmpcol.getBlue() / 255.0f); for (GLMesh *mesh : node->TransparentMesh[TM_DEFAULT]) pushVector(ListBlendTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, fogmax, startH, endH, start, end, col); for (GLMesh *mesh : node->TransparentMesh[TM_ADDITIVE]) pushVector(ListAdditiveTransparentFog::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, fogmax, startH, endH, start, end, col); } else { for (GLMesh *mesh : node->TransparentMesh[TM_DEFAULT]) pushVector(ListBlendTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, 1.0f); for (GLMesh *mesh : node->TransparentMesh[TM_ADDITIVE]) pushVector(ListAdditiveTransparent::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, 1.0f); } // Use sun color to determine custom alpha for ghost karts float custom_alpha = 1.0f; if (World::getWorld()) { const video::SColor& c = World::getWorld()->getTrack()->getSunColor(); float y = 0.2126f * c.getRed() + 0.7152f * c.getGreen() + 0.0722f * c.getBlue(); custom_alpha = y > 128.0f ? 0.5f : 0.35f; } for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_STD]) pushVector(ListTranslucentStandard::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, custom_alpha); for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_TAN]) pushVector(ListTranslucentTangents::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, custom_alpha); for (GLMesh *mesh : node->TransparentMesh[TM_TRANSLUCENT_2TC]) pushVector(ListTranslucent2TCoords::getInstance(), mesh, Node->getAbsoluteTransformation(), mesh->texture_trans, custom_alpha); for (GLMesh *mesh : node->TransparentMesh[TM_DISPLACEMENT]) pushVector(ListDisplacement::getInstance(), mesh, Node->getAbsoluteTransformation()); if (!culled_for_cams[0]) { for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat) { if (CVS->supportsIndirectInstancingRendering()) { for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { if (node->glow()) { m_glow_pass_mesh[mesh->mb].m_mesh = mesh; m_glow_pass_mesh[mesh->mb].m_instance_settings .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f)); } if (Mat == Material::SHADERTYPE_SPLATTING) { // Notice: splatting will be drawn using non-instanced shader only // It's only used one place (in overworld) and may be removed eventually core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix); } else { // Only take render info into account if the node is not static (animated) // So they can have different animation std::pair<scene::IMeshBuffer*, RenderInfo*> mesh_render_info(mesh->mb, dynamic_cast<STKMeshSceneNode*>(Node) == NULL ? mesh->m_render_info : NULL); m_solid_pass_mesh[Mat][mesh_render_info].m_mesh = mesh; m_solid_pass_mesh[Mat][mesh_render_info].m_instance_settings.emplace_back(Node, mesh->texture_trans, (mesh->m_render_info && mesh->m_material ? core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(0.0f, 0.0f))); } } } else { core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { switch (Mat) { case Material::SHADERTYPE_SOLID: ListMatDefault::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, (mesh->m_render_info && mesh->m_material ? core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(0.0f, 0.0f))); break; case Material::SHADERTYPE_ALPHA_TEST: ListMatAlphaRef::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, (mesh->m_render_info && mesh->m_material ? core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(0.0f, 0.0f))); break; case Material::SHADERTYPE_NORMAL_MAP: ListMatNormalMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, (mesh->m_render_info && mesh->m_material ? core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(0.0f, 0.0f))); break; case Material::SHADERTYPE_DETAIL_MAP: ListMatDetails::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SOLID_UNLIT: ListMatUnlit::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SPHERE_MAP: ListMatSphereMap::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SPLATTING: ListMatSplatting::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix); break; case Material::SHADERTYPE_VEGETATION: ListMatGrass::getInstance()->SolidPass.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir, (mesh->m_render_info && mesh->m_material ? core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(0.0f, 0.0f))); break; case Material::SHADERTYPE_ALPHA_BLEND: break; case Material::SHADERTYPE_ADDITIVE: break; case Material::SHADERTYPE_WATER: break; default: Log::warn("DrawCalls", "Unknown material type: %d", Mat); } } } } } if (!CVS->isShadowEnabled()) return; for (unsigned cascade = 0; cascade < 4; ++cascade) { if (culled_for_cams[cascade + 2]) continue; for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat) { if (CVS->supportsIndirectInstancingRendering()) { for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_mesh = mesh; m_shadow_pass_mesh[cascade * Material::SHADERTYPE_COUNT + Mat][mesh->mb].m_instance_settings .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f)); } } else { core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { switch (Mat) { case Material::SHADERTYPE_SOLID: ListMatDefault::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); break; case Material::SHADERTYPE_ALPHA_TEST: ListMatAlphaRef::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); break; case Material::SHADERTYPE_NORMAL_MAP: ListMatNormalMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); break; case Material::SHADERTYPE_DETAIL_MAP: ListMatDetails::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SOLID_UNLIT: ListMatUnlit::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SPHERE_MAP: ListMatSphereMap::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SPLATTING: ListMatSplatting::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix); break; case Material::SHADERTYPE_VEGETATION: ListMatGrass::getInstance()->Shadows[cascade].emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir, (mesh->m_render_info && mesh->m_material ? core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(0.0f, 0.0f))); case Material::SHADERTYPE_ALPHA_BLEND: break; case Material::SHADERTYPE_ADDITIVE: break; case Material::SHADERTYPE_WATER: break; default: Log::warn("DrawCalls", "Unknown material type: %d", Mat); } } } } } if (!UserConfigParams::m_gi || shadow_matrices.isRSMMapAvail()) return; if (!culled_for_cams[1]) { for (unsigned Mat = 0; Mat < Material::SHADERTYPE_COUNT; ++Mat) { if (CVS->supportsIndirectInstancingRendering()) { for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { if (Mat == Material::SHADERTYPE_SPLATTING) { core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix); } else { m_reflective_shadow_map_mesh[Mat][mesh->mb].m_mesh = mesh; m_reflective_shadow_map_mesh[Mat][mesh->mb].m_instance_settings .emplace_back(Node, core::vector2df(0.0f, 0.0f), core::vector2df(0.0f, 0.0f)); } } } else { core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); for (GLMesh *mesh : node->MeshSolidMaterial[Mat]) { switch (Mat) { case Material::SHADERTYPE_SOLID: ListMatDefault::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); break; case Material::SHADERTYPE_ALPHA_TEST: ListMatAlphaRef::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); break; case Material::SHADERTYPE_NORMAL_MAP: ListMatNormalMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans, core::vector2df(0.0f, 0.0f)); break; case Material::SHADERTYPE_DETAIL_MAP: ListMatDetails::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SOLID_UNLIT: ListMatUnlit::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SPHERE_MAP: ListMatSphereMap::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, mesh->texture_trans); break; case Material::SHADERTYPE_SPLATTING: ListMatSplatting::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix); break; case Material::SHADERTYPE_VEGETATION: ListMatGrass::getInstance()->RSM.emplace_back(mesh, ModelMatrix, InvModelMatrix, m_wind_dir, (mesh->m_render_info && mesh->m_material ? core::vector2df(mesh->m_render_info->getHue(), mesh->m_material->getColorizationFactor()) : core::vector2df(0.0f, 0.0f))); break; case Material::SHADERTYPE_ALPHA_BLEND: break; case Material::SHADERTYPE_ADDITIVE: break; case Material::SHADERTYPE_WATER: break; default: Log::warn("DrawCalls", "Unknown material type: %d", Mat); } } } } } }
bool drawLine( video::IImage* dst, s32 x0, s32 y0, s32 x1, s32 y1, const video::SColor& color_a, const video::SColor& color_b, bool blend ) { if (!dst) return false; const core::dimension2du img_size = dst->getDimension(); if ((img_size.Width == 0) || (img_size.Height == 0)) return false; const s32 dx = core::abs_<s32>( x1 - x0 ); const s32 dy = core::abs_<s32>( y1 - y0 ); if ((dx==0) && (dy==0)) return false; s32 sx = 1; // sign s32 sy = 1; // sign if (x0 > x1) sx = -1; if (y0 > y1) sy = -1; s32 err = dx-dy; s32 e2 = 0; s32 x = x0; s32 y = y0; s32 numpixels = 0; // count pixels while (1) { numpixels++; if ((x==x1) && (y==y1)) break; e2 = err << 1; if (e2 > -dy) { err -= dy; x += sx; } if (e2 < dx) { err += dx; y += sy; } } // reset vars; err = dx-dy; e2 = 0; x = x0; y = y0; // values for linear color interpolation const f32 A1=(f32)color_a.getAlpha(); const f32 R1=(f32)color_a.getRed(); const f32 G1=(f32)color_a.getGreen(); const f32 B1=(f32)color_a.getBlue(); const f32 dA=(f32)color_b.getAlpha()-A1; const f32 dR=(f32)color_b.getRed()-R1; const f32 dG=(f32)color_b.getGreen()-G1; const f32 dB=(f32)color_b.getBlue()-B1; // actual drawing f32 f=0.f; s32 k=0; u32 cR=0, cG=0, cB=0, cA=0; while (1) { f = (f32)k/(f32)numpixels; k++; cA=A1; cR=R1; cG=G1; cB=B1; // maybe faster under the assumption that colors have most likely same alpha value if (dA>0) cA = (u32)core::clamp( core::round32(A1+dA*f), 0, 255); if (dR>0) cR = (u32)core::clamp( core::round32(R1+dR*f), 0, 255); if (dG>0) cG = (u32)core::clamp( core::round32(G1+dG*f), 0, 255); if (dB>0) cB = (u32)core::clamp( core::round32(B1+dB*f), 0, 255); drawPixel( dst, x, y, video::SColor( cA, cR, cG, cB), blend ); if (x == x1 && y == y1) break; e2 = err << 1; if (e2 > -dy) { err -= dy; x += sx; } if (e2 < dx) { err += dx; y += sy; } } return true; }