1
0
forked from 0ad/0ad

Adds render debug modes.

Tested By: Langbart
Differential Revision: https://code.wildfiregames.com/D4311
This was SVN commit r25992.
This commit is contained in:
Vladislav Belov 2021-11-12 11:22:18 +00:00
parent dc361048aa
commit 36eb92f9a4
19 changed files with 288 additions and 67 deletions

View File

@ -10,9 +10,13 @@ class DeveloperOverlay
this.devCommandsOverlay.onPress = this.toggle.bind(this);
this.checkBoxes = this.getCheckboxNames().map((name, i) =>
new DeveloperOverlayCheckbox(
new DeveloperOverlayCheckboxes.prototype[name](playerViewControl, selection),
new DeveloperOverlayControlCheckbox(
new DeveloperOverlayControlCheckboxes.prototype[name](playerViewControl, selection),
i));
this.dropDowns = this.getDropDownNames().map((name, i) =>
new DeveloperOverlayControlDropDown(
new DeveloperOverlayControlDrowDowns.prototype[name](playerViewControl, selection),
i + this.checkBoxes.length));
this.resize();
}
@ -22,7 +26,12 @@ class DeveloperOverlay
*/
getCheckboxNames()
{
return Object.keys(DeveloperOverlayCheckboxes.prototype);
return Object.keys(DeveloperOverlayControlCheckboxes.prototype);
}
getDropDownNames()
{
return Object.keys(DeveloperOverlayControlDrowDowns.prototype);
}
toggle()
@ -35,6 +44,9 @@ class DeveloperOverlay
this.checkBoxes.forEach(checkbox => {
checkbox.setHidden(this.devCommandsOverlay.hidden);
});
this.dropDowns.forEach(dropDown => {
dropDown.setHidden(this.devCommandsOverlay.hidden);
});
}
sendNotification()
@ -59,7 +71,8 @@ class DeveloperOverlay
let size = this.devCommandsOverlay.size;
size.bottom =
size.top +
this.checkBoxes.reduce((height, checkbox) => height + checkbox.getHeight(), 0);
this.checkBoxes.reduce((height, checkbox) => height + checkbox.getHeight(), 0) +
this.dropDowns.reduce((height, dropDown) => height + dropDown.getHeight(), 0);
this.devCommandsOverlay.size = size;
}
}

View File

@ -4,15 +4,16 @@
name="devCommandsOverlay"
type="image"
sprite="sessionOverlayBackground"
size="100%-250 50%-200 100%-8 50%"
size="100%-250 50%-280 100%-8 50%"
z="40"
hidden="true"
hotkey="session.devcommands.toggle"
>
<repeat count="20">
<object name="dev_command[n]" size="0 0 100% 20" hidden="true">
<object name="dev_command_label[n]" size="0 0 100%-26 100%" type="text" style="devCommandsText"/>
<object name="dev_command_checkbox[n]" size="100%-24 1 100% 100%" type="checkbox" style="ModernTickBox"/>
<object name="dev_command[n]" size="0 0 100% 24" hidden="true">
<object name="dev_command_label[n]" size="0 0 100%-26 100%" type="text" style="devCommandsText" hidden="true"/>
<object name="dev_command_checkbox[n]" size="100%-24 1 100% 100%" type="checkbox" style="ModernTickBox" hidden="true"/>
<object name="dev_command_dropdown[n]" size="0 0 100% 100%" type="dropdown" style="devCommandsDropDown" tooltip_style="tooltipInstant" hidden="true"/>
</object>
</repeat>
</object>

View File

@ -0,0 +1,35 @@
/**
* Base class for all controls on the developer overlay.
*/
class DeveloperOverlayControl
{
constructor(handler, i)
{
this.handler = handler;
this.handler.update = () => this.update();
this.body = Engine.GetGUIObjectByName("dev_command[" + i + "]");
this.resize(i);
this.updater = this.update.bind(this);
if (this.handler.checked)
registerPlayersInitHandler(this.updater);
}
getHeight()
{
return this.body.size.bottom - this.body.size.top;
}
resize(i)
{
let size = this.body.size;
let height = size.bottom;
size.top = height * i;
size.bottom = height * (i + 1);
this.body.size = size;
this.body.hidden = false;
}
}

View File

@ -1,26 +1,19 @@
/**
* This class sets up a checkbox in the developer overlay and assigns its specific handler.
*/
class DeveloperOverlayCheckbox
class DeveloperOverlayControlCheckbox extends DeveloperOverlayControl
{
constructor(handler, i)
{
this.handler = handler;
this.handler.update = () => this.update();
super(handler, i);
this.label = Engine.GetGUIObjectByName("dev_command_label[" + i + "]");
this.label.caption = this.handler.label();
this.label.hidden = false;
this.checkbox = Engine.GetGUIObjectByName("dev_command_checkbox[" + i + "]");
this.checkbox.onPress = this.onPress.bind(this);
this.body = Engine.GetGUIObjectByName("dev_command[" + i + "]");
this.resize(i);
this.updater = this.update.bind(this);
if (this.handler.checked)
registerPlayersInitHandler(this.updater);
this.checkbox.hidden = false;
}
onPress()
@ -47,19 +40,5 @@ class DeveloperOverlayCheckbox
else
registerSimulationUpdateHandler(this.updater);
}
getHeight()
{
return this.body.size.bottom - this.body.size.top;
}
resize(i)
{
let size = this.body.size;
let height = size.bottom;
size.top = height * i;
size.bottom = height * (i + 1);
this.body.size = size;
this.body.hidden = false;
}
}

View File

@ -4,11 +4,11 @@
* If the class has a checked property, then that will be called every simulation update to
* synchronize the state of the checkbox (only if the developer overaly is opened).
*/
class DeveloperOverlayCheckboxes
class DeveloperOverlayControlCheckboxes
{
}
DeveloperOverlayCheckboxes.prototype.ControlAll = class
DeveloperOverlayControlCheckboxes.prototype.ControlAll = class
{
label()
{
@ -30,7 +30,7 @@ DeveloperOverlayCheckboxes.prototype.ControlAll = class
}
};
DeveloperOverlayCheckboxes.prototype.ChangePerspective = class
DeveloperOverlayControlCheckboxes.prototype.ChangePerspective = class
{
constructor(playerViewControl)
{
@ -48,7 +48,7 @@ DeveloperOverlayCheckboxes.prototype.ChangePerspective = class
}
};
DeveloperOverlayCheckboxes.prototype.SelectionEntityState = class
DeveloperOverlayControlCheckboxes.prototype.SelectionEntityState = class
{
constructor(playerViewControl, selection)
{
@ -66,7 +66,7 @@ DeveloperOverlayCheckboxes.prototype.SelectionEntityState = class
}
};
DeveloperOverlayCheckboxes.prototype.PathfinderOverlay = class
DeveloperOverlayControlCheckboxes.prototype.PathfinderOverlay = class
{
label()
{
@ -79,7 +79,7 @@ DeveloperOverlayCheckboxes.prototype.PathfinderOverlay = class
}
};
DeveloperOverlayCheckboxes.prototype.HierarchicalPathfinderOverlay = class
DeveloperOverlayControlCheckboxes.prototype.HierarchicalPathfinderOverlay = class
{
label()
{
@ -92,7 +92,7 @@ DeveloperOverlayCheckboxes.prototype.HierarchicalPathfinderOverlay = class
}
};
DeveloperOverlayCheckboxes.prototype.ObstructionOverlay = class
DeveloperOverlayControlCheckboxes.prototype.ObstructionOverlay = class
{
label()
{
@ -105,7 +105,7 @@ DeveloperOverlayCheckboxes.prototype.ObstructionOverlay = class
}
};
DeveloperOverlayCheckboxes.prototype.UnitMotionOverlay = class
DeveloperOverlayControlCheckboxes.prototype.UnitMotionOverlay = class
{
label()
{
@ -118,7 +118,7 @@ DeveloperOverlayCheckboxes.prototype.UnitMotionOverlay = class
}
};
DeveloperOverlayCheckboxes.prototype.RangeOverlay = class
DeveloperOverlayControlCheckboxes.prototype.RangeOverlay = class
{
label()
{
@ -131,7 +131,7 @@ DeveloperOverlayCheckboxes.prototype.RangeOverlay = class
}
};
DeveloperOverlayCheckboxes.prototype.BoundingBoxOverlay = class
DeveloperOverlayControlCheckboxes.prototype.BoundingBoxOverlay = class
{
label()
{
@ -144,7 +144,7 @@ DeveloperOverlayCheckboxes.prototype.BoundingBoxOverlay = class
}
};
DeveloperOverlayCheckboxes.prototype.RestrictCamera = class
DeveloperOverlayControlCheckboxes.prototype.RestrictCamera = class
{
label()
{
@ -162,7 +162,7 @@ DeveloperOverlayCheckboxes.prototype.RestrictCamera = class
}
};
DeveloperOverlayCheckboxes.prototype.RevealMap = class
DeveloperOverlayControlCheckboxes.prototype.RevealMap = class
{
label()
{
@ -183,7 +183,7 @@ DeveloperOverlayCheckboxes.prototype.RevealMap = class
}
};
DeveloperOverlayCheckboxes.prototype.EnableTimeWarp = class
DeveloperOverlayControlCheckboxes.prototype.EnableTimeWarp = class
{
constructor()
{
@ -202,7 +202,7 @@ DeveloperOverlayCheckboxes.prototype.EnableTimeWarp = class
};
DeveloperOverlayCheckboxes.prototype.ActivateRejoinTest = class
DeveloperOverlayControlCheckboxes.prototype.ActivateRejoinTest = class
{
constructor()
{
@ -241,7 +241,7 @@ DeveloperOverlayCheckboxes.prototype.ActivateRejoinTest = class
}
};
DeveloperOverlayCheckboxes.prototype.PromoteSelectedUnits = class
DeveloperOverlayControlCheckboxes.prototype.PromoteSelectedUnits = class
{
label()
{
@ -262,7 +262,7 @@ DeveloperOverlayCheckboxes.prototype.PromoteSelectedUnits = class
}
};
DeveloperOverlayCheckboxes.prototype.EnableCulling = class
DeveloperOverlayControlCheckboxes.prototype.EnableCulling = class
{
label()
{
@ -280,7 +280,7 @@ DeveloperOverlayCheckboxes.prototype.EnableCulling = class
}
};
DeveloperOverlayCheckboxes.prototype.LockCullCamera = class
DeveloperOverlayControlCheckboxes.prototype.LockCullCamera = class
{
label()
{
@ -298,7 +298,7 @@ DeveloperOverlayCheckboxes.prototype.LockCullCamera = class
}
};
DeveloperOverlayCheckboxes.prototype.DisplayCameraFrustum = class
DeveloperOverlayControlCheckboxes.prototype.DisplayCameraFrustum = class
{
label()
{
@ -316,7 +316,7 @@ DeveloperOverlayCheckboxes.prototype.DisplayCameraFrustum = class
}
};
DeveloperOverlayCheckboxes.prototype.DisplayShadowsFrustum = class
DeveloperOverlayControlCheckboxes.prototype.DisplayShadowsFrustum = class
{
label()
{

View File

@ -0,0 +1,38 @@
/**
* This class sets up a dropdown in the developer overlay and assigns its specific handler.
*/
class DeveloperOverlayControlDropDown extends DeveloperOverlayControl
{
constructor(handler, i)
{
super(handler, i);
this.dropdown = Engine.GetGUIObjectByName("dev_command_dropdown[" + i + "]");
this.dropdown.onSelectionChange = this.onSelectionChange.bind(this);
this.dropdown.hidden = false;
}
onSelectionChange()
{
this.handler.onSelectionChange(this.dropdown.selected);
this.update();
}
update()
{
this.dropdown.list = this.handler.values().map(e => e.label);
this.dropdown.list_data = this.handler.values().map(e => e.value);
if (this.handler.selected && this.dropdown.selected != this.handler.selected())
this.dropdown.selected = this.handler.selected();
if (this.handler.enabled)
this.dropdown.enabled = this.handler.enabled();
}
setHidden(hidden)
{
if (hidden)
unregisterSimulationUpdateHandler(this.updater);
else
registerSimulationUpdateHandler(this.updater);
}
}

View File

@ -0,0 +1,37 @@
/**
* This class stores the handlers for the individual dropdowns available in the developer overlay.
* Such a class must have onSelectionChange function.
* If the class has a selected property, then that will be called every simulation update to
* synchronize the state of the dropdown (only if the developer overaly is opened).
*/
class DeveloperOverlayControlDrowDowns
{
}
DeveloperOverlayControlDrowDowns.prototype.RenderDebugMode = class
{
constructor()
{
this.selectedIndex = this.values().map(e => e.value).indexOf(
Engine.Renderer_GetRenderDebugMode());
}
values()
{
return [
{ "value": "RENDER_DEBUG_MODE_NONE", "label": translate("Render Debug Mode Disabled") },
{ "value": "RENDER_DEBUG_MODE_AO", "label": translate("Render Debug Mode AO") }
];
}
onSelectionChange(selectedIndex)
{
this.selectedIndex = selectedIndex;
Engine.Renderer_SetRenderDebugMode(this.values()[this.selectedIndex].value);
}
selected()
{
return this.selectedIndex;
}
};

View File

@ -103,11 +103,39 @@
/>
<style name="devCommandsText"
font="sans-10"
font="sans-12"
textcolor="255 255 255"
text_align="right"
/>
<style name="devCommandsDropDown"
dropdown_buffer="0"
font="sans-12"
textcolor="white"
text_align="left"
text_valign="top"
button_width="20"
sprite_disabled="ModernDarkBoxDisabled"
sprite_overlay_disabled="ModernDarkBoxGoldBorderDisabled"
sprite2="ModernDropDownArrow"
sprite2_disabled="ModernDropDownArrowDisabled"
sprite2_pressed="ModernDropDownArrowHighlight"
buffer_zone="8"
dropdown_size="225"
minimum_visible_items="3"
sprite_list="GrayBackground"
sprite_list_overlay="BlackBorder"
sprite_selectarea="ModernDarkBox"
sprite_selectarea_overlay="ModernDarkBoxWhiteBorder"
textcolor_selected="white"
textcolor_disabled="140 140 140 255"
scrollbar="true"
scrollbar_style="ModernScrollBar"
sound_opened="audio/interface/ui/ui_button_click.ogg"
sound_closed="audio/interface/ui/ui_button_click.ogg"
sound_selected="audio/interface/ui/ui_button_click.ogg"
/>
<style name="resourceText"
textcolor="white"
font="sans-bold-stroke-14"

View File

@ -0,0 +1,20 @@
#ifndef INCLUDED_DEBUG_FRAGMENT
#define INCLUDED_DEBUG_FRAGMENT
#define RENDER_DEBUG_MODE_NONE 0
#define RENDER_DEBUG_MODE_AO 1
#ifndef RENDER_DEBUG_MODE
#define RENDER_DEBUG_MODE RENDER_DEBUG_MODE_NONE
#endif
vec3 applyDebugColor(vec3 color, float ao)
{
#if RENDER_DEBUG_MODE == RENDER_DEBUG_MODE_AO
return vec3(ao);
#else
return color;
#endif
}
#endif // INCLUDED_DEBUG_FRAGMENT

View File

@ -1,5 +1,6 @@
#version 120
#include "common/debug_fragment.h"
#include "common/fog.h"
#include "common/los_fragment.h"
#include "common/shadows_fragment.h"
@ -153,16 +154,15 @@ void main()
specular.rgb = sunColor * specCol * pow(max(0.0, dot(normalize(normal), v_half)), specPow);
#endif
vec3 color = (texdiffuse * sundiffuse + specular.rgb) * getShadow();
vec3 ambColor = texdiffuse * ambient;
#if (USE_INSTANCING || USE_GPU_SKINNING) && USE_AO
vec3 ao = texture2D(aoTex, v_tex2).rrr;
ao = mix(vec3(1.0), ao * 2.0, effectSettings.w);
ambColor *= ao;
float ao = texture2D(aoTex, v_tex2).r;
ao = mix(1.0, ao * 2.0, effectSettings.w);
#else
float ao = 1.0;
#endif
color += ambColor;
vec3 ambientColor = texdiffuse * ambient * ao;
vec3 color = (texdiffuse * sundiffuse + specular.rgb) * getShadow() + ambientColor;
#if USE_SPECULAR_MAP && USE_SELF_LIGHT
color = mix(texdiffuse, color, specular.a);
@ -174,5 +174,7 @@ void main()
color *= shadingColor;
color = applyDebugColor(color, ao);
gl_FragColor.rgb = color;
}

View File

@ -1,5 +1,6 @@
#version 120
#include "common/debug_fragment.h"
#include "common/los_fragment.h"
#include "common/shadows_fragment.h"
@ -90,8 +91,9 @@ void main()
#endif
vec3 color = mix(refrColor + 0.3*specular, reflColor + specular, fresShadow);
color *= getLOS();
gl_FragColor.rgb = color * getLOS();
gl_FragColor.rgb = applyDebugColor(color, 1.0);
// Make alpha vary based on both depth (so it blends with the shore) and view angle (make it
// become opaque faster at lower view angles so we can't look "underneath" the water plane)

View File

@ -1,5 +1,6 @@
#version 120
#include "common/debug_fragment.h"
#include "common/los_fragment.h"
#include "common/shadows_fragment.h"
@ -37,6 +38,6 @@ void main()
color *= getLOS();
gl_FragColor.rgb = color;
gl_FragColor.rgb = applyDebugColor(color, 1.0);
gl_FragColor.a = texdiffuse.a;
}

View File

@ -1,5 +1,6 @@
#version 120
#include "common/debug_fragment.h"
#include "common/los_fragment.h"
uniform sampler2D baseTex;
@ -29,5 +30,5 @@ void main()
color *= getLOS();
gl_FragColor = vec4(color, alpha * base.a);
gl_FragColor = vec4(applyDebugColor(color, 1.0), alpha * base.a);
}

View File

@ -1,5 +1,6 @@
#version 120
#include "common/debug_fragment.h"
#include "common/fog.h"
#include "common/los_fragment.h"
#include "common/shadows_fragment.h"
@ -183,7 +184,7 @@ void main()
color *= shadingColor;
#endif
gl_FragColor.rgb = color;
gl_FragColor.rgb = applyDebugColor(color, 1.0);
#if USE_GRASS
gl_FragColor.a = tex.a;

View File

@ -56,6 +56,9 @@ X(MODE_SHADOWCAST)
X(MODE_SILHOUETTEDISPLAY)
X(MODE_SILHOUETTEOCCLUDER)
X(MODE_WIREFRAME)
X(RENDER_DEBUG_MODE)
X(RENDER_DEBUG_MODE_AO)
X(RENDER_DEBUG_MODE_NONE)
X(SHADOWS_CASCADE_COUNT)
X(SYS_HAS_ARB)
X(SYS_HAS_GLSL)

View File

@ -515,6 +515,9 @@ void CRenderer::ReloadShaders()
#endif
}
m->globalContext.Add(str_RENDER_DEBUG_MODE,
RenderDebugModeEnum::ToString(g_RenderingOptions.GetRenderDebugMode()));
if (g_RenderingOptions.GetPreferGLSL() && g_RenderingOptions.GetFog())
m->globalContext.Add(str_USE_FOG, str_1);

View File

@ -22,6 +22,7 @@
#include "ps/CLogger.h"
#include "ps/ConfigDB.h"
#include "ps/CStr.h"
#include "ps/CStrInternStatic.h"
#include "renderer/Renderer.h"
#include "renderer/PostprocManager.h"
#include "renderer/ShadowMap.h"
@ -74,6 +75,29 @@ CStr8 RenderPathEnum::ToString(RenderPath path)
return "default"; // Silence warning about reaching end of non-void function.
}
RenderDebugMode RenderDebugModeEnum::FromString(const CStr8& name)
{
if (name == str_RENDER_DEBUG_MODE_NONE.c_str())
return RenderDebugMode::NONE;
if (name == str_RENDER_DEBUG_MODE_AO.c_str())
return RenderDebugMode::AO;
LOGWARNING("Unknown render debug mode %s", name.c_str());
return RenderDebugMode::NONE;
}
CStrIntern RenderDebugModeEnum::ToString(RenderDebugMode mode)
{
switch (mode)
{
case RenderDebugMode::AO:
return str_RENDER_DEBUG_MODE_AO;
default:
break;
}
return str_RENDER_DEBUG_MODE_NONE;
}
CRenderingOptions::CRenderingOptions() : m_ConfigHooks(new ConfigHooks())
{
m_RenderPath = RenderPath::DEFAULT;
@ -243,10 +267,16 @@ void CRenderingOptions::SetPreferGLSL(bool value)
g_Renderer.RecomputeSystemShaderDefines();
}
void CRenderingOptions::SetRenderPath(RenderPath value)
{
m_RenderPath = value;
if (CRenderer::IsInitialised())
g_Renderer.SetRenderPath(m_RenderPath);
}
void CRenderingOptions::SetRenderDebugMode(RenderDebugMode value)
{
m_RenderDebugMode = value;
if (CRenderer::IsInitialised())
g_Renderer.MakeShadersDirty();
}

View File

@ -28,6 +28,7 @@
#define INCLUDED_RENDERINGOPTIONS
#include "ps/CStr.h"
#include "ps/CStrIntern.h"
class CRenderer;
@ -50,6 +51,18 @@ struct RenderPathEnum
static CStr8 ToString(RenderPath);
};
enum class RenderDebugMode
{
NONE,
AO
};
struct RenderDebugModeEnum
{
static RenderDebugMode FromString(const CStr8& name);
static CStrIntern ToString(RenderDebugMode mode);
};
class CRenderingOptions
{
// The renderer needs access to our private variables directly because capabilities have not yet been extracted
@ -88,6 +101,8 @@ OPTION_CUSTOM_SETTER(NAME, TYPE); OPTION_GETTER(NAME, TYPE); OPTION_DEF(NAME, TY
OPTION_WITH_SIDE_EFFECT(RenderPath, RenderPath);
OPTION_WITH_SIDE_EFFECT(RenderDebugMode, RenderDebugMode);
OPTION(WaterEffects, bool);
OPTION(WaterFancyEffects, bool);
OPTION(WaterRealDepth, bool);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2020 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -47,6 +47,16 @@ std::string GetRenderPath()
return RenderPathEnum::ToString(g_RenderingOptions.GetRenderPath());
}
std::string GetRenderDebugMode()
{
return RenderDebugModeEnum::ToString(g_RenderingOptions.GetRenderDebugMode()).c_str();
}
void SetRenderDebugMode(const std::string& mode)
{
g_RenderingOptions.SetRenderDebugMode(RenderDebugModeEnum::FromString(mode));
}
bool TextureExists(const std::wstring& filename)
{
return g_Renderer.GetTextureManager().TextureExists(filename);
@ -60,6 +70,8 @@ void RegisterScriptFunctions(const ScriptRequest& rq)
{
ScriptFunction::Register<&GetRenderPath>(rq, "Renderer_GetRenderPath");
ScriptFunction::Register<&TextureExists>(rq, "TextureExists");
ScriptFunction::Register<&GetRenderDebugMode>(rq, "Renderer_GetRenderDebugMode");
ScriptFunction::Register<&SetRenderDebugMode>(rq, "Renderer_SetRenderDebugMode");
REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayFrustum);
REGISTER_BOOLEAN_SCRIPT_SETTING(DisplayShadowsFrustum);
}