Demo using Direct3D 9 for rendering
This commit is contained in:
parent
6ac034c803
commit
e14dd1cb1b
6
demo/d3d9/build.bat
Normal file
6
demo/d3d9/build.bat
Normal file
@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
|
||||
rem This will use VS2015 for compiler
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86
|
||||
|
||||
cl /D_CRT_SECURE_NO_DEPRECATE /nologo /W3 /O2 /fp:fast /Gm- /Fedemo.exe main.c user32.lib d3d9.lib /link /incremental:no
|
298
demo/d3d9/main.c
Normal file
298
demo/d3d9/main.c
Normal file
@ -0,0 +1,298 @@
|
||||
/* nuklear - 1.32.0 - public domain */
|
||||
#define COBJMACROS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_D3D9_IMPLEMENTATION
|
||||
#include "../../nuklear.h"
|
||||
#include "nuklear_d3d9.h"
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* ===============================================================*/
|
||||
/* This are some code examples to provide a small overview of what can be
|
||||
* done with this library. To try out an example uncomment the include
|
||||
* and the corresponding function. */
|
||||
#define UNUSED(a) (void)a
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
#define LEN(a) (sizeof(a)/sizeof(a)[0])
|
||||
|
||||
/*#include "../style.c"*/
|
||||
/*#include "../calculator.c"*/
|
||||
/*#include "../overview.c"*/
|
||||
/*#include "../node_editor.c"*/
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* DEMO
|
||||
*
|
||||
* ===============================================================*/
|
||||
static IDirect3DDevice9 *device;
|
||||
static IDirect3DDevice9Ex *deviceEx;
|
||||
static D3DPRESENT_PARAMETERS present;
|
||||
|
||||
static LRESULT CALLBACK
|
||||
WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
|
||||
case WM_SIZE:
|
||||
if (device)
|
||||
{
|
||||
UINT width = LOWORD(lparam);
|
||||
UINT height = HIWORD(lparam);
|
||||
if (width != 0 && height != 0 &&
|
||||
(width != present.BackBufferWidth || height != present.BackBufferHeight))
|
||||
{
|
||||
nk_d3d9_release();
|
||||
present.BackBufferWidth = width;
|
||||
present.BackBufferHeight = height;
|
||||
HRESULT hr = IDirect3DDevice9_Reset(device, &present);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
nk_d3d9_resize(width, height);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (nk_d3d9_handle_event(wnd, msg, wparam, lparam))
|
||||
return 0;
|
||||
|
||||
return DefWindowProcW(wnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
static void create_d3d9_device(HWND wnd)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
present.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
present.BackBufferWidth = WINDOW_WIDTH;
|
||||
present.BackBufferHeight = WINDOW_HEIGHT;
|
||||
present.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
present.BackBufferCount = 1;
|
||||
present.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
present.hDeviceWindow = wnd;
|
||||
present.EnableAutoDepthStencil = TRUE;
|
||||
present.AutoDepthStencilFormat = D3DFMT_D24S8;
|
||||
present.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
|
||||
present.Windowed = TRUE;
|
||||
|
||||
{/* first try to create Direct3D9Ex device if possible (on Windows 7+) */
|
||||
typedef HRESULT WINAPI Direct3DCreate9ExPtr(UINT, IDirect3D9Ex**);
|
||||
Direct3DCreate9ExPtr *Direct3DCreate9Ex = (void *)GetProcAddress(GetModuleHandleA("d3d9.dll"), "Direct3DCreate9Ex");
|
||||
if (Direct3DCreate9Ex) {
|
||||
IDirect3D9Ex *d3d9ex;
|
||||
if (SUCCEEDED(Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex))) {
|
||||
hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_FPU_PRESERVE,
|
||||
&present, NULL, &deviceEx);
|
||||
if (SUCCEEDED(hr)) {
|
||||
device = (IDirect3DDevice9 *)deviceEx;
|
||||
} else {
|
||||
/* hardware vertex processing not supported, no big deal
|
||||
retry with software vertex processing */
|
||||
hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_FPU_PRESERVE,
|
||||
&present, NULL, &deviceEx);
|
||||
if (SUCCEEDED(hr)) {
|
||||
device = (IDirect3DDevice9 *)deviceEx;
|
||||
}
|
||||
}
|
||||
IDirect3D9Ex_Release(d3d9ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!device) {
|
||||
/* otherwise do regular D3D9 setup */
|
||||
IDirect3D9 *d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
|
||||
hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_FPU_PRESERVE,
|
||||
&present, &device);
|
||||
if (FAILED(hr)) {
|
||||
/* hardware vertex processing not supported, no big deal
|
||||
retry with software vertex processing */
|
||||
hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE | D3DCREATE_FPU_PRESERVE,
|
||||
&present, &device);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
IDirect3D9_Release(d3d9);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct nk_context *ctx;
|
||||
struct nk_color background;
|
||||
|
||||
WNDCLASSW wc;
|
||||
RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
|
||||
DWORD style = WS_OVERLAPPEDWINDOW;
|
||||
DWORD exstyle = WS_EX_APPWINDOW;
|
||||
HWND wnd;
|
||||
int running = 1;
|
||||
|
||||
/* Win32 */
|
||||
memset(&wc, 0, sizeof(wc));
|
||||
wc.style = CS_DBLCLKS;
|
||||
wc.lpfnWndProc = WindowProc;
|
||||
wc.hInstance = GetModuleHandleW(0);
|
||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.lpszClassName = L"NuklearWindowClass";
|
||||
RegisterClassW(&wc);
|
||||
|
||||
AdjustWindowRectEx(&rect, style, FALSE, exstyle);
|
||||
|
||||
wnd = CreateWindowExW(exstyle, wc.lpszClassName, L"Nuklear Demo",
|
||||
style | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
NULL, NULL, wc.hInstance, NULL);
|
||||
|
||||
create_d3d9_device(wnd);
|
||||
|
||||
/* GUI */
|
||||
ctx = nk_d3d9_init(device, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
/* Load Fonts: if none of these are loaded a default font will be used */
|
||||
/* Load Cursor: if you uncomment cursor loading please hide the cursor */
|
||||
{struct nk_font_atlas *atlas;
|
||||
nk_d3d9_font_stash_begin(&atlas);
|
||||
/*struct nk_font *droid = nk_font_atlas_add_from_file(atlas, "../../extra_font/DroidSans.ttf", 14, 0);*/
|
||||
/*struct nk_font *robot = nk_font_atlas_add_from_file(atlas, "../../extra_font/Roboto-Regular.ttf", 14, 0);*/
|
||||
/*struct nk_font *future = nk_font_atlas_add_from_file(atlas, "../../extra_font/kenvector_future_thin.ttf", 13, 0);*/
|
||||
/*struct nk_font *clean = nk_font_atlas_add_from_file(atlas, "../../extra_font/ProggyClean.ttf", 12, 0);*/
|
||||
/*struct nk_font *tiny = nk_font_atlas_add_from_file(atlas, "../../extra_font/ProggyTiny.ttf", 10, 0);*/
|
||||
/*struct nk_font *cousine = nk_font_atlas_add_from_file(atlas, "../../extra_font/Cousine-Regular.ttf", 13, 0);*/
|
||||
nk_d3d9_font_stash_end();
|
||||
/*nk_style_load_all_cursors(ctx, atlas->cursors);*/
|
||||
/*nk_style_set_font(ctx, &droid->handle)*/;}
|
||||
|
||||
/* style.c */
|
||||
/*set_style(ctx, THEME_WHITE);*/
|
||||
/*set_style(ctx, THEME_RED);*/
|
||||
/*set_style(ctx, THEME_BLUE);*/
|
||||
/*set_style(ctx, THEME_DARK);*/
|
||||
|
||||
background = nk_rgb(28,48,62);
|
||||
while (running)
|
||||
{
|
||||
/* Input */
|
||||
MSG msg;
|
||||
nk_input_begin(ctx);
|
||||
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT)
|
||||
running = 0;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
nk_input_end(ctx);
|
||||
|
||||
/* GUI */
|
||||
if (nk_begin(ctx, "Demo", nk_rect(50, 50, 230, 250),
|
||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|
|
||||
NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE))
|
||||
{
|
||||
enum {EASY, HARD};
|
||||
static int op = EASY;
|
||||
static int property = 20;
|
||||
|
||||
nk_layout_row_static(ctx, 30, 80, 1);
|
||||
if (nk_button_label(ctx, "button"))
|
||||
fprintf(stdout, "button pressed\n");
|
||||
nk_layout_row_dynamic(ctx, 30, 2);
|
||||
if (nk_option_label(ctx, "easy", op == EASY)) op = EASY;
|
||||
if (nk_option_label(ctx, "hard", op == HARD)) op = HARD;
|
||||
nk_layout_row_dynamic(ctx, 22, 1);
|
||||
nk_property_int(ctx, "Compression:", 0, &property, 100, 10, 1);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label(ctx, "background:", NK_TEXT_LEFT);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
if (nk_combo_begin_color(ctx, background, nk_vec2(nk_widget_width(ctx),400))) {
|
||||
nk_layout_row_dynamic(ctx, 120, 1);
|
||||
background = nk_color_picker(ctx, background, NK_RGBA);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
background.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, background.r, 255, 1,1);
|
||||
background.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, background.g, 255, 1,1);
|
||||
background.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, background.b, 255, 1,1);
|
||||
background.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, background.a, 255, 1,1);
|
||||
nk_combo_end(ctx);
|
||||
}
|
||||
}
|
||||
nk_end(ctx);
|
||||
|
||||
/* -------------- EXAMPLES ---------------- */
|
||||
/*calculator(ctx);*/
|
||||
/*overview(ctx);*/
|
||||
/*node_editor(ctx);*/
|
||||
/* ----------------------------------------- */
|
||||
|
||||
/* Draw */
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,
|
||||
D3DCOLOR_ARGB(background.a, background.r, background.g, background.b), 0.0f, 0);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
nk_d3d9_render(NK_ANTI_ALIASING_ON);
|
||||
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
if (deviceEx) {
|
||||
hr = IDirect3DDevice9Ex_PresentEx(deviceEx, NULL, NULL, NULL, NULL, 0);
|
||||
} else {
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICEHUNG || hr == D3DERR_DEVICEREMOVED) {
|
||||
/* to recover from this, you'll need to recreate device and all the resources */
|
||||
MessageBoxW(NULL, L"D3D9 device is lost or removed!", L"Error", 0);
|
||||
break;
|
||||
} else if (hr == S_PRESENT_OCCLUDED) {
|
||||
/* window is not visible, so vsync won't work. Let's sleep a bit to reduce CPU usage */
|
||||
Sleep(10);
|
||||
}
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
}
|
||||
}
|
||||
|
||||
nk_d3d9_shutdown();
|
||||
if (deviceEx) {
|
||||
IDirect3DDevice9Ex_Release(deviceEx);
|
||||
} else {
|
||||
IDirect3DDevice9_Release(device);
|
||||
}
|
||||
UnregisterClassW(wc.lpszClassName, wc.hInstance);
|
||||
return 0;
|
||||
}
|
533
demo/d3d9/nuklear_d3d9.h
Normal file
533
demo/d3d9/nuklear_d3d9.h
Normal file
@ -0,0 +1,533 @@
|
||||
/*
|
||||
* Nuklear - 1.32.0 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2016 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_D3D9_H_
|
||||
#define NK_D3D9_H_
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct IDirect3DDevice9 IDirect3DDevice9;
|
||||
|
||||
NK_API struct nk_context *nk_d3d9_init(IDirect3DDevice9 *device, int width, int height);
|
||||
NK_API void nk_d3d9_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_d3d9_font_stash_end(void);
|
||||
NK_API int nk_d3d9_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
NK_API void nk_d3d9_render(enum nk_anti_aliasing);
|
||||
NK_API void nk_d3d9_release(void);
|
||||
NK_API void nk_d3d9_resize(int width, int height);
|
||||
NK_API void nk_d3d9_shutdown(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_D3D9_IMPLEMENTATION
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define COBJMACROS
|
||||
#include <d3d9.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
struct nk_d3d9_vertex {
|
||||
/* D3d9 FFP requires three coordinate position, but nuklear writes only 2 elements
|
||||
projection matrix doesn't use z coordinate => so it can be any value.
|
||||
Member order here is important! Do not rearrange them! */
|
||||
float position[3];
|
||||
nk_uchar col[4];
|
||||
float uv[2];
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
struct nk_buffer cmds;
|
||||
|
||||
struct nk_draw_null_texture null;
|
||||
|
||||
D3DVIEWPORT9 viewport;
|
||||
D3DMATRIX projection;
|
||||
IDirect3DDevice9 *device;
|
||||
IDirect3DTexture9 *texture;
|
||||
IDirect3DStateBlock9 *state;
|
||||
} d3d9;
|
||||
|
||||
NK_API void
|
||||
nk_d3d9_render(enum nk_anti_aliasing AA)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = IDirect3DStateBlock9_Apply(d3d9.state);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* projection matrix */
|
||||
IDirect3DDevice9_SetTransform(d3d9.device, D3DTS_PROJECTION, &d3d9.projection);
|
||||
|
||||
/* viewport */
|
||||
IDirect3DDevice9_SetViewport(d3d9.device, &d3d9.viewport);
|
||||
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
{
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
const struct nk_draw_command *cmd;
|
||||
const nk_draw_index *offset = NULL;
|
||||
UINT vertex_count;
|
||||
|
||||
/* fill converting configuration */
|
||||
struct nk_convert_config config;
|
||||
NK_STORAGE const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d9_vertex, position)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_B8G8R8A8, NK_OFFSETOF(struct nk_d3d9_vertex, col)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_d3d9_vertex, uv)},
|
||||
{NK_VERTEX_LAYOUT_END}
|
||||
};
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_d3d9_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_d3d9_vertex);
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.null = d3d9.null;
|
||||
|
||||
/* convert shapes into vertexes */
|
||||
nk_buffer_init_default(&vbuf);
|
||||
nk_buffer_init_default(&ebuf);
|
||||
nk_convert(&d3d9.ctx, &d3d9.cmds, &vbuf, &ebuf, &config);
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
offset = (const nk_draw_index *)nk_buffer_memory_const(&ebuf);
|
||||
vertex_count = (UINT)vbuf.needed / sizeof(struct nk_d3d9_vertex);
|
||||
|
||||
nk_draw_foreach(cmd, &d3d9.ctx, &d3d9.cmds)
|
||||
{
|
||||
RECT scissor;
|
||||
if (!cmd->elem_count) continue;
|
||||
|
||||
hr = IDirect3DDevice9_SetTexture(d3d9.device, 0, (IDirect3DBaseTexture9 *)cmd->texture.ptr);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
scissor.left = (LONG)cmd->clip_rect.x;
|
||||
scissor.right = (LONG)(cmd->clip_rect.x + cmd->clip_rect.w);
|
||||
scissor.top = (LONG)cmd->clip_rect.y;
|
||||
scissor.bottom = (LONG)(cmd->clip_rect.y + cmd->clip_rect.h);
|
||||
|
||||
hr = IDirect3DDevice9_SetScissorRect(d3d9.device, &scissor);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
NK_ASSERT(sizeof(nk_draw_index) == sizeof(NK_UINT16));
|
||||
hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(d3d9.device, D3DPT_TRIANGLELIST,
|
||||
0, vertex_count, cmd->elem_count/3, offset, D3DFMT_INDEX16,
|
||||
nk_buffer_memory_const(&vbuf), sizeof(struct nk_d3d9_vertex));
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
|
||||
nk_buffer_free(&vbuf);
|
||||
nk_buffer_free(&ebuf);
|
||||
}
|
||||
|
||||
nk_clear(&d3d9.ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_d3d9_get_projection_matrix(int width, int height, float *result)
|
||||
{
|
||||
const float L = 0.5f;
|
||||
const float R = (float)width + 0.5f;
|
||||
const float T = 0.5f;
|
||||
const float B = (float)height + 0.5f;
|
||||
float matrix[4][4] = {
|
||||
{ 2.0f / (R - L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f / (T - B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ (R + L) / (L - R), (T + B) / (B - T), 0.0f, 1.0f },
|
||||
};
|
||||
memcpy(result, matrix, sizeof(matrix));
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_d3d9_release(void)
|
||||
{
|
||||
IDirect3DTexture9_Release(d3d9.texture);
|
||||
IDirect3DStateBlock9_Release(d3d9.state);
|
||||
}
|
||||
|
||||
static void
|
||||
nk_d3d9_create_font_texture()
|
||||
{
|
||||
int w, h, y;
|
||||
const void *image;
|
||||
|
||||
HRESULT hr;
|
||||
D3DLOCKED_RECT locked;
|
||||
|
||||
image = nk_font_atlas_bake(&d3d9.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
|
||||
hr = IDirect3DDevice9_CreateTexture(d3d9.device, w, h, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9.texture, NULL);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
hr = IDirect3DTexture9_LockRect(d3d9.texture, 0, &locked, NULL, 0);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
void *src = (char *)image + y * w * 4;
|
||||
void *dst = (char *)locked.pBits + y * locked.Pitch;
|
||||
memcpy(dst, src, w * 4);
|
||||
}
|
||||
|
||||
hr = IDirect3DTexture9_UnlockRect(d3d9.texture, 0);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
nk_font_atlas_end(&d3d9.atlas, nk_handle_ptr(d3d9.texture), &d3d9.null);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_d3d9_resize(int width, int height)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (d3d9.texture) {
|
||||
nk_d3d9_create_font_texture();
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_BeginStateBlock(d3d9.device);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
/* vertex format */
|
||||
IDirect3DDevice9_SetFVF(d3d9.device, D3DFVF_XYZ + D3DFVF_DIFFUSE + D3DFVF_TEX1);
|
||||
|
||||
/* blend state */
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
|
||||
/* render state */
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_LIGHTING, FALSE);
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_ZENABLE, FALSE);
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_ZWRITEENABLE, FALSE);
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
IDirect3DDevice9_SetRenderState(d3d9.device, D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
|
||||
/* sampler state */
|
||||
IDirect3DDevice9_SetSamplerState(d3d9.device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(d3d9.device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
IDirect3DDevice9_SetSamplerState(d3d9.device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
IDirect3DDevice9_SetSamplerState(d3d9.device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
/* texture stage state */
|
||||
IDirect3DDevice9_SetTextureStageState(d3d9.device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
IDirect3DDevice9_SetTextureStageState(d3d9.device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
IDirect3DDevice9_SetTextureStageState(d3d9.device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
IDirect3DDevice9_SetTextureStageState(d3d9.device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
IDirect3DDevice9_SetTextureStageState(d3d9.device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
IDirect3DDevice9_SetTextureStageState(d3d9.device, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
|
||||
hr = IDirect3DDevice9_EndStateBlock(d3d9.device, &d3d9.state);
|
||||
NK_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
nk_d3d9_get_projection_matrix(width, height, &d3d9.projection.m[0][0]);
|
||||
d3d9.viewport.Width = width;
|
||||
d3d9.viewport.Height = height;
|
||||
}
|
||||
|
||||
NK_API int
|
||||
nk_d3d9_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
int down = !((lparam >> 31) & 1);
|
||||
int ctrl = GetKeyState(VK_CONTROL) & (1 << 15);
|
||||
|
||||
switch (wparam)
|
||||
{
|
||||
case VK_SHIFT:
|
||||
case VK_LSHIFT:
|
||||
case VK_RSHIFT:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_SHIFT, down);
|
||||
return 1;
|
||||
|
||||
case VK_DELETE:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_DEL, down);
|
||||
return 1;
|
||||
|
||||
case VK_RETURN:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_ENTER, down);
|
||||
return 1;
|
||||
|
||||
case VK_TAB:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_TAB, down);
|
||||
return 1;
|
||||
|
||||
case VK_LEFT:
|
||||
if (ctrl)
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_TEXT_WORD_LEFT, down);
|
||||
else
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_LEFT, down);
|
||||
return 1;
|
||||
|
||||
case VK_RIGHT:
|
||||
if (ctrl)
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_TEXT_WORD_RIGHT, down);
|
||||
else
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_RIGHT, down);
|
||||
return 1;
|
||||
|
||||
case VK_BACK:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_BACKSPACE, down);
|
||||
return 1;
|
||||
|
||||
case VK_HOME:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_TEXT_START, down);
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_SCROLL_START, down);
|
||||
return 1;
|
||||
|
||||
case VK_END:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_TEXT_END, down);
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_SCROLL_END, down);
|
||||
return 1;
|
||||
|
||||
case VK_NEXT:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_SCROLL_DOWN, down);
|
||||
return 1;
|
||||
|
||||
case VK_PRIOR:
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_SCROLL_UP, down);
|
||||
return 1;
|
||||
|
||||
case 'C':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_COPY, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_PASTE, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_CUT, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_TEXT_UNDO, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
if (ctrl) {
|
||||
nk_input_key(&d3d9.ctx, NK_KEY_TEXT_REDO, down);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_CHAR:
|
||||
if (wparam >= 32)
|
||||
{
|
||||
nk_input_unicode(&d3d9.ctx, (nk_rune)wparam);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_RBUTTONDOWN:
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_RBUTTONUP:
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_MBUTTONDOWN:
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
SetCapture(wnd);
|
||||
return 1;
|
||||
|
||||
case WM_MBUTTONUP:
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
|
||||
ReleaseCapture();
|
||||
return 1;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
nk_input_scroll(&d3d9.ctx, nk_vec2(0,(float)(short)HIWORD(wparam) / WHEEL_DELTA));
|
||||
return 1;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
nk_input_motion(&d3d9.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam));
|
||||
return 1;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
nk_input_button(&d3d9.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nk_d3d9_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
(void)usr;
|
||||
if (!IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
|
||||
if (!mem) {
|
||||
CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
SIZE_T size = GlobalSize(mem) - 1;
|
||||
if (!size) {
|
||||
CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
|
||||
if (!wstr) {
|
||||
CloseClipboard();
|
||||
return;
|
||||
}
|
||||
|
||||
int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)size / sizeof(wchar_t), NULL, 0, NULL, NULL);
|
||||
if (utf8size) {
|
||||
char *utf8 = (char *)malloc(utf8size);
|
||||
if (utf8) {
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, (int)size / sizeof(wchar_t), utf8, utf8size, NULL, NULL);
|
||||
nk_textedit_paste(edit, utf8, utf8size);
|
||||
free(utf8);
|
||||
}
|
||||
}
|
||||
|
||||
GlobalUnlock(mem);
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
static void
|
||||
nk_d3d9_clipboard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
(void)usr;
|
||||
if (!OpenClipboard(NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
|
||||
if (wsize) {
|
||||
HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
|
||||
if (mem) {
|
||||
wchar_t *wstr = (wchar_t*)GlobalLock(mem);
|
||||
if (wstr) {
|
||||
MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
|
||||
wstr[wsize] = 0;
|
||||
GlobalUnlock(mem);
|
||||
SetClipboardData(CF_UNICODETEXT, mem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseClipboard();
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_d3d9_init(IDirect3DDevice9 *device, int width, int height)
|
||||
{
|
||||
d3d9.device = device;
|
||||
IDirect3DDevice9_AddRef(device);
|
||||
|
||||
nk_init_default(&d3d9.ctx, 0);
|
||||
d3d9.state = NULL;
|
||||
d3d9.texture = NULL;
|
||||
d3d9.ctx.clip.copy = nk_d3d9_clipboard_copy;
|
||||
d3d9.ctx.clip.paste = nk_d3d9_clipboard_paste;
|
||||
d3d9.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
|
||||
nk_buffer_init_default(&d3d9.cmds);
|
||||
|
||||
/* viewport */
|
||||
d3d9.viewport.X = 0;
|
||||
d3d9.viewport.Y = 0;
|
||||
d3d9.viewport.MinZ = 0.0f;
|
||||
d3d9.viewport.MaxZ = 1.0f;
|
||||
|
||||
nk_d3d9_resize(width, height);
|
||||
|
||||
return &d3d9.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_d3d9_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&d3d9.atlas);
|
||||
nk_font_atlas_begin(&d3d9.atlas);
|
||||
*atlas = &d3d9.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_d3d9_font_stash_end(void)
|
||||
{
|
||||
nk_d3d9_create_font_texture();
|
||||
|
||||
if (d3d9.atlas.default_font)
|
||||
nk_style_set_font(&d3d9.ctx, &d3d9.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_d3d9_shutdown(void)
|
||||
{
|
||||
nk_d3d9_release();
|
||||
|
||||
nk_font_atlas_clear(&d3d9.atlas);
|
||||
nk_buffer_free(&d3d9.cmds);
|
||||
nk_free(&d3d9.ctx);
|
||||
}
|
||||
|
||||
#endif
|
@ -3137,6 +3137,7 @@ NK_FORMAT_COLOR_BEGIN,
|
||||
NK_FORMAT_R32G32B32,
|
||||
|
||||
NK_FORMAT_R8G8B8A8,
|
||||
NK_FORMAT_B8G8R8A8,
|
||||
NK_FORMAT_R16G15B16A16,
|
||||
NK_FORMAT_R32G32B32A32,
|
||||
NK_FORMAT_R32G32B32A32_FLOAT,
|
||||
@ -7906,6 +7907,11 @@ nk_draw_vertex_color(void *attribute, const float *values,
|
||||
struct nk_color col = nk_rgba_fv(values);
|
||||
NK_MEMCPY(attribute, &col.r, sizeof(col));
|
||||
} break;
|
||||
case NK_FORMAT_B8G8R8A8: {
|
||||
struct nk_color col = nk_rgba_fv(values);
|
||||
struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a);
|
||||
NK_MEMCPY(attribute, &bgra, sizeof(bgra));
|
||||
} break;
|
||||
case NK_FORMAT_R16G15B16: {
|
||||
nk_ushort col[3];
|
||||
col[0] = (nk_ushort)NK_CLAMP(NK_USHORT_MIN, values[0] * NK_USHORT_MAX, NK_USHORT_MAX);
|
||||
|
Loading…
Reference in New Issue
Block a user