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:
static float acos (float ) ;
static float asin (float ) ;
static float atan (float ) ;
static float atan2 (float y, float x) ;
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 ;
.....
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;
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;
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.