# Added more control for water shader

(Murkiness, colour, tint, reflection tint, reflection tint strength)

This was SVN commit r4357.
This commit is contained in:
Ykkrosh 2006-09-18 18:09:07 +00:00
parent 87598ebf40
commit bfae07a0bc
5 changed files with 166 additions and 135 deletions

View File

@ -399,6 +399,10 @@ void CXMLReader::ReadEnvironment(XMBElement parent)
EL(height); EL(height);
EL(shininess); EL(shininess);
EL(waviness); EL(waviness);
EL(murkiness);
EL(tint);
EL(reflectiontint);
EL(reflectiontintstrength);
AT(r); AT(g); AT(b); AT(r); AT(g); AT(b);
#undef AT #undef AT
#undef EL #undef EL
@ -458,27 +462,36 @@ void CXMLReader::ReadEnvironment(XMBElement parent)
{ {
// TODO: implement this, when WaterManager supports it // TODO: implement this, when WaterManager supports it
} }
else if (element_name == el_colour)
{ #define READ_COLOUR(el, out) \
XMBAttributeList attrs = waterelement.getAttributes(); else if (element_name == el) \
m_MapReader.pWaterMan->m_WaterColor = CColor( { \
CStr(attrs.getNamedItem(at_r)).ToFloat(), XMBAttributeList attrs = waterelement.getAttributes(); \
CStr(attrs.getNamedItem(at_g)).ToFloat(), out = CColor( \
CStr(attrs.getNamedItem(at_b)).ToFloat(), CStr(attrs.getNamedItem(at_r)).ToFloat(), \
1.f); CStr(attrs.getNamedItem(at_g)).ToFloat(), \
} CStr(attrs.getNamedItem(at_b)).ToFloat(), \
else if (element_name == el_height) 1.f); \
{
m_MapReader.pWaterMan->m_WaterHeight = CStr(waterelement.getText()).ToFloat();
}
else if (element_name == el_shininess)
{
m_MapReader.pWaterMan->m_Shininess = CStr(waterelement.getText()).ToFloat();
}
else if (element_name == el_waviness)
{
m_MapReader.pWaterMan->m_Waviness = CStr(waterelement.getText()).ToFloat();
} }
#define READ_FLOAT(el, out) \
else if (element_name == el) \
{ \
out = CStr(waterelement.getText()).ToFloat(); \
} \
READ_COLOUR(el_colour, m_MapReader.pWaterMan->m_WaterColor)
READ_FLOAT(el_height, m_MapReader.pWaterMan->m_WaterHeight)
READ_FLOAT(el_shininess, m_MapReader.pWaterMan->m_Shininess)
READ_FLOAT(el_waviness, m_MapReader.pWaterMan->m_Waviness)
READ_FLOAT(el_murkiness, m_MapReader.pWaterMan->m_Murkiness)
READ_COLOUR(el_tint, m_MapReader.pWaterMan->m_WaterTint)
READ_COLOUR(el_reflectiontint, m_MapReader.pWaterMan->m_ReflectionTint)
READ_FLOAT(el_reflectiontintstrength, m_MapReader.pWaterMan->m_ReflectionTintStrength)
#undef READ_FLOAT
#undef READ_COLOUR
else else
debug_warn("Invalid map XML data"); debug_warn("Invalid map XML data");
} }

View File

@ -219,6 +219,20 @@ void CMapWriter::WriteXML(const char* filename,
XML_Setting("Height", pWaterMan->m_WaterHeight); XML_Setting("Height", pWaterMan->m_WaterHeight);
XML_Setting("Shininess", pWaterMan->m_Shininess); XML_Setting("Shininess", pWaterMan->m_Shininess);
XML_Setting("Waviness", pWaterMan->m_Waviness); XML_Setting("Waviness", pWaterMan->m_Waviness);
XML_Setting("Murkiness", pWaterMan->m_Murkiness);
{
XML_Element("Tint");
XML_Attribute("r", pWaterMan->m_WaterTint.r);
XML_Attribute("g", pWaterMan->m_WaterTint.g);
XML_Attribute("b", pWaterMan->m_WaterTint.b);
}
{
XML_Element("ReflectionTint");
XML_Attribute("r", pWaterMan->m_ReflectionTint.r);
XML_Attribute("g", pWaterMan->m_ReflectionTint.g);
XML_Attribute("b", pWaterMan->m_ReflectionTint.b);
}
XML_Setting("ReflectionTintStrength", pWaterMan->m_ReflectionTintStrength);
} }
} }
} }

View File

@ -14,14 +14,26 @@ static Observable<AtlasMessage::sEnvironmentSettings> g_EnvironmentSettings;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
class VariableSlider : public wxSlider class VariableSliderBox : public wxPanel
{ {
static const int range = 1024; static const int range = 1024;
public: public:
VariableSlider(wxWindow* parent, Shareable<float>& var, ObservableConnection& conn, float min, float max) VariableSliderBox(wxWindow* parent, const wxString& label, Shareable<float>& var, float min, float max)
: wxSlider(parent, wxID_ANY, 0, 0, range), : wxPanel(parent),
m_Var(var), m_Conn(conn), m_Min(min), m_Max(max) m_Var(var), m_Min(min), m_Max(max)
{ {
m_Conn = g_EnvironmentSettings.RegisterObserver(0, &VariableSliderBox::OnSettingsChange, this);
m_Sizer = new wxStaticBoxSizer(wxVERTICAL, this, label);
SetSizer(m_Sizer);
m_Slider = new wxSlider(this, -1, 0, 0, range);
m_Sizer->Add(m_Slider, wxSizerFlags().Expand());
}
void OnSettingsChange(const AtlasMessage::sEnvironmentSettings& WXUNUSED(env))
{
m_Slider->SetValue((m_Var - m_Min) * (range / (m_Max - m_Min)));
} }
void OnScroll(wxScrollEvent& evt) void OnScroll(wxScrollEvent& evt)
@ -31,90 +43,36 @@ public:
g_EnvironmentSettings.NotifyObserversExcept(m_Conn); g_EnvironmentSettings.NotifyObserversExcept(m_Conn);
} }
void UpdateFromVar()
{
SetValue((m_Var - m_Min) * (range / (m_Max - m_Min)));
}
private: private:
ObservableScopedConnection m_Conn;
wxStaticBoxSizer* m_Sizer;
wxSlider* m_Slider;
Shareable<float>& m_Var; Shareable<float>& m_Var;
ObservableConnection& m_Conn;
float m_Min, m_Max; float m_Min, m_Max;
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
}; };
BEGIN_EVENT_TABLE(VariableSlider, wxSlider) BEGIN_EVENT_TABLE(VariableSliderBox, wxPanel)
EVT_SCROLL(OnScroll) EVT_SCROLL(OnScroll)
END_EVENT_TABLE() END_EVENT_TABLE()
class VariableSliderBox : public wxStaticBoxSizer
{
public:
VariableSliderBox(wxWindow* parent, const wxString& label, Shareable<float>& var, float min, float max)
: wxStaticBoxSizer(wxVERTICAL, parent, label)
{
m_Conn = g_EnvironmentSettings.RegisterObserver(0, &VariableSliderBox::OnSettingsChange, this);
m_Slider = new VariableSlider(parent, var, m_Conn, min, max);
Add(m_Slider);
}
void OnSettingsChange(const AtlasMessage::sEnvironmentSettings& WXUNUSED(env))
{
m_Slider->UpdateFromVar();
}
private:
ObservableScopedConnection m_Conn;
VariableSlider* m_Slider;
};
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
class VariableCombo : public wxComboBox class VariableListBox : public wxPanel
{
static const int range = 1024;
public:
VariableCombo(wxWindow* parent, Shareable<std::wstring>& var, ObservableConnection& conn)
: wxComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY),
m_Var(var), m_Conn(conn)
{
}
void OnSelect(wxCommandEvent& WXUNUSED(evt))
{
m_Var = std::wstring(GetValue().c_str());
g_EnvironmentSettings.NotifyObserversExcept(m_Conn);
}
void UpdateFromVar()
{
SetValue(m_Var.c_str());
}
private:
Shareable<std::wstring>& m_Var;
ObservableConnection& m_Conn;
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(VariableCombo, wxComboBox)
EVT_COMBOBOX(wxID_ANY, OnSelect)
END_EVENT_TABLE()
class VariableListBox : public wxStaticBoxSizer
{ {
public: public:
VariableListBox(wxWindow* parent, const wxString& label, Shareable<std::wstring>& var) VariableListBox(wxWindow* parent, const wxString& label, Shareable<std::wstring>& var)
: wxStaticBoxSizer(wxVERTICAL, parent, label) : wxPanel(parent),
m_Var(var)
{ {
m_Conn = g_EnvironmentSettings.RegisterObserver(0, &VariableListBox::OnSettingsChange, this); m_Conn = g_EnvironmentSettings.RegisterObserver(0, &VariableListBox::OnSettingsChange, this);
m_Combo = new VariableCombo(parent, var, m_Conn); m_Sizer = new wxStaticBoxSizer(wxVERTICAL, this, label);
Add(m_Combo); SetSizer(m_Sizer);
m_Combo = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_READONLY),
m_Sizer->Add(m_Combo, wxSizerFlags().Expand());
} }
void SetChoices(const std::vector<std::wstring>& choices) void SetChoices(const std::vector<std::wstring>& choices)
@ -126,90 +84,98 @@ public:
m_Combo->Clear(); m_Combo->Clear();
m_Combo->Append(choices_arraystr); m_Combo->Append(choices_arraystr);
m_Combo->UpdateFromVar(); m_Combo->SetValue(m_Var.c_str());
} }
void OnSettingsChange(const AtlasMessage::sEnvironmentSettings& WXUNUSED(env)) void OnSettingsChange(const AtlasMessage::sEnvironmentSettings& WXUNUSED(env))
{ {
m_Combo->UpdateFromVar(); m_Combo->SetValue(m_Var.c_str());
}
void OnSelect(wxCommandEvent& WXUNUSED(evt))
{
m_Var = std::wstring(m_Combo->GetValue().c_str());
g_EnvironmentSettings.NotifyObserversExcept(m_Conn);
} }
private: private:
ObservableScopedConnection m_Conn; ObservableScopedConnection m_Conn;
VariableCombo* m_Combo; wxStaticBoxSizer* m_Sizer;
wxComboBox* m_Combo;
Shareable<std::wstring>& m_Var;
DECLARE_EVENT_TABLE();
}; };
BEGIN_EVENT_TABLE(VariableListBox, wxPanel)
EVT_COMBOBOX(wxID_ANY, OnSelect)
END_EVENT_TABLE()
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
class VariableColourButton : public wxButton class VariableColourBox : public wxPanel
{ {
public: public:
VariableColourButton(wxWindow* parent, Shareable<AtlasMessage::Colour>& colour, ObservableConnection& conn) VariableColourBox(wxWindow* parent, const wxString& label, Shareable<AtlasMessage::Colour>& colour)
: wxButton(parent, wxID_ANY), m_Colour(colour), m_Conn(conn) : wxPanel(parent),
m_Colour(colour)
{ {
UpdateDisplay(); m_Conn = g_EnvironmentSettings.RegisterObserver(0, &VariableColourBox::OnSettingsChange, this);
m_Sizer = new wxStaticBoxSizer(wxVERTICAL, this, label);
SetSizer(m_Sizer);
m_Button = new wxButton(this, -1);
m_Sizer->Add(m_Button, wxSizerFlags().Expand());
}
void OnSettingsChange(const AtlasMessage::sEnvironmentSettings& WXUNUSED(env))
{
UpdateButton();
} }
void OnClick(wxCommandEvent& WXUNUSED(evt)) void OnClick(wxCommandEvent& WXUNUSED(evt))
{ {
ColourDialog dlg (NULL, _T("Scenario Editor/LightingColour"), ColourDialog dlg (this, _T("Scenario Editor/LightingColour"),
wxColour(m_Colour->r, m_Colour->g, m_Colour->b)); wxColour(m_Colour->r, m_Colour->g, m_Colour->b));
if (dlg.ShowModal() == wxID_OK) if (dlg.ShowModal() == wxID_OK)
{ {
wxColour& c = dlg.GetColourData().GetColour(); wxColour& c = dlg.GetColourData().GetColour();
m_Colour = AtlasMessage::Colour(c.Red(), c.Green(), c.Blue()); m_Colour = AtlasMessage::Colour(c.Red(), c.Green(), c.Blue());
UpdateDisplay(); UpdateButton();
g_EnvironmentSettings.NotifyObserversExcept(m_Conn); g_EnvironmentSettings.NotifyObserversExcept(m_Conn);
} }
} }
void UpdateDisplay() void UpdateButton()
{ {
SetBackgroundColour(wxColour(m_Colour->r, m_Colour->g, m_Colour->b)); m_Button->SetBackgroundColour(wxColour(m_Colour->r, m_Colour->g, m_Colour->b));
SetLabel(wxString::Format(_T("%02X %02X %02X"), m_Colour->r, m_Colour->g, m_Colour->b)); m_Button->SetLabel(wxString::Format(_T("%02X %02X %02X"), m_Colour->r, m_Colour->g, m_Colour->b));
int y = 3*m_Colour->r + 6*m_Colour->g + 1*m_Colour->b; int y = 3*m_Colour->r + 6*m_Colour->g + 1*m_Colour->b;
if (y > 1280) if (y > 1280)
SetForegroundColour(wxColour(0, 0, 0)); m_Button->SetForegroundColour(wxColour(0, 0, 0));
else else
SetForegroundColour(wxColour(255, 255, 255)); m_Button->SetForegroundColour(wxColour(255, 255, 255));
} }
private: private:
ObservableScopedConnection m_Conn;
wxStaticBoxSizer* m_Sizer;
wxButton* m_Button;
Shareable<AtlasMessage::Colour>& m_Colour; Shareable<AtlasMessage::Colour>& m_Colour;
ObservableConnection& m_Conn;
DECLARE_EVENT_TABLE(); DECLARE_EVENT_TABLE();
}; };
BEGIN_EVENT_TABLE(VariableColourButton, wxButton) BEGIN_EVENT_TABLE(VariableColourBox, wxPanel)
EVT_BUTTON(wxID_ANY, OnClick) EVT_BUTTON(wxID_ANY, OnClick)
END_EVENT_TABLE() END_EVENT_TABLE()
class VariableColourBox : public wxStaticBoxSizer
{
public:
VariableColourBox(wxWindow* parent, const wxString& label, Shareable<AtlasMessage::Colour>& colour)
: wxStaticBoxSizer(wxVERTICAL, parent, label)
{
m_Conn = g_EnvironmentSettings.RegisterObserver(0, &VariableColourBox::OnSettingsChange, this);
m_Button = new VariableColourButton(parent, colour, m_Conn);
Add(m_Button);
}
void OnSettingsChange(const AtlasMessage::sEnvironmentSettings& WXUNUSED(env))
{
m_Button->UpdateDisplay();
}
private:
ObservableScopedConnection m_Conn;
VariableColourButton* m_Button;
};
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static void SendToGame(const AtlasMessage::sEnvironmentSettings& settings) static void SendToGame(const AtlasMessage::sEnvironmentSettings& settings)
@ -220,11 +186,27 @@ static void SendToGame(const AtlasMessage::sEnvironmentSettings& settings)
EnvironmentSidebar::EnvironmentSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer) EnvironmentSidebar::EnvironmentSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer)
: Sidebar(sidebarContainer, bottomBarContainer) : Sidebar(sidebarContainer, bottomBarContainer)
{ {
m_MainSizer->Add(new VariableSliderBox(this, _("Water height"), g_EnvironmentSettings.waterheight, 0, 1.2f)); wxSizer* waterSizer = new wxGridSizer(2);
m_MainSizer->Add(new VariableSliderBox(this, _("Water shininess"), g_EnvironmentSettings.watershininess, 0, 500.f)); m_MainSizer->Add(waterSizer, wxSizerFlags().Expand());
m_MainSizer->Add(new VariableSliderBox(this, _("Water waviness"), g_EnvironmentSettings.waterwaviness, 0, 10.f));
m_MainSizer->Add(new VariableSliderBox(this, _("Sun rotation"), g_EnvironmentSettings.sunrotation, -M_PI, M_PI)); waterSizer->Add(new VariableSliderBox(this, _("Water height"), g_EnvironmentSettings.waterheight, 0.f, 1.2f), wxSizerFlags().Expand());
m_MainSizer->Add(new VariableSliderBox(this, _("Sun elevation"), g_EnvironmentSettings.sunelevation, -M_PI/2, M_PI/2)); waterSizer->Add(new VariableSliderBox(this, _("Water shininess"), g_EnvironmentSettings.watershininess, 0.f, 500.f), wxSizerFlags().Expand());
waterSizer->Add(new VariableSliderBox(this, _("Water waviness"), g_EnvironmentSettings.waterwaviness, 0.f, 10.f), wxSizerFlags().Expand());
waterSizer->Add(new VariableSliderBox(this, _("Water murkiness"), g_EnvironmentSettings.watermurkiness, 0.f, 1.f), wxSizerFlags().Expand());
waterSizer->Add(new VariableColourBox(this, _("Water colour"), g_EnvironmentSettings.watercolour), wxSizerFlags().Expand());
waterSizer->Add(new VariableColourBox(this, _("Water tint"), g_EnvironmentSettings.watertint), wxSizerFlags().Expand());
waterSizer->Add(new VariableColourBox(this, _("Reflection tint"), g_EnvironmentSettings.waterreflectiontint), wxSizerFlags().Expand());
waterSizer->Add(new VariableSliderBox(this, _("Refl. tint strength"), g_EnvironmentSettings.waterreflectiontintstrength, 0.f, 1.f), wxSizerFlags().Expand());
wxSizer* sunSizer = new wxGridSizer(2);
m_MainSizer->Add(sunSizer, wxSizerFlags().Expand().Border(wxTOP, 8));
sunSizer->Add(new VariableSliderBox(this, _("Sun rotation"), g_EnvironmentSettings.sunrotation, -M_PI, M_PI), wxSizerFlags().Expand());
sunSizer->Add(new VariableSliderBox(this, _("Sun elevation"), g_EnvironmentSettings.sunelevation, -M_PI/2, M_PI/2), wxSizerFlags().Expand());
m_MainSizer->Add(new LightControl(this, wxSize(150, 150), g_EnvironmentSettings)); m_MainSizer->Add(new LightControl(this, wxSize(150, 150), g_EnvironmentSettings));
m_MainSizer->Add(m_SkyList = new VariableListBox(this, _("Sky set"), g_EnvironmentSettings.skyset)); m_MainSizer->Add(m_SkyList = new VariableListBox(this, _("Sky set"), g_EnvironmentSettings.skyset));
m_MainSizer->Add(new VariableColourBox(this, _("Sun colour"), g_EnvironmentSettings.suncolour)); m_MainSizer->Add(new VariableColourBox(this, _("Sun colour"), g_EnvironmentSettings.suncolour));

View File

@ -22,6 +22,14 @@ sEnvironmentSettings GetSettings()
s.waterheight = wm->m_WaterHeight / (65536.f * HEIGHT_SCALE); s.waterheight = wm->m_WaterHeight / (65536.f * HEIGHT_SCALE);
s.watershininess = wm->m_Shininess; s.watershininess = wm->m_Shininess;
s.waterwaviness = wm->m_Waviness; s.waterwaviness = wm->m_Waviness;
s.watermurkiness = wm->m_Murkiness;
s.waterreflectiontintstrength = wm->m_ReflectionTintStrength;
#define COLOUR(A, B) A = Colour(B.r*255, B.g*255, B.b*255)
COLOUR(s.watercolour, wm->m_WaterColor);
COLOUR(s.watertint, wm->m_WaterTint);
COLOUR(s.waterreflectiontint, wm->m_ReflectionTint);
#undef COLOUR
float sunrotation = g_LightEnv.GetRotation(); float sunrotation = g_LightEnv.GetRotation();
if (sunrotation > PI) if (sunrotation > PI)
@ -46,6 +54,14 @@ void SetSettings(const sEnvironmentSettings& s)
wm->m_WaterHeight = s.waterheight * (65536.f * HEIGHT_SCALE); wm->m_WaterHeight = s.waterheight * (65536.f * HEIGHT_SCALE);
wm->m_Shininess = s.watershininess; wm->m_Shininess = s.watershininess;
wm->m_Waviness = s.waterwaviness; wm->m_Waviness = s.waterwaviness;
wm->m_Murkiness = s.watermurkiness;
wm->m_ReflectionTintStrength = s.waterreflectiontintstrength;
#define COLOUR(A, B) B = CColor(A->r/255.f, A->g/255.f, A->b/255.f, 1.f)
COLOUR(s.watercolour, wm->m_WaterColor);
COLOUR(s.watertint, wm->m_WaterTint);
COLOUR(s.waterreflectiontint, wm->m_ReflectionTint);
#undef COLOUR
g_LightEnv.SetRotation(s.sunrotation); g_LightEnv.SetRotation(s.sunrotation);
g_LightEnv.SetElevation(s.sunelevation); g_LightEnv.SetElevation(s.sunelevation);

View File

@ -200,8 +200,14 @@ MESSAGE(LookAt,
struct sEnvironmentSettings struct sEnvironmentSettings
{ {
Shareable<float> waterheight; // range 0..1 corresponds to min..max terrain height; out-of-bounds values allowed Shareable<float> waterheight; // range 0..1 corresponds to min..max terrain height; out-of-bounds values allowed
Shareable<float> watershininess; Shareable<float> watershininess; // range ???
Shareable<float> waterwaviness; Shareable<float> waterwaviness; // range ???
Shareable<float> watermurkiness; // range ???
Shareable<Colour> watercolour;
Shareable<Colour> watertint;
Shareable<Colour> waterreflectiontint;
Shareable<float> waterreflectiontintstrength; // range ???
Shareable<float> sunrotation; // range -pi..+pi Shareable<float> sunrotation; // range -pi..+pi
Shareable<float> sunelevation; // range -pi/2 .. +pi/2 Shareable<float> sunelevation; // range -pi/2 .. +pi/2