From e6f5e43d854981e9f67395b5699df1a788cf0406 Mon Sep 17 00:00:00 2001 From: shuiyu1123 Date: Sat, 11 Jul 2026 01:17:42 +0800 Subject: [PATCH] fix: editor rendering - depth test, shader binding, atlas SRV, projection transpose --- Demo/editor_main.c | 432 +++++++++++++++++---------------------------- 1 file changed, 160 insertions(+), 272 deletions(-) diff --git a/Demo/editor_main.c b/Demo/editor_main.c index 90d53f3..b986742 100644 --- a/Demo/editor_main.c +++ b/Demo/editor_main.c @@ -17,14 +17,14 @@ static GlyphAtlas g_atlas; static ID3D11DepthStencilState* g_no_depth = NULL; static ID3D11RasterizerState* g_no_cull = NULL; static ID3D11BlendState* g_alpha_blend = NULL; +static ID3D11SamplerState* g_sampler = NULL; +static ID3D11Buffer* g_cb = NULL; static ID3D11VertexShader* g_vs = NULL; static ID3D11PixelShader* g_ps = NULL; static ID3D11InputLayout* g_layout = NULL; -static ID3D11Buffer* g_cb = NULL; -static ID3D11SamplerState* g_sampler = NULL; -static ID3D11PixelShader* g_tex_ps = NULL; static ID3D11VertexShader* g_tex_vs = NULL; +static ID3D11PixelShader* g_tex_ps = NULL; static ID3D11InputLayout* g_tex_layout = NULL; typedef struct { float p[3], n[3], uv[2], c[4]; } V; @@ -54,6 +54,13 @@ static void draw_quad(ID3D11DeviceContext* ctx, float x, float y, float w, float static void draw_text(ID3D11DeviceContext* ctx, const wchar_t* text, int x, int y, float r, float g, float b, float a) { typedef struct { float p[3], n[3], uv[2], c[4]; } TV; + ctx->lpVtbl->VSSetShader(ctx, g_tex_vs, NULL, 0); + ctx->lpVtbl->PSSetShader(ctx, g_tex_ps, NULL, 0); + ctx->lpVtbl->IASetInputLayout(ctx, g_tex_layout); + ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_cb); + ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_atlas.srv); + ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &g_sampler); + ctx->lpVtbl->OMSetBlendState(ctx, g_alpha_blend, NULL, 0xFFFFFFFF); for (const wchar_t* p = text; *p; p++) { float u0, v0, u1, v1, adv_x, adv_y; if (!glyph_atlas_get_or_create(&g_atlas, g_dev->device, ctx, *p, &u0, &v0, &u1, &v1, &adv_x, &adv_y)) continue; @@ -79,374 +86,255 @@ static void draw_text(ID3D11DeviceContext* ctx, const wchar_t* text, } } +static void setup_solid(ID3D11DeviceContext* ctx) { + ctx->lpVtbl->VSSetShader(ctx, g_vs, NULL, 0); + ctx->lpVtbl->PSSetShader(ctx, g_ps, NULL, 0); + ctx->lpVtbl->IASetInputLayout(ctx, g_layout); + ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_cb); + ctx->lpVtbl->OMSetBlendState(ctx, NULL, NULL, 0xFFFFFFFF); +} + static void setup_2d(ID3D11DeviceContext* ctx, float sw, float sh) { float proj[16] = {0}; proj[0] = 2.0f / sw; proj[5] = -2.0f / sh; proj[10] = 1.0f; proj[12] = -1.0f; proj[13] = 1.0f; proj[15] = 1.0f; - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_cb, 0, NULL, proj, 0, 0); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_cb); + Mat4 proj_m, proj_t; + memcpy(&proj_m, proj, sizeof(Mat4)); + mat4_transpose(&proj_m, &proj_t); + ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_cb, 0, NULL, &proj_t, 0, 0); D3D11_VIEWPORT vp = {0}; vp.Width = sw; vp.Height = sh; vp.MaxDepth = 1.0f; ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); ctx->lpVtbl->RSSetState(ctx, g_no_cull); ctx->lpVtbl->OMSetDepthStencilState(ctx, g_no_depth, 0); ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); -} - -static void setup_text_shader(ID3D11DeviceContext* ctx) { - ctx->lpVtbl->VSSetShader(ctx, g_tex_vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, g_tex_ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, g_tex_layout); - ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &g_sampler); - ctx->lpVtbl->OMSetBlendState(ctx, g_alpha_blend, NULL, 0xFFFFFFFF); + setup_solid(ctx); } typedef struct { char name[64]; - float x, y, z; - float rx, ry, rz; - float sx, sy, sz; + float x, y, z, rx, ry, rz, sx, sy, sz; int visible; } SceneEntity; #define MAX_ENTITIES 64 static SceneEntity g_entities[MAX_ENTITIES]; static int g_entity_count = 0; -static int g_selected = -1; - -typedef struct { - char lines[64][256]; - int count; - int scroll; -} ConsoleState; -static ConsoleState g_console = {0}; - +static int g_selected = 2; +static char g_console_lines[32][256]; +static int g_console_count = 0; static char g_file_path[512] = "untitled.ly"; static void console_add(const char* msg) { - if (g_console.count >= 64) { - for (int i = 0; i < 63; i++) - strcpy(g_console.lines[i], g_console.lines[i+1]); - g_console.count = 63; + if (g_console_count >= 32) { + for (int i = 0; i < 31; i++) strcpy(g_console_lines[i], g_console_lines[i+1]); + g_console_count = 31; } - strncpy(g_console.lines[g_console.count], msg, 255); - g_console.lines[g_console.count][255] = 0; - g_console.count++; + strncpy(g_console_lines[g_console_count], msg, 255); + g_console_lines[g_console_count][255] = 0; + g_console_count++; } -static void save_ly_file(const char* path) { +static void save_ly(const char* path) { FILE* f = fopen(path, "w"); - if (!f) { console_add("ERROR: cannot save file"); return; } - fprintf(f, "# lity3d scene file\n"); - fprintf(f, "# format: ly (lity)\n\n"); + if (!f) { console_add("ERROR: save failed"); return; } + fprintf(f, "# lity3d scene\n# format: .ly\n\n"); for (int i = 0; i < g_entity_count; i++) { SceneEntity* e = &g_entities[i]; - fprintf(f, "[Entity]\n"); - fprintf(f, "name = %s\n", e->name); + fprintf(f, "[Entity]\nname = %s\n", e->name); fprintf(f, "position = %.2f, %.2f, %.2f\n", e->x, e->y, e->z); fprintf(f, "rotation = %.2f, %.2f, %.2f\n", e->rx, e->ry, e->rz); fprintf(f, "scale = %.2f, %.2f, %.2f\n", e->sx, e->sy, e->sz); fprintf(f, "visible = %d\n\n", e->visible); } fclose(f); - char buf[256]; - snprintf(buf, sizeof(buf), "Saved %d entities to %s", g_entity_count, path); + char buf[128]; snprintf(buf, sizeof(buf), "Saved %d entities -> %s", g_entity_count, path); console_add(buf); } -static void load_ly_file(const char* path) { +static void load_ly(const char* path) { FILE* f = fopen(path, "r"); - if (!f) { console_add("ERROR: cannot open file"); return; } - g_entity_count = 0; - g_selected = -1; - char line[256]; - SceneEntity tmp = {0}; - int in_entity = 0; + if (!f) { console_add("ERROR: open failed"); return; } + g_entity_count = 0; g_selected = -1; + char line[256]; SceneEntity tmp = {0}; int in_e = 0; while (fgets(line, sizeof(line), f)) { if (line[0] == '#' || line[0] == '\n') continue; if (strstr(line, "[Entity]")) { - if (in_entity && g_entity_count < MAX_ENTITIES) - g_entities[g_entity_count++] = tmp; - memset(&tmp, 0, sizeof(tmp)); - tmp.visible = 1; - tmp.sx = tmp.sy = tmp.sz = 1.0f; - in_entity = 1; - continue; + if (in_e && g_entity_count < MAX_ENTITIES) g_entities[g_entity_count++] = tmp; + memset(&tmp, 0, sizeof(tmp)); tmp.visible = 1; tmp.sx = tmp.sy = tmp.sz = 1.0f; in_e = 1; continue; } - if (!in_entity) continue; - char* eq = strchr(line, '='); - if (!eq) continue; - *eq = 0; eq++; - char* key = line; - while (*key == ' ' || *key == '\t') key++; - char* nl = strchr(eq, '\n'); if (nl) *nl = 0; - while (*eq == ' ') eq++; + if (!in_e) continue; + char* eq = strchr(line, '='); if (!eq) continue; + *eq = 0; eq++; char* key = line; while (*key == ' ') key++; + char* nl = strchr(eq, '\n'); if (nl) *nl = 0; while (*eq == ' ') eq++; if (strstr(key, "name")) strncpy(tmp.name, eq, 63); else if (strstr(key, "position")) sscanf(eq, "%f, %f, %f", &tmp.x, &tmp.y, &tmp.z); else if (strstr(key, "rotation")) sscanf(eq, "%f, %f, %f", &tmp.rx, &tmp.ry, &tmp.rz); else if (strstr(key, "scale")) sscanf(eq, "%f, %f, %f", &tmp.sx, &tmp.sy, &tmp.sz); else if (strstr(key, "visible")) tmp.visible = atoi(eq); } - if (in_entity && g_entity_count < MAX_ENTITIES) - g_entities[g_entity_count++] = tmp; - fclose(f); - char buf[256]; - snprintf(buf, sizeof(buf), "Loaded %d entities from %s", g_entity_count, path); - console_add(buf); - strncpy(g_file_path, path, 511); + if (in_e && g_entity_count < MAX_ENTITIES) g_entities[g_entity_count++] = tmp; + fclose(f); char buf[128]; + snprintf(buf, sizeof(buf), "Loaded %d entities <- %s", g_entity_count, path); + console_add(buf); strncpy(g_file_path, path, 511); } -static void add_default_scene(void) { +static void init_default_scene(void) { g_entity_count = 0; - const char* names[] = {"Camera", "Directional Light", "Player", "Ground", "Tree", "Rock", "Water", "Skybox"}; - for (int i = 0; i < 8 && i < 8; i++) { - strncpy(g_entities[i].name, names[i], 63); - g_entities[i].visible = 1; + const char* n[] = {"Camera","DirectionalLight","Player","Ground","Tree","Rock","Water","Skybox"}; + for (int i = 0; i < 8; i++) { + strncpy(g_entities[i].name, n[i], 63); g_entities[i].visible = 1; g_entities[i].sx = g_entities[i].sy = g_entities[i].sz = 1.0f; } - g_entity_count = 8; - g_selected = 2; + g_entity_count = 8; g_selected = 2; } static void on_render(Engine* engine) { if (!g_dev) return; ID3D11DeviceContext* ctx = g_dev->context; - float sw = (float)g_dev->width; - float sh = (float)g_dev->height; + float sw = (float)g_dev->width, sh = (float)g_dev->height; - graphics_device_clear(g_dev, 0.12f, 0.12f, 0.14f, 1.0f); + graphics_device_clear(g_dev, 0.10f, 0.10f, 0.12f, 1.0f); setup_2d(ctx, sw, sh); - float menu_h = 28, toolbar_h = 28, console_h = 180, panel_w = 220; - float status_h = 22; + float mh = 28, th = 28, ch = 180, pw = 220, sh2 = 22; + draw_quad(ctx, 0, 0, sw, mh, 0.20f, 0.22f, 0.35f, 1.0f); + draw_quad(ctx, 0, mh, sw, th, 0.17f, 0.18f, 0.28f, 1.0f); + draw_quad(ctx, 0, mh+th, pw, sh-mh-th-ch-sh2, 0.15f, 0.15f, 0.22f, 1.0f); + draw_quad(ctx, pw, mh+th, sw-2*pw, sh-mh-th-ch-sh2, 0.10f, 0.10f, 0.14f, 1.0f); + draw_quad(ctx, sw-pw, mh+th, pw, sh-mh-th-ch-sh2, 0.15f, 0.15f, 0.22f, 1.0f); + draw_quad(ctx, 0, sh-ch-sh2, sw, ch, 0.12f, 0.12f, 0.18f, 1.0f); + draw_quad(ctx, 0, sh-sh2, sw, sh2, 0.18f, 0.18f, 0.28f, 1.0f); - draw_quad(ctx, 0, 0, sw, menu_h, 0.18f, 0.18f, 0.22f, 1.0f); - draw_quad(ctx, 0, menu_h, sw, toolbar_h, 0.16f, 0.16f, 0.19f, 1.0f); - draw_quad(ctx, 0, menu_h + toolbar_h, panel_w, sh - menu_h - toolbar_h - console_h - status_h, 0.14f, 0.14f, 0.16f, 1.0f); - draw_quad(ctx, panel_w, menu_h + toolbar_h, sw - 2*panel_w, sh - menu_h - toolbar_h - console_h - status_h, 0.10f, 0.10f, 0.12f, 1.0f); - draw_quad(ctx, sw - panel_w, menu_h + toolbar_h, panel_w, sh - menu_h - toolbar_h - console_h - status_h, 0.14f, 0.14f, 0.16f, 1.0f); - draw_quad(ctx, 0, sh - console_h - status_h, sw, console_h, 0.13f, 0.13f, 0.15f, 1.0f); - draw_quad(ctx, 0, sh - status_h, sw, status_h, 0.16f, 0.16f, 0.20f, 1.0f); + draw_quad(ctx, 0, 0, sw, 2, 0.30f, 0.40f, 0.80f, 1.0f); - draw_quad(ctx, 0, 0, sw, 1, 0.30f, 0.30f, 0.35f, 1.0f); - - setup_text_shader(ctx); - ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_atlas.srv); - - draw_text(ctx, L"lity3d Editor", 10, 6, 0.6f, 0.8f, 1.0f, 1.0f); + draw_text(ctx, L"lity3d Editor", 10, 6, 0.7f, 0.85f, 1.0f, 1.0f); const wchar_t* menus[] = {L"\u6587\u4ef6", L"\u7f16\u8f91", L"\u89c6\u56fe", L"\u6784\u5efa", L"\u5e2e\u52a9"}; int mx = 120; - for (int i = 0; i < 5; i++) { - draw_text(ctx, menus[i], mx, 6, 0.85f, 0.85f, 0.88f, 1.0f); - mx += 70; - } - - draw_text(ctx, L"\u573a\u666f", 10, 36, 0.85f, 0.85f, 0.88f, 1.0f); - draw_text(ctx, L"\u89c6\u53e3", (int)(panel_w + 10), 36, 0.85f, 0.85f, 0.88f, 1.0f); - draw_text(ctx, L"\u5c5e\u6027", (int)(sw - panel_w + 10), 36, 0.85f, 0.85f, 0.88f, 1.0f); - draw_text(ctx, L"\u63a7\u5236\u53f0", 10, (int)(sh - console_h - status_h + 6), 0.85f, 0.85f, 0.88f, 1.0f); + for (int i = 0; i < 5; i++) { draw_text(ctx, menus[i], mx, 8, 0.9f, 0.9f, 0.92f, 1.0f); mx += 70; } + draw_text(ctx, L"\u573a\u666f", 10, 36, 0.9f, 0.9f, 0.92f, 1.0f); + draw_text(ctx, L"\u89c6\u53e3", (int)(pw+10), 36, 0.9f, 0.9f, 0.92f, 1.0f); + draw_text(ctx, L"\u5c5e\u6027", (int)(sw-pw+10), 36, 0.9f, 0.9f, 0.92f, 1.0f); + draw_text(ctx, L"\u63a7\u5236\u53f0", 10, (int)(sh-ch-sh2+6), 0.9f, 0.9f, 0.92f, 1.0f); for (int i = 0; i < g_entity_count; i++) { float ey = 60 + i * 22; - if (i == g_selected) - draw_quad(ctx, 4, (float)(int)ey - 2, panel_w - 8, 20, 0.25f, 0.30f, 0.45f, 1.0f); - float cr = (g_entities[i].visible) ? 0.9f : 0.5f; - draw_text(ctx, L"\u25b6", 10, (int)ey, cr, cr, cr, 1.0f); - wchar_t wname[64]; - int len = (int)strlen(g_entities[i].name); - for (int j = 0; j < len && j < 63; j++) wname[j] = (wchar_t)g_entities[i].name[j]; - wname[len] = 0; - draw_text(ctx, wname, 28, (int)ey, cr, cr, cr, 1.0f); + if (i == g_selected) draw_quad(ctx, 4, ey-2, pw-8, 20, 0.25f, 0.30f, 0.50f, 1.0f); + wchar_t wn[64]; int len = (int)strlen(g_entities[i].name); + for (int j = 0; j < len && j < 63; j++) wn[j] = (wchar_t)g_entities[i].name[j]; + wn[len] = 0; + draw_text(ctx, wn, 28, (int)ey, 0.85f, 0.85f, 0.88f, 1.0f); } if (g_selected >= 0 && g_selected < g_entity_count) { - SceneEntity* e = &g_entities[g_selected]; - int ix = (int)(sw - panel_w + 10); - int iy = 60; + SceneEntity* e = &g_entities[g_selected]; int ix = (int)(sw-pw+10), iy = 60; draw_text(ctx, L"\u540d\u79f0:", ix, iy, 0.6f, 0.7f, 0.9f, 1.0f); - wchar_t wname[64]; - int len = (int)strlen(e->name); - for (int j = 0; j < len && j < 63; j++) wname[j] = (wchar_t)e->name[j]; - wname[len] = 0; - draw_text(ctx, wname, ix + 40, iy, 0.9f, 0.9f, 0.92f, 1.0f); - iy += 26; - draw_text(ctx, L"\u4f4d\u7f6e:", ix, iy, 0.6f, 0.7f, 0.9f, 1.0f); - iy += 18; - draw_text(ctx, L"\u65cb\u8f6c:", ix, iy, 0.6f, 0.7f, 0.9f, 1.0f); - iy += 18; - draw_text(ctx, L"\u7f29\u653e:", ix, iy, 0.6f, 0.7f, 0.9f, 1.0f); - iy += 26; - draw_text(ctx, L"\u53ef\u89c1:", ix, iy, 0.6f, 0.7f, 0.9f, 1.0f); - draw_text(ctx, e->visible ? L"\u2611" : L"\u2610", ix + 40, iy, 0.9f, 0.9f, 0.92f, 1.0f); + wchar_t wn[64]; int len = (int)strlen(e->name); + for (int j = 0; j < len && j < 63; j++) wn[j] = (wchar_t)e->name[j]; wn[len] = 0; + draw_text(ctx, wn, ix+40, iy, 0.9f, 0.9f, 0.92f, 1.0f); + iy += 22; + draw_text(ctx, L"\u53ef\u89c1: \u2611", ix, iy, 0.9f, 0.9f, 0.92f, 1.0f); } - int cy = (int)(sh - console_h - status_h + 22); - for (int i = 0; i < g_console.count && i < 8; i++) { - int li = g_console.count - 1 - i; - if (li < 0) break; - wchar_t wline[256]; - int len = (int)strlen(g_console.lines[li]); - for (int j = 0; j < len && j < 255; j++) wline[j] = (wchar_t)g_console.lines[li][j]; - wline[len] = 0; - draw_text(ctx, wline, 10, cy, 0.7f, 0.7f, 0.72f, 1.0f); - cy += 18; + int cy = (int)(sh-ch-sh2+24); + for (int i = g_console_count-1; i >= 0 && i >= g_console_count-6; i--) { + wchar_t wl[256]; int len = (int)strlen(g_console_lines[i]); + for (int j = 0; j < len && j < 255; j++) wl[j] = (wchar_t)g_console_lines[i][j]; + wl[len] = 0; draw_text(ctx, wl, 10, cy, 0.65f, 0.65f, 0.7f, 1.0f); cy += 18; } char status[256]; - snprintf(status, sizeof(status), "%s | %d entities | %.1fs", g_file_path, g_entity_count, engine->total_time); - wchar_t wstatus[256]; - int slen = (int)strlen(status); - for (int j = 0; j < slen && j < 255; j++) wstatus[j] = (wchar_t)status[j]; - wstatus[slen] = 0; - draw_text(ctx, wstatus, 10, (int)(sh - 18), 0.55f, 0.55f, 0.6f, 1.0f); + snprintf(status, sizeof(status), "%s | %d entities | Ctrl+S save .ly | Esc quit", g_file_path, g_entity_count); + wchar_t ws[256]; int sl = (int)strlen(status); + for (int j = 0; j < sl && j < 255; j++) ws[j] = (wchar_t)status[j]; ws[sl] = 0; + draw_text(ctx, ws, 10, (int)(sh-18), 0.5f, 0.5f, 0.55f, 1.0f); graphics_device_present(g_dev); } static void on_key(Engine* engine, int key) { if (key == VK_ESCAPE) engine_request_quit(engine); - if (key == 'S' && GetAsyncKeyState(VK_CONTROL) & 0x8000) { - save_ly_file(g_file_path); - } - if (key == 'O' && GetAsyncKeyState(VK_CONTROL) & 0x8000) { - load_ly_file(g_file_path); - } + if (key == 'S' && GetAsyncKeyState(VK_CONTROL) & 0x8000) save_ly(g_file_path); + if (key == 'O' && GetAsyncKeyState(VK_CONTROL) & 0x8000) load_ly(g_file_path); } -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - (void)hInstance; (void)hPrevInstance; (void)nCmdShow; +static int compile_shader(ID3D11Device* dev, const char* vs, const char* ps, + ID3D11VertexShader** out_vs, ID3D11PixelShader** out_ps, + ID3D11InputLayout** out_layout) { + ID3DBlob *b1=NULL,*b2=NULL,*e=NULL; + D3DCompile(vs,(UINT)strlen(vs),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&e); if(e){e->lpVtbl->Release(e);e=NULL;} + D3DCompile(ps,(UINT)strlen(ps),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&e); if(e){e->lpVtbl->Release(e);e=NULL;} + if(!b1||!b2) return 0; + dev->lpVtbl->CreateVertexShader(dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,out_vs); + dev->lpVtbl->CreatePixelShader(dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,out_ps); + D3D11_INPUT_ELEMENT_DESC layout[] = { + {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, + {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, + {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, + {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, + }; + dev->lpVtbl->CreateInputLayout(dev,layout,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),out_layout); + b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); + return 1; +} + +int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { + (void)hI;(void)hP;(void)nS; LOG_INFO("=== lity3d Editor ==="); - - EngineConfig config = engine_default_config(); - config.app_name = "lity3d Editor"; - config.vsync = 1; - config.window_width = 1440; - config.window_height = 900; - + EngineConfig cfg = engine_default_config(); + cfg.app_name = "lity3d Editor"; + cfg.vsync = 1; cfg.window_width = 1440; cfg.window_height = 900; Engine* engine = engine_create(); - if (!engine_init(engine, &config)) return -1; - + if (!engine_init(engine, &cfg)) return -1; g_dev = graphics_device_create(); - if (!graphics_device_init(g_dev, window_get_handle(engine->window), config.window_width, config.window_height, 1)) { - LOG_FATAL("D3D11 init failed"); - return -1; - } - + if (!graphics_device_init(g_dev, window_get_handle(engine->window), cfg.window_width, cfg.window_height, 1)) return -1; glyph_atlas_init(&g_atlas, g_dev->device); - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device, &dsdesc, &g_no_depth); - - D3D11_RASTERIZER_DESC rdesc = {0}; - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device, &rdesc, &g_no_cull); - - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; - g_dev->device->lpVtbl->CreateBlendState(g_dev->device, &bdesc, &g_alpha_blend); - - D3D11_SAMPLER_DESC sdesc = {0}; - sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sdesc.AddressU = sdesc.AddressV = sdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - g_dev->device->lpVtbl->CreateSamplerState(g_dev->device, &sdesc, &g_sampler); - - const char* solid_vs = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float4 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(i.p,WVP);o.u=i.u;o.c=i.c;return o;}"; - const char* solid_ps = - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{return i.c;}"; - const char* tex_vs = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float4 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(i.p,WVP);o.u=i.u;o.c=i.c;return o;}"; - const char* tex_ps = - "Texture2D t:register(t0);SamplerState s:register(s0);" - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{float a=t.t.Sample(s,i.u).a;return float4(i.c.rgb,i.c.a*a);}"; - - ID3DBlob *b1 = NULL, *b2 = NULL, *e1 = NULL, *e2 = NULL; - D3DCompile(solid_vs, (UINT)strlen(solid_vs), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &b1, &e1); - if (e1) { e1->lpVtbl->Release(e1); e1 = NULL; } - D3DCompile(solid_ps, (UINT)strlen(solid_ps), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &b2, &e2); - if (e2) { e2->lpVtbl->Release(e2); e2 = NULL; } - if (b1 && b2) { - g_dev->device->lpVtbl->CreateVertexShader(g_dev->device, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), NULL, &g_vs); - g_dev->device->lpVtbl->CreatePixelShader(g_dev->device, b2->lpVtbl->GetBufferPointer(b2), b2->lpVtbl->GetBufferSize(b2), NULL, &g_ps); - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - g_dev->device->lpVtbl->CreateInputLayout(g_dev->device, layout, 4, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), &g_layout); - b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); - } - - ID3DBlob *b3 = NULL, *b4 = NULL, *e3 = NULL, *e4 = NULL; - D3DCompile(tex_vs, (UINT)strlen(tex_vs), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &b3, &e3); - if (e3) { e3->lpVtbl->Release(e3); e3 = NULL; } - D3DCompile(tex_ps, (UINT)strlen(tex_ps), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &b4, &e4); - if (e4) { e4->lpVtbl->Release(e4); e4 = NULL; } - if (b3 && b4) { - g_dev->device->lpVtbl->CreateVertexShader(g_dev->device, b3->lpVtbl->GetBufferPointer(b3), b3->lpVtbl->GetBufferSize(b3), NULL, &g_tex_vs); - g_dev->device->lpVtbl->CreatePixelShader(g_dev->device, b4->lpVtbl->GetBufferPointer(b4), b4->lpVtbl->GetBufferSize(b4), NULL, &g_tex_ps); - D3D11_INPUT_ELEMENT_DESC layout2[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - g_dev->device->lpVtbl->CreateInputLayout(g_dev->device, layout2, 4, b3->lpVtbl->GetBufferPointer(b3), b3->lpVtbl->GetBufferSize(b3), &g_tex_layout); - b3->lpVtbl->Release(b3); b4->lpVtbl->Release(b4); - } - - D3D11_BUFFER_DESC cbd = {0}; - cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + D3D11_DEPTH_STENCIL_DESC dsd = {0}; dsd.DepthEnable = FALSE; dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device, &dsd, &g_no_depth); + D3D11_RASTERIZER_DESC rd = {0}; rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; + g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device, &rd, &g_no_cull); + D3D11_BLEND_DESC bd = {0}; bd.RenderTarget[0].BlendEnable = TRUE; + bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + bd.RenderTarget[0].RenderTargetWriteMask = 0x0F; + g_dev->device->lpVtbl->CreateBlendState(g_dev->device, &bd, &g_alpha_blend); + D3D11_SAMPLER_DESC sd = {0}; sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + sd.AddressU = sd.AddressV = sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + g_dev->device->lpVtbl->CreateSamplerState(g_dev->device, &sd, &g_sampler); + D3D11_BUFFER_DESC cbd = {0}; cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &cbd, NULL, &g_cb); - if (lpCmdLine && lpCmdLine[0]) { - char fname[512] = {0}; - if (lpCmdLine[0] == '"') { strncpy(fname, lpCmdLine+1, 510); char* q = strchr(fname, '"'); if (q) *q = 0; } - else strncpy(fname, lpCmdLine, 510); - load_ly_file(fname); - } else { - add_default_scene(); - } + const char* solid_vs = "cbuffer CB:register(b0){float4x4 WVP;};struct I{float4 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};O main(I i){O o;o.p=mul(i.p,WVP);o.u=i.u;o.c=i.c;return o;}"; + const char* solid_ps = "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};float4 main(O i):SV_TARGET{return i.c;}"; + compile_shader(g_dev->device, solid_vs, solid_ps, &g_vs, &g_ps, &g_layout); - console_add("lity3d Editor started"); - console_add("Ctrl+S: save .ly | Ctrl+O: load .ly | Esc: quit"); + const char* tex_vs = "cbuffer CB:register(b0){float4x4 WVP;};struct I{float4 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};O main(I i){O o;o.p=mul(i.p,WVP);o.u=i.u;o.c=i.c;return o;}"; + const char* tex_ps = "Texture2D t:register(t0);SamplerState s:register(s0);struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};float4 main(O i):SV_TARGET{float a=t.Sample(s,i.u).a;return float4(i.c.rgb,i.c.a*a);}"; + compile_shader(g_dev->device, tex_vs, tex_ps, &g_tex_vs, &g_tex_ps, &g_tex_layout); + + if (cmd && cmd[0]) { load_ly(cmd); } + else { init_default_scene(); } + console_add("lity3d Editor ready"); + console_add("Ctrl+S save .ly | Ctrl+O load .ly | Esc quit"); engine_set_render_callback(engine, on_render); engine_set_key_callback(engine, on_key); engine_run(engine); - if (g_tex_layout) g_tex_layout->lpVtbl->Release(g_tex_layout); - if (g_tex_ps) g_tex_ps->lpVtbl->Release(g_tex_ps); - if (g_tex_vs) g_tex_vs->lpVtbl->Release(g_tex_vs); - if (g_layout) g_layout->lpVtbl->Release(g_layout); - if (g_ps) g_ps->lpVtbl->Release(g_ps); - if (g_vs) g_vs->lpVtbl->Release(g_vs); - if (g_cb) g_cb->lpVtbl->Release(g_cb); - if (g_sampler) g_sampler->lpVtbl->Release(g_sampler); - if (g_alpha_blend) g_alpha_blend->lpVtbl->Release(g_alpha_blend); - if (g_no_cull) g_no_cull->lpVtbl->Release(g_no_cull); - if (g_no_depth) g_no_depth->lpVtbl->Release(g_no_depth); + if(g_tex_layout)g_tex_layout->lpVtbl->Release(g_tex_layout); + if(g_tex_ps)g_tex_ps->lpVtbl->Release(g_tex_ps); + if(g_tex_vs)g_tex_vs->lpVtbl->Release(g_tex_vs); + if(g_layout)g_layout->lpVtbl->Release(g_layout); + if(g_ps)g_ps->lpVtbl->Release(g_ps); + if(g_vs)g_vs->lpVtbl->Release(g_vs); + if(g_cb)g_cb->lpVtbl->Release(g_cb); + if(g_sampler)g_sampler->lpVtbl->Release(g_sampler); + if(g_alpha_blend)g_alpha_blend->lpVtbl->Release(g_alpha_blend); + if(g_no_cull)g_no_cull->lpVtbl->Release(g_no_cull); + if(g_no_depth)g_no_depth->lpVtbl->Release(g_no_depth); glyph_atlas_destroy(&g_atlas); - graphics_device_destroy(g_dev); - engine_shutdown(engine); + graphics_device_destroy(g_dev); engine_shutdown(engine); return 0; }