#include "Main.h"
float SphereFunction(const Vec3f &Pos)
{
return Pos.x * Pos.x + Pos.y * Pos.y + Pos.z * Pos.z - 1.0f;
}
float RandomFunction(const Vec3f &Pos)
{
Vec3f P = Pos * 10.0f;
return sinf(P.Length()) * P.x + sinf(P.Length()) * P.y;
}
float CrazyFunction(const Vec3f &Pos)
{
Vec3f P = Pos * 3.0f;
return sinf(P.x * P.y + P.x * P.z + P.y * P.z) + sinf(P.x * P.y) + sinf(P.y * P.z) + sinf(P.x * P.z) - 1.0f;
}
enum MenuEntryType
{
MenuEntryFile,
MenuEntryFileQuit,
};
void Controller::FreeMemory()
{
ReleaseAssets();
}
void Controller::InitMenu()
{
_menu.Init(_state->window);
Menu &FileMenu = _menu.MenuBar().AddSubMenu(_state->window, MenuEntryFile, "File");
FileMenu.AddString(_state->window, MenuEntryFileQuit, "Quit\tCtrl+Q");
}
void Controller::ProcessEvents()
{
_menu.DispatchKeyboardShortcuts(_state->input);
while(_state->input.EventPresent())
{
InputEvent CurEvent = _state->input.PopEvent();
if(CurEvent.Type == InputEventMenu)
{
switch(CurEvent.Id)
{
case MenuEntryFileQuit:
PostQuitMessage(0);
break;
}
}
}
}
void Controller::ResetCamera()
{
_camera.Reset(Vec3f(2.0f, 0.0f, 5.0f), Vec3f::eZ, Vec3f::Origin);
}
void Controller::ReleaseAssets()
{
for(UINT assetIndex = 0; assetIndex < _assetList.Length(); assetIndex++)
{
_assetList[assetIndex]->ReleaseMemory();
}
}
void Controller::ResetAssets()
{
for(UINT assetIndex = 0; assetIndex < _assetList.Length(); assetIndex++)
{
_assetList[assetIndex]->Reset(*_state->graphics);
}
ReloadTextures();
}
void Controller::ReSize()
{
_projection = Matrix4::PerspectiveFov(
60.0f * Math::PIf / 180.0f,
_state->window.AspectRatio(),
0.01f,
200.0f);
}
void Controller::UpdateIsoSurface()
{
IsoSurface surfaceGenerator;
surfaceGenerator.IsoApproximate(1.25f, 0.025f, _assets.surface, _functions[_functionIndex]);
}
void Controller::Init(AppState &state)
{
_state = &state;
AllocConsole();
InitMenu();
}
void Controller::Init3D()
{
InitAssets();
ResetCamera();
_functionIndex = 2;
_functions[0] = SphereFunction;
_functions[1] = RandomFunction;
_functions[2] = CrazyFunction;
UpdateIsoSurface();
}
void Controller::InitAssets()
{
_assets.surface.SetGD(*_state->graphics);
_assets.font.Init(*_state->graphics, "Verdana", 20, FW_BOLD);
_assets.psBase.Init(*_state->graphics, "Assets\\NormalColor.ps");
_assets.vsBase.Init(*_state->graphics, "Assets\\NormalColor.vs");
_assetList.PushEnd(&_assets.font);
_assetList.PushEnd(&_assets.psBase);
_assetList.PushEnd(&_assets.vsBase);
ReloadTextures();
}
void Controller::ReloadTextures()
{
Bitmap white(2, 2);
white.Clear(RGBColor::White);
}
void Controller::UpdateCamera()
{
_camera.KeyboardWASD (_state->input, _state->timer.SPF() * 5.0f);
_camera.KeyboardNumpad(_state->input, _state->timer.SPF());
_camera.Update();
}
void Controller::ProcessKeyboardInput()
{
if(_state->input.KeyCheckOnce(KEY_F))
{
_state->graphics->ToggleWireframe();
}
if(_state->input.KeyCheckOnce(KEY_1))
{
_functionIndex = 0;
UpdateIsoSurface();
}
if(_state->input.KeyCheckOnce(KEY_2))
{
_functionIndex = 1;
UpdateIsoSurface();
}
if(_state->input.KeyCheckOnce(KEY_3))
{
_functionIndex = 2;
UpdateIsoSurface();
}
}
void Controller::Status(const String &s, RGBColor c)
{
_assets.font.DrawString(s, Vec2i(2, _consoleY), c);
_consoleY += 20;
}
void Controller::StatusText()
{
_consoleY = 2;
Status(String("FPS: ") + String(_state->timer.FPS()), RGBColor::Red);
Status(String("Function ") + String(_functionIndex + 1) + " / " + String(FunctionCount) + String(" (use number keys to switch functions)"), RGBColor::Yellow);
}
void Controller::Render()
{
_assets.vsBase.Set();
_assets.psBase.Set();
Matrix4 viewProj = _camera.Matrix() * _projection;
_assets.vsBase.SetMatrix("WorldViewProj", viewProj);
_assets.vsBase.SetMatrix("World", Matrix4::Identity());
_assets.surface.Render();
}
void Controller::Frame()
{
ProcessKeyboardInput();
ProcessEvents();
UpdateCamera();
Render();
StatusText();
}