Delta time
Delta time is a time for one iteration of main loop.
Add `float m_deltaTime = 0.f;` in slFrameworkImpl
Add `static float* GetDeltaTime();` in slFramework and return pointer.
Calculate delta time in `void slFramework::Update()`
static clock_t then = 0;
clock_t now = clock();
g_framework->m_deltaTime = (float)(now - then) / CLOCKS_PER_SEC;
then = now;
Log
Framework should be able to write some information, warnings, errors.
class slLog
{
public:
static void Print(const char* s, ...);
static void Print(const wchar_t* s, ...);
static void PrintInfo(const char* s, ...);
static void PrintInfo(const wchar_t* s, ...);
static void PrintWarning(const char* s, ...);
static void PrintWarning(const wchar_t* s, ...);
static void PrintError(const char* s, ...);
static void PrintError(const wchar_t* s, ...);
static void SetCallbackA(void(*)(const char*));
static void SetCallbackW(void(*)(const wchar_t*));
};
In implementation I use other class.
static slLogImpl g_log;
void slLog::Print(const char* s, ...)
{
va_list vl;
va_start(vl, s);
g_log.vprintf(s, vl);
va_end(vl);
}
void slLog::PrintInfo(const char* s, ...)
{
Print("%s", "Info: ");
va_list vl;
va_start(vl, s);
g_log.vprintf(s, vl);
va_end(vl);
}
Class.
class slLogImpl
{
public:
slLogImpl()
{
m_cba = slLogDefaultCallbackA;
m_cbw = slLogDefaultCallbackW;
}
void vprintf(const char* s, va_list vl);
void vwprintf(const wchar_t* s, va_list vl);
void(*m_cba)(const char*);
void(*m_cbw)(const wchar_t*);
};
void slLogImpl::vprintf(const char* s, va_list vl)
{
char buffer[1002];
vsnprintf_s(buffer, 1002, s, vl);
m_cba(buffer);
}
void slLogImpl::vwprintf(const wchar_t* s, va_list vl)
{
wchar_t buffer[1002];
vswprintf_s(buffer, 1002, s, vl);
m_cbw(buffer);
}
Default print functions
void slLogDefaultCallbackA(const char* s)
{
printf(s);
}
void slLogDefaultCallbackW(const wchar_t* s)
{
wprintf(s);
}
Also I changed code in assert and stacktracer. Now they use slLog.
Math
Another static class.
It will have even functions like `cross` or `dot` for vectors, so I don't need
to add them in vector classes.
In this class I will add all other functions, like for matrices and other things.
Another thing is I use precomputed values for some functions:
// Expect value form -1 to +1
static float acos(float);
// Expect value form -1 to +1
static float asin(float);
// Expect value form -2 to +2
static float atan(float);
// Expect value form -1 to +1
static float atan2(float y, float x);
// Expect value from -PI to +PI
static float cos(float);
static float sin(float);
static float tan(float);
And there is double versions too.
Implemetation for `cos`
float slMath::cos(float v)
{
if (v < -3.141f) v = -3.141f;
if (v < 0.f) v = slMath::abs(v);
if (v > 3.141f) v = 3.141f;
uint32_t ind = (uint32_t)roundf(v * 1000.0f);
if(ind < 3143)
return g_cosf[ind];
return 0;
}
User must provide right values.
g_cosf is an array
static float g_cosf[] = {
#include "cosf.inl"
};
cosf.inl is a file with numbers.
Vector
4 versions. 2 xyz, 2 xyzw. float and double
I will use only like `operator+`. All functions must be in slMath.
class slVec3
{
public:
slVec3();
slVec3(double x, double y, double z);
slVec3(float v);
slVec3(double v);
slVec3(int32_t v);
slVec3(const slVec3&);
slVec3(const slVec3f&);
slVec3(const slVec4&);
slVec3(const slVec4f&);
double operator[](uint32_t index) const;
double& operator[](uint32_t index);
slVec3 operator+(const slVec3& v)const;
slVec3 operator+(const slVec3f& v)const;
slVec3 operator+(const slVec4& v)const;
slVec3 operator+(const slVec4f& v)const;
slVec3 operator-(const slVec3& v)const;
slVec3 operator-(const slVec3f& v)const;
slVec3 operator-(const slVec4& v)const;
slVec3 operator-(const slVec4f& v)const;
slVec3 operator*(const slVec3& v)const;
slVec3 operator*(const slVec3f& v)const;
slVec3 operator*(const slVec4& v)const;
slVec3 operator*(const slVec4f& v)const;
slVec3 operator/(const slVec3& v)const;
slVec3 operator/(const slVec3f& v)const;
slVec3 operator/(const slVec4& v)const;
slVec3 operator/(const slVec4f& v)const;
slVec3 operator-()const;
slVec3& operator=(const slVec3& v);
slVec3& operator=(const slVec3f& v);
slVec3& operator=(const slVec4& v);
slVec3& operator=(const slVec4f& v);
bool operator==(const slVec3& v)const;
bool operator!=(const slVec3& v)const;
double x = 0.0;
double y = 0.0;
double z = 0.0;
double* data() { return &x; }
};
For example `cross` method (in slMath)
void slMath::cross(const slVec3& v1, const slVec3& v2, slVec3& r)
{
r.x = (v1.y * v2.z) - (v1.z * v2.y);
r.y = (v1.z * v2.x) - (v1.x * v2.z);
r.z = (v1.x * v2.y) - (v1.y * v2.x);
}
Other things
In window I added
void ToFullscreenMode();
void ToWindowMode();
New data for this
slPoint m_currentSize;
slPoint m_creationSize;
slPoint m_sizePreFullscreen;
bool m_isFullscreen = false;
.....
//slWindowWin32
LONG m_stylePreFullscreen = 0;
WINDOWPLACEMENT m_wndPlcmnt;
Implementation
void slWindow::ToFullscreenMode()
{
SL_ASSERT_ST(m_data.m_implementation);
if (m_data.m_isFullscreen)
return;
#ifdef SL_PLATFORM_WINDOWS
slWindowWin32* w32 = (slWindowWin32*)m_data.m_implementation;
w32->m_stylePreFullscreen = GetWindowLong(w32->m_hWnd, GWL_STYLE);
MONITORINFO mi = { sizeof(mi) };
if (GetWindowPlacement(w32->m_hWnd, &w32->m_wndPlcmnt) &&
GetMonitorInfo(MonitorFromWindow(w32->m_hWnd, MONITOR_DEFAULTTOPRIMARY), &mi))
{
m_data.m_sizePreFullscreen = m_data.m_currentSize;
m_data.m_currentSize.x = mi.rcMonitor.right - mi.rcMonitor.left;
m_data.m_currentSize.y = mi.rcMonitor.bottom - mi.rcMonitor.top;
// _set_current_rect();
SetWindowLong(w32->m_hWnd, GWL_STYLE, WS_POPUP);
SetWindowPos(w32->m_hWnd, HWND_TOP,
mi.rcMonitor.left, mi.rcMonitor.top,
mi.rcMonitor.right - mi.rcMonitor.left,
mi.rcMonitor.bottom - mi.rcMonitor.top,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
m_data.m_isFullscreen = true;
ShowWindow(w32->m_hWnd, SW_NORMAL);
}
#endif
}
void slWindow::ToWindowMode()
{
SL_ASSERT_ST(m_data.m_implementation);
if (!m_data.m_isFullscreen)
return;
#ifdef SL_PLATFORM_WINDOWS
slWindowWin32* w32 = (slWindowWin32*)m_data.m_implementation;
SetWindowLong(w32->m_hWnd, GWL_STYLE, w32->m_stylePreFullscreen);
m_data.m_currentSize = m_data.m_sizePreFullscreen;
// _set_current_rect();
SetWindowPlacement(w32->m_hWnd, &w32->m_wndPlcmnt);
SetWindowPos(w32->m_hWnd, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
m_data.m_isFullscreen = false;
ShowWindow(w32->m_hWnd, SW_NORMAL);
#endif
}
Download code
Please enable JavaScript to view the comments powered by Disqus.