void ShaderRenderModifier::BeginPass(const CShaderProgramPtr& shader) { shader->Uniform("transform", g_Renderer.GetViewCamera().GetViewProjection()); shader->Uniform("cameraPos", g_Renderer.GetViewCamera().GetOrientation().GetTranslation()); if (GetShadowMap() && shader->GetTextureBinding("shadowTex").Active()) { shader->BindTexture("shadowTex", GetShadowMap()->GetTexture()); shader->Uniform("shadowTransform", GetShadowMap()->GetTextureMatrix()); int width = GetShadowMap()->GetWidth(); int height = GetShadowMap()->GetHeight(); shader->Uniform("shadowScale", width, height, 1.0f / width, 1.0f / height); } if (GetLightEnv()) { shader->Uniform("ambient", GetLightEnv()->m_UnitsAmbientColor); shader->Uniform("sunDir", GetLightEnv()->GetSunDir()); shader->Uniform("sunColor", GetLightEnv()->m_SunColor); shader->Uniform("fogColor", GetLightEnv()->m_FogColor); shader->Uniform("fogParams", GetLightEnv()->m_FogFactor, GetLightEnv()->m_FogMax, 0.f, 0.f); } if (shader->GetTextureBinding("losTex").Active()) { CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture(); shader->BindTexture("losTex", los.GetTextureSmooth()); // Don't bother sending the whole matrix, we just need two floats (scale and translation) shader->Uniform("losTransform", los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f); } m_BindingInstancingTransform = shader->GetUniformBinding("instancingTransform"); m_BindingShadingColor = shader->GetUniformBinding("shadingColor"); m_BindingPlayerColor = shader->GetUniformBinding("playerColor"); }
void ShadowMap::RenderDebugTexture() { glDepthMask(0); glDisable(GL_DEPTH_TEST); #if !CONFIG2_GLES g_Renderer.BindTexture(0, m->Texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); #endif CShaderTechniquePtr texTech = g_Renderer.GetShaderManager().LoadEffect("gui_basic"); texTech->BeginPass(); CShaderProgramPtr texShader = texTech->GetShader(); texShader->Uniform("transform", GetDefaultGuiMatrix()); texShader->BindTexture("tex", m->Texture); float s = 256.f; float boxVerts[] = { 0,0, 0,s, s,0, s,0, 0,s, s,s }; float boxUV[] = { 0,0, 0,1, 1,0, 1,0, 0,1, 1,1 }; texShader->VertexPointer(2, GL_FLOAT, 0, boxVerts); texShader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, boxUV); texShader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); texTech->EndPass(); #if !CONFIG2_GLES g_Renderer.BindTexture(0, m->Texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); #endif glEnable(GL_DEPTH_TEST); glDepthMask(1); }
//Render Manager. void CConsole::Render() { if (! (m_bVisible || m_bToggle) ) return; PROFILE3_GPU("console"); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid); solidTech->BeginPass(); CShaderProgramPtr solidShader = solidTech->GetShader(); CMatrix3D transform = GetDefaultGuiMatrix(); // animation: slide in from top of screen const float DeltaY = (1.0f - m_fVisibleFrac) * m_fHeight; transform.PostTranslate(m_fX, m_fY - DeltaY, 0.0f); // move to window position solidShader->Uniform(str_transform, transform); DrawWindow(solidShader); solidTech->EndPass(); CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text); textTech->BeginPass(); CTextRenderer textRenderer(textTech->GetShader()); textRenderer.Font(CStrIntern(CONSOLE_FONT)); textRenderer.SetTransform(transform); DrawHistory(textRenderer); DrawBuffer(textRenderer); textRenderer.Render(); textTech->EndPass(); glDisable(GL_BLEND); }
int ShaderRenderModifier::BeginPass(int pass) { m_Technique.BeginPass(pass); CShaderProgramPtr shader = m_Technique.GetShader(pass); if (GetShadowMap() && shader->HasTexture("shadowTex")) { shader->BindTexture("shadowTex", GetShadowMap()->GetTexture()); shader->Uniform("shadowTransform", GetShadowMap()->GetTextureMatrix()); const float* offsets = GetShadowMap()->GetFilterOffsets(); shader->Uniform("shadowOffsets1", offsets[0], offsets[1], offsets[2], offsets[3]); shader->Uniform("shadowOffsets2", offsets[4], offsets[5], offsets[6], offsets[7]); } if (GetLightEnv()) { shader->Uniform("ambient", GetLightEnv()->m_UnitsAmbientColor); shader->Uniform("sunDir", GetLightEnv()->GetSunDir()); shader->Uniform("sunColor", GetLightEnv()->m_SunColor); } if (shader->HasTexture("losTex")) { CLOSTexture& los = g_Renderer.GetScene().GetLOSTexture(); shader->BindTexture("losTex", los.GetTexture()); // Don't bother sending the whole matrix, we just need two floats (scale and translation) shader->Uniform("losTransform", los.GetTextureMatrix()[0], los.GetTextureMatrix()[12], 0.f, 0.f); } m_BindingInstancingTransform = shader->GetUniformBinding("instancingTransform"); m_BindingShadingColor = shader->GetUniformBinding("shadingColor"); m_BindingObjectColor = shader->GetUniformBinding("objectColor"); m_BindingPlayerColor = shader->GetUniformBinding("playerColor"); return shader->GetStreamFlags(); }
void WaterManager::RenderWaves(const CFrustum& frustrum) { #if CONFIG2_GLES #warning Fix WaterManager::RenderWaves on GLES #else if (g_Renderer.m_SkipSubmit || !m_WaterFancyEffects) return; pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FancyEffectsFBO); GLuint attachments[2] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; pglDrawBuffers(2, attachments); glClearColor(0.0f,0.0f, 0.0f,0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); CShaderDefines none; CShaderProgramPtr shad = g_Renderer.GetShaderManager().LoadProgram("glsl/waves", none); shad->Bind(); shad->BindTexture(str_waveTex, m_WaveTex); shad->BindTexture(str_foamTex, m_FoamTex); shad->Uniform(str_time, (float)m_WaterTexTimer); shad->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection()); for (size_t a = 0; a < m_ShoreWaves.size(); ++a) { if (!frustrum.IsBoxVisible(m_ShoreWaves[a]->m_AABB)) continue; CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBvertices; SWavesVertex* base = (SWavesVertex*)VBchunk->m_Owner->Bind(); // setup data pointers GLsizei stride = sizeof(SWavesVertex); shad->VertexPointer(3, GL_FLOAT, stride, &base[VBchunk->m_Index].m_BasePosition); shad->TexCoordPointer(GL_TEXTURE0, 2, GL_UNSIGNED_BYTE, stride, &base[VBchunk->m_Index].m_UV); // NormalPointer(gl_FLOAT, stride, &base[m_VBWater->m_Index].m_UV) pglVertexAttribPointerARB(2, 2, GL_FLOAT, GL_TRUE, stride, &base[VBchunk->m_Index].m_PerpVect); // replaces commented above because my normal is vec2 shad->VertexAttribPointer(str_a_apexPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_ApexPosition); shad->VertexAttribPointer(str_a_splashPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_SplashPosition); shad->VertexAttribPointer(str_a_retreatPosition, 3, GL_FLOAT, false, stride, &base[VBchunk->m_Index].m_RetreatPosition); shad->AssertPointersBound(); shad->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff); shad->Uniform(str_width, (int)m_ShoreWaves[a]->m_Width); u8* indexBase = m_ShoreWaves_VBIndices->m_Owner->Bind(); glDrawElements(GL_TRIANGLES, (GLsizei) (m_ShoreWaves[a]->m_Width-1)*(7*6), GL_UNSIGNED_SHORT, indexBase + sizeof(u16)*(m_ShoreWaves_VBIndices->m_Index)); shad->Uniform(str_translation, m_ShoreWaves[a]->m_TimeDiff + 6.0f); // TODO: figure out why this doesn't work. //g_Renderer.m_Stats.m_DrawCalls++; //g_Renderer.m_Stats.m_WaterTris += m_ShoreWaves_VBIndices->m_Count / 3; CVertexBuffer::Unbind(); } shad->Unbind(); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDisable(GL_BLEND); glDepthFunc(GL_LEQUAL); #endif }
void TerrainRenderer::RenderTerrainShader(ShadowMap* shadow, bool filtered) { ENSURE(m->phase == Phase_Render); std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches; std::vector<CDecalRData*>& visibleDecals = filtered ? m->filteredDecals : m->visibleDecals; if (visiblePatches.empty() && visibleDecals.empty()) return; CShaderManager& shaderManager = g_Renderer.GetShaderManager(); typedef std::map<CStr, CStr> Defines; Defines defBasic; if (shadow) { defBasic["USE_SHADOW"] = "1"; if (g_Renderer.m_Caps.m_ARBProgramShadow && g_Renderer.m_Options.m_ARBProgramShadow) defBasic["USE_FP_SHADOW"] = "1"; if (g_Renderer.m_Options.m_ShadowPCF) defBasic["USE_SHADOW_PCF"] = "1"; #if !CONFIG2_GLES defBasic["USE_SHADOW_SAMPLER"] = "1"; #endif } defBasic["LIGHTING_MODEL_" + g_Renderer.GetLightEnv().GetLightingModel()] = "1"; CShaderTechniquePtr techBase(shaderManager.LoadEffect("terrain_base", defBasic)); CShaderTechniquePtr techBlend(shaderManager.LoadEffect("terrain_blend", defBasic)); CShaderTechniquePtr techDecal(shaderManager.LoadEffect("terrain_decal", defBasic)); // render the solid black sides of the map first CShaderTechniquePtr techSolid = g_Renderer.GetShaderManager().LoadEffect("gui_solid"); techSolid->BeginPass(); CShaderProgramPtr shaderSolid = techSolid->GetShader(); shaderSolid->Uniform("transform", g_Renderer.GetViewCamera().GetViewProjection()); shaderSolid->Uniform("color", 0.0f, 0.0f, 0.0f, 1.0f); PROFILE_START("render terrain sides"); for (size_t i = 0; i < visiblePatches.size(); ++i) visiblePatches[i]->RenderSides(shaderSolid); PROFILE_END("render terrain sides"); techSolid->EndPass(); techBase->BeginPass(); PrepareShader(techBase->GetShader(), shadow); PROFILE_START("render terrain base"); CPatchRData::RenderBases(visiblePatches, techBase->GetShader(), false); PROFILE_END("render terrain base"); techBase->EndPass(); // render blends techBlend->BeginPass(); PrepareShader(techBlend->GetShader(), shadow); // switch on blending glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // no need to write to the depth buffer a second time glDepthMask(0); // render blend passes for each patch PROFILE_START("render terrain blends"); CPatchRData::RenderBlends(visiblePatches, techBlend->GetShader(), false); PROFILE_END("render terrain blends"); techBlend->EndPass(); // Render terrain decals techDecal->BeginPass(); PrepareShader(techDecal->GetShader(), shadow); PROFILE_START("render terrain decals"); for (size_t i = 0; i < visibleDecals.size(); ++i) visibleDecals[i]->Render(techDecal->GetShader(), false); PROFILE_END("render terrain decals"); techDecal->EndPass(); // restore OpenGL state g_Renderer.BindTexture(1, 0); g_Renderer.BindTexture(2, 0); g_Renderer.BindTexture(3, 0); glDepthMask(1); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); }
void ShadowMap::RenderDebugBounds() { CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect("gui_solid"); shaderTech->BeginPass(); CShaderProgramPtr shader = shaderTech->GetShader(); glDepthMask(0); glDisable(GL_CULL_FACE); // Render shadow bound shader->Uniform("transform", g_Renderer.GetViewCamera().GetViewProjection() * m->InvLightTransform); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); shader->Uniform("color", 0.0f, 0.0f, 1.0f, 0.25f); m->ShadowBound.Render(shader); glDisable(GL_BLEND); shader->Uniform("color", 0.0f, 0.0f, 1.0f, 1.0f); m->ShadowBound.RenderOutline(shader); // Draw a funny line/triangle direction indicator thing for unknown reasons float shadowLineVerts[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 50.0, 0.0, 0.0, 50.0, 50.0, 0.0, 50.0, 50.0, 0.0, 50.0, 0.0, 50.0, 50.0, 0.0, 50.0, 50.0, 0.0, 0.0, 50.0 }; shader->VertexPointer(3, GL_FLOAT, 0, shadowLineVerts); shader->AssertPointersBound(); glDrawArrays(GL_LINES, 0, 8); shaderTech->EndPass(); #if 0 CMatrix3D InvTexTransform; m->TextureMatrix.GetInverse(InvTexTransform); // Render representative texture rectangle glPushMatrix(); glMultMatrixf(&InvTexTransform._11); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4ub(255,0,0,64); glBegin(GL_QUADS); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glVertex3f(1.0, 1.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glEnd(); glDisable(GL_BLEND); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glColor3ub(255,0,0); glBegin(GL_QUADS); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glVertex3f(1.0, 1.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glEnd(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPopMatrix(); #endif glEnable(GL_CULL_FACE); glDepthMask(1); }
void GUIRenderer::Draw(DrawCalls& Calls, float Z) { // Called every frame, to draw the object (based on cached calculations) // TODO: batching by shader/texture/etc would be nice CMatrix3D matrix = GetDefaultGuiMatrix(); glDisable(GL_BLEND); // Set LOD bias so mipmapped textures are prettier #if CONFIG2_GLES #warning TODO: implement GUI LOD bias for GLES #else glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.f); #endif // Iterate through each DrawCall, and execute whatever drawing code is being called for (DrawCalls::const_iterator cit = Calls.begin(); cit != Calls.end(); ++cit) { cit->m_Shader->BeginPass(); CShaderProgramPtr shader = cit->m_Shader->GetShader(); shader->Uniform(str_transform, matrix); if (cit->m_HasTexture) { shader->Uniform(str_color, cit->m_ShaderColorParameter); shader->BindTexture(str_tex, cit->m_Texture); if (cit->m_EnableBlending || cit->m_Texture->HasAlpha()) // (shouldn't call HasAlpha before BindTexture) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } CRect TexCoords = cit->ComputeTexCoords(); // Ensure the quad has the correct winding order, and update texcoords to match CRect Verts = cit->m_Vertices; if (Verts.right < Verts.left) { std::swap(Verts.right, Verts.left); std::swap(TexCoords.right, TexCoords.left); } if (Verts.bottom < Verts.top) { std::swap(Verts.bottom, Verts.top); std::swap(TexCoords.bottom, TexCoords.top); } std::vector<float> data; #define ADD(u, v, x, y, z) STMT(data.push_back(u); data.push_back(v); data.push_back(x); data.push_back(y); data.push_back(z)) ADD(TexCoords.left, TexCoords.bottom, Verts.left, Verts.bottom, Z + cit->m_DeltaZ); ADD(TexCoords.right, TexCoords.bottom, Verts.right, Verts.bottom, Z + cit->m_DeltaZ); ADD(TexCoords.right, TexCoords.top, Verts.right, Verts.top, Z + cit->m_DeltaZ); ADD(TexCoords.right, TexCoords.top, Verts.right, Verts.top, Z + cit->m_DeltaZ); ADD(TexCoords.left, TexCoords.top, Verts.left, Verts.top, Z + cit->m_DeltaZ); ADD(TexCoords.left, TexCoords.bottom, Verts.left, Verts.bottom, Z + cit->m_DeltaZ); #undef ADD shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]); shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]); glDrawArrays(GL_TRIANGLES, 0, 6); } else { shader->Uniform(str_color, cit->m_BackColor); if (cit->m_EnableBlending) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } // Ensure the quad has the correct winding order CRect Verts = cit->m_Vertices; if (Verts.right < Verts.left) std::swap(Verts.right, Verts.left); if (Verts.bottom < Verts.top) std::swap(Verts.bottom, Verts.top); std::vector<float> data; #define ADD(x, y, z) STMT(data.push_back(x); data.push_back(y); data.push_back(z)) ADD(Verts.left, Verts.bottom, Z + cit->m_DeltaZ); ADD(Verts.right, Verts.bottom, Z + cit->m_DeltaZ); ADD(Verts.right, Verts.top, Z + cit->m_DeltaZ); ADD(Verts.right, Verts.top, Z + cit->m_DeltaZ); ADD(Verts.left, Verts.top, Z + cit->m_DeltaZ); ADD(Verts.left, Verts.bottom, Z + cit->m_DeltaZ); shader->VertexPointer(3, GL_FLOAT, 3*sizeof(float), &data[0]); glDrawArrays(GL_TRIANGLES, 0, 6); if (cit->m_BorderColor != CColor()) { shader->Uniform(str_color, cit->m_BorderColor); data.clear(); ADD(Verts.left + 0.5f, Verts.top + 0.5f, Z + cit->m_DeltaZ); ADD(Verts.right - 0.5f, Verts.top + 0.5f, Z + cit->m_DeltaZ); ADD(Verts.right - 0.5f, Verts.bottom - 0.5f, Z + cit->m_DeltaZ); ADD(Verts.left + 0.5f, Verts.bottom - 0.5f, Z + cit->m_DeltaZ); shader->VertexPointer(3, GL_FLOAT, 3*sizeof(float), &data[0]); glDrawArrays(GL_LINE_LOOP, 0, 4); } #undef ADD } cit->m_Shader->EndPass(); glDisable(GL_BLEND); } #if CONFIG2_GLES #warning TODO: implement GUI LOD bias for GLES #else glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.f); #endif }
void CChart::Draw() { PROFILE3("render chart"); if (!GetGUI()) return; if (m_Series.empty()) return; const float bz = GetBufferedZ(); CRect rect = GetChartRect(); const float width = rect.GetWidth(); const float height = rect.GetHeight(); // Disable depth updates to prevent apparent z-fighting-related issues // with some drivers causing units to get drawn behind the texture. glDepthMask(0); // Setup the render state CMatrix3D transform = GetDefaultGuiMatrix(); CShaderDefines lineDefines; CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid, g_Renderer.GetSystemShaderDefines(), lineDefines); tech->BeginPass(); CShaderProgramPtr shader = tech->GetShader(); shader->Uniform(str_transform, transform); CVector2D leftBottom, rightTop; leftBottom = rightTop = m_Series[0].m_Points[0]; for (const CChartData& data : m_Series) for (const CVector2D& point : data.m_Points) { if (point.X < leftBottom.X) leftBottom.X = point.X; if (point.Y < leftBottom.Y) leftBottom.Y = point.Y; if (point.X > rightTop.X) rightTop.X = point.X; if (point.Y > rightTop.Y) rightTop.Y = point.Y; } CVector2D scale(width / (rightTop.X - leftBottom.X), height / (rightTop.Y - leftBottom.Y)); for (const CChartData& data : m_Series) { if (data.m_Points.empty()) continue; std::vector<float> vertices; vertices.reserve(data.m_Points.size() * 3); for (const CVector2D& point : data.m_Points) { vertices.push_back(rect.left + (point.X - leftBottom.X) * scale.X); vertices.push_back(rect.bottom - (point.Y - leftBottom.Y) * scale.Y); vertices.push_back(bz + 0.5f); } shader->Uniform(str_color, data.m_Color); shader->VertexPointer(3, GL_FLOAT, 0, &vertices[0]); shader->AssertPointersBound(); glEnable(GL_LINE_SMOOTH); glLineWidth(1.1f); if (!g_Renderer.m_SkipSubmit) glDrawArrays(GL_LINE_STRIP, 0, vertices.size() / 3); glLineWidth(1.0f); glDisable(GL_LINE_SMOOTH); } tech->EndPass(); // Reset depth mask glDepthMask(1); }
void CPostprocManager::ApplyBlurGauss(GLuint inOutTex, GLuint tempTex, int inWidth, int inHeight) { // Set tempTex as our rendering target. pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tempTex, 0); // Get bloom shader, for a horizontal Gaussian blur pass. CShaderDefines defines2; defines2.Add(str_BLOOM_PASS_H, str_1); CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, g_Renderer.GetSystemShaderDefines(), defines2); tech->BeginPass(); CShaderProgramPtr shader = tech->GetShader(); shader->BindTexture(str_renderedTex, inOutTex); shader->Uniform(str_texSize, inWidth, inHeight, 0.0f, 0.0f); const SViewPort oldVp = g_Renderer.GetViewport(); const SViewPort vp = { 0, 0, inWidth, inHeight }; g_Renderer.SetViewport(vp); float quadVerts[] = { 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; float quadTex[] = { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }; shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex); shader->VertexPointer(2, GL_FLOAT, 0, quadVerts); shader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); g_Renderer.SetViewport(oldVp); tech->EndPass(); // Set result texture as our render target. pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, inOutTex, 0); // Get bloom shader, for a vertical Gaussian blur pass. CShaderDefines defines3; defines3.Add(str_BLOOM_PASS_V, str_1); tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, g_Renderer.GetSystemShaderDefines(), defines3); tech->BeginPass(); shader = tech->GetShader(); // Our input texture to the shader is the output of the horizontal pass. shader->BindTexture(str_renderedTex, tempTex); shader->Uniform(str_texSize, inWidth, inHeight, 0.0f, 0.0f); g_Renderer.SetViewport(vp); shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex); shader->VertexPointer(2, GL_FLOAT, 0, quadVerts); shader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); g_Renderer.SetViewport(oldVp); tech->EndPass(); }
void CPostprocManager::ApplyEffect(CShaderTechniquePtr &shaderTech1, int pass) { // select the other FBO for rendering if (!m_WhichBuffer) pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo); else pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); shaderTech1->BeginPass(pass); CShaderProgramPtr shader = shaderTech1->GetShader(pass); shader->Bind(); // Use the textures from the current FBO as input to the shader. // We also bind a bunch of other textures and parameters, but since // this only happens once per frame the overhead is negligible. if (m_WhichBuffer) shader->BindTexture(str_renderedTex, m_ColourTex1); else shader->BindTexture(str_renderedTex, m_ColourTex2); shader->BindTexture(str_depthTex, m_DepthTex); shader->BindTexture(str_blurTex2, m_BlurTex2a); shader->BindTexture(str_blurTex4, m_BlurTex4a); shader->BindTexture(str_blurTex8, m_BlurTex8a); shader->Uniform(str_width, m_Width); shader->Uniform(str_height, m_Height); shader->Uniform(str_zNear, g_Game->GetView()->GetNear()); shader->Uniform(str_zFar, g_Game->GetView()->GetFar()); shader->Uniform(str_brightness, g_LightEnv.m_Brightness); shader->Uniform(str_hdr, g_LightEnv.m_Contrast); shader->Uniform(str_saturation, g_LightEnv.m_Saturation); shader->Uniform(str_bloom, g_LightEnv.m_Bloom); float quadVerts[] = { 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; float quadTex[] = { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f }; shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex); shader->VertexPointer(2, GL_FLOAT, 0, quadVerts); shader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); shader->Unbind(); shaderTech1->EndPass(pass); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); m_WhichBuffer = !m_WhichBuffer; }
// TODO: render the minimap in a framebuffer and just draw the frambuffer texture // most of the time, updating the framebuffer twice a frame. // Here it updates as ping-pong either texture or vertex array each sec to lower gpu stalling // (those operations cause a gpu sync, which slows down the way gpu works) void CMiniMap::Draw() { PROFILE3("render minimap"); // The terrain isn't actually initialized until the map is loaded, which // happens when the game is started, so abort until then. if (!(GetGUI() && g_Game && g_Game->IsGameStarted())) return; CSimulation2* sim = g_Game->GetSimulation2(); CmpPtr<ICmpRangeManager> cmpRangeManager(*sim, SYSTEM_ENTITY); ENSURE(cmpRangeManager); // Set our globals in case they hadn't been set before m_Camera = g_Game->GetView()->GetCamera(); m_Terrain = g_Game->GetWorld()->GetTerrain(); m_Width = (u32)(m_CachedActualSize.right - m_CachedActualSize.left); m_Height = (u32)(m_CachedActualSize.bottom - m_CachedActualSize.top); m_MapSize = m_Terrain->GetVerticesPerSide(); m_TextureSize = (GLsizei)round_up_to_pow2((size_t)m_MapSize); m_MapScale = (cmpRangeManager->GetLosCircular() ? 1.f : 1.414f); if (!m_TerrainTexture || g_GameRestarted) CreateTextures(); // only update 2x / second // (note: since units only move a few pixels per second on the minimap, // we can get away with infrequent updates; this is slow) // TODO: Update all but camera at same speed as simulation static double last_time; const double cur_time = timer_Time(); const bool doUpdate = cur_time - last_time > 0.5; if (doUpdate) { last_time = cur_time; if (m_TerrainDirty) RebuildTerrainTexture(); } const float x = m_CachedActualSize.left, y = m_CachedActualSize.bottom; const float x2 = m_CachedActualSize.right, y2 = m_CachedActualSize.top; const float z = GetBufferedZ(); const float texCoordMax = (float)(m_MapSize - 1) / (float)m_TextureSize; const float angle = GetAngle(); const float unitScale = (cmpRangeManager->GetLosCircular() ? 1.f : m_MapScale/2.f); // Disable depth updates to prevent apparent z-fighting-related issues // with some drivers causing units to get drawn behind the texture. glDepthMask(0); CShaderProgramPtr shader; CShaderTechniquePtr tech; CShaderDefines baseDefines; baseDefines.Add(str_MINIMAP_BASE, str_1); tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), baseDefines); tech->BeginPass(); shader = tech->GetShader(); // Draw the main textured quad shader->BindTexture(str_baseTex, m_TerrainTexture); const CMatrix3D baseTransform = GetDefaultGuiMatrix(); CMatrix3D baseTextureTransform; baseTextureTransform.SetIdentity(); shader->Uniform(str_transform, baseTransform); shader->Uniform(str_textureTransform, baseTextureTransform); DrawTexture(shader, texCoordMax, angle, x, y, x2, y2, z); // Draw territory boundaries glEnable(GL_BLEND); CTerritoryTexture& territoryTexture = g_Game->GetView()->GetTerritoryTexture(); shader->BindTexture(str_baseTex, territoryTexture.GetTexture()); const CMatrix3D* territoryTransform = territoryTexture.GetMinimapTextureMatrix(); shader->Uniform(str_transform, baseTransform); shader->Uniform(str_textureTransform, *territoryTransform); DrawTexture(shader, 1.0f, angle, x, y, x2, y2, z); tech->EndPass(); // Draw the LOS quad in black, using alpha values from the LOS texture CLOSTexture& losTexture = g_Game->GetView()->GetLOSTexture(); CShaderDefines losDefines; losDefines.Add(str_MINIMAP_LOS, str_1); tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), losDefines); tech->BeginPass(); shader = tech->GetShader(); shader->BindTexture(str_baseTex, losTexture.GetTexture()); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); const CMatrix3D* losTransform = losTexture.GetMinimapTextureMatrix(); shader->Uniform(str_transform, baseTransform); shader->Uniform(str_textureTransform, *losTransform); DrawTexture(shader, 1.0f, angle, x, y, x2, y2, z); tech->EndPass(); glDisable(GL_BLEND); PROFILE_START("minimap units"); CShaderDefines pointDefines; pointDefines.Add(str_MINIMAP_POINT, str_1); tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap, g_Renderer.GetSystemShaderDefines(), pointDefines); tech->BeginPass(); shader = tech->GetShader(); shader->Uniform(str_transform, baseTransform); shader->Uniform(str_pointSize, 3.f); CMatrix3D unitMatrix; unitMatrix.SetIdentity(); // Center the minimap on the origin of the axis of rotation. unitMatrix.Translate(-(x2 - x) / 2.f, -(y2 - y) / 2.f, 0.f); // Rotate the map. unitMatrix.RotateZ(angle); // Scale square maps to fit. unitMatrix.Scale(unitScale, unitScale, 1.f); // Move the minimap back to it's starting position. unitMatrix.Translate((x2 - x) / 2.f, (y2 - y) / 2.f, 0.f); // Move the minimap to it's final location. unitMatrix.Translate(x, y, z); // Apply the gui matrix. unitMatrix *= GetDefaultGuiMatrix(); // Load the transform into the shader. shader->Uniform(str_transform, unitMatrix); const float sx = (float)m_Width / ((m_MapSize - 1) * TERRAIN_TILE_SIZE); const float sy = (float)m_Height / ((m_MapSize - 1) * TERRAIN_TILE_SIZE); CSimulation2::InterfaceList ents = sim->GetEntitiesWithInterface(IID_Minimap); if (doUpdate) { VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>(); VertexArrayIterator<u8[4]> attrColor = m_AttributeColor.GetIterator<u8[4]>(); m_EntitiesDrawn = 0; MinimapUnitVertex v; std::vector<MinimapUnitVertex> pingingVertices; pingingVertices.reserve(MAX_ENTITIES_DRAWN / 2); if (cur_time > m_NextBlinkTime) { m_BlinkState = !m_BlinkState; m_NextBlinkTime = cur_time + m_HalfBlinkDuration; } entity_pos_t posX, posZ; for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it) { ICmpMinimap* cmpMinimap = static_cast<ICmpMinimap*>(it->second); if (cmpMinimap->GetRenderData(v.r, v.g, v.b, posX, posZ)) { ICmpRangeManager::ELosVisibility vis = cmpRangeManager->GetLosVisibility(it->first, g_Game->GetPlayerID()); if (vis != ICmpRangeManager::VIS_HIDDEN) { v.a = 255; v.x = posX.ToFloat() * sx; v.y = -posZ.ToFloat() * sy; // Check minimap pinging to indicate something if (m_BlinkState && cmpMinimap->CheckPing(cur_time, m_PingDuration)) { v.r = 255; // ping color is white v.g = 255; v.b = 255; pingingVertices.push_back(v); } else { addVertex(v, attrColor, attrPos); ++m_EntitiesDrawn; } } } } // Add the pinged vertices at the end, so they are drawn on top for (size_t v = 0; v < pingingVertices.size(); ++v) { addVertex(pingingVertices[v], attrColor, attrPos); ++m_EntitiesDrawn; } ENSURE(m_EntitiesDrawn < MAX_ENTITIES_DRAWN); m_VertexArray.Upload(); } m_VertexArray.PrepareForRendering(); if (m_EntitiesDrawn > 0) { #if !CONFIG2_GLES if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); #endif u8* indexBase = m_IndexArray.Bind(); u8* base = m_VertexArray.Bind(); const GLsizei stride = (GLsizei)m_VertexArray.GetStride(); shader->VertexPointer(2, GL_FLOAT, stride, base + m_AttributePos.offset); shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset); shader->AssertPointersBound(); if (!g_Renderer.m_SkipSubmit) glDrawElements(GL_POINTS, (GLsizei)(m_EntitiesDrawn), GL_UNSIGNED_SHORT, indexBase); g_Renderer.GetStats().m_DrawCalls++; CVertexBuffer::Unbind(); #if !CONFIG2_GLES if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); #endif } tech->EndPass(); DrawViewRect(unitMatrix); PROFILE_END("minimap units"); // Reset depth mask glDepthMask(1); }
void CPostprocManager::ApplyBlurGauss(GLuint inOutTex, GLuint tempTex, int inWidth, int inHeight) { // Set tempTex as our rendering target. pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tempTex, 0); // Get bloom shader, for a horizontal Gaussian blur pass. CShaderDefines defines2; defines2.Add(str_BLOOM_PASS_H, str_1); CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, g_Renderer.GetSystemShaderDefines(), defines2); tech->BeginPass(); CShaderProgramPtr shader = tech->GetShader(); shader->BindTexture(str_renderedTex, inOutTex); shader->Uniform(str_texSize, inWidth, inHeight, 0.0f, 0.0f); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0, 0, inWidth, inHeight); glBegin(GL_QUADS); glColor4f(1.f, 1.f, 1.f, 1.f); glTexCoord2f(1.0, 1.0); glVertex2f(1,1); glTexCoord2f(0.0, 1.0); glVertex2f(-1,1); glTexCoord2f(0.0, 0.0); glVertex2f(-1,-1); glTexCoord2f(1.0, 0.0); glVertex2f(1,-1); glEnd(); glPopAttrib(); tech->EndPass(); // Set result texture as our render target. pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, inOutTex, 0); // Get bloom shader, for a vertical Gaussian blur pass. CShaderDefines defines3; defines3.Add(str_BLOOM_PASS_V, str_1); tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom, g_Renderer.GetSystemShaderDefines(), defines3); tech->BeginPass(); shader = tech->GetShader(); // Our input texture to the shader is the output of the horizontal pass. shader->BindTexture(str_renderedTex, tempTex); shader->Uniform(str_texSize, inWidth, inHeight, 0.0f, 0.0f); glPushAttrib(GL_VIEWPORT_BIT); glViewport(0, 0, inWidth, inHeight); glBegin(GL_QUADS); glColor4f(1.f, 1.f, 1.f, 1.f); glTexCoord2f(1.0, 1.0); glVertex2f(1,1); glTexCoord2f(0.0, 1.0); glVertex2f(-1,1); glTexCoord2f(0.0, 0.0); glVertex2f(-1,-1); glTexCoord2f(1.0, 0.0); glVertex2f(1,-1); glEnd(); glPopAttrib(); tech->EndPass(); }
// Render void CProfileViewer::RenderProfile() { if (!m->profileVisible) return; if (!m->path.size()) { m->profileVisible = false; return; } PROFILE3_GPU("profile viewer"); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); AbstractProfileTable* table = m->path[m->path.size() - 1]; const std::vector<ProfileColumn>& columns = table->GetColumns(); size_t numrows = table->GetNumberRows(); CStrIntern font_name("mono-stroke-10"); CFontMetrics font(font_name); int lineSpacing = font.GetLineSpacing(); // Render background GLint estimate_height; GLint estimate_width; estimate_width = 50; for(size_t i = 0; i < columns.size(); ++i) estimate_width += (GLint)columns[i].width; estimate_height = 3 + (GLint)numrows; if (m->path.size() > 1) estimate_height += 2; estimate_height = lineSpacing*estimate_height; CShaderTechniquePtr solidTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_solid); solidTech->BeginPass(); CShaderProgramPtr solidShader = solidTech->GetShader(); solidShader->Uniform(str_color, 0.0f, 0.0f, 0.0f, 0.5f); CMatrix3D transform = GetDefaultGuiMatrix(); solidShader->Uniform(str_transform, transform); float backgroundVerts[] = { (float)estimate_width, 0.0f, 0.0f, 0.0f, 0.0f, (float)estimate_height, 0.0f, (float)estimate_height, (float)estimate_width, (float)estimate_height, (float)estimate_width, 0.0f }; solidShader->VertexPointer(2, GL_FLOAT, 0, backgroundVerts); solidShader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); transform.PostTranslate(22.0f, lineSpacing*3.0f, 0.0f); solidShader->Uniform(str_transform, transform); // Draw row backgrounds for (size_t row = 0; row < numrows; ++row) { if (row % 2) solidShader->Uniform(str_color, 1.0f, 1.0f, 1.0f, 0.1f); else solidShader->Uniform(str_color, 0.0f, 0.0f, 0.0f, 0.1f); float rowVerts[] = { -22.f, 2.f, estimate_width-22.f, 2.f, estimate_width-22.f, 2.f-lineSpacing, estimate_width-22.f, 2.f-lineSpacing, -22.f, 2.f-lineSpacing, -22.f, 2.f }; solidShader->VertexPointer(2, GL_FLOAT, 0, rowVerts); solidShader->AssertPointersBound(); glDrawArrays(GL_TRIANGLES, 0, 6); transform.PostTranslate(0.0f, lineSpacing, 0.0f); solidShader->Uniform(str_transform, transform); } solidTech->EndPass(); // Print table and column titles CShaderTechniquePtr textTech = g_Renderer.GetShaderManager().LoadEffect(str_gui_text); textTech->BeginPass(); CTextRenderer textRenderer(textTech->GetShader()); textRenderer.Font(font_name); textRenderer.Color(1.0f, 1.0f, 1.0f); textRenderer.PrintfAt(2.0f, lineSpacing, L"%hs", table->GetTitle().c_str()); textRenderer.Translate(22.0f, lineSpacing*2.0f, 0.0f); float colX = 0.0f; for (size_t col = 0; col < columns.size(); ++col) { CStrW text = columns[col].title.FromUTF8(); int w, h; font.CalculateStringSize(text.c_str(), w, h); float x = colX; if (col > 0) // right-align all but the first column x += columns[col].width - w; textRenderer.Put(x, 0.0f, text.c_str()); colX += columns[col].width; } textRenderer.Translate(0.0f, lineSpacing, 0.0f); // Print rows int currentExpandId = 1; for (size_t row = 0; row < numrows; ++row) { if (table->IsHighlightRow(row)) textRenderer.Color(1.0f, 0.5f, 0.5f); else textRenderer.Color(1.0f, 1.0f, 1.0f); if (table->GetChild(row)) { textRenderer.PrintfAt(-15.0f, 0.0f, L"%d", currentExpandId); currentExpandId++; } float colX = 0.0f; for (size_t col = 0; col < columns.size(); ++col) { CStrW text = table->GetCellText(row, col).FromUTF8(); int w, h; font.CalculateStringSize(text.c_str(), w, h); float x = colX; if (col > 0) // right-align all but the first column x += columns[col].width - w; textRenderer.Put(x, 0.0f, text.c_str()); colX += columns[col].width; } textRenderer.Translate(0.0f, lineSpacing, 0.0f); } textRenderer.Color(1.0f, 1.0f, 1.0f); if (m->path.size() > 1) { textRenderer.Translate(0.0f, lineSpacing, 0.0f); textRenderer.Put(-15.0f, 0.0f, L"0"); textRenderer.Put(0.0f, 0.0f, L"back to parent"); } textRenderer.Render(); textTech->EndPass(); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); }
void TerrainRenderer::RenderTerrainShader(const CShaderDefines& context, ShadowMap* shadow, bool filtered) { ENSURE(m->phase == Phase_Render); std::vector<CPatchRData*>& visiblePatches = filtered ? m->filteredPatches : m->visiblePatches; std::vector<CDecalRData*>& visibleDecals = filtered ? m->filteredDecals : m->visibleDecals; if (visiblePatches.empty() && visibleDecals.empty()) return; CShaderManager& shaderManager = g_Renderer.GetShaderManager(); CShaderTechniquePtr techBase(shaderManager.LoadEffect(CStrIntern("terrain_base"), context, CShaderDefines())); CShaderTechniquePtr techBlend(shaderManager.LoadEffect(CStrIntern("terrain_blend"), context, CShaderDefines())); CShaderTechniquePtr techDecal(shaderManager.LoadEffect(CStrIntern("terrain_decal"), context, CShaderDefines())); // render the solid black sides of the map first CShaderTechniquePtr techSolid = g_Renderer.GetShaderManager().LoadEffect("gui_solid"); techSolid->BeginPass(); CShaderProgramPtr shaderSolid = techSolid->GetShader(); shaderSolid->Uniform("transform", g_Renderer.GetViewCamera().GetViewProjection()); shaderSolid->Uniform("color", 0.0f, 0.0f, 0.0f, 1.0f); PROFILE_START("render terrain sides"); for (size_t i = 0; i < visiblePatches.size(); ++i) visiblePatches[i]->RenderSides(shaderSolid); PROFILE_END("render terrain sides"); techSolid->EndPass(); techBase->BeginPass(); PrepareShader(techBase->GetShader(), shadow); PROFILE_START("render terrain base"); CPatchRData::RenderBases(visiblePatches, techBase->GetShader(), false); PROFILE_END("render terrain base"); techBase->EndPass(); // render blends techBlend->BeginPass(); PrepareShader(techBlend->GetShader(), shadow); // switch on blending glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // no need to write to the depth buffer a second time glDepthMask(0); // render blend passes for each patch PROFILE_START("render terrain blends"); CPatchRData::RenderBlends(visiblePatches, techBlend->GetShader(), false); PROFILE_END("render terrain blends"); techBlend->EndPass(); // Render terrain decals techDecal->BeginPass(); PrepareShader(techDecal->GetShader(), shadow); PROFILE_START("render terrain decals"); for (size_t i = 0; i < visibleDecals.size(); ++i) visibleDecals[i]->Render(techDecal->GetShader(), false); PROFILE_END("render terrain decals"); techDecal->EndPass(); // restore OpenGL state g_Renderer.BindTexture(1, 0); g_Renderer.BindTexture(2, 0); g_Renderer.BindTexture(3, 0); glDepthMask(1); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); }
void OverlayRenderer::RenderForegroundOverlays(const CCamera& viewCamera) { PROFILE3_GPU("overlays (fg)"); #if CONFIG2_GLES #warning TODO: implement OverlayRenderer::RenderForegroundOverlays for GLES #else pglActiveTextureARB(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); CVector3D right = -viewCamera.m_Orientation.GetLeft(); CVector3D up = viewCamera.m_Orientation.GetUp(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); CShaderProgramPtr shader; CShaderTechniquePtr tech; if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) { tech = g_Renderer.GetShaderManager().LoadEffect(str_foreground_overlay); tech->BeginPass(); shader = tech->GetShader(); } float uvs[8] = { 0,1, 1,1, 1,0, 0,0 }; if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, sizeof(float)*2, &uvs[0]); else glTexCoordPointer(2, GL_FLOAT, sizeof(float)*2, &uvs); for (size_t i = 0; i < m->sprites.size(); ++i) { SOverlaySprite* sprite = m->sprites[i]; if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->BindTexture(str_baseTex, sprite->m_Texture); else sprite->m_Texture->Bind(); shader->Uniform(str_colorMul, sprite->m_Color); CVector3D pos[4] = { sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y0, sprite->m_Position + right*sprite->m_X1 + up*sprite->m_Y0, sprite->m_Position + right*sprite->m_X1 + up*sprite->m_Y1, sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y1 }; if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) shader->VertexPointer(3, GL_FLOAT, sizeof(float)*3, &pos[0].X); else glVertexPointer(3, GL_FLOAT, sizeof(float)*3, &pos[0].X); glDrawArrays(GL_QUADS, 0, (GLsizei)4); g_Renderer.GetStats().m_DrawCalls++; g_Renderer.GetStats().m_OverlayTris += 2; } if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER) tech->EndPass(); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); #endif }