Skip to content

Commit

Permalink
Add another VBO for selected aircraft to draw them after water (#3965)
Browse files Browse the repository at this point in the history
Aircraft, due to often being much higher up in Z, are now drawn in DrawWorld instead of DrawWorldPreUnit to prevent water distortion from affecting them. Note that this causes subtle other rendering problems later, but meh.
  • Loading branch information
Beherith authored Dec 12, 2024
1 parent 78c9ded commit ab9c6a1
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 14 deletions.
5 changes: 3 additions & 2 deletions luaui/Widgets/Include/DrawPrimitiveAtUnit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ local shaderConfig = {
BILLBOARD = 0, -- 1 if you want camera facing billboards, 0 is flat on ground
POST_ANIM = " ", -- what you want to do in the animation post function (glsl snippet, see shader source)
POST_VERTEX = "v_color = v_color;", -- noop
POST_GEOMETRY = "gl_Position.z = (gl_Position.z) - 256.0 / (gl_Position.w);", --"g_uv.zw = dataIn[0].v_parameters.xy;", -- noop
ZPULL = 256.0, -- how much to pull the z (depth) value towards the camera , 256 is about 16 elmos
POST_GEOMETRY = "", --"g_uv.zw = dataIn[0].v_parameters.xy;", -- noop
POST_SHADING = "fragColor.rgba = fragColor.rgba;", -- noop
MAXVERTICES = 64, -- The max number of vertices we can emit, make sure this is consistent with what you are trying to draw (tris 3, quads 4, corneredrect 8, circle 64
USE_CIRCLES = 1, -- set to nil if you dont want circles
Expand Down Expand Up @@ -64,7 +65,7 @@ local function InitDrawPrimitiveAtUnit(shaderConfig, DPATname)

shaderSourceCache.shaderName = DPATname .. "Shader GL4"

DrawPrimitiveAtUnitShader = LuaShader.CheckShaderUpdates(shaderSourceCache)
DrawPrimitiveAtUnitShader = LuaShader.CheckShaderUpdates(shaderSourceCache) or DrawPrimitiveAtUnitShader

if not DrawPrimitiveAtUnitShader then
Spring.Echo("Failed to compile shader for ", DPATname)
Expand Down
6 changes: 6 additions & 0 deletions luaui/Widgets/Shaders/DrawPrimitiveAtUnit.geom.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ void offsetVertex4(float x, float y, float z, float u, float v, float addRadiusC
vec3 vecnorm = normalize(primitiveCoords);
PRE_OFFSET
gl_Position = cameraViewProj * vec4(centerpos.xyz + rotY * (addRadius * addRadiusCorr * vecnorm + primitiveCoords ), 1.0);
#ifdef ZPULL
// Note that this is a hack that can be used to make sure that the geometry is drawn in front of the unit
// or behind the unit. Positive values will draw the geometry in front of the unit, negative values will draw
// the value is approximately elmos squared, so 512 is 16 elmos
gl_Position.z = (gl_Position.z) - ZPULL / (gl_Position.w); // send 16 elmos forward in depth buffer
#endif
g_uv.zw = dataIn[0].v_parameters.zw;
POST_GEOMETRY
EmitVertex();
Expand Down
2 changes: 1 addition & 1 deletion luaui/Widgets/gui_ground_ao_plates_features_gl4.lua
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ function widget:Initialize()
shaderConfig.CLIPTOLERANCE = 1.2
-- MATCH CUS position as seed to sin, then pass it through geoshader into fragshader
--shaderConfig.POST_VERTEX = "v_parameters.w = max(-0.2, sin(timeInfo.x * 2.0/30.0 + (v_centerpos.x + v_centerpos.z) * 0.1)) + 0.2; // match CUS glow rate"
shaderConfig.POST_GEOMETRY = " gl_Position.z = (gl_Position.z) - 512.0 / (gl_Position.w); // send 16 elmos forward in depth buffer"
shaderConfig.ZPULL = 512.0 -- send 16 elmos forward in depth buffer"
shaderConfig.POST_SHADING = "fragColor.rgba = vec4(texcolor.rgb, pow(texcolor.a,0.5) * g_uv.z);"
shaderConfig.MAXVERTICES = 4
shaderConfig.USE_CIRCLES = nil
Expand Down
3 changes: 2 additions & 1 deletion luaui/Widgets/gui_ground_ao_plates_gl4.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ function widget:Initialize()
shaderConfig.ANIMATION = 0
-- MATCH CUS position as seed to sin, then pass it through geoshader into fragshader
shaderConfig.POST_VERTEX = "v_parameters.w = max(-0.2, sin((timeInfo.x + timeInfo.w) * 2.0/30.0 + float(UNITID) * 0.1)) + 0.2; // match CUS glow rate"
shaderConfig.POST_GEOMETRY = "g_uv.w = dataIn[0].v_parameters.w; gl_Position.z = (gl_Position.z) - 512.0 / (gl_Position.w); // send 16 elmos forward in depth buffer"
shaderConfig.ZPULL = 512.0 -- send 16 elmos forward in depth buffer"
shaderConfig.POST_GEOMETRY = "g_uv.w = dataIn[0].v_parameters.w;" -- pass the glow rate to the frag shader
shaderConfig.POST_SHADING = "fragColor.rgba = vec4(texcolor.rgb* (1.0 + g_uv.w), texcolor.a * g_uv.z);"
shaderConfig.MAXVERTICES = 4
shaderConfig.USE_CIRCLES = nil
Expand Down
42 changes: 34 additions & 8 deletions luaui/Widgets/gui_selectedunits_gl4.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ local selectionHighlight = true
local mouseoverHighlight = true

---- GL4 Backend Stuff----
local selectionVBO = nil
local selectionVBOGround = nil
local selectionVBOAir = nil

local mapHasWater = (Spring.GetGroundExtremes() < 0)

local selectShader = nil
local luaShaderDir = "LuaUI/Widgets/Include/"

Expand Down Expand Up @@ -103,7 +107,7 @@ local function AddPrimitiveAtUnit(unitID)
end
--Spring.Echo(unitID,radius,radius, Spring.GetUnitTeam(unitID), numvertices, 1, gf)
pushElementInstance(
selectionVBO, -- push into this Instance VBO Table
(unitCanFly[unitDefID] and selectionVBOAir) or selectionVBOGround, -- push into this Instance VBO Table
{
length, width, cornersize, additionalheight, -- lengthwidthcornerheight
unitTeam[unitID], -- teamID
Expand All @@ -119,9 +123,8 @@ local function AddPrimitiveAtUnit(unitID)
)
end

local drawFrame = 0
function widget:DrawWorldPreUnit()
drawFrame = drawFrame + 1

local function DrawSelections(selectionVBO, isAir)
if selectionVBO.usedElements > 0 then
if hasBadCulling then
gl.Culling(false)
Expand All @@ -131,7 +134,7 @@ function widget:DrawWorldPreUnit()
selectShader:Activate()
selectShader:SetUniform("iconDistance", 99999) -- pass
glStencilTest(true) --https://learnopengl.com/Advanced-OpenGL/Stencil-testing
glDepthTest(true)
glDepthTest(true) -- One really interesting thing is that the depth test does not seem to be obeyed within DrawWorldPreUnit
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE) -- Set The Stencil Buffer To 1 Where Draw Any Polygon this to the shader
glClear(GL_STENCIL_BUFFER_BIT ) -- set stencil buffer to 0

Expand Down Expand Up @@ -165,7 +168,21 @@ function widget:DrawWorldPreUnit()
end
end

if mapHasWater then
function widget:DrawWorld()
DrawSelections(selectionVBOAir, true)
end
end

function widget:DrawWorldPreUnit()
DrawSelections(selectionVBOGround, false)
end

local function RemovePrimitive(unitID)
local selectionVBO
if selectionVBOGround.instanceIDtoIndex[unitID] then selectionVBO = selectionVBOGround end
if selectionVBOAir.instanceIDtoIndex[unitID] then selectionVBO = selectionVBOAir end

if selectionVBO.instanceIDtoIndex[unitID] then
if selectionHighlight then
unitBufferUniformCache[1] = 0
Expand Down Expand Up @@ -287,9 +304,18 @@ local function init()
shaderConfig.TEAMCOLORIZATION = teamcolorOpacity -- not implemented, doing it via POST_SHADING below instead
shaderConfig.HEIGHTOFFSET = 4
shaderConfig.POST_SHADING = "fragColor.rgba = vec4(mix(g_color.rgb * texcolor.rgb + addRadius, vec3(1.0), "..(1-teamcolorOpacity)..") , texcolor.a * TRANSPARENCY + addRadius);"
selectionVBO, selectShader = InitDrawPrimitiveAtUnit(shaderConfig, "selectedUnits")
selectionVBOGround, selectShader = InitDrawPrimitiveAtUnit(shaderConfig, "selectedUnitsGround")
if mapHasWater then
selectionVBOAir = InitDrawPrimitiveAtUnit(shaderConfig, "selectedUnitsAir")
else
selectionVBOAir = selectionVBOGround
end
ClearLastMouseOver()
if selectionVBO == nil then
if selectionVBOGround == nil then
widgetHandler:RemoveWidget()
return false
end
if selectionVBOAir == nil then
widgetHandler:RemoveWidget()
return false
end
Expand Down
2 changes: 1 addition & 1 deletion luaui/Widgets/gui_unit_energy_icons.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ local function initGL4()
shaderConfig.BREATHESIZE = 0.1
-- MATCH CUS position as seed to sin, then pass it through geoshader into fragshader
--shaderConfig.POST_VERTEX = "v_parameters.w = max(-0.2, sin(timeInfo.x * 2.0/30.0 + (v_centerpos.x + v_centerpos.z) * 0.1)) + 0.2; // match CUS glow rate"
shaderConfig.POST_GEOMETRY = " gl_Position.z = (gl_Position.z) - 512.0 / (gl_Position.w); // send 16 elmos forward in depth buffer"
shaderConfig.ZPULL = 512.0 -- send 32 elmos forward in depth buffer"
shaderConfig.POST_SHADING = "fragColor.rgba = vec4(texcolor.rgb, texcolor.a * g_uv.z);"
shaderConfig.MAXVERTICES = 4
shaderConfig.USE_CIRCLES = nil
Expand Down
2 changes: 1 addition & 1 deletion luaui/Widgets/gui_unit_idlebuilder_icons.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ local function initGL4()
shaderConfig.BREATHESIZE = 0--0.1
-- MATCH CUS position as seed to sin, then pass it through geoshader into fragshader
--shaderConfig.POST_VERTEX = "v_parameters.w = max(-0.2, sin(timeInfo.x * 2.0/30.0 + (v_centerpos.x + v_centerpos.z) * 0.1)) + 0.2; // match CUS glow rate"
shaderConfig.POST_GEOMETRY = " gl_Position.z = (gl_Position.z) - 512.0 / (gl_Position.w); // send 16 elmos forward in depth buffer"
shaderConfig.ZPULL = 512.0 -- send 16 elmos forward in depth buffer"
shaderConfig.POST_SHADING = "fragColor.rgba = vec4(texcolor.rgb, texcolor.a * g_uv.z);"
shaderConfig.MAXVERTICES = 4
shaderConfig.USE_CIRCLES = nil
Expand Down

0 comments on commit ab9c6a1

Please sign in to comment.