more microui

This commit is contained in:
2026-03-25 17:48:46 +05:45
parent 5bc235f1ab
commit 00ae6cbc4e
5 changed files with 239 additions and 42 deletions
+114 -7
View File
@@ -1346,6 +1346,7 @@ Draw :: struct
solid_circles : SolidCircle, solid_circles : SolidCircle,
solid_capsules : SolidCapsules, solid_capsules : SolidCapsules,
polygons : SolidPolygon, polygons : SolidPolygon,
textures : Texture,
drawCounters : bool, drawCounters : bool,
//regular_font : im.Font, //regular_font : im.Font,
frame_buffer : u32, frame_buffer : u32,
@@ -1435,11 +1436,33 @@ draw_flush :: proc(draw : ^Draw) {
lines_flush(&draw.lines, &draw.cam) lines_flush(&draw.lines, &draw.cam)
points_flush(&draw.points, &draw.cam) points_flush(&draw.points, &draw.cam)
circle_flush(&draw.circles, &draw.cam) circle_flush(&draw.circles, &draw.cam)
textures_flush(draw)
text_flush(draw) text_flush(draw)
check_opengl() check_opengl()
} }
Rect :: struct {
x, y, w, h : f32,
}
TextureData :: struct
{
texture_id : u32, //opengl texture id
width, height : i32,
src_rect : Rect, // in pixel format
dst_rect : Rect, // in pixel format
}
//Contains multiple textures
Texture :: struct
{
textures : [dynamic]TextureData,
vao, vbo, ebo: u32,
uniforms : gl.Uniforms,
program_id : u32,
}
/* /*
Create texture and render texture Create texture and render texture
@@ -1449,7 +1472,51 @@ draw_flush :: proc(draw : ^Draw) {
render_texture :: gets a texture_id and rect and displays the texture (generic but convinent for micorui) render_texture :: gets a texture_id and rect and displays the texture (generic but convinent for micorui)
*/ */
create_texutre :: proc(data: []u8, width, height: i32) -> u32 textures_create :: proc(texture: ^Texture)
{
texture.program_id, _ = gl.load_shaders_source(#load("shaders/texture.vs"), #load("shaders/texture.fs"))
gl.UseProgram(texture.program_id)
gl.Enable(gl.BLEND)
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
texture.uniforms = gl.get_uniforms_from_program(texture.program_id)
vertices : []f32 = {
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 0.0, 0.0,
1.0, 0.0, 1.0, 0.0,
1.0, 1.0, 1.0, 1.0,
}
indices := []u32 {
0, 1, 2,
0, 2, 3,
}
gl.GenVertexArrays(1, &texture.vao)
gl.GenBuffers(1, &texture.vbo)
gl.GenBuffers(1, &texture.ebo)
gl.BindVertexArray(texture.vao)
gl.BindBuffer(gl.ARRAY_BUFFER, texture.vbo)
gl.BufferData(gl.ARRAY_BUFFER, len(vertices) * size_of(f32), raw_data(vertices), gl.DYNAMIC_DRAW)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, texture.ebo)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices) * size_of(u32), raw_data(indices), gl.DYNAMIC_DRAW)
gl.VertexAttribPointer(0, 2, gl.FLOAT, false, 4 * size_of(f32), 0)
gl.EnableVertexAttribArray(0)
gl.VertexAttribPointer(1, 2, gl.FLOAT, false, 4 * size_of(f32), 2 * size_of(f32))
gl.EnableVertexAttribArray(1)
//gl.BindBuffer(gl.ARRAY_BUFFER, 0)
//gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
gl.UseProgram(0)
}
create_texture :: proc(data: []u8, width, height: i32) -> u32
{ {
texture : u32 texture : u32
@@ -1457,16 +1524,55 @@ create_texutre :: proc(data: []u8, width, height: i32) -> u32
gl.BindTexture(gl.TEXTURE_2D, texture) gl.BindTexture(gl.TEXTURE_2D, texture)
gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, raw_data(data)) gl.TexImage2D( gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, raw_data(data))
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) gl.BindTexture( gl.TEXTURE_2D, 0)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
gl.BindTexture(gl.TEXTURE_2D, 0)
return texture return texture
} }
textures_flush :: proc(d: ^Draw)
{
texture := &d.textures
gl.UseProgram(texture.program_id)
gl.Uniform2f(texture.uniforms["u_resolution"].location, f32(d.cam.width), f32(d.cam.height))
gl.Enable(gl.BLEND)
gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
gl.ActiveTexture(gl.TEXTURE0)
for &t in &texture.textures
{
vertices := []f32{
0.0, 1.0, t.src_rect.x , (t.src_rect.y+ f32(t.src_rect.h)),
0.0, 0.0, t.src_rect.x , (t.src_rect.y ),
1.0, 0.0, (t.src_rect.x + f32(t.src_rect.w)), (t.src_rect.y ),
1.0, 1.0, (t.src_rect.x + f32(t.src_rect.w)), (t.src_rect.y+ f32(t.src_rect.h))
}
gl.BindBuffer(gl.ARRAY_BUFFER, texture.vbo)
gl.BufferData(gl.ARRAY_BUFFER, len(vertices) * size_of(f32), raw_data(vertices), gl.DYNAMIC_DRAW)
gl.Uniform2f(texture.uniforms["u_position"].location, t.dst_rect.x, t.dst_rect.y)
gl.Uniform2f(texture.uniforms["u_size"].location, t.dst_rect.w, t.dst_rect.h)
gl.BindTexture(gl.TEXTURE_2D, t.texture_id)
gl.Uniform1i(texture.uniforms["ourTexture"].location, 0)
gl.BindVertexArray(texture.vao)
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
}
gl.Disable(gl.BLEND)
gl.UseProgram(0)
check_opengl()
clear(&texture.textures)
}
@@ -1481,6 +1587,7 @@ draw_create :: proc(draw : ^Draw, camera : ^Camera, font_path : string = "")
circle_create(&draw.circles) circle_create(&draw.circles)
solid_circle_create(&draw.solid_circles) solid_circle_create(&draw.solid_circles)
solid_polygon_create(&draw.polygons) solid_polygon_create(&draw.polygons)
textures_create(&draw.textures)
{ {
draw.glyph.atlas_width = draw.cam.width draw.glyph.atlas_width = draw.cam.width
+1 -1
View File
@@ -18,7 +18,7 @@ void main(){
vec2 ndc; vec2 ndc;
ndc.x = (screen_pos.x / u_resolution.x) * 2.0 - 1.0; ndc.x = (screen_pos.x / u_resolution.x) * 2.0 - 1.0;
ndc.y = 1.0 - (screen_pos.y / u_resolution.x) * 2.0; ndc.y = 1.0 - (screen_pos.y / u_resolution.y) * 2.0;
gl_Position = vec4(ndc, 0.0, 1.0); gl_Position = vec4(ndc, 0.0, 1.0);
TexCoord = aTexCoord; TexCoord = aTexCoord;
+37 -18
View File
@@ -36,6 +36,7 @@ engine_state :: struct
input : input_state, input : input_state,
mu_ctx : mu.Context, mu_ctx : mu.Context,
mu_tex : u32,
} }
MAX_KEYS :: 512 MAX_KEYS :: 512
@@ -177,12 +178,41 @@ engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : strin
//Glyph and microui //Glyph and microui
{ {
//Create index
mu.init(&state.mu_ctx) mu.init(&state.mu_ctx)
state.mu_ctx.style.font = cast(mu.Font)&state.draw.glyph state.mu_ctx.style.font = cast(mu.Font)&state.draw.glyph
state.mu_ctx.text_width = mui_text_width state.mu_ctx.text_width = mui_text_width
state.mu_ctx.text_height = mui_text_height state.mu_ctx.text_height = mui_text_height
texture_data := make([]u8, mu.DEFAULT_ATLAS_WIDTH* mu.DEFAULT_ATLAS_HEIGHT * 4)
idx :i32 = 0
for y in 0..<mu.DEFAULT_ATLAS_HEIGHT
{
for x in 0..<mu.DEFAULT_ATLAS_WIDTH
{
texture_data[idx + 0] = 255
texture_data[idx + 1] = 255
texture_data[idx + 2] = 255
texture_data[idx + 3] = mu.default_atlas_alpha[idx/4]
idx += 4
} }
}
state.mu_tex = e2_draw.create_texture(texture_data, mu.DEFAULT_ATLAS_WIDTH, mu.DEFAULT_ATLAS_HEIGHT)
}
}
normalize_rect :: proc(rect : mu.Rect, size : i32) -> e2_draw.Rect
{
points : e2_draw.Rect
points.x = f32(rect.x) / f32(size)
points.y = f32(rect.y) / f32(size)
points.w = f32(rect.w) / f32(size)
points.h = f32(rect.h) / f32(size)
return points
} }
@@ -264,7 +294,7 @@ end_frame :: proc(state: ^engine_state)
for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p) for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p)
color := c.color color := c.color
//hex_color := e2_draw.make_hex_color({color.r, color.g, color.b, color.a}) //hex_color := e2_draw.make_hex_color({color.r, color.g, color.b, color.a})
e2_draw.solid_polygon_add(&draw.polygons, {q = e2_draw.Rot{c = 1}}, &points[0], 4, 0, transmute([4]u8)color) e2_draw.solid_polygon_add(&draw.polygons, {q = e2_draw.Rot{c = 1}}, &points[0], 4, 0.01, transmute([4]u8)color)
} }
case ^mu.Command_Clip: case ^mu.Command_Clip:
{ {
@@ -272,19 +302,13 @@ end_frame :: proc(state: ^engine_state)
gl.Scissor(rect.x, state.height - (rect.y + rect.h), rect.w, rect.h) gl.Scissor(rect.x, state.height - (rect.y + rect.h), rect.w, rect.h)
} }
case ^mu.Command_Icon:{ case ^mu.Command_Icon:{
rect := mu.default_atlas[c.id]
if c.id == .CHECK append(&draw.textures.textures, e2_draw.TextureData{
{ texture_id = state.mu_tex,
pos :[2]f32= {f32(c.rect.x), f32(c.rect.y)} src_rect = normalize_rect(rect, mu.DEFAULT_ATLAS_WIDTH),
dst_rect = e2_draw.Rect{f32(c.rect.x), f32(c.rect.y), f32(rect.w), f32(rect.h)},
pos.x += f32(c.rect.w)/2.0 })
pos.y += f32(c.rect.h)/2.0
pos = e2_draw.camera_convert_screen_to_world(&draw.cam, pos)
e2_draw.solid_circle_add(&draw.solid_circles,{p = pos, q = e2_draw.Rot{c = 1}} , 0.1,{255, 255, 255, 255})
}else{
fmt.println(c.id)
}
} }
} }
@@ -346,8 +370,3 @@ draw_flush :: proc(d: ^e2_draw.Draw)
e2_draw.draw_flush(d) e2_draw.draw_flush(d)
} }
+4 -3
View File
@@ -103,6 +103,7 @@ interface_get_default :: proc(interface: ^interface_state)
} }
/* /*
interface_draw_options :: proc(state: ^engine_state)
{ {
debug_draw := &state.debug_draw debug_draw := &state.debug_draw
@@ -123,10 +124,11 @@ interface_draw_options :: proc(state: ^engine_state)
im.SliderFloat("Rotation", &state.draw.cam.rotation, 0, 360) im.SliderFloat("Rotation", &state.draw.cam.rotation, 0, 360)
} }
*/ */
mu_interface_game_mode :: proc(state: ^engine_state, interface: ^interface_state) mu_interface_game_mode :: proc(state: ^engine_state, interface: ^interface_state)
{ {
if mu.begin_window(&state.mu_ctx, "Edit Mode", {1630, 0, 250, 170}) if mu.begin_window(&state.mu_ctx, "Edit Mode", {1630, 0, 250, 170})
{ {
for type in EditMode for type in EditMode
{ {
b : bool = interface.edit_mode == type b : bool = interface.edit_mode == type
@@ -187,12 +189,11 @@ interface_all :: proc(interface: ^interface_state) -> bool
{ {
if mu.begin_window(&state.mu_ctx, "B2d Interface", {1630, 170, 250, 450}) if mu.begin_window(&state.mu_ctx, "B2d Interface", {1630, 170, 250, 450})
{ {
if .ACTIVE in mu.header(&state.mu_ctx, "Entity", {.AUTO_SIZE}) if .ACTIVE in mu.header(&state.mu_ctx, "Entity", {.AUTO_SIZE})
{ {
if interface_entity(interface) do ret = true if interface_entity(interface) do ret = true
} }
}
mu.end_window(&state.mu_ctx) mu.end_window(&state.mu_ctx)
} }
+79 -9
View File
@@ -27,6 +27,7 @@ import "core:fmt"
By doing comparasion on def By doing comparasion on def
*/ */
/*
interface_body_def_editor :: proc(def: ^engine_entity_def) interface_body_def_editor :: proc(def: ^engine_entity_def)
{ {
if im.BeginCombo("Body Type", fmt.ctprint(def.body_def.type)) if im.BeginCombo("Body Type", fmt.ctprint(def.body_def.type))
@@ -59,13 +60,57 @@ interface_body_def_editor :: proc(def: ^engine_entity_def)
def.body_def.name = cstring(&def.name_buf[0]) def.body_def.name = cstring(&def.name_buf[0])
} }
} }
*/
mu_interface_body_def_editor :: proc(interface: ^interface_state, def : ^engine_entity_def)
{
ctx := &interface.state.mu_ctx
if .ACTIVE in mu.begin_treenode(ctx, "Body Type")
{
for type in b2.BodyType
{
state := def.body_def.type == type
if .CHANGE in mu.checkbox(ctx, fmt.tprint(type), &state)
{
def.body_def.type = type
}
}
mu.end_treenode(ctx)
}
mu.label(ctx, "Position")
mu.slider(ctx, &def.body_def.position[0], -50, 50)
mu.slider(ctx, &def.body_def.position[1], -50, 50)
angle := draw.RAD2DEG * b2.Rot_GetAngle(def.body_def.rotation)
mu.label(ctx, "Rotation")
if .CHANGE in mu.slider(ctx, &angle, 0, 359)
{
def.body_def.rotation = b2.MakeRot(draw.DEG2RAD * angle)
}
mu.label(ctx, "Linear Velocity")
mu.slider(ctx, &def.body_def.linearVelocity[0], 0, 500)
mu.slider(ctx, &def.body_def.linearVelocity[1], 0, 500)
mu.label(ctx, "Angular Velocity")
mu.slider(ctx, &def.body_def.angularVelocity, 0, 500)
mu.label(ctx, "Linear Damping")
mu.slider(ctx, &def.body_def.linearDamping, 0, 500)
mu.label(ctx, "Angular Damping")
mu.slider(ctx, &def.body_def.angularDamping, 0, 500)
mu.label(ctx, "Gravity Scale")
mu.slider(ctx, &def.body_def.gravityScale, 0, 100)
mu.checkbox(ctx, "Fixed rotation", &def.body_def.fixedRotation)
}
interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_entity_def) -> bool interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_entity_def) -> bool
{ {
curr_index := &interface.curr_static_index curr_index := &interface.curr_static_index
entity := interface.entities[interface.selected_entity] entity := interface.entities[interface.selected_entity]
level := interface.world level := interface.world
@@ -123,6 +168,26 @@ interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_ent
return false return false
} }
mu_interface_edit_static_index :: proc(interface: ^interface_state, def : ^engine_entity_def) -> bool
{
curr_index := &interface.curr_static_index
entity := interface.entities[interface.selected_entity]
level := interface.world
ctx := &interface.state.mu_ctx
if level.relations[entity.index] == nil
{
level.relations[entity.index] = {}
}
indexes := &level.relations[entity.index]
//if mu.slider()
}
mu_interface_shape_def_editor :: proc( mu_interface_shape_def_editor :: proc(
state : ^engine_state, state : ^engine_state,
def : ^engine_entity_def) -> bool def : ^engine_entity_def) -> bool
@@ -210,6 +275,7 @@ mu_interface_shape_def_editor :: proc(
} }
/*
interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
{ {
shape_def := &def.shape_def shape_def := &def.shape_def
@@ -300,6 +366,7 @@ interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
} }
return false return false
} }
*/
interface_entity :: proc(interface: ^interface_state) -> bool interface_entity :: proc(interface: ^interface_state) -> bool
{ {
@@ -322,20 +389,23 @@ interface_entity :: proc(interface: ^interface_state) -> bool
im.Separator() im.Separator()
if im.CollapsingHeader("Shape Edit")
if .ACTIVE in mu.begin_treenode(&interface.state.mu_ctx, "Body Def")
{ {
//interface_shape_def_editor(def) mu_interface_body_def_editor(interface, def)
mu.end_treenode(&interface.state.mu_ctx)
} }
if .ACTIVE in mu.begin_treenode(&interface.state.mu_ctx, "Shape Def")
{
mu_interface_shape_def_editor(interface.state, def) mu_interface_shape_def_editor(interface.state, def)
mu.end_treenode(&interface.state.mu_ctx)
}
im.Separator() im.Separator()
if im.CollapsingHeader("Body Edit")
{
interface_body_def_editor(def)
}
if im.CollapsingHeader("Static Index") if .ACTIVE in mu.begin_treenode(&interface.state.mu_ctx, "Static Index")
{ {
ret |= interface_edit_static_index(interface, def) ret |= interface_edit_static_index(interface, def)
} }