Bloom on sculpture
This commit is contained in:
parent
d7520367e2
commit
1b7a9c6841
|
@ -1,3 +1,3 @@
|
||||||
SCRIPT_REL_DIR=$(dirname "${BASH_SOURCE[0]}")
|
SCRIPT_REL_DIR=$(dirname "${BASH_SOURCE[0]}")
|
||||||
$SCRIPT_REL_DIR/build_.sh prod osx arm64
|
$SCRIPT_REL_DIR/build_.sh debug osx arm64
|
||||||
# $SCRIPT_REL_DIR/build_.sh debug wasm intel
|
# $SCRIPT_REL_DIR/build_.sh debug wasm intel
|
Binary file not shown.
Binary file not shown.
|
@ -42,12 +42,18 @@ struct Geometry_Buffer
|
||||||
u32 indices_len;
|
u32 indices_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct Texture_Desc Texture_Desc;
|
||||||
|
struct Texture_Desc
|
||||||
|
{
|
||||||
|
u32 w, h, s;
|
||||||
|
u32 mag_filter, min_filter, fmt_internal, fmt_data;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct Texture Texture;
|
typedef struct Texture Texture;
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
u32 id;
|
u32 id;
|
||||||
|
Texture_Desc desc;
|
||||||
u32 w, h, s;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Graphics_Frame_Desc Graphics_Frame_Desc;
|
typedef struct Graphics_Frame_Desc Graphics_Frame_Desc;
|
||||||
|
@ -66,6 +72,8 @@ Geometry_Buffer geometry_buffer_create(r32* vertices, u32 vertices_len, u32* ind
|
||||||
Shader shader_create(String code_vert, String code_frag, String* attribs, u32 attribs_len, String* uniforms, u32 uniforms_len);
|
Shader shader_create(String code_vert, String code_frag, String* attribs, u32 attribs_len, String* uniforms, u32 uniforms_len);
|
||||||
void geometry_buffer_update(Geometry_Buffer* buffer, r32* verts, u32 verts_offset, u32 verts_len, u32* indices, u32 indices_offset, u32 indices_len);
|
void geometry_buffer_update(Geometry_Buffer* buffer, r32* verts, u32 verts_offset, u32 verts_len, u32* indices, u32 indices_offset, u32 indices_len);
|
||||||
|
|
||||||
|
Geometry_Buffer unit_quad_create();
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
void geometry_bind(Geometry_Buffer geo);
|
void geometry_bind(Geometry_Buffer geo);
|
||||||
void shader_bind(Shader shader);
|
void shader_bind(Shader shader);
|
||||||
|
@ -75,7 +83,7 @@ void vertex_attrib_pointer(Geometry_Buffer geo, Shader shader, u32 count, u32 at
|
||||||
void set_uniform(Shader shader, u32 index, m44 u);
|
void set_uniform(Shader shader, u32 index, m44 u);
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
Texture texture_create(u8* pixels, u32 width, u32 height, u32 stride);
|
Texture texture_create(Texture_Desc desc, u8* pixels);
|
||||||
void texture_bind(Texture tex);
|
void texture_bind(Texture tex);
|
||||||
void texture_update(Texture tex, u8* new_pixels, u32 width, u32 height, u32 stride);
|
void texture_update(Texture tex, u8* new_pixels, u32 width, u32 height, u32 stride);
|
||||||
|
|
||||||
|
@ -170,6 +178,22 @@ geometry_buffer_update(
|
||||||
os_gl_no_error();
|
os_gl_no_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Geometry_Buffer
|
||||||
|
unit_quad_create()
|
||||||
|
{
|
||||||
|
r32 z = 0;
|
||||||
|
r32 r = 1;
|
||||||
|
r32 verts[] = {
|
||||||
|
// pos uv
|
||||||
|
-r, -r, z, 0, 0,
|
||||||
|
r, -r, z, 1, 0,
|
||||||
|
r, r, z, 1, 1,
|
||||||
|
-1, r, z, 0, 1,
|
||||||
|
};
|
||||||
|
u32 indices[] = { 0, 1, 2, 0, 2, 3 };
|
||||||
|
return geometry_buffer_create(verts, sizeof(verts) / sizeof(r32), indices, 6);
|
||||||
|
}
|
||||||
|
|
||||||
Shader
|
Shader
|
||||||
shader_create(String code_vert, String code_frag, String* attrs, u32 attrs_len, String* uniforms, u32 uniforms_len){
|
shader_create(String code_vert, String code_frag, String* attrs, u32 attrs_len, String* uniforms, u32 uniforms_len){
|
||||||
Shader result = {};
|
Shader result = {};
|
||||||
|
@ -300,8 +324,22 @@ void vertex_attrib_pointer(Geometry_Buffer geo, Shader shader, GLuint count, GLu
|
||||||
os_gl_no_error();
|
os_gl_no_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture_Desc
|
||||||
|
texture_desc_default(u32 width, u32 height)
|
||||||
|
{
|
||||||
|
return (Texture_Desc){
|
||||||
|
.w = width,
|
||||||
|
.h = height,
|
||||||
|
.s = width,
|
||||||
|
.min_filter = GL_NEAREST,
|
||||||
|
.mag_filter = GL_LINEAR,
|
||||||
|
.fmt_internal = GL_RGBA,
|
||||||
|
.fmt_data = GL_RGBA
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Texture
|
Texture
|
||||||
texture_create(u8* pixels, u32 width, u32 height, u32 stride)
|
texture_create(Texture_Desc desc, u8* pixels)
|
||||||
{
|
{
|
||||||
Texture result = {};
|
Texture result = {};
|
||||||
glGenTextures(1, &result.id);
|
glGenTextures(1, &result.id);
|
||||||
|
@ -312,27 +350,26 @@ texture_create(u8* pixels, u32 width, u32 height, u32 stride)
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, desc.min_filter);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, desc.mag_filter);
|
||||||
os_gl_no_error();
|
os_gl_no_error();
|
||||||
|
|
||||||
glTexImage2D(
|
glTexImage2D(
|
||||||
GL_TEXTURE_2D,
|
GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
GL_RGBA,
|
desc.fmt_internal,
|
||||||
width,
|
desc.w,
|
||||||
height,
|
desc.h,
|
||||||
0,
|
0,
|
||||||
GL_RGBA,
|
desc.fmt_data,
|
||||||
GL_UNSIGNED_BYTE,
|
GL_UNSIGNED_BYTE,
|
||||||
pixels
|
pixels
|
||||||
);
|
);
|
||||||
os_gl_no_error();
|
os_gl_no_error();
|
||||||
|
|
||||||
result.w = width;
|
result.desc = desc;
|
||||||
result.h = height;
|
|
||||||
result.s = stride;
|
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +379,7 @@ texture_update(Texture tex, u8* new_pixels, u32 width, u32 height, u32 stride)
|
||||||
// NOTE(PS): this function simply replaces the entire image
|
// NOTE(PS): this function simply replaces the entire image
|
||||||
// we can write a more granular version if we need it
|
// we can write a more granular version if we need it
|
||||||
|
|
||||||
assert(tex.w == width && tex.h == height && tex.s == stride);
|
assert(tex.desc.w == width && tex.desc.h == height && tex.desc.s == stride);
|
||||||
texture_bind(tex);
|
texture_bind(tex);
|
||||||
glTexSubImage2D(
|
glTexSubImage2D(
|
||||||
GL_TEXTURE_2D,
|
GL_TEXTURE_2D,
|
||||||
|
@ -370,8 +407,8 @@ frame_begin(Graphics_Frame_Desc desc)
|
||||||
glClearColor(cc.r, cc.g, cc.b, cc.a);
|
glClearColor(cc.r, cc.g, cc.b, cc.a);
|
||||||
|
|
||||||
v2 vmin = desc.viewport_min;
|
v2 vmin = desc.viewport_min;
|
||||||
v2 vmax = desc.viewport_max;
|
v2 vdim = HMM_SubtractVec2(desc.viewport_max, desc.viewport_min);
|
||||||
glViewport((GLsizei)vmin.x, (GLsizei)vmin.y, (GLint)vmax.x, (GLint)vmax.y);
|
glViewport((GLsizei)vmin.x, (GLsizei)vmin.y, (GLint)vdim.x, (GLint)vdim.y);
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
|
@ -11,7 +11,7 @@ ed_load_font_cb(File_Async_Job_Args result, u8* user_data)
|
||||||
invalid_code_path;
|
invalid_code_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
r32 scale = stbtt_ScaleForPixelHeight(&font, 18.0f);
|
r32 scale = stbtt_ScaleForPixelHeight(&font, 16.0f);
|
||||||
s32 ascent, descent, line_gap;
|
s32 ascent, descent, line_gap;
|
||||||
stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
|
stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
|
||||||
ui->font_ascent = (r32)ascent * scale;
|
ui->font_ascent = (r32)ascent * scale;
|
||||||
|
@ -19,6 +19,8 @@ ed_load_font_cb(File_Async_Job_Args result, u8* user_data)
|
||||||
ui->font_line_gap = (r32)line_gap * scale;
|
ui->font_line_gap = (r32)line_gap * scale;
|
||||||
if (ui->font_line_gap == 0) ui->font_line_gap = 5;
|
if (ui->font_line_gap == 0) ui->font_line_gap = 5;
|
||||||
|
|
||||||
|
ui->font_texture_scale = 2;
|
||||||
|
scale *= ui->font_texture_scale;
|
||||||
String c = lit_str("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]{}\\|;:'\",<.>/?`~");
|
String c = lit_str("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+[]{}\\|;:'\",<.>/?`~");
|
||||||
for (u64 i = 0; i < c.len; i++)
|
for (u64 i = 0; i < c.len; i++)
|
||||||
{
|
{
|
||||||
|
@ -28,7 +30,7 @@ ed_load_font_cb(File_Async_Job_Args result, u8* user_data)
|
||||||
s32 x0, y0, x1, y1;
|
s32 x0, y0, x1, y1;
|
||||||
stbtt_GetCodepointBitmapBoxSubpixel(&font, (char)c.str[i], scale, scale, 0, 0, &x0, &y0, &x1, &y1);
|
stbtt_GetCodepointBitmapBoxSubpixel(&font, (char)c.str[i], scale, scale, 0, 0, &x0, &y0, &x1, &y1);
|
||||||
|
|
||||||
v2 offset = (v2){ 0, (r32)y0 };
|
v2 offset = (v2){ 0, (r32)y0 / ui->font_texture_scale };
|
||||||
texture_atlas_register(&state->editor->ui.atlas, bp, (u32)w, (u32)h, id, offset, TextureAtlasRegistration_PixelFormat_Alpha);
|
texture_atlas_register(&state->editor->ui.atlas, bp, (u32)w, (u32)h, id, offset, TextureAtlasRegistration_PixelFormat_Alpha);
|
||||||
stbtt_FreeBitmap(bp, 0);
|
stbtt_FreeBitmap(bp, 0);
|
||||||
}
|
}
|
||||||
|
@ -103,14 +105,15 @@ Shader shd;
|
||||||
Texture tex;
|
Texture tex;
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
ed_init(App_State* state)
|
ed_init(App_State* state, Editor_Desc* desc)
|
||||||
{
|
{
|
||||||
lumenarium_env_validate();
|
lumenarium_env_validate();
|
||||||
|
|
||||||
Editor* editor = allocator_alloc_struct(permanent, Editor);
|
Editor* editor = allocator_alloc_struct(permanent, Editor);
|
||||||
zero_struct(*editor);
|
zero_struct(*editor);
|
||||||
state->editor = editor;
|
state->editor = editor;
|
||||||
editor->content_scale = (v2){1,1};
|
editor->window_dim = desc->init_window_dim;
|
||||||
|
editor->content_scale = desc->content_scale;
|
||||||
editor->ui = ui_create(4096, 4096, state->input_state, permanent);
|
editor->ui = ui_create(4096, 4096, state->input_state, permanent);
|
||||||
editor->ui.draw_panel_cb = ed_draw_panel;
|
editor->ui.draw_panel_cb = ed_draw_panel;
|
||||||
editor->ui.draw_panel_cb_data = (u8*)state;
|
editor->ui.draw_panel_cb_data = (u8*)state;
|
||||||
|
@ -158,7 +161,7 @@ ed_init(App_State* state)
|
||||||
vertex_attrib_pointer(b, shd, 2, shd.attrs[1], 5, 3);
|
vertex_attrib_pointer(b, shd, 2, shd.attrs[1], 5, 3);
|
||||||
|
|
||||||
u32 tex_pix[] = { 0xFFFFFFFF, 0xFF00FFFF, 0xFFFFFF00, 0xFFFF00FF };
|
u32 tex_pix[] = { 0xFFFFFFFF, 0xFF00FFFF, 0xFFFFFF00, 0xFFFF00FF };
|
||||||
tex = texture_create((u8*)tex_pix, 2, 2, 2);
|
tex = texture_create(texture_desc_default(2, 2), (u8*)tex_pix);
|
||||||
|
|
||||||
ed_sculpture_visualizer_init(state);
|
ed_sculpture_visualizer_init(state);
|
||||||
lumenarium_env_validate();
|
lumenarium_env_validate();
|
||||||
|
@ -270,27 +273,20 @@ ed_sculpture_updated(App_State* state, r32 scale, r32 led_size)
|
||||||
geo.buffer_index.values,
|
geo.buffer_index.values,
|
||||||
geo.buffer_index.len
|
geo.buffer_index.len
|
||||||
);
|
);
|
||||||
|
|
||||||
for (u32 i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
u32 index = geo.buffer_index.values[1008 + i];
|
|
||||||
r32* values = geo.buffer_vertex.values + (index * 5);
|
|
||||||
printf("%d -> %f %f %f, %f %f\n", index, values[0], values[1], values[2], values[3], values[4]);
|
|
||||||
}
|
|
||||||
vertex_attrib_pointer(ed->sculpture_geo, ed->sculpture_shd, 3, ed->sculpture_shd.attrs[0], 5, 0);
|
vertex_attrib_pointer(ed->sculpture_geo, ed->sculpture_shd, 3, ed->sculpture_shd.attrs[0], 5, 0);
|
||||||
vertex_attrib_pointer(ed->sculpture_geo, ed->sculpture_shd, 2, ed->sculpture_shd.attrs[1], 5, 3);
|
vertex_attrib_pointer(ed->sculpture_geo, ed->sculpture_shd, 2, ed->sculpture_shd.attrs[1], 5, 3);
|
||||||
|
|
||||||
// TODO(PS): make this have enough pixels for the sculpture
|
// TODO(PS): make this have enough pixels for the sculpture
|
||||||
// TODO(PS): map leds to pixels
|
// TODO(PS): map leds to pixels
|
||||||
|
|
||||||
if (ed->sculpture_tex.w != 0)
|
if (ed->sculpture_tex.desc.w != 0)
|
||||||
{
|
{
|
||||||
invalid_code_path;
|
invalid_code_path;
|
||||||
// TODO(PS): destroy the old texture
|
// TODO(PS): destroy the old texture
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* pixels = ed_leds_to_texture(state, &scratch, pixels_dim);
|
u8* pixels = ed_leds_to_texture(state, &scratch, pixels_dim);
|
||||||
ed->sculpture_tex = texture_create(pixels, pixels_dim, pixels_dim, pixels_dim);
|
ed->sculpture_tex = texture_create(texture_desc_default(pixels_dim, pixels_dim), pixels);
|
||||||
|
|
||||||
scratch_release(scratch);
|
scratch_release(scratch);
|
||||||
lumenarium_env_validate();
|
lumenarium_env_validate();
|
||||||
|
@ -313,7 +309,7 @@ ed_frame(App_State* state)
|
||||||
|
|
||||||
{
|
{
|
||||||
scratch_get(scratch);
|
scratch_get(scratch);
|
||||||
u32 w = ed->sculpture_tex.w;
|
u32 w = ed->sculpture_tex.desc.w;
|
||||||
u8* pixels = ed_leds_to_texture(state, &scratch, w);
|
u8* pixels = ed_leds_to_texture(state, &scratch, w);
|
||||||
texture_update(ed->sculpture_tex, pixels, w, w, w);
|
texture_update(ed->sculpture_tex, pixels, w, w, w);
|
||||||
scratch_release(scratch);
|
scratch_release(scratch);
|
||||||
|
|
|
@ -3,6 +3,13 @@
|
||||||
#ifndef LUMENARIUM_EDITOR_H
|
#ifndef LUMENARIUM_EDITOR_H
|
||||||
#define LUMENARIUM_EDITOR_H
|
#define LUMENARIUM_EDITOR_H
|
||||||
|
|
||||||
|
typedef struct Editor_Desc Editor_Desc;
|
||||||
|
struct Editor_Desc
|
||||||
|
{
|
||||||
|
v2 content_scale;
|
||||||
|
v2 init_window_dim;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct Editor Editor;
|
typedef struct Editor Editor;
|
||||||
struct Editor
|
struct Editor
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
#include "lumenarium_editor_sculpture_visualizer_shaders.h"
|
#include "lumenarium_editor_sculpture_visualizer_shaders.h"
|
||||||
|
|
||||||
|
u32 fbo;
|
||||||
|
Texture fbo_tex_c;
|
||||||
|
u32 fbo_rbo;
|
||||||
|
Geometry_Buffer fs_quad;
|
||||||
|
Shader fs_shd;
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
ed_sculpture_visualizer_init(App_State* state)
|
ed_sculpture_visualizer_init(App_State* state)
|
||||||
{
|
{
|
||||||
|
@ -11,6 +17,64 @@ ed_sculpture_visualizer_init(App_State* state)
|
||||||
String attrs[] = { lit_str("a_pos"), lit_str("a_uv") };
|
String attrs[] = { lit_str("a_pos"), lit_str("a_uv") };
|
||||||
String uniforms[] = { lit_str("proj") };
|
String uniforms[] = { lit_str("proj") };
|
||||||
editor->sculpture_shd = shader_create(vert, frag, attrs, 2, uniforms, 1);
|
editor->sculpture_shd = shader_create(vert, frag, attrs, 2, uniforms, 1);
|
||||||
|
|
||||||
|
{
|
||||||
|
glGenFramebuffers(1, &fbo);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
|
||||||
|
v2 wds = HMM_MultiplyVec2(editor->window_dim, editor->content_scale);
|
||||||
|
s32 w = (s32)wds.x;
|
||||||
|
s32 h = (s32)wds.y;
|
||||||
|
fbo_tex_c = texture_create(
|
||||||
|
(Texture_Desc){
|
||||||
|
.w = w, .h = h, .s = w,
|
||||||
|
.min_filter = GL_LINEAR,
|
||||||
|
.mag_filter = GL_LINEAR,
|
||||||
|
.fmt_internal = GL_RGBA,
|
||||||
|
.fmt_data = GL_RGBA,
|
||||||
|
},
|
||||||
|
0
|
||||||
|
);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex_c.id, 0);
|
||||||
|
|
||||||
|
glGenRenderbuffers(1, &fbo_rbo);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, fbo_rbo);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo_rbo);
|
||||||
|
|
||||||
|
u32 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
u32 complete = GL_FRAMEBUFFER_COMPLETE;
|
||||||
|
if (status != complete)
|
||||||
|
{
|
||||||
|
#define GL_ENUM_ERROR_CASE(e, msg) case e: { printf("Error: %s - %s\n", #e, msg); } break
|
||||||
|
switch (status) {
|
||||||
|
GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_UNDEFINED, "");
|
||||||
|
GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, "");
|
||||||
|
GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, "");
|
||||||
|
GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER, "");
|
||||||
|
GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER, "");
|
||||||
|
GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_UNSUPPORTED, "");
|
||||||
|
GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE, "");
|
||||||
|
//GL_ENUM_ERROR_CASE(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS, "");
|
||||||
|
default: {
|
||||||
|
os_gl_no_error();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
printf("Error: unable to complete framebuffer\n");
|
||||||
|
}
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
String vert = xplatform_shader_program_get_vert(sculpture_comp_shd);
|
||||||
|
String frag = xplatform_shader_program_get_frag(sculpture_comp_shd);
|
||||||
|
String shd_a[] = { lit_str("a_pos"), lit_str("a_uv") };
|
||||||
|
String shd_u[] = { lit_str("proj") };
|
||||||
|
fs_shd = shader_create(vert, frag, shd_a, 2, shd_u, 1);
|
||||||
|
|
||||||
|
fs_quad = unit_quad_create();
|
||||||
|
vertex_attrib_pointer(fs_quad, fs_shd, 3, fs_shd.attrs[0], 5, 0);
|
||||||
|
vertex_attrib_pointer(fs_quad, fs_shd, 2, fs_shd.attrs[1], 5, 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r32 cam_theta = 0;
|
r32 cam_theta = 0;
|
||||||
|
@ -21,24 +85,11 @@ ed_sculpture_visualizer(App_State* state)
|
||||||
{
|
{
|
||||||
Editor* ed = state->editor;
|
Editor* ed = state->editor;
|
||||||
|
|
||||||
Input_State* in = state->input_state;
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
u32 delta = 1;
|
os_gl_no_error();
|
||||||
if (input_key_is_down(in, KeyCode_LeftShift) || input_key_is_down(in, KeyCode_RightShift))
|
glClearColor(0, 0, 0, 1);
|
||||||
{
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
delta = 100;
|
glEnable(GL_DEPTH_TEST);
|
||||||
}
|
|
||||||
if (input_key_went_down(in, KeyCode_UpArrow))
|
|
||||||
{
|
|
||||||
offset += delta;
|
|
||||||
printf("%d\n", offset);
|
|
||||||
}
|
|
||||||
if (input_key_went_down(in, KeyCode_DownArrow))
|
|
||||||
{
|
|
||||||
offset -= delta;
|
|
||||||
printf("%d\n", offset);
|
|
||||||
}
|
|
||||||
offset = clamp(0, offset, ed->sculpture_geo.indices_len);
|
|
||||||
|
|
||||||
|
|
||||||
// Set the viewport to the current layout's region so that the sculpture
|
// Set the viewport to the current layout's region so that the sculpture
|
||||||
// never overlaps any other ui elements
|
// never overlaps any other ui elements
|
||||||
|
@ -75,6 +126,19 @@ ed_sculpture_visualizer(App_State* state)
|
||||||
geometry_drawi(ed->sculpture_geo, k, 0);
|
geometry_drawi(ed->sculpture_geo, k, 0);
|
||||||
|
|
||||||
// reset the viewport for all other rendering
|
// reset the viewport for all other rendering
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
v2 wds = HMM_MultiplyVec2(ed->window_dim, ed->content_scale);
|
v2 wds = HMM_MultiplyVec2(ed->window_dim, ed->content_scale);
|
||||||
glViewport(0, 0, (s32)wds.x, (s32)wds.y);
|
glViewport(0, 0, (s32)wds.x, (s32)wds.y);
|
||||||
|
|
||||||
|
m44 ortho = HMM_Orthographic(0, ed->window_dim.x, ed->window_dim.y, 0, 0.01f, 200.0f);
|
||||||
|
m44 scale = HMM_Scale((v3){ed->window_dim.x / 2, ed->window_dim.y / 2, 100});
|
||||||
|
m44 pos = HMM_Translate((v3){ed->window_dim.x / 2, ed->window_dim.y / 2, -99});
|
||||||
|
m44 model = HMM_MultiplyMat4(pos, scale);
|
||||||
|
m44 mvp = HMM_MultiplyMat4(ortho, model);
|
||||||
|
|
||||||
|
shader_bind(fs_shd);
|
||||||
|
set_uniform(fs_shd, 0, mvp);
|
||||||
|
texture_bind(fbo_tex_c);
|
||||||
|
geometry_bind(fs_quad);
|
||||||
|
geometry_drawi(fs_quad, 6, 0);
|
||||||
}
|
}
|
|
@ -63,3 +63,74 @@ global XPlatform_Shader_Program_Src sculpture_shd = {
|
||||||
"}"
|
"}"
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
global XPlatform_Shader_Program_Src sculpture_comp_shd = {
|
||||||
|
.win32_vert = lit_str(""
|
||||||
|
),
|
||||||
|
.win32_frag = lit_str(
|
||||||
|
""
|
||||||
|
),
|
||||||
|
|
||||||
|
.osx_vert = lit_str(
|
||||||
|
"#version 330 core\n"
|
||||||
|
"layout (location = 0) in vec3 a_pos;\n"
|
||||||
|
"layout (location = 1) in vec2 a_uv;\n"
|
||||||
|
"out vec2 uv;\n"
|
||||||
|
"uniform mat4 proj;\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" gl_Position = proj * vec4(a_pos, 1.0);\n"
|
||||||
|
" uv = a_uv;\n"
|
||||||
|
"}"
|
||||||
|
),
|
||||||
|
.osx_frag = lit_str(
|
||||||
|
"#version 330 core\n"
|
||||||
|
"in vec2 uv;\n"
|
||||||
|
"out vec4 FragColor;\n"
|
||||||
|
"uniform sampler2D tex;\n"
|
||||||
|
"float normpdf(in float x, in float sigma) { return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma; }\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" vec4 orig_p = texture(tex, uv);\n"
|
||||||
|
" vec2 tex_size = textureSize(tex, 0);\n"
|
||||||
|
" vec2 tex_offset = 1.0 / tex_size;\n"
|
||||||
|
" "
|
||||||
|
" const int m_size = 15;\n // must be odd\n"
|
||||||
|
" const int k_size = (m_size - 1) / 2;\n"
|
||||||
|
" float kernel[m_size];\n"
|
||||||
|
" float sigma = 7.0;\n"
|
||||||
|
" float z = 0;\n"
|
||||||
|
" for (int i = 0; i <= k_size; i++) {\n"
|
||||||
|
" float v = normpdf(float(i), sigma);\n"
|
||||||
|
" kernel[k_size + i] = v; kernel[k_size - i] = v;\n"
|
||||||
|
" }\n"
|
||||||
|
" for (int i = 0; i < m_size; i++) {\n"
|
||||||
|
" z += kernel[i];\n"
|
||||||
|
" }\n"
|
||||||
|
" vec3 bloom_acc = vec3(0);\n"
|
||||||
|
" for (int i = -k_size; i <= k_size; i++) {\n"
|
||||||
|
" for (int j = -k_size; j <= k_size; j++) {\n"
|
||||||
|
" vec2 uvp = uv + (vec2(float(i), float(j)) / tex_size);\n"
|
||||||
|
" bloom_acc += kernel[k_size + j] * kernel[k_size + i] * texture(tex, uvp).xyz;\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" vec3 bloom_color = bloom_acc / (z * z);\n"
|
||||||
|
" vec3 final_color = orig_p.xyz + bloom_color;\n"
|
||||||
|
// tone mapping
|
||||||
|
" float exposure = 1.0;\n"
|
||||||
|
" float gamma = 2.2;\n"
|
||||||
|
" vec3 result = vec3(1.0) - exp(-final_color * exposure);\n"
|
||||||
|
// also gamma correct while we're at it
|
||||||
|
" result = pow(result, vec3(1.0 / gamma));\n"
|
||||||
|
" FragColor = vec4(result, 1.0);\n"
|
||||||
|
"}"
|
||||||
|
),
|
||||||
|
|
||||||
|
.wasm_vert = lit_str(
|
||||||
|
""
|
||||||
|
),
|
||||||
|
.wasm_frag = lit_str(
|
||||||
|
""
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ ui_create(u32 widget_pool_cap, u32 verts_cap, Input_State* input, Allocator* a)
|
||||||
|
|
||||||
// Texture Atlas
|
// Texture Atlas
|
||||||
result.atlas = texture_atlas_create(1024, 1024, 512, permanent);
|
result.atlas = texture_atlas_create(1024, 1024, 512, permanent);
|
||||||
result.atlas_texture = texture_create(result.atlas.pixels, 1024, 1024, 1024);
|
result.atlas_texture = texture_create(texture_desc_default(1024, 1024), result.atlas.pixels);
|
||||||
|
|
||||||
u32 white_sprite[] = {
|
u32 white_sprite[] = {
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
|
||||||
|
@ -117,8 +117,8 @@ ui_sprite_char_get_draw_cmd(UI* ui, v3 at, u32 codepoint)
|
||||||
result.uv = texture_atlas_sprite_get_uvs(&ui->atlas, sprite);
|
result.uv = texture_atlas_sprite_get_uvs(&ui->atlas, sprite);
|
||||||
|
|
||||||
v3 dim = (v3){
|
v3 dim = (v3){
|
||||||
(r32)(sprite.max_x - sprite.min_x),
|
(r32)(sprite.max_x - sprite.min_x) / ui->font_texture_scale,
|
||||||
(r32)(sprite.max_y - sprite.min_y),
|
(r32)(sprite.max_y - sprite.min_y) / ui->font_texture_scale,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
result.pmin = at;
|
result.pmin = at;
|
||||||
|
@ -126,7 +126,7 @@ ui_sprite_char_get_draw_cmd(UI* ui, v3 at, u32 codepoint)
|
||||||
result.pmin.XY = v2_floor(result.pmin.XY);
|
result.pmin.XY = v2_floor(result.pmin.XY);
|
||||||
result.pmax = HMM_AddVec3(result.pmin, dim);
|
result.pmax = HMM_AddVec3(result.pmin, dim);
|
||||||
|
|
||||||
result.baseline_after = (v3){ result.pmax.x, at.y, at.z };
|
result.baseline_after = (v3){ result.pmax.x + 1.5f, at.y, at.z };
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -193,12 +193,10 @@ ui_draw_panel(BSP* tree, BSP_Node_Id id, BSP_Node* node, u8* user_data)
|
||||||
c = PINK_V4;
|
c = PINK_V4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
ui_sprite_push_color(ui, l0p0, l0p1, sid, c);
|
ui_sprite_push_color(ui, l0p0, l0p1, sid, c);
|
||||||
ui_sprite_push_color(ui, l1p0, l1p1, sid, c);
|
ui_sprite_push_color(ui, l1p0, l1p1, sid, c);
|
||||||
ui_sprite_push_color(ui, l2p0, l2p1, sid, c);
|
ui_sprite_push_color(ui, l2p0, l2p1, sid, c);
|
||||||
ui_sprite_push_color(ui, l3p0, l3p1, sid, c);
|
ui_sprite_push_color(ui, l3p0, l3p1, sid, c);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
|
|
@ -187,6 +187,7 @@ struct UI
|
||||||
|
|
||||||
Texture_Atlas atlas;
|
Texture_Atlas atlas;
|
||||||
r32 font_ascent, font_descent, font_line_gap, font_space_width;
|
r32 font_ascent, font_descent, font_line_gap, font_space_width;
|
||||||
|
r32 font_texture_scale;
|
||||||
|
|
||||||
UI_Widget_Pool widgets;
|
UI_Widget_Pool widgets;
|
||||||
UI_Style_Sheet* style_sheet;
|
UI_Style_Sheet* style_sheet;
|
||||||
|
|
|
@ -73,3 +73,4 @@ global XPlatform_Shader_Program_Src ui_shader = {
|
||||||
"}"
|
"}"
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "user_space/user_space_incenter.cpp"
|
#include "user_space/user_space_incenter.cpp"
|
||||||
|
|
||||||
internal App_State*
|
internal App_State*
|
||||||
lumenarium_init()
|
lumenarium_init(Editor_Desc* ed_desc)
|
||||||
{
|
{
|
||||||
App_State* state = 0;
|
App_State* state = 0;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ lumenarium_init()
|
||||||
|
|
||||||
|
|
||||||
en_init(state, desc);
|
en_init(state, desc);
|
||||||
if (has_flag(state->flags, AppState_RunEditor)) ed_init(state);
|
if (has_flag(state->flags, AppState_RunEditor)) ed_init(state, ed_desc);
|
||||||
if (has_flag(state->flags, AppState_RunUserSpace)) incenter_init(state);
|
if (has_flag(state->flags, AppState_RunUserSpace)) incenter_init(state);
|
||||||
scratch_release(scratch);
|
scratch_release(scratch);
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -289,12 +289,15 @@ int main (int arg_count, char** args)
|
||||||
}
|
}
|
||||||
glfwSetErrorCallback(glfw_error_callback);
|
glfwSetErrorCallback(glfw_error_callback);
|
||||||
|
|
||||||
|
s32 init_window_width = 1400;
|
||||||
|
s32 init_window_height = 700;
|
||||||
|
|
||||||
glfwWindowHint(GLFW_DOUBLEBUFFER, true);
|
glfwWindowHint(GLFW_DOUBLEBUFFER, true);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
GLFWwindow* window = glfwCreateWindow(1400, 700, "Lumenarium", NULL, NULL);
|
GLFWwindow* window = glfwCreateWindow(init_window_width, init_window_width, "Lumenarium", NULL, NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
printf("Error: Unable to create a glfw window\n");
|
printf("Error: Unable to create a glfw window\n");
|
||||||
|
@ -310,15 +313,14 @@ int main (int arg_count, char** args)
|
||||||
glfwSetCursorPosCallback(window, cursor_position_callback);
|
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||||
glfwSetScrollCallback(window, scroll_callback);
|
glfwSetScrollCallback(window, scroll_callback);
|
||||||
|
|
||||||
App_State* state = lumenarium_init();
|
Editor_Desc ed_desc = {};
|
||||||
app_state_data = (u8*)state;
|
|
||||||
|
|
||||||
if (has_flag(state->flags, AppState_RunEditor))
|
|
||||||
{
|
|
||||||
float xscale, yscale;
|
float xscale, yscale;
|
||||||
glfwGetWindowContentScale(window, &xscale, &yscale);
|
glfwGetWindowContentScale(window, &xscale, &yscale);
|
||||||
state->editor->content_scale = (v2){ xscale, yscale };
|
ed_desc.content_scale = (v2){ xscale, yscale };
|
||||||
}
|
ed_desc.init_window_dim = (v2){init_window_width, init_window_height};
|
||||||
|
|
||||||
|
App_State* state = lumenarium_init(&ed_desc);
|
||||||
|
app_state_data = (u8*)state;
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
r64 target_seconds_per_frame = 1.0 / 30.0f;
|
r64 target_seconds_per_frame = 1.0 / 30.0f;
|
||||||
|
|
Loading…
Reference in New Issue