4coder/test_data/lots_of_files/jam_rendering_win32.cpp

219 lines
6.6 KiB
C++

/*
* Overreact - Mr. 4th Dimention
* Allen Webster
* 03.21.2015 (mm.dd.yyyy)
*
* Win32 Rendering System Layer.
*/
#define SIG_STARTUP(name) void(name)(Win32RenderingVars *render_vars)
#define SIG_SHUTDOWN(name) void(name)(Win32RenderingVars *render_vars)
#define SIG_REDRAW(name) void(name)(Win32RenderingVars *render_vars)
#define SIG_SET_SIZE(name) void(name)(Win32RenderingVars *render_vars, i32 port_width, i32 port_height, i32 view_width, i32 view_height)
#define SIG_GET_RENDER_TARGET(name) Game_Render_Target(name)(Win32RenderingVars *render_vars)
#if RENDER_MODE == SOFTWARE
struct Win32RenderingVars{
HDC hdc;
BITMAPINFO bmp_info;
i32 width, height, pitch;
i32 pixel_data_size;
void *pixel_data;
};
internal
SIG_STARTUP(render_startup){}
internal
SIG_SHUTDOWN(render_shutdown){}
internal
SIG_REDRAW(render_redraw_screen){
render_vars->bmp_info.bmiHeader.biHeight =
-render_vars->bmp_info.bmiHeader.biHeight;
SetDIBitsToDevice(render_vars->hdc, 0, 0,
render_vars->width, render_vars->height,
0, 0,
0, render_vars->height,
render_vars->pixel_data,
&render_vars->bmp_info,
DIB_RGB_COLORS);
render_vars->bmp_info.bmiHeader.biHeight =
-render_vars->bmp_info.bmiHeader.biHeight;
}
// TODO(allen): This version ignores view / port ratio. It simply resize
// to the dimensions of the port and the game will render in the top
// left leaving the rest of the window ignored. Either implement
// software stretching, or at least center the view like the original Push.
internal
SIG_SET_SIZE(render_set_screen_size){
render_vars->width = port_width;
render_vars->height = port_height;
render_vars->pitch = port_width*4;
render_vars->bmp_info = {};
BITMAPINFOHEADER bmi_header = {};
bmi_header.biSize = sizeof(BITMAPINFOHEADER);
bmi_header.biWidth = render_vars->width;
bmi_header.biHeight = render_vars->height;
bmi_header.biPlanes = 1;
bmi_header.biBitCount = 32;
bmi_header.biCompression = BI_RGB;
render_vars->bmp_info.bmiHeader = bmi_header;
// TODO(allen): Bulletproof this.
i32 new_size = port_height*port_width*4;
if (new_size > render_vars->pixel_data_size){
if (render_vars->pixel_data){
VirtualFree(render_vars->pixel_data,
0, MEM_RELEASE);
}
render_vars->pixel_data_size = new_size;
render_vars->pixel_data =
VirtualAlloc(0, height*width*4,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!render_vars->pixel_data){
WINERROR("Failed to setup window pixel memory");
}
}
}
SIG_GET_RENDER_TARGET(render_get_render_target){
Game_Render_Target render;
render.pixels = (u8*)render_vars->pixel_data;
render.width = render_vars->width;
render.height = render_vars->height;
render.pitch = render_vars->pitch;
return render;
}
#elif RENDER_MODE == OPENGL
struct Win32RenderingVars{
HDC hdc;
HGLRC context;
i32 width, height;
};
internal
SIG_STARTUP(render_startup){
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), //size of structure
1, //default version
PFD_DRAW_TO_WINDOW | //window drawing support
PFD_SUPPORT_OPENGL | //opengl support
PFD_DOUBLEBUFFER, //double buffering support
PFD_TYPE_RGBA, //RGBA color mode
32, //32 bit color mode
0, 0, 0, 0, 0, 0, //ignore color bits
0, //no alpha buffer
0, //ignore shift bit
0, //no accumulation buffer
0, 0, 0, 0, //ignore accumulation bits
16, //16 bit z-buffer size
0, //no stencil buffer
0, //no aux buffer
PFD_MAIN_PLANE, //main drawing plane
0, //reserved
0, 0, 0 }; //layer masks ignored
nPixelFormat = ChoosePixelFormat(render_vars->hdc, &pfd);
SetPixelFormat(render_vars->hdc, nPixelFormat, &pfd);
render_vars->context = wglCreateContext(render_vars->hdc);
wglMakeCurrent(render_vars->hdc, render_vars->context);
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
//glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLenum error;
error = glGetError();
error = error;
}
internal
SIG_SHUTDOWN(render_shutdown){
wglMakeCurrent(render_vars->hdc, 0);
wglDeleteContext(render_vars->context);
}
internal
SIG_REDRAW(render_redraw_screen){
glFlush();
SwapBuffers(render_vars->hdc);
}
// NOTE(allen): This changes the aspect ratio of the view to perfectly
// fill the window. The height is untouched, the width is the only part
// of the view that is effected.
internal
SIG_SET_SIZE(render_set_screen_size){
render_vars->height = view_height;
render_vars->width = (i32)((port_width / ((real32)port_height)) * view_height);
glViewport(0, 0, port_width, port_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.f, render_vars->width, view_height, 0.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// NOTE(allen): This maintains a fixed aspect ratio and
// puts the game port in the center, expecting the game to
// add bars
#if 0
internal
SIG_SET_SIZE(render_set_screen_size){
render_vars->width = view_width;
render_vars->height = view_height;
real32 ratio_width, ratio_height;
ratio_width = (real32)(port_width) / view_width;
ratio_height = (real32)(port_height) / view_height;
i32 start_x, start_y;
if (ratio_width > ratio_height){
ratio_width = ratio_height;
start_y = 0;
start_x = (port_width - (ratio_width*view_width))/2;
}
else{
ratio_height = ratio_width;
start_x = 0;
start_y = (port_height - (ratio_height*view_height))/2;
}
glViewport(start_x, start_y, ratio_width*view_width, ratio_height*view_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.f, view_width, view_height, 0.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
#endif
SIG_GET_RENDER_TARGET(render_get_render_target){
Game_Render_Target render = {};
render.width = render_vars->width;
render.height = render_vars->height;
return render;
}
#endif