# HG changeset patch # User John Tsiombikas # Date 1371885099 -10800 # Node ID ecc040281dc973286cd43505b4fccfa58af66e90 initial commit diff -r 000000000000 -r ecc040281dc9 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,10 @@ +\.o$ +\.swp$ +\.exe$ +\.lib$ +\.dll$ +Debug$ +Release$ +\.user$ +\.sdf$ +\.suo$ diff -r 000000000000 -r ecc040281dc9 d3dut.sln --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/d3dut.sln Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3dut", "d3dut.vcxproj", "{0F0AE967-A4DD-4DB5-B191-5EA35701BA95}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example\example.vcxproj", "{6B237CAC-3616-46E8-B62F-4A4CC26AD117}" + ProjectSection(ProjectDependencies) = postProject + {0F0AE967-A4DD-4DB5-B191-5EA35701BA95} = {0F0AE967-A4DD-4DB5-B191-5EA35701BA95} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0F0AE967-A4DD-4DB5-B191-5EA35701BA95}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F0AE967-A4DD-4DB5-B191-5EA35701BA95}.Debug|Win32.Build.0 = Debug|Win32 + {0F0AE967-A4DD-4DB5-B191-5EA35701BA95}.Release|Win32.ActiveCfg = Release|Win32 + {0F0AE967-A4DD-4DB5-B191-5EA35701BA95}.Release|Win32.Build.0 = Release|Win32 + {6B237CAC-3616-46E8-B62F-4A4CC26AD117}.Debug|Win32.ActiveCfg = Debug|Win32 + {6B237CAC-3616-46E8-B62F-4A4CC26AD117}.Debug|Win32.Build.0 = Debug|Win32 + {6B237CAC-3616-46E8-B62F-4A4CC26AD117}.Release|Win32.ActiveCfg = Release|Win32 + {6B237CAC-3616-46E8-B62F-4A4CC26AD117}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff -r 000000000000 -r ecc040281dc9 d3dut.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/d3dut.vcxproj Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {0F0AE967-A4DD-4DB5-B191-5EA35701BA95} + Win32Proj + d3dut + + + + DynamicLibrary + true + v100 + MultiByte + + + DynamicLibrary + false + v100 + true + MultiByte + + + + + + + + + + + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;D3DUT_EXPORTS;D3DUT_IMPLEMENTATION;%(PreprocessorDefinitions) + $(ProjectDir)\include + + + Windows + true + %(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;D3DUT_EXPORTS;D3DUT_IMPLEMENTATION;%(PreprocessorDefinitions) + $(ProjectDir)\include + + + Windows + true + true + true + %(AdditionalDependencies) + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 d3dut.vcxproj.filters --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/d3dut.vcxproj.filters Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 example/example.vcxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/example.vcxproj Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {6B237CAC-3616-46E8-B62F-4A4CC26AD117} + Win32Proj + example + + + + Application + true + v100 + MultiByte + + + Application + false + v100 + true + MultiByte + + + + + + + + + + + + + false + $(SolutionDir)\$(Configuration);$(ExecutablePath) + + + false + $(SolutionDir)\$(Configuration);$(ExecutablePath) + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)\include + + + Console + true + %(AdditionalDependencies) + $(SolutionDir)\$(Configuration) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)\include + + + Console + true + true + true + %(AdditionalDependencies) + $(SolutionDir)\$(Configuration) + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 example/example.vcxproj.filters --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/example.vcxproj.filters Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {3c0a494b-a31b-4938-9d51-78e7cbed4e2c} + + + + + Source Files + + + + + shaders + + + \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 example/shader.hlsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/shader.hlsl Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,31 @@ +cbuffer RenderState : register(b0) { + matrix modelview_matrix : packoffset(c0); + matrix projection_matrix : packoffset(c4); +}; + +struct VSInput { + float4 pos : POSITION; + float4 color : COLOR; +}; + +struct VSOutput { + float4 pos : SV_POSITION; + float4 color : COLOR0; +}; + +VSOutput vertex_main(VSInput input) +{ + VSOutput res; + + float4 vpos = mul(input.pos, modelview_matrix); + + res.pos = mul(vpos, projection_matrix); + res.color = input.color; + return res; +} + + +float4 pixel_main(VSOutput input) : SV_TARGET +{ + return input.color; +} \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 example/src/example.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example/src/example.cc Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,234 @@ +#include +#include +#include +#include "d3dut.h" + +struct Vertex { + float pos[3]; + float color[4]; +}; + +struct RenderState { + float modelview[16]; + float projection[16]; +}; + +static bool init(); +static void cleanup(); +static void display(); +static void reshape(int x, int y); +static void keyb(unsigned char key, int x, int y); + +static int width, height; + +static ID3D11InputLayout *vertex_layout; +static ID3D11VertexShader *vsdr; +static ID3D11PixelShader *psdr; +static ID3D11Buffer *vbuf; +static ID3D11Buffer *rstate_buf; + +static RenderState rstate; + +int main(int argc, char **argv) +{ + d3dut_init(&argc, argv); + d3dut_init_window_size(800, 600); + d3dut_init_display_mode(D3DUT_RGB | D3DUT_DEPTH | D3DUT_DOUBLE); + d3dut_create_window("d3dut example"); + + d3dut_display_func(display); + d3dut_idle_func(d3dut_post_redisplay); + d3dut_reshape_func(reshape); + d3dut_keyboard_func(keyb); + + if(!init()) { + return 1; + } + atexit(cleanup); + + d3dut_main_loop(); + return 0; +} + +static bool init() +{ + unsigned int sdrflags = 0;//D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG; + + ID3DBlob *vsbuf, *psbuf, *msgblob = 0; + if(D3DX11CompileFromFile("shader.hlsl", 0, 0, "vertex_main", "vs_4_0", sdrflags, 0, 0, &vsbuf, &msgblob, 0) != 0) { + fprintf(stderr, "failed to load vertex shader\n"); + if(msgblob && msgblob->GetBufferSize() > 0) { + fprintf(stderr, "Vertex Shader:\n%s\n", (char*)msgblob->GetBufferPointer()); + } + return false; + } + if(D3DX11CompileFromFile("shader.hlsl", 0, 0, "pixel_main", "ps_4_0", sdrflags, 0, 0, &psbuf, &msgblob, 0) != 0) { + fprintf(stderr, "failed to load pixel shader\n"); + if(msgblob && msgblob->GetBufferSize() > 0) { + fprintf(stderr, "Pixel Shader:\n%s\n", (char*)msgblob->GetBufferPointer()); + } + return false; + } + + if(d3dut_dev->CreateVertexShader(vsbuf->GetBufferPointer(), vsbuf->GetBufferSize(), 0, &vsdr) != 0) { + fprintf(stderr, "failed to create vertex shader\n"); + return false; + } + if(d3dut_dev->CreatePixelShader(psbuf->GetBufferPointer(), psbuf->GetBufferSize(), 0, &psdr) != 0) { + fprintf(stderr, "failed to create pixel shader\n"); + return false; + } + + D3D11_INPUT_ELEMENT_DESC elem_desc[2]; + elem_desc[0].SemanticName = "position"; + elem_desc[0].SemanticIndex = 0; + elem_desc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; + elem_desc[0].InputSlot = 0; + elem_desc[0].AlignedByteOffset = 0; + elem_desc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + elem_desc[0].InstanceDataStepRate = 0; + + elem_desc[1].SemanticName = "color"; + elem_desc[1].SemanticIndex = 0; + elem_desc[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + elem_desc[1].InputSlot = 0; + elem_desc[1].AlignedByteOffset = offsetof(Vertex, color); + elem_desc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + elem_desc[1].InstanceDataStepRate = 0; + + if(d3dut_dev->CreateInputLayout(elem_desc, 2, vsbuf->GetBufferPointer(), vsbuf->GetBufferSize(), &vertex_layout) != 0) { + fprintf(stderr, "failed to create vertex layout\n"); + return 0; + } + vsbuf->Release(); + psbuf->Release(); + + // --- create vertex buffer --- + Vertex varr[] = { + {{-0.6, -0.4, 0}, {1, 0, 0, 1}}, + {{0.0, 0.6, 0}, {0, 1, 0, 1}}, + {{0.6, -0.4, 0}, {0, 0, 1, 1}} + }; + + D3D11_BUFFER_DESC buf_desc; + memset(&buf_desc, 0, sizeof buf_desc); + buf_desc.Usage = D3D11_USAGE_DEFAULT; + buf_desc.ByteWidth = sizeof varr; + buf_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + + D3D11_SUBRESOURCE_DATA subdata; + memset(&subdata, 0, sizeof subdata); + subdata.pSysMem = varr; + if(d3dut_dev->CreateBuffer(&buf_desc, &subdata, &vbuf) != 0) { + fprintf(stderr, "failed to create vertex buffer\n"); + return false; + } + + // render state buffer + memset(&buf_desc, 0, sizeof buf_desc); + buf_desc.Usage = D3D11_USAGE_DEFAULT; + buf_desc.ByteWidth = sizeof(RenderState); + buf_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + memset(&subdata, 0, sizeof subdata); + subdata.pSysMem = &rstate; + if(d3dut_dev->CreateBuffer(&buf_desc, &subdata, &rstate_buf) != 0) { + fprintf(stderr, "failed to create render state buffer\n"); + return false; + } + + return true; +} + +static void cleanup() +{ + vbuf->Release(); + rstate_buf->Release(); + vsdr->Release(); + psdr->Release(); + vertex_layout->Release(); +} + +static void set_identity(float *mat) +{ + mat[0] = mat[5] = mat[10] = mat[15] = 1.0; + mat[1] = mat[2] = mat[3] = mat[4] = mat[6] = mat[7] = mat[8] = mat[9] = mat[11] = mat[12] = mat[13] = mat[14] = 0.0; +} + +static void set_rotation_z(float *mat, float angle) +{ + set_identity(mat); + + mat[0] = cos(angle); + mat[1] = -sin(angle); + mat[4] = sin(angle); + mat[5] = cos(angle); +} + +static void set_ortho(float *mat, float aspect) +{ + set_identity(mat); + mat[0] = 1.0 / aspect; +} + +static void display() +{ + unsigned int msec = timeGetTime(); + + float fbcolor[] = {0.2f, 0.2f, 0.2f, 1.0f}; + d3dut_ctx->ClearRenderTargetView(d3dut_rtview, fbcolor); + + // set render state constant buffer data + set_ortho(rstate.projection, (float)width / (float)height); + set_rotation_z(rstate.modelview, msec / 1000.0); + + d3dut_ctx->UpdateSubresource(rstate_buf, 0, 0, &rstate, 0, 0); + d3dut_ctx->VSSetConstantBuffers(0, 1, &rstate_buf); + + + unsigned int stride = sizeof(Vertex); + unsigned int offset = 0; + d3dut_ctx->IASetVertexBuffers(0, 1, &vbuf, &stride, &offset); + d3dut_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + d3dut_ctx->IASetInputLayout(vertex_layout); + + d3dut_ctx->VSSetShader(vsdr, 0, 0); + d3dut_ctx->PSSetShader(psdr, 0, 0); + + d3dut_ctx->Draw(3, 0); + + d3dut_swap_buffers(); +} + +static void reshape(int x, int y) +{ + width = x; + height = y; + + D3D11_VIEWPORT vp; + vp.Width = (float)x; + vp.Height = (float)y; + vp.MinDepth = 0; + vp.MaxDepth = 1; + vp.TopLeftX = 0; + vp.TopLeftY = 0; + d3dut_ctx->RSSetViewports(1, &vp); + + // TODO probably we also need to resize render targets or whatever... +} + +static void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + exit(0); + + case ' ': + { + static bool anim = true; + anim = !anim; + d3dut_idle_func(anim ? d3dut_post_redisplay : 0); + } + break; + } +} \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 include/d3dut.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/d3dut.h Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,95 @@ +#ifndef D3DUT_H_ +#define D3DUT_H_ + +#ifdef _MSC_VER +#pragma comment(lib, "d3d11.lib") +#pragma comment(lib, "d3dx11.lib") +#pragma comment(lib, "winmm.lib") + +#ifndef D3DUT_IMPLEMENTATION +#pragma comment(lib, "d3dut.lib") +#endif +#endif + +#ifdef D3DUT_IMPLEMENTATION +#define D3DUTAPI __declspec(dllexport) +#else +#define D3DUTAPI __declspec(dllimport) +#endif + +#include +#include + +#define D3DUT_RGB 0 +#define D3DUT_RGBA 0 +#define D3DUT_SINGLE 0 + +#define D3DUT_DOUBLE 1 +#define D3DUT_DEPTH 2 +#define D3DUT_STENCIL 4 +#define D3DUT_STEREO 8 +#define D3DUT_MULTISAMPLE 16 + +enum { + D3DUT_WINDOW_WIDTH, + D3DUT_WINDOW_HEIGHT, + D3DUT_ELAPSED_TIME +}; + +enum { + D3DUT_LEFT_BUTTON, + D3DUT_MIDDLE_BUTTON, + D3DUT_RIGHT_BUTTON, + + D3DUT_WHEELDOWN_BUTTON, + D3DUT_WHEELUP_BUTTON +}; + +enum {D3DUT_DOWN = 0, D3DUT_UP = 1}; + +typedef void (*D3DUT_DisplayFunc)(); +typedef void (*D3DUT_IdleFunc)(); +typedef void (*D3DUT_ReshapeFunc)(int, int); +typedef void (*D3DUT_KeyboardFunc)(unsigned char, int, int); +typedef void (*D3DUT_KeyboardUpFunc)(unsigned char, int, int); +typedef void (*D3DUT_SpecialFunc)(int, int, int); +typedef void (*D3DUT_SpecialUpFunc)(int, int, int); +typedef void (*D3DUT_MouseFunc)(int, int, int, int); +typedef void (*D3DUT_MotionFunc)(int, int); +typedef void (*D3DUT_PassiveMotionFunc)(int, int); + +extern D3DUTAPI ID3D11Device *d3dut_dev; +extern D3DUTAPI ID3D11DeviceContext *d3dut_ctx; +extern D3DUTAPI ID3D11RenderTargetView *d3dut_rtview; + +void D3DUTAPI d3dut_init(int *argc, char **argv); +void D3DUTAPI d3dut_init_display_mode(unsigned int dmflags); +void D3DUTAPI d3dut_init_window_size(int xsz, int ysz); + +int D3DUTAPI d3dut_create_window(const char *title); +void D3DUTAPI d3dut_destroy_window(int win); +void D3DUTAPI d3dut_set_window(int idx); +int D3DUTAPI d3dut_get_window(); + +void D3DUTAPI d3dut_display_func(D3DUT_DisplayFunc func); +void D3DUTAPI d3dut_idle_func(D3DUT_IdleFunc func); +void D3DUTAPI d3dut_reshape_func(D3DUT_ReshapeFunc func); +void D3DUTAPI d3dut_keyboard_func(D3DUT_KeyboardFunc func); +void D3DUTAPI d3dut_keyboard_up_func(D3DUT_KeyboardUpFunc func); +void D3DUTAPI d3dut_special_func(D3DUT_SpecialFunc func); +void D3DUTAPI d3dut_special_up_func(D3DUT_SpecialUpFunc func); +void D3DUTAPI d3dut_mouse_func(D3DUT_MouseFunc func); +void D3DUTAPI d3dut_motion_func(D3DUT_MotionFunc func); +void D3DUTAPI d3dut_passive_motion_func(D3DUT_PassiveMotionFunc func); + +void D3DUTAPI d3dut_post_redisplay(); +void D3DUTAPI d3dut_swap_buffers(); + +void D3DUTAPI d3dut_main_loop(); + +int D3DUTAPI d3dut_get(unsigned int what); + +void D3DUTAPI d3dut_solid_sphere(double radius, int slices, int stacks); +// TODO ... more stuff + +#endif // D3DUT_H_ \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 src/d3dut.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/d3dut.cc Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,255 @@ +#include +#include +#include +#include "d3dut.h" +#include "win.h" +#include "logmsg.h" + +static void d3dut_cleanup(); + +D3DUTAPI ID3D11Device *d3dut_dev; +D3DUTAPI ID3D11DeviceContext *d3dut_ctx; +D3DUTAPI ID3D11RenderTargetView *d3dut_rtview; + +static int init_xsz = 640; +static int init_ysz = 480; +static int init_dmflags = 0; + +static long init_time = -1; + +static D3DUT_IdleFunc idle_func; + +void D3DUTAPI d3dut_init(int *argc, char **argv) +{ + if(init_time >= 0) { + warning("already initialized!\n"); + return; + } + + WNDCLASS wclass; + memset(&wclass, 0, sizeof wclass); + wclass.hInstance = GetModuleHandle(0); + wclass.lpfnWndProc = win_handle_event; + wclass.lpszClassName = WINCLASSNAME; + wclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wclass.hIcon = LoadIcon(0, IDI_APPLICATION); + wclass.hCursor = LoadCursor(0, IDC_ARROW); + wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + RegisterClass(&wclass); + + // create D3D device + D3D_FEATURE_LEVEL feature_level[] = { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0 + }; + if(D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, feature_level, 3, D3D11_SDK_VERSION, + &d3dut_dev, 0, &d3dut_ctx) != 0) { + fatal_error("failed to create D3D11 device\n"); + } + atexit(d3dut_cleanup); + + init_time = timeGetTime(); +} + +static void d3dut_cleanup() +{ + for(size_t i=0; iRelease(); + d3dut_dev = 0; + } + if(d3dut_ctx) { + d3dut_ctx->Release(); + d3dut_ctx = 0; + } + d3dut_rtview = 0; + + UnregisterClass(WINCLASSNAME, GetModuleHandle(0)); + init_time = -1; +} + +void D3DUTAPI d3dut_init_display_mode(unsigned int dmflags) +{ + init_dmflags = dmflags; +} + +void D3DUTAPI d3dut_init_window_size(int xsz, int ysz) +{ + init_xsz = xsz; + init_ysz = ysz; +} + + +int D3DUTAPI d3dut_create_window(const char *title) +{ + return create_window(title, init_xsz, init_ysz, init_dmflags); +} + +void D3DUTAPI d3dut_destroy_window(int win) +{ + destroy_window(win); +} + +void D3DUTAPI d3dut_set_window(int idx) +{ + set_active_win(idx); +} + +int D3DUTAPI d3dut_get_window() +{ + return get_active_win(); +} + +void D3DUTAPI d3dut_display_func(D3DUT_DisplayFunc func) +{ + Window *win = get_window(); + win->display_func = func; +} + +void D3DUTAPI d3dut_idle_func(D3DUT_IdleFunc func) +{ + idle_func = func; +} + +void D3DUTAPI d3dut_reshape_func(D3DUT_ReshapeFunc func) +{ + Window *win = get_window(); + win->reshape_func = func; +} + +void D3DUTAPI d3dut_keyboard_func(D3DUT_KeyboardFunc func) +{ + Window *win = get_window(); + win->keyboard_func = func; +} + +void D3DUTAPI d3dut_keyboard_up_func(D3DUT_KeyboardUpFunc func) +{ + Window *win = get_window(); + win->keyboard_up_func = func; +} + +void D3DUTAPI d3dut_special_func(D3DUT_SpecialFunc func) +{ + Window *win = get_window(); + win->special_func = func; +} + +void D3DUTAPI d3dut_special_up_func(D3DUT_SpecialUpFunc func) +{ + Window *win = get_window(); + win->special_up_func = func; +} + +void D3DUTAPI d3dut_mouse_func(D3DUT_MouseFunc func) +{ + Window *win = get_window(); + win->mouse_func = func; +} + +void D3DUTAPI d3dut_motion_func(D3DUT_MotionFunc func) +{ + Window *win = get_window(); + win->motion_func = func; +} + +void D3DUTAPI d3dut_passive_motion_func(D3DUT_PassiveMotionFunc func) +{ + Window *win = get_window(); + win->passive_motion_func = func; +} + + +void D3DUTAPI d3dut_post_redisplay() +{ + Window *win = get_window(); + win->must_redisplay = true; +} + +void D3DUTAPI d3dut_swap_buffers() +{ + Window *win = get_window(); + win->swap->Present(0, 0); +} + +void D3DUTAPI d3dut_main_loop() +{ + MSG msg; + + for(;;) { + bool must_redisplay = false; + for(size_t i=0; ichanged_size && win->reshape_func) { + win->changed_size = false; + set_active_win(i); + win->reshape_func(win->width, win->height); + } + if(win->must_redisplay) { + must_redisplay = true; + } + } + + if(idle_func || must_redisplay) { + while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + if(msg.message == WM_QUIT) { + return; + } + } + + if(idle_func) { // checking again because a handler might have set this to 0 + idle_func(); + } + } else { + if(!GetMessage(&msg, 0, 0, 0)) { + return; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + for(size_t i=0; imust_redisplay && win->display_func) { + win->must_redisplay = false; + set_active_win(i); + win->display_func(); + ValidateRect(win->win, 0); + } + } + } +} + + +int D3DUTAPI d3dut_get(unsigned int what) +{ + Window *win = get_window(); + + switch(what) { + case D3DUT_WINDOW_WIDTH: + return win->width; + case D3DUT_WINDOW_HEIGHT: + return win->height; + + case D3DUT_ELAPSED_TIME: + return (long)timeGetTime() - init_time; + + default: + break; + } + return 0; +} + + +void D3DUTAPI d3dut_solid_sphere(double radius, int slices, int stacks) +{ +} diff -r 000000000000 -r ecc040281dc9 src/logmsg.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/logmsg.cc Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,26 @@ +#include +#include +#include +#include "logmsg.h" + +void fatal_error(const char *fmt, ...) +{ + fputs("D3DUT FATAL ERROR: ", stderr); + + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + abort(); +} + +void warning(const char *fmt, ...) +{ + fputs("D3DUT WARNING: ", stderr); + + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 src/logmsg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/logmsg.h Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,7 @@ +#ifndef LOGMSG_H_ +#define LOGMSG_H_ + +void fatal_error(const char *fmt, ...); +void warning(const char *fmt, ...); + +#endif // LOGMSG_H_ \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 src/win.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win.cc Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,251 @@ +#include +#include "d3dut.h" +#include "win.h" +#include "logmsg.h" + +std::vector windows; +int active_win = -1; + +int create_window(const char *title, int xsz, int ysz, unsigned int dmflags) +{ + IDXGIDevice *dxgidev; + if(d3dut_dev->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgidev) != 0) { + fatal_error("failed to get IDXGIDevice interface\n"); + return 0; + } + IDXGIAdapter *adapter; + if(dxgidev->GetParent(__uuidof(IDXGIAdapter), (void**)&adapter) != 0) { + fatal_error("failed to get IDXGIAdapter pointer\n"); + return 0; + } + IDXGIFactory *dxgi_factory; + if(adapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgi_factory) != 0) { + fatal_error("failed to get IDXGIFactory pointer\n"); + return 0; + } + adapter->Release(); + dxgidev->Release(); + + Window *win = new Window; + memset(win, 0, sizeof *win); + win->must_redisplay = true; + win->changed_size = true; + win->width = xsz; + win->height = ysz; + + int xpos = (GetSystemMetrics(SM_CXSCREEN) - xsz) / 2; + int ypos = (GetSystemMetrics(SM_CYSCREEN) - ysz) / 2; + win->win = CreateWindow(WINCLASSNAME, title, WS_OVERLAPPEDWINDOW, xpos, ypos, xsz, ysz, 0, 0, GetModuleHandle(0), 0); + if(!win->win) { + fprintf(stderr, "failed to create window: %s\n", title); + return 0; + } + ShowWindow(win->win, SW_SHOW); + + unsigned int nsamples = 1; + unsigned int quality = 0; + if(dmflags & D3DUT_MULTISAMPLE) { + nsamples = D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; + d3dut_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, nsamples, &quality); + } + + DXGI_SWAP_CHAIN_DESC sd; + memset(&sd, 0, sizeof sd); + sd.OutputWindow = win->win; + sd.BufferDesc.Width = xsz; + sd.BufferDesc.Height = ysz; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + //sd.Stereo = (dmflags & D3DUT_STEREO) ? 1 : 0; + sd.BufferDesc.RefreshRate.Numerator = 60; + sd.BufferDesc.RefreshRate.Denominator = 1; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.BufferCount = (dmflags & D3DUT_DOUBLE) ? 1 : 0; + sd.SampleDesc.Count = nsamples; + sd.SampleDesc.Quality = quality; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + sd.Windowed = 1; + + if(dxgi_factory->CreateSwapChain(d3dut_dev, &sd, &win->swap) != 0) { + warning("failed to create swap chain\n"); + return 0; + } + dxgi_factory->Release(); + + ID3D11Texture2D *rtex; + if(win->swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&rtex) != 0) { + warning("failed to get default render target texture\n"); + return 0; + } + if(d3dut_dev->CreateRenderTargetView(rtex, 0, &win->rtarg_view) != 0) { + warning("failed to create render target view\n"); + rtex->Release(); + return 0; + } + rtex->Release(); + d3dut_ctx->OMSetRenderTargets(1, &win->rtarg_view, 0); + + int idx = (int)windows.size(); + windows.push_back(win); + set_active_win(idx); + return idx; +} + +void destroy_window(int idx) +{ + if(idx < 0 || idx >= (int)windows.size()) { + warning("destroy_window: invalid index: %d\n", idx); + return; + } + + Window *win = windows[idx]; + if(win) { + DestroyWindow(win->win); + win->rtarg_view->Release(); + win->swap->Release(); + delete win; + windows[idx] = 0; + } +} + +void set_active_win(int idx) +{ + if(idx < 0 || idx >= (int)windows.size()) { + warning("set_active_win: invalid window: %d\n", idx); + return; + } + d3dut_rtview = windows[idx]->rtarg_view; + active_win = idx; +} + +int get_active_win() +{ + return active_win; +} + +Window *get_window(int idx) +{ + if(idx < 0) { + idx = active_win; + } + if(idx < 0 || idx >= (int)windows.size()) { + return 0; + } + return windows[idx]; +} + +static int find_window(HWND syswin) +{ + for(size_t i=0; iwin == syswin) { + return i; + } + } + return -1; +} + +static void mouse_handler(Window *win, int bn, bool pressed); + +long CALLBACK win_handle_event(HWND syswin, unsigned int msg, unsigned int wparam, long lparam) +{ + Window *win = 0; + int winid = find_window(syswin); + if(winid != -1) { + set_active_win(winid); + win = get_window(); + } + + switch(msg) { + case WM_PAINT: + win->must_redisplay = true; + ValidateRect(win->win, 0); + break; + + case WM_CLOSE: + destroy_window(winid); + break; + + case WM_SIZE: + win->width = LOWORD(lparam); + win->height = HIWORD(lparam); + win->changed_size = true; + break; + + case WM_KEYDOWN: + if(wparam < 256) { + if(win->keyboard_func) { + win->keyboard_func(wparam, win->mousex, win->mousey); + } + } else { + if(win->special_func) { + win->special_func(wparam, win->mousex, win->mousey); + } + } + break; + + case WM_KEYUP: + if(wparam < 256) { + if(win->keyboard_up_func) { + win->keyboard_up_func(wparam, win->mousex, win->mousey); + } + } else { + if(win->special_up_func) { + win->special_up_func(wparam, win->mousex, win->mousey); + } + } + break; + + case WM_MOUSEMOVE: + win->mousex = LOWORD(lparam); + win->mousey = HIWORD(lparam); + + if(wparam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) { + if(win->motion_func) { + win->motion_func(win->mousex, win->mousey); + } + } else { + if(win->passive_motion_func) { + win->passive_motion_func(win->mousex, win->mousey); + } + } + break; + + case WM_LBUTTONDOWN: + mouse_handler(win, D3DUT_LEFT_BUTTON, true); + break; + case WM_RBUTTONDOWN: + mouse_handler(win, D3DUT_RIGHT_BUTTON, true); + break; + case WM_MBUTTONDOWN: + mouse_handler(win, D3DUT_MIDDLE_BUTTON, true); + break; + case WM_LBUTTONUP: + mouse_handler(win, D3DUT_LEFT_BUTTON, false); + break; + case WM_RBUTTONUP: + mouse_handler(win, D3DUT_RIGHT_BUTTON, false); + break; + case WM_MBUTTONUP: + mouse_handler(win, D3DUT_MIDDLE_BUTTON, false); + break; + + case WM_MOUSEWHEEL: + { + int delta = GET_WHEEL_DELTA_WPARAM(wparam); + mouse_handler(win, delta < 0 ? D3DUT_WHEELDOWN_BUTTON : D3DUT_WHEELUP_BUTTON, true); + } + break; + + default: + return DefWindowProc(syswin, msg, wparam, lparam); + } + + return 0; +} + +static void mouse_handler(Window *win, int bn, bool pressed) +{ + if(win->mouse_func) { + win->mouse_func(bn, pressed ? D3DUT_DOWN : D3DUT_UP, win->mousex, win->mousey); + } +} \ No newline at end of file diff -r 000000000000 -r ecc040281dc9 src/win.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/win.h Sat Jun 22 10:11:39 2013 +0300 @@ -0,0 +1,42 @@ +#ifndef D3DUT_WIN_H_ +#define D3DUT_WIN_H_ + +#include +#include + +#define WINCLASSNAME "d3dutwindow" + +struct Window { + HWND win; + int width, height; + + IDXGISwapChain *swap; + ID3D11RenderTargetView *rtarg_view; + + bool must_redisplay, changed_size; + int mousex, mousey; + + D3DUT_DisplayFunc display_func; + D3DUT_ReshapeFunc reshape_func; + D3DUT_KeyboardFunc keyboard_func; + D3DUT_KeyboardUpFunc keyboard_up_func; + D3DUT_SpecialFunc special_func; + D3DUT_SpecialUpFunc special_up_func; + D3DUT_MouseFunc mouse_func; + D3DUT_MotionFunc motion_func; + D3DUT_PassiveMotionFunc passive_motion_func; +}; + +extern std::vector windows; + +int create_window(const char *title, int xsz, int ysz, unsigned int dmflags); +void destroy_window(int idx); + +void set_active_win(int idx); +int get_active_win(); + +Window *get_window(int idx = -1); + +long CALLBACK win_handle_event(HWND syswin, unsigned int msg, unsigned int wparam, long lparam); + +#endif // D3DUT_WIN_H_ \ No newline at end of file