Refactor draw to be separate and handle ortho draw
This commit is contained in:
+221
-147
@@ -1,5 +1,7 @@
|
|||||||
package edit2draw
|
package edit2draw
|
||||||
|
|
||||||
|
import e2_glyph "shared:Edit2D/glyph"
|
||||||
|
import "core:strings"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:math/linalg"
|
import "core:math/linalg"
|
||||||
@@ -7,15 +9,37 @@ import gl "vendor:OpenGL"
|
|||||||
import b2 "vendor:box2d"
|
import b2 "vendor:box2d"
|
||||||
|
|
||||||
|
|
||||||
|
CameraType :: enum
|
||||||
|
{
|
||||||
|
BOX_2D,
|
||||||
|
ORTHO,
|
||||||
|
}
|
||||||
|
|
||||||
Camera :: struct {
|
Camera :: struct {
|
||||||
center : b2.Vec2,
|
center : [2]f32,
|
||||||
width, height : i32,
|
width, height : i32,
|
||||||
zoom : f32,
|
zoom, rotation : f32,
|
||||||
rotation : f32,
|
type : CameraType,
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBA8 :: [4]u8
|
RGBA8 :: [4]u8
|
||||||
|
|
||||||
|
/*
|
||||||
|
just coping the box2d here because the shaders depends on these structure but we don't want to depend on it
|
||||||
|
*/
|
||||||
|
|
||||||
|
Rot :: struct
|
||||||
|
{
|
||||||
|
c, s : f32, //cosine and sine
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform :: struct
|
||||||
|
{
|
||||||
|
p: Vec2,
|
||||||
|
q: Rot,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
make_rgba :: proc(color : b2.HexColor, alpha : f32) -> RGBA8 {
|
make_rgba :: proc(color : b2.HexColor, alpha : f32) -> RGBA8 {
|
||||||
c := i32(color)
|
c := i32(color)
|
||||||
return {
|
return {
|
||||||
@@ -26,6 +50,16 @@ make_rgba :: proc(color : b2.HexColor, alpha : f32) -> RGBA8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
make_rgba_i32 :: proc(color : i32, alpha : f32) -> RGBA8 {
|
||||||
|
c := i32(color)
|
||||||
|
return {
|
||||||
|
u8((c >> 16) & 0xFF),
|
||||||
|
u8((c >> 8) & 0xFF),
|
||||||
|
u8(c & 0xFF),
|
||||||
|
u8(0xFF * alpha),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
make_hex_color :: proc(rgba: RGBA8) -> b2.HexColor {
|
make_hex_color :: proc(rgba: RGBA8) -> b2.HexColor {
|
||||||
return b2.HexColor((u32(rgba.r) << 16) | (u32(rgba.g) << 8) | u32(rgba.b))
|
return b2.HexColor((u32(rgba.r) << 16) | (u32(rgba.g) << 8) | u32(rgba.b))
|
||||||
}
|
}
|
||||||
@@ -51,18 +85,17 @@ camera_init :: proc() -> Camera {
|
|||||||
camera_convert_screen_to_world_64 :: proc(
|
camera_convert_screen_to_world_64 :: proc(
|
||||||
cam : ^Camera,
|
cam : ^Camera,
|
||||||
ps : [2]f64,
|
ps : [2]f64,
|
||||||
) -> b2.Vec2 {
|
) -> [2]f32 {
|
||||||
|
|
||||||
ps_32 :[2]f32= {f32(ps.x), f32(ps.y)}
|
ps_32 :[2]f32= {f32(ps.x), f32(ps.y)}
|
||||||
|
|
||||||
return camera_convert_screen_to_world_32(cam, ps_32)
|
return camera_convert_screen_to_world_32(cam, ps_32)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
camera_convert_screen_to_world_32 :: proc(
|
camera_convert_screen_to_world_32 :: proc(
|
||||||
cam : ^Camera,
|
cam : ^Camera,
|
||||||
ps : b2.Vec2,
|
ps : [2]f32,
|
||||||
) -> b2.Vec2 {
|
) -> [2]f32 {
|
||||||
|
|
||||||
ps :[2]f32= {f32(ps.x), f32(ps.y)}
|
ps :[2]f32= {f32(ps.x), f32(ps.y)}
|
||||||
|
|
||||||
@@ -71,13 +104,14 @@ camera_convert_screen_to_world_32 :: proc(
|
|||||||
u := ps.x / w
|
u := ps.x / w
|
||||||
v := (h - ps.y) / h
|
v := (h - ps.y) / h
|
||||||
|
|
||||||
|
|
||||||
ratio := w / h
|
ratio := w / h
|
||||||
extents : b2.Vec2 = {cam.zoom * ratio, cam.zoom}
|
extents : [2]f32 = {cam.zoom * ratio, cam.zoom}
|
||||||
|
|
||||||
lower := cam.center - extents
|
lower := cam.center - extents
|
||||||
upper := cam.center + extents
|
upper := cam.center + extents
|
||||||
|
|
||||||
pw : b2.Vec2 = {
|
pw : [2]f32 = {
|
||||||
(1.0 - u) * lower.x + u * upper.x,
|
(1.0 - u) * lower.x + u * upper.x,
|
||||||
(1.0 - v) * lower.y + v * upper.y,
|
(1.0 - v) * lower.y + v * upper.y,
|
||||||
}
|
}
|
||||||
@@ -92,8 +126,8 @@ camera_convert_screen_to_world :: proc {
|
|||||||
|
|
||||||
camera_convert_world_to_screen :: proc(
|
camera_convert_world_to_screen :: proc(
|
||||||
cam : ^Camera,
|
cam : ^Camera,
|
||||||
pw : b2.Vec2,
|
pw : [2]f32,
|
||||||
) -> b2.Vec2 {
|
) -> [2]f32 {
|
||||||
cam := cam
|
cam := cam
|
||||||
pw := pw
|
pw := pw
|
||||||
|
|
||||||
@@ -109,7 +143,7 @@ camera_convert_world_to_screen :: proc(
|
|||||||
}
|
}
|
||||||
ratio := w / h
|
ratio := w / h
|
||||||
|
|
||||||
extents : b2.Vec2 = {cam.zoom * ratio, cam.zoom}
|
extents : [2]f32 = {cam.zoom * ratio, cam.zoom}
|
||||||
|
|
||||||
|
|
||||||
rotated_pw := pw
|
rotated_pw := pw
|
||||||
@@ -120,7 +154,7 @@ camera_convert_world_to_screen :: proc(
|
|||||||
u := (rotated_pw.x - lower.x) / (upper.x - lower.x)
|
u := (rotated_pw.x - lower.x) / (upper.x - lower.x)
|
||||||
v := (rotated_pw.y - lower.y) / (upper.y - lower.y)
|
v := (rotated_pw.y - lower.y) / (upper.y - lower.y)
|
||||||
|
|
||||||
ps : b2.Vec2 = {u * w, (1.0 - v) * h}
|
ps : [2]f32 = {u * w, (1.0 - v) * h}
|
||||||
return ps
|
return ps
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,19 +163,57 @@ DEG2RAD :: PI / 180.0
|
|||||||
RAD2DEG :: 180.0 / PI
|
RAD2DEG :: 180.0 / PI
|
||||||
|
|
||||||
|
|
||||||
|
orthographic_matrix :: proc(cam: ^Camera) -> matrix[4,4]f32{
|
||||||
|
|
||||||
|
left :f32= 0
|
||||||
|
right :f32= f32(cam.width)
|
||||||
|
|
||||||
|
bottom :f32= f32(cam.height)
|
||||||
|
top :f32= 0
|
||||||
|
|
||||||
|
near : f32 = 1
|
||||||
|
far : f32 = -1
|
||||||
|
|
||||||
|
m: matrix[4,4]f32
|
||||||
|
|
||||||
|
m[0][0] = 2.0 / (right - left)
|
||||||
|
m[0][1] = 0.0
|
||||||
|
m[0][2] = 0.0
|
||||||
|
m[0][3] = 0.0
|
||||||
|
|
||||||
|
m[1][0] = 0.0
|
||||||
|
m[1][1] = 2.0 / (top - bottom)
|
||||||
|
m[1][2] = 0.0
|
||||||
|
m[1][3] = 0.0
|
||||||
|
|
||||||
|
m[2][0] = 0.0
|
||||||
|
m[2][1] = 0.0
|
||||||
|
m[2][2] = -2.0 / (far - near)
|
||||||
|
m[2][3] = 0.0
|
||||||
|
|
||||||
|
m[3][0] = -(right + left) / (right - left)
|
||||||
|
m[3][1] = -(top + bottom) / (top - bottom)
|
||||||
|
m[3][2] = -(far + near) / (far - near)
|
||||||
|
m[3][3] = 1.0
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Convert from world coordinates to normalized device coordinates
|
//Convert from world coordinates to normalized device coordinates
|
||||||
// http://www.songho.ca/opengl/gl_projectionmatrix.html
|
// http://www.songho.ca/opengl/gl_projectionmatrix.html
|
||||||
camera_build_project_matrix :: proc(
|
camera_build_project_matrix :: proc(
|
||||||
cam : ^Camera,
|
cam : ^Camera,
|
||||||
z_bias : f32,
|
z_bias : f32,
|
||||||
) -> matrix[4, 4]f32 {
|
) -> matrix[4, 4]f32 {
|
||||||
|
|
||||||
|
if cam.type == .ORTHO do return orthographic_matrix(cam)
|
||||||
|
|
||||||
m : matrix[4, 4]f32
|
m : matrix[4, 4]f32
|
||||||
|
|
||||||
mat_rot := linalg.matrix4_rotate_f32(DEG2RAD * cam.rotation, {0, 0, 1})
|
mat_rot := linalg.matrix4_rotate_f32(DEG2RAD * cam.rotation, {0, 0, 1})
|
||||||
|
|
||||||
ratio := f32(cam.width) / f32(cam.height)
|
ratio := f32(cam.width) / f32(cam.height)
|
||||||
extents : b2.Vec2 = {cam.zoom * ratio, cam.zoom}
|
extents : [2]f32 = {cam.zoom * ratio, cam.zoom}
|
||||||
lower := cam.center - extents
|
lower := cam.center - extents
|
||||||
upper := cam.center + extents
|
upper := cam.center + extents
|
||||||
|
|
||||||
@@ -161,8 +233,8 @@ camera_build_project_matrix :: proc(
|
|||||||
|
|
||||||
camera_get_view_bounds :: proc(cam : ^Camera) -> b2.AABB {
|
camera_get_view_bounds :: proc(cam : ^Camera) -> b2.AABB {
|
||||||
return b2.AABB {
|
return b2.AABB {
|
||||||
lowerBound = camera_convert_screen_to_world(cam, b2.Vec2{0, f32(cam.height)}),
|
lowerBound = camera_convert_screen_to_world(cam, [2]f32{0, f32(cam.height)}),
|
||||||
upperBound = camera_convert_screen_to_world(cam, b2.Vec2{f32(cam.width), 0}),
|
upperBound = camera_convert_screen_to_world(cam, [2]f32{f32(cam.width), 0}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +252,6 @@ check_opengl :: proc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
background_create :: proc(back : ^Background) {
|
background_create :: proc(back : ^Background) {
|
||||||
|
|
||||||
ok : bool
|
ok : bool
|
||||||
@@ -201,7 +272,7 @@ background_create :: proc(back : ^Background) {
|
|||||||
gl.EnableVertexAttribArray(vertex_attribute)
|
gl.EnableVertexAttribArray(vertex_attribute)
|
||||||
|
|
||||||
//Single quad
|
//Single quad
|
||||||
vertices : [4]b2.Vec2 = {{-1.0, 1.0}, {-1.0, -1.0}, {1.0, 1.0}, {1.0, -1}}
|
vertices : [4][2]f32 = {{-1.0, 1.0}, {-1.0, -1.0}, {1.0, 1.0}, {1.0, -1}}
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, back.vbo)
|
gl.BindBuffer(gl.ARRAY_BUFFER, back.vbo)
|
||||||
gl.BufferData(
|
gl.BufferData(
|
||||||
gl.ARRAY_BUFFER,
|
gl.ARRAY_BUFFER,
|
||||||
@@ -252,7 +323,7 @@ background_draw :: proc(back : ^Background, cam : ^Camera) {
|
|||||||
|
|
||||||
|
|
||||||
PointData :: struct {
|
PointData :: struct {
|
||||||
pos : b2.Vec2,
|
pos : [2]f32,
|
||||||
size : f32,
|
size : f32,
|
||||||
rgba : RGBA8,
|
rgba : RGBA8,
|
||||||
}
|
}
|
||||||
@@ -359,7 +430,7 @@ points_destroy :: proc(point : ^Point) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
points_add :: proc(point : ^Point, v : b2.Vec2, size : f32, c : b2.HexColor) {
|
points_add :: proc(point : ^Point, v : [2]f32, size : f32, c : b2.HexColor) {
|
||||||
rgba := make_rgba(c, 1.0)
|
rgba := make_rgba(c, 1.0)
|
||||||
append(&point.points, PointData{v, size, rgba})
|
append(&point.points, PointData{v, size, rgba})
|
||||||
}
|
}
|
||||||
@@ -373,12 +444,7 @@ points_flush :: proc(point : ^Point, cam : ^Camera) {
|
|||||||
|
|
||||||
proj := camera_build_project_matrix(cam, 0)
|
proj := camera_build_project_matrix(cam, 0)
|
||||||
|
|
||||||
gl.UniformMatrix4fv(
|
gl.UniformMatrix4fv(point.uniforms["projectionMatrix"].location, 1, gl.FALSE, &proj[0][0])
|
||||||
point.uniforms["projectionMatrix"].location,
|
|
||||||
1,
|
|
||||||
gl.FALSE,
|
|
||||||
&proj[0][0],
|
|
||||||
)
|
|
||||||
|
|
||||||
gl.BindVertexArray(point.vao)
|
gl.BindVertexArray(point.vao)
|
||||||
|
|
||||||
@@ -391,11 +457,8 @@ points_flush :: proc(point : ^Point, cam : ^Camera) {
|
|||||||
batch_count : i32 = min(count, 2048)
|
batch_count : i32 = min(count, 2048)
|
||||||
|
|
||||||
gl.BufferSubData(
|
gl.BufferSubData(
|
||||||
gl.ARRAY_BUFFER,
|
gl.ARRAY_BUFFER, 0, int(batch_count * size_of(PointData)), &point.points[base])
|
||||||
0,
|
|
||||||
int(batch_count * size_of(PointData)),
|
|
||||||
&point.points[base],
|
|
||||||
)
|
|
||||||
gl.DrawArrays(gl.POINTS, 0, batch_count)
|
gl.DrawArrays(gl.POINTS, 0, batch_count)
|
||||||
|
|
||||||
check_opengl()
|
check_opengl()
|
||||||
@@ -413,7 +476,7 @@ points_flush :: proc(point : ^Point, cam : ^Camera) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VertexData :: struct {
|
VertexData :: struct {
|
||||||
pos : b2.Vec2,
|
pos : [2]f32,
|
||||||
rgba : RGBA8,
|
rgba : RGBA8,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,7 +573,7 @@ lines_destroy :: proc(line : ^Lines) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lines_add :: proc(line : ^Lines, p1, p2 : b2.Vec2, c : b2.HexColor) {
|
lines_add :: proc(line : ^Lines, p1, p2 : [2]f32, c : b2.HexColor) {
|
||||||
rgba := make_rgba(c, 1.0)
|
rgba := make_rgba(c, 1.0)
|
||||||
append(&line.points, VertexData{p1, rgba})
|
append(&line.points, VertexData{p1, rgba})
|
||||||
append(&line.points, VertexData{p2, rgba})
|
append(&line.points, VertexData{p2, rgba})
|
||||||
@@ -563,7 +626,7 @@ lines_flush :: proc(line : ^Lines, cam : ^Camera) {
|
|||||||
|
|
||||||
|
|
||||||
CircleData :: struct {
|
CircleData :: struct {
|
||||||
pos : b2.Vec2,
|
pos : [2]f32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
rgba : RGBA8,
|
rgba : RGBA8,
|
||||||
}
|
}
|
||||||
@@ -604,7 +667,7 @@ circle_create :: proc(circle : ^Circles) {
|
|||||||
//vertex buffer for single quad
|
//vertex buffer for single quad
|
||||||
a : f32 = 1.1
|
a : f32 = 1.1
|
||||||
|
|
||||||
vertices : []b2.Vec2 = {
|
vertices : [][2]f32 = {
|
||||||
{-a, -a},
|
{-a, -a},
|
||||||
{a, -a},
|
{a, -a},
|
||||||
{-a, a},
|
{-a, a},
|
||||||
@@ -616,7 +679,7 @@ circle_create :: proc(circle : ^Circles) {
|
|||||||
gl.BindBuffer(gl.ARRAY_BUFFER, circle.vbos[0])
|
gl.BindBuffer(gl.ARRAY_BUFFER, circle.vbos[0])
|
||||||
gl.BufferData(
|
gl.BufferData(
|
||||||
gl.ARRAY_BUFFER,
|
gl.ARRAY_BUFFER,
|
||||||
size_of(b2.Vec2) * 6,
|
size_of([2]f32) * 6,
|
||||||
&vertices[0],
|
&vertices[0],
|
||||||
gl.STATIC_DRAW,
|
gl.STATIC_DRAW,
|
||||||
)
|
)
|
||||||
@@ -682,10 +745,10 @@ circle_destroy :: proc(circle : ^Circles) {
|
|||||||
|
|
||||||
circle_add :: proc(
|
circle_add :: proc(
|
||||||
circle : ^Circles,
|
circle : ^Circles,
|
||||||
center : b2.Vec2,
|
center : [2]f32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
) {
|
) {
|
||||||
rgba := make_rgba(color, 1.0)
|
rgba := make_rgba(color, 1.0)
|
||||||
append(&circle.circles, CircleData{center, radius, rgba})
|
append(&circle.circles, CircleData{center, radius, rgba})
|
||||||
}
|
}
|
||||||
@@ -744,13 +807,15 @@ circle_flush :: proc(circle : ^Circles, cam : ^Camera) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SolidCircleData :: struct {
|
SolidCircleData :: struct
|
||||||
transform : b2.Transform,
|
{
|
||||||
|
transform : Transform,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
rgba : RGBA8,
|
rgba : RGBA8,
|
||||||
}
|
}
|
||||||
|
|
||||||
SolidCircle :: struct {
|
SolidCircle :: struct
|
||||||
|
{
|
||||||
circles : [dynamic]SolidCircleData,
|
circles : [dynamic]SolidCircleData,
|
||||||
program, vao : u32,
|
program, vao : u32,
|
||||||
vbo : [2]u32,
|
vbo : [2]u32,
|
||||||
@@ -758,16 +823,14 @@ SolidCircle :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
solid_circle_create :: proc(circle : ^SolidCircle) {
|
solid_circle_create :: proc(circle : ^SolidCircle)
|
||||||
circle.program, _ = gl.load_shaders_source(
|
{
|
||||||
#load("shaders/solid_circle.vs"),
|
|
||||||
#load("shaders/solid_circle.fs"),
|
circle.program, _ = gl.load_shaders_source(#load("shaders/solid_circle.vs"), #load("shaders/solid_circle.fs"))
|
||||||
)
|
|
||||||
circle.uniforms = gl.get_uniforms_from_program(circle.program)
|
circle.uniforms = gl.get_uniforms_from_program(circle.program)
|
||||||
|
|
||||||
gl.GenVertexArrays(1, &circle.vao)
|
gl.GenVertexArrays(1, &circle.vao)
|
||||||
gl.GenBuffers(2, &circle.vbo[0])
|
gl.GenBuffers(2, &circle.vbo[0])
|
||||||
|
|
||||||
gl.BindVertexArray(circle.vao)
|
gl.BindVertexArray(circle.vao)
|
||||||
|
|
||||||
vertex_attribute : u32 = 0
|
vertex_attribute : u32 = 0
|
||||||
@@ -785,7 +848,7 @@ solid_circle_create :: proc(circle : ^SolidCircle) {
|
|||||||
//Vertex buffer for single quad
|
//Vertex buffer for single quad
|
||||||
a : f32 = 1.1
|
a : f32 = 1.1
|
||||||
|
|
||||||
vertices : []b2.Vec2 = {
|
vertices : [][2]f32 = {
|
||||||
{-a, -a},
|
{-a, -a},
|
||||||
{a, -a},
|
{a, -a},
|
||||||
{-a, a},
|
{-a, a},
|
||||||
@@ -795,47 +858,16 @@ solid_circle_create :: proc(circle : ^SolidCircle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, circle.vbo[0])
|
gl.BindBuffer(gl.ARRAY_BUFFER, circle.vbo[0])
|
||||||
gl.BufferData(
|
gl.BufferData(gl.ARRAY_BUFFER, size_of([2]f32) * 6, &vertices[0], gl.STATIC_DRAW)
|
||||||
gl.ARRAY_BUFFER,
|
|
||||||
size_of(b2.Vec2) * 6,
|
|
||||||
&vertices[0],
|
|
||||||
gl.STATIC_DRAW,
|
|
||||||
)
|
|
||||||
gl.VertexAttribPointer(vertex_attribute, 2, gl.FLOAT, gl.FALSE, 0, 0)
|
gl.VertexAttribPointer(vertex_attribute, 2, gl.FLOAT, gl.FALSE, 0, 0)
|
||||||
|
|
||||||
//
|
//
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, circle.vbo[1])
|
gl.BindBuffer(gl.ARRAY_BUFFER, circle.vbo[1])
|
||||||
gl.BufferData(
|
gl.BufferData(gl.ARRAY_BUFFER, int(batch_size * size_of(SolidCircleData)), nil, gl.DYNAMIC_DRAW)
|
||||||
gl.ARRAY_BUFFER,
|
|
||||||
int(batch_size * size_of(SolidCircleData)),
|
|
||||||
nil,
|
|
||||||
gl.DYNAMIC_DRAW,
|
|
||||||
)
|
|
||||||
|
|
||||||
gl.VertexAttribPointer(
|
gl.VertexAttribPointer(transform_instance, 4, gl.FLOAT, gl.FALSE, size_of(SolidCircleData), offset_of(SolidCircleData, transform))
|
||||||
transform_instance,
|
gl.VertexAttribPointer(radius_instance, 1, gl.FLOAT, gl.FALSE, size_of(SolidCircleData), offset_of(SolidCircleData, radius))
|
||||||
4,
|
gl.VertexAttribPointer(color_instance, 4, gl.UNSIGNED_BYTE, gl.TRUE, size_of(SolidCircleData), offset_of(SolidCircleData, rgba))
|
||||||
gl.FLOAT,
|
|
||||||
gl.FALSE,
|
|
||||||
size_of(SolidCircleData),
|
|
||||||
offset_of(SolidCircleData, transform),
|
|
||||||
)
|
|
||||||
gl.VertexAttribPointer(
|
|
||||||
radius_instance,
|
|
||||||
1,
|
|
||||||
gl.FLOAT,
|
|
||||||
gl.FALSE,
|
|
||||||
size_of(SolidCircleData),
|
|
||||||
offset_of(SolidCircleData, radius),
|
|
||||||
)
|
|
||||||
gl.VertexAttribPointer(
|
|
||||||
color_instance,
|
|
||||||
4,
|
|
||||||
gl.UNSIGNED_BYTE,
|
|
||||||
gl.TRUE,
|
|
||||||
size_of(SolidCircleData),
|
|
||||||
offset_of(SolidCircleData, rgba),
|
|
||||||
)
|
|
||||||
|
|
||||||
gl.VertexAttribDivisor(transform_instance, 1)
|
gl.VertexAttribDivisor(transform_instance, 1)
|
||||||
gl.VertexAttribDivisor(radius_instance, 1)
|
gl.VertexAttribDivisor(radius_instance, 1)
|
||||||
@@ -865,12 +897,11 @@ solid_circle_destroy :: proc(circle : ^SolidCircle) {
|
|||||||
|
|
||||||
solid_circle_add :: proc(
|
solid_circle_add :: proc(
|
||||||
circle : ^SolidCircle,
|
circle : ^SolidCircle,
|
||||||
transform : b2.Transform,
|
transform : Transform,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : RGBA8,
|
||||||
) {
|
) {
|
||||||
rgba := make_rgba(color, 1.0)
|
append(&circle.circles, SolidCircleData{transform, radius, color})
|
||||||
append(&circle.circles, SolidCircleData{transform, radius, rgba})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
solid_circle_flush :: proc(circle : ^SolidCircle, cam : ^Camera) {
|
solid_circle_flush :: proc(circle : ^SolidCircle, cam : ^Camera) {
|
||||||
@@ -928,7 +959,7 @@ solid_circle_flush :: proc(circle : ^SolidCircle, cam : ^Camera) {
|
|||||||
|
|
||||||
|
|
||||||
CapsuleData :: struct {
|
CapsuleData :: struct {
|
||||||
transform : b2.Transform,
|
transform : Transform,
|
||||||
radius, length : f32,
|
radius, length : f32,
|
||||||
rgba : RGBA8,
|
rgba : RGBA8,
|
||||||
}
|
}
|
||||||
@@ -977,7 +1008,7 @@ solid_capsules_create :: proc(capsule : ^SolidCapsules) {
|
|||||||
//Vertex buffer for single quad
|
//Vertex buffer for single quad
|
||||||
a : f32 = 1.1
|
a : f32 = 1.1
|
||||||
|
|
||||||
vertices : []b2.Vec2 = {
|
vertices : [][2]f32 = {
|
||||||
{-a, -a},
|
{-a, -a},
|
||||||
{a, -a},
|
{a, -a},
|
||||||
{-a, a},
|
{-a, a},
|
||||||
@@ -989,7 +1020,7 @@ solid_capsules_create :: proc(capsule : ^SolidCapsules) {
|
|||||||
gl.BindBuffer(gl.ARRAY_BUFFER, capsule.vbo[0])
|
gl.BindBuffer(gl.ARRAY_BUFFER, capsule.vbo[0])
|
||||||
gl.BufferData(
|
gl.BufferData(
|
||||||
gl.ARRAY_BUFFER,
|
gl.ARRAY_BUFFER,
|
||||||
size_of(b2.Vec2) * 6,
|
size_of([2]f32) * 6,
|
||||||
&vertices[0],
|
&vertices[0],
|
||||||
gl.STATIC_DRAW,
|
gl.STATIC_DRAW,
|
||||||
)
|
)
|
||||||
@@ -1065,10 +1096,10 @@ solid_capsules_destroy :: proc(capsule : ^SolidCapsules) {
|
|||||||
|
|
||||||
solid_capsules_add :: proc(
|
solid_capsules_add :: proc(
|
||||||
capsule : ^SolidCapsules,
|
capsule : ^SolidCapsules,
|
||||||
p1, p2 : b2.Vec2,
|
p1, p2 : [2]f32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
c : b2.HexColor,
|
c : b2.HexColor,
|
||||||
) {
|
) {
|
||||||
d := p2 - p1
|
d := p2 - p1
|
||||||
|
|
||||||
length := b2.Length(d)
|
length := b2.Length(d)
|
||||||
@@ -1076,7 +1107,7 @@ solid_capsules_add :: proc(
|
|||||||
|
|
||||||
axis := d / length
|
axis := d / length
|
||||||
|
|
||||||
transform : b2.Transform = {
|
transform : Transform = {
|
||||||
p = 0.5 * (p1 + p2),
|
p = 0.5 * (p1 + p2),
|
||||||
q = {c = axis.x, s = axis.y},
|
q = {c = axis.x, s = axis.y},
|
||||||
}
|
}
|
||||||
@@ -1119,12 +1150,7 @@ solid_capsules_flush :: proc(capsule : ^SolidCapsules, cam : ^Camera) {
|
|||||||
for count > 0 {
|
for count > 0 {
|
||||||
batch_count := min(count, 2048)
|
batch_count := min(count, 2048)
|
||||||
|
|
||||||
gl.BufferSubData(
|
gl.BufferSubData(gl.ARRAY_BUFFER, 0, int(batch_count * size_of(CapsuleData)), &capsule.capsules[base])
|
||||||
gl.ARRAY_BUFFER,
|
|
||||||
0,
|
|
||||||
int(batch_count * size_of(CapsuleData)),
|
|
||||||
&capsule.capsules[base],
|
|
||||||
)
|
|
||||||
gl.DrawArraysInstanced(gl.TRIANGLES, 0, 6, batch_count)
|
gl.DrawArraysInstanced(gl.TRIANGLES, 0, 6, batch_count)
|
||||||
|
|
||||||
check_opengl()
|
check_opengl()
|
||||||
@@ -1143,8 +1169,8 @@ solid_capsules_flush :: proc(capsule : ^SolidCapsules, cam : ^Camera) {
|
|||||||
|
|
||||||
|
|
||||||
PolygonData :: struct #packed {
|
PolygonData :: struct #packed {
|
||||||
transform : b2.Transform,
|
transform : Transform,
|
||||||
p1, p2, p3, p4, p5, p6, p7, p8 : b2.Vec2,
|
p1, p2, p3, p4, p5, p6, p7, p8 : [2]f32,
|
||||||
count : i32,
|
count : i32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
|
|
||||||
@@ -1199,7 +1225,7 @@ solid_polygon_create :: proc(polygon : ^SolidPolygon) {
|
|||||||
|
|
||||||
a : f32 = 1.1
|
a : f32 = 1.1
|
||||||
|
|
||||||
vertices : []b2.Vec2 = {
|
vertices : [][2]f32 = {
|
||||||
{-a, -a},
|
{-a, -a},
|
||||||
{a, -a},
|
{a, -a},
|
||||||
{-a, a},
|
{-a, a},
|
||||||
@@ -1211,7 +1237,7 @@ solid_polygon_create :: proc(polygon : ^SolidPolygon) {
|
|||||||
gl.BindBuffer(gl.ARRAY_BUFFER, polygon.vbo[0])
|
gl.BindBuffer(gl.ARRAY_BUFFER, polygon.vbo[0])
|
||||||
gl.BufferData(
|
gl.BufferData(
|
||||||
gl.ARRAY_BUFFER,
|
gl.ARRAY_BUFFER,
|
||||||
size_of(b2.Vec2) * 6,
|
size_of([2]f32) * 6,
|
||||||
&vertices[0],
|
&vertices[0],
|
||||||
gl.STATIC_DRAW,
|
gl.STATIC_DRAW,
|
||||||
)
|
)
|
||||||
@@ -1309,12 +1335,12 @@ solid_polygon_create :: proc(polygon : ^SolidPolygon) {
|
|||||||
|
|
||||||
solid_polygon_add :: proc(
|
solid_polygon_add :: proc(
|
||||||
polygon : ^SolidPolygon,
|
polygon : ^SolidPolygon,
|
||||||
transform : b2.Transform,
|
transform : Transform,
|
||||||
points : [^]b2.Vec2,
|
points : [^][2]f32,
|
||||||
count : i32,
|
count : i32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
data : PolygonData
|
data : PolygonData
|
||||||
@@ -1323,7 +1349,7 @@ solid_polygon_add :: proc(
|
|||||||
|
|
||||||
n := min(count, 8)
|
n := min(count, 8)
|
||||||
|
|
||||||
ps := cast([^]b2.Vec2)&data.p1
|
ps := cast([^][2]f32)&data.p1
|
||||||
|
|
||||||
for i in 0 ..< count {
|
for i in 0 ..< count {
|
||||||
ps[i] = points[i]
|
ps[i] = points[i]
|
||||||
@@ -1349,14 +1375,8 @@ solid_polygon_flush :: proc(polygon : ^SolidPolygon, cam : ^Camera) {
|
|||||||
|
|
||||||
proj := camera_build_project_matrix(cam, 0.2)
|
proj := camera_build_project_matrix(cam, 0.2)
|
||||||
|
|
||||||
//proj := linalg.MATRIX4F32_IDENTITY
|
|
||||||
|
|
||||||
gl.UniformMatrix4fv(polygon.uniforms["projectionMatrix"].location, 1, gl.FALSE, &proj[0][0])
|
gl.UniformMatrix4fv(polygon.uniforms["projectionMatrix"].location, 1, gl.FALSE, &proj[0][0])
|
||||||
gl.Uniform1f(polygon.uniforms["pixelScale"].location, f32(cam.height) / cam.zoom)
|
gl.Uniform1f(polygon.uniforms["pixelScale"].location, f32(cam.height) / cam.zoom)
|
||||||
/*
|
|
||||||
gl.UniformMatrix4fv(polygon.uniforms["projectionMatrix"].location, 1, gl.FALSE, &proj[0][0])
|
|
||||||
gl.Uniform1f(polygon.uniforms["pixelScale"].location, 0.001)
|
|
||||||
*/
|
|
||||||
|
|
||||||
gl.BindVertexArray(polygon.vao)
|
gl.BindVertexArray(polygon.vao)
|
||||||
|
|
||||||
@@ -1389,7 +1409,15 @@ solid_polygon_flush :: proc(polygon : ^SolidPolygon, cam : ^Camera) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Draw :: struct {
|
TextItem :: struct
|
||||||
|
{
|
||||||
|
str : string,
|
||||||
|
pos : [2]f32,
|
||||||
|
color : [4]u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
Draw :: struct
|
||||||
|
{
|
||||||
show_ui : bool,
|
show_ui : bool,
|
||||||
debug_draw : b2.DebugDraw,
|
debug_draw : b2.DebugDraw,
|
||||||
cam : Camera,
|
cam : Camera,
|
||||||
@@ -1403,6 +1431,9 @@ Draw :: struct {
|
|||||||
drawCounters : bool,
|
drawCounters : bool,
|
||||||
//regular_font : im.Font,
|
//regular_font : im.Font,
|
||||||
frame_buffer : u32,
|
frame_buffer : u32,
|
||||||
|
glyph : e2_glyph.GlyphState,
|
||||||
|
|
||||||
|
texts : [dynamic]TextItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_aabb :: proc(draw : ^Draw, aabb : b2.AABB, c : b2.HexColor) {
|
draw_aabb :: proc(draw : ^Draw, aabb : b2.AABB, c : b2.HexColor) {
|
||||||
@@ -1419,11 +1450,11 @@ draw_aabb :: proc(draw : ^Draw, aabb : b2.AABB, c : b2.HexColor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DrawPolygonFcn :: proc "c" (
|
DrawPolygonFcn :: proc "c" (
|
||||||
vertices : [^]b2.Vec2,
|
vertices : [^][2]f32,
|
||||||
vertexCount : i32,
|
vertexCount : i32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
@@ -1437,13 +1468,13 @@ DrawPolygonFcn :: proc "c" (
|
|||||||
}
|
}
|
||||||
|
|
||||||
DrawSolidPolygonFcn :: proc "c" (
|
DrawSolidPolygonFcn :: proc "c" (
|
||||||
transform : b2.Transform,
|
transform : Transform,
|
||||||
vertices : [^]b2.Vec2,
|
vertices : [^][2]f32,
|
||||||
vertexCount : i32,
|
vertexCount : i32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
@@ -1461,11 +1492,11 @@ DrawSolidPolygonFcn :: proc "c" (
|
|||||||
|
|
||||||
|
|
||||||
DrawCircleFcn :: proc "c" (
|
DrawCircleFcn :: proc "c" (
|
||||||
center : b2.Vec2,
|
center : [2]f32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
circle_add(&draw.circles, center, radius, color)
|
circle_add(&draw.circles, center, radius, color)
|
||||||
@@ -1473,20 +1504,22 @@ DrawCircleFcn :: proc "c" (
|
|||||||
|
|
||||||
DrawSolidCircle :: proc(
|
DrawSolidCircle :: proc(
|
||||||
circle : ^SolidCircle,
|
circle : ^SolidCircle,
|
||||||
transform : b2.Transform,
|
transform : Transform,
|
||||||
center : b2.Vec2,
|
center : [2]f32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
) {
|
) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
|
|
||||||
transform := transform
|
transform := transform
|
||||||
|
|
||||||
|
rgba := make_rgba(color, 1.0)
|
||||||
|
|
||||||
transform.p = b2.TransformPoint(transform, center)
|
transform.p = b2.TransformPoint(transform, center)
|
||||||
solid_circle_add(circle, transform, radius, color)
|
solid_circle_add(circle, transform, radius, rgba)
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTransform :: proc "c" (lines : ^Lines, transform : b2.Transform) {
|
DrawTransform :: proc "c" (lines : ^Lines, transform : Transform) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
k_axis_scale : f32 = 0.2
|
k_axis_scale : f32 = 0.2
|
||||||
p1 := transform.p
|
p1 := transform.p
|
||||||
@@ -1499,87 +1532,114 @@ DrawTransform :: proc "c" (lines : ^Lines, transform : b2.Transform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DrawSolidCircleFcn :: proc "c" (
|
DrawSolidCircleFcn :: proc "c" (
|
||||||
transform : b2.Transform,
|
transform : Transform,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
DrawSolidCircle(
|
DrawSolidCircle(
|
||||||
&draw.solid_circles,
|
&draw.solid_circles,
|
||||||
transform,
|
transform,
|
||||||
b2.Vec2_zero,
|
{0, 0},
|
||||||
radius,
|
radius,
|
||||||
color,
|
color,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawSolidCapsuleFcn :: proc "c" (
|
DrawSolidCapsuleFcn :: proc "c" (
|
||||||
p1, p2 : b2.Vec2,
|
p1, p2 : [2]f32,
|
||||||
radius : f32,
|
radius : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
solid_capsules_add(&draw.solid_capsules, p1, p2, radius, color)
|
solid_capsules_add(&draw.solid_capsules, p1, p2, radius, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawSegmentFcn :: proc "c" (
|
DrawSegmentFcn :: proc "c" (
|
||||||
p1, p2 : b2.Vec2,
|
p1, p2 : [2]f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
lines_add(&draw.lines, p1, p2, color)
|
lines_add(&draw.lines, p1, p2, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawTransformFcn :: proc "c" (transform : b2.Transform, ctx : rawptr) {
|
DrawTransformFcn :: proc "c" (transform : Transform, ctx : rawptr) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
DrawTransform(&draw.lines, transform)
|
DrawTransform(&draw.lines, transform)
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawPointFcn :: proc "c" (
|
DrawPointFcn :: proc "c" (
|
||||||
p : b2.Vec2,
|
p : [2]f32,
|
||||||
size : f32,
|
size : f32,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
points_add(&draw.points, p, size, color)
|
points_add(&draw.points, p, size, color)
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawString :: proc(draw : ^Draw, x, y : int, str: cstring)
|
DrawString :: proc(draw : ^Draw, x, y : int, cstr: cstring)
|
||||||
{
|
{
|
||||||
|
ps := camera_convert_world_to_screen(&draw.cam, {f32(x), f32(y)})
|
||||||
|
str := strings.clone_from_cstring(cstr)
|
||||||
|
str = strings.trim_left_space(str)
|
||||||
|
str = strings.trim_right_space(str)
|
||||||
|
str = strings.trim_null(str)
|
||||||
|
append(&draw.texts, TextItem{"0.00", {f32(ps.x), f32(ps.y)}, {1,1,1,1}})
|
||||||
/*
|
/*
|
||||||
draw_list := im.GetForegroundDrawList()
|
draw_list := im.GetForegroundDrawList()
|
||||||
im.DrawList_AddText(draw_list, {f32(x), f32(y)},im.GetColorU32(.Text), str)
|
im.DrawList_AddText(draw_list, {f32(x), f32(y)},im.GetColorU32(.Text), str)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawStringVec :: proc(draw : ^Draw, p : b2.Vec2, str: cstring)
|
DrawStringVec :: proc(draw : ^Draw, p : [2]f32, cstr: cstring)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
|
p := p
|
||||||
|
|
||||||
ps := camera_convert_world_to_screen(&draw.cam, p)
|
ps := camera_convert_world_to_screen(&draw.cam, p)
|
||||||
|
|
||||||
|
str := strings.clone_from_cstring(cstr)
|
||||||
|
str = strings.trim_left_space(str)
|
||||||
|
str = strings.trim_right_space(str)
|
||||||
|
str = strings.trim_null(str)
|
||||||
|
|
||||||
|
|
||||||
|
append(&draw.texts, TextItem{str, {f32(ps.x), f32(ps.y)}, {200,200,200,255}})
|
||||||
|
/*
|
||||||
im.DrawList_AddText(im.GetForegroundDrawList(), ps,im.GetColorU32(.Text), str)
|
im.DrawList_AddText(im.GetForegroundDrawList(), ps,im.GetColorU32(.Text), str)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawStringFcn :: proc "c" (
|
DrawStringFcn :: proc "c" (
|
||||||
p : b2.Vec2,
|
p : [2]f32,
|
||||||
s : cstring,
|
s : cstring,
|
||||||
color : b2.HexColor,
|
color : b2.HexColor,
|
||||||
ctx : rawptr,
|
ctx : rawptr,
|
||||||
) {
|
) {
|
||||||
context = runtime.default_context()
|
context = runtime.default_context()
|
||||||
draw : ^Draw = cast(^Draw)ctx
|
draw : ^Draw = cast(^Draw)ctx
|
||||||
DrawStringVec(draw, p, s)
|
DrawStringVec(draw, p, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text_flush :: proc(draw: ^Draw)
|
||||||
|
{
|
||||||
|
for &t in &draw.texts{
|
||||||
|
e2_glyph.glyph_draw_font(&draw.glyph, t.str, t.pos, t.color)
|
||||||
|
}
|
||||||
|
|
||||||
|
clear(&draw.texts)
|
||||||
|
}
|
||||||
|
|
||||||
draw_flush :: proc(draw : ^Draw) {
|
draw_flush :: proc(draw : ^Draw) {
|
||||||
|
|
||||||
background_draw(&draw.background, &draw.cam)
|
background_draw(&draw.background, &draw.cam)
|
||||||
@@ -1587,15 +1647,18 @@ draw_flush :: proc(draw : ^Draw) {
|
|||||||
solid_circle_flush(&draw.solid_circles, &draw.cam)
|
solid_circle_flush(&draw.solid_circles, &draw.cam)
|
||||||
solid_polygon_flush(&draw.polygons, &draw.cam)
|
solid_polygon_flush(&draw.polygons, &draw.cam)
|
||||||
solid_capsules_flush(&draw.solid_capsules, &draw.cam)
|
solid_capsules_flush(&draw.solid_capsules, &draw.cam)
|
||||||
circle_flush(&draw.circles, &draw.cam)
|
|
||||||
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)
|
||||||
|
text_flush(draw)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
check_opengl()
|
check_opengl()
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_create :: proc(draw : ^Draw, camera : ^Camera) {
|
//This should be handled in engine code separately
|
||||||
|
draw_create :: proc(draw : ^Draw, camera : ^Camera, font_path : string = "") {
|
||||||
|
|
||||||
background_create(&draw.background)
|
background_create(&draw.background)
|
||||||
points_create(&draw.points)
|
points_create(&draw.points)
|
||||||
@@ -1604,6 +1667,17 @@ draw_create :: proc(draw : ^Draw, camera : ^Camera) {
|
|||||||
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)
|
||||||
|
|
||||||
|
{
|
||||||
|
draw.glyph.atlas_width = draw.cam.width
|
||||||
|
draw.glyph.atlas_height = draw.cam.height
|
||||||
|
draw.glyph.font_size_pt = 9
|
||||||
|
draw.glyph.width = draw.cam.width
|
||||||
|
draw.glyph.height = draw.cam.height
|
||||||
|
|
||||||
|
e2_glyph.glyph_init(&draw.glyph, font_path)
|
||||||
|
}
|
||||||
|
|
||||||
check_opengl()
|
check_opengl()
|
||||||
|
|
||||||
|
|
||||||
@@ -1625,7 +1699,7 @@ draw_create :: proc(draw : ^Draw, camera : ^Camera) {
|
|||||||
draw.debug_draw.drawJoints = true
|
draw.debug_draw.drawJoints = true
|
||||||
draw.debug_draw.drawJointExtras = false
|
draw.debug_draw.drawJointExtras = false
|
||||||
draw.debug_draw.drawBounds = false
|
draw.debug_draw.drawBounds = false
|
||||||
draw.debug_draw.drawMass = false
|
draw.debug_draw.drawMass = true
|
||||||
draw.debug_draw.drawContacts = false
|
draw.debug_draw.drawContacts = false
|
||||||
draw.debug_draw.drawGraphColors = false
|
draw.debug_draw.drawGraphColors = false
|
||||||
draw.debug_draw.drawContactNormals = false
|
draw.debug_draw.drawContactNormals = false
|
||||||
|
|||||||
+110
-8
@@ -1,23 +1,26 @@
|
|||||||
package edit2d
|
package edit2d
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
import "core:encoding/cbor"
|
import "core:encoding/cbor"
|
||||||
|
import b2 "vendor:box2d"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
import im "shared:odin-imgui"
|
import im "shared:odin-imgui"
|
||||||
import "shared:odin-imgui/imgui_impl_glfw"
|
import "shared:odin-imgui/imgui_impl_glfw"
|
||||||
import "shared:odin-imgui/imgui_impl_opengl3"
|
import "shared:odin-imgui/imgui_impl_opengl3"
|
||||||
import gl "vendor:OpenGL"
|
import gl "vendor:OpenGL"
|
||||||
import "vendor:glfw"
|
import "vendor:glfw"
|
||||||
import draw "shared:Edit2D/draw"
|
import e2_draw "shared:Edit2D/draw"
|
||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
|
import mu "vendor:microui"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
engine_state :: struct
|
engine_state :: struct
|
||||||
{
|
{
|
||||||
window : glfw.WindowHandle,
|
window : glfw.WindowHandle,
|
||||||
draw : draw.Draw,
|
draw : e2_draw.Draw,
|
||||||
restart, pause : bool,
|
restart, pause : bool,
|
||||||
substep_count : u32,
|
substep_count : u32,
|
||||||
|
|
||||||
@@ -30,6 +33,7 @@ engine_state :: struct
|
|||||||
|
|
||||||
input : input_state,
|
input : input_state,
|
||||||
|
|
||||||
|
mu_ctx : mu.Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
MAX_KEYS :: 512
|
MAX_KEYS :: 512
|
||||||
@@ -95,18 +99,25 @@ engine_check_types :: proc($Game: typeid)
|
|||||||
This will only be called once to initilize the engine
|
This will only be called once to initilize the engine
|
||||||
initilize graphics library, glfw, callbacks
|
initilize graphics library, glfw, callbacks
|
||||||
*/
|
*/
|
||||||
engine_init :: proc($GameType : typeid, state: ^engine_state)
|
engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : string="")
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
engine_check_types(GameType)
|
engine_check_types(GameType)
|
||||||
|
|
||||||
assert(glfw.Init() == true)
|
assert(glfw.Init() == true)
|
||||||
|
|
||||||
glfw.WindowHint(glfw.SCALE_TO_MONITOR, 1)
|
glfw.WindowHint(glfw.SCALE_TO_MONITOR, 1)
|
||||||
|
|
||||||
|
glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 4)
|
||||||
|
glfw.WindowHint(glfw.OPENGL_DEBUG_CONTEXT, true)
|
||||||
|
glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 5)
|
||||||
|
glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
|
||||||
|
|
||||||
state.window = glfw.CreateWindow(state.width, state.height, state.title, nil, nil)
|
state.window = glfw.CreateWindow(state.width, state.height, state.title, nil, nil)
|
||||||
|
|
||||||
|
|
||||||
|
//gl.DebugMessageControl(gl.DONT_CARE, gl.DONT_CARE, gl.DONT_CARE, 0, nil, gl.TRUE);
|
||||||
|
|
||||||
assert(state.window != nil)
|
assert(state.window != nil)
|
||||||
|
|
||||||
glfw.MakeContextCurrent(state.window)
|
glfw.MakeContextCurrent(state.window)
|
||||||
@@ -139,7 +150,7 @@ engine_init :: proc($GameType : typeid, state: ^engine_state)
|
|||||||
imgui_impl_glfw.InitForOpenGL(state.window, true)
|
imgui_impl_glfw.InitForOpenGL(state.window, true)
|
||||||
imgui_impl_opengl3.Init("#version 150")
|
imgui_impl_opengl3.Init("#version 150")
|
||||||
|
|
||||||
state.draw.cam = draw.camera_init()
|
state.draw.cam = e2_draw.camera_init()
|
||||||
|
|
||||||
display_w, display_h := glfw.GetFramebufferSize(state.window)
|
display_w, display_h := glfw.GetFramebufferSize(state.window)
|
||||||
state.draw.cam.width = display_w
|
state.draw.cam.width = display_w
|
||||||
@@ -147,7 +158,7 @@ engine_init :: proc($GameType : typeid, state: ^engine_state)
|
|||||||
state.draw.cam.zoom = 15
|
state.draw.cam.zoom = 15
|
||||||
state.draw.show_ui = true
|
state.draw.show_ui = true
|
||||||
|
|
||||||
draw.draw_create(&state.draw, &state.draw.cam)
|
e2_draw.draw_create(&state.draw, &state.draw.cam, font_path)
|
||||||
|
|
||||||
cbor.tag_register_type({
|
cbor.tag_register_type({
|
||||||
marshal = proc(_: ^cbor.Tag_Implementation, e: cbor.Encoder, v: any) -> cbor.Marshal_Error {
|
marshal = proc(_: ^cbor.Tag_Implementation, e: cbor.Encoder, v: any) -> cbor.Marshal_Error {
|
||||||
@@ -159,6 +170,16 @@ engine_init :: proc($GameType : typeid, state: ^engine_state)
|
|||||||
},
|
},
|
||||||
}, 201, rawptr)
|
}, 201, rawptr)
|
||||||
|
|
||||||
|
|
||||||
|
//Glyph and microui
|
||||||
|
{
|
||||||
|
|
||||||
|
mu.init(&state.mu_ctx)
|
||||||
|
state.mu_ctx.style.font = cast(mu.Font)&state.draw.glyph
|
||||||
|
state.mu_ctx.text_width = mui_text_width
|
||||||
|
state.mu_ctx.text_height = mui_text_height
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -169,6 +190,25 @@ update_frame :: proc(state: ^engine_state)
|
|||||||
|
|
||||||
keyboard_update(state)
|
keyboard_update(state)
|
||||||
|
|
||||||
|
x, y:= glfw.GetCursorPos(state.window)
|
||||||
|
|
||||||
|
mu.input_mouse_move(&state.mu_ctx, i32(x), i32(y))
|
||||||
|
{
|
||||||
|
for key in key_map
|
||||||
|
{
|
||||||
|
if is_key_pressed(state, key) do mu.input_key_down(&state.mu_ctx, key_map[key])
|
||||||
|
if is_key_released(state, key) do mu.input_key_up(&state.mu_ctx, key_map[key])
|
||||||
|
}
|
||||||
|
|
||||||
|
for key in mouse_map
|
||||||
|
{
|
||||||
|
if is_key_pressed(state, key) do mu.input_mouse_down(&state.mu_ctx, i32(x), i32(y), mouse_map[key])
|
||||||
|
if is_key_released(state, key) do mu.input_mouse_up(&state.mu_ctx,i32(x), i32(y), mouse_map[key])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gl.ClearColor(0.4, 0.5, 0.6, 1.0)
|
gl.ClearColor(0.4, 0.5, 0.6, 1.0)
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
@@ -187,6 +227,68 @@ end_frame :: proc(state: ^engine_state)
|
|||||||
{
|
{
|
||||||
im.Render()
|
im.Render()
|
||||||
imgui_impl_opengl3.RenderDrawData(im.GetDrawData())
|
imgui_impl_opengl3.RenderDrawData(im.GetDrawData())
|
||||||
|
|
||||||
|
|
||||||
|
//Microui
|
||||||
|
{
|
||||||
|
|
||||||
|
cmd: ^mu.Command
|
||||||
|
|
||||||
|
draw := &state.draw
|
||||||
|
for mu.next_command(&state.mu_ctx, &cmd)
|
||||||
|
{
|
||||||
|
#partial switch c in cmd.variant{
|
||||||
|
case ^mu.Command_Text:
|
||||||
|
{
|
||||||
|
color := c.color
|
||||||
|
append(&draw.texts, e2_draw.TextItem{c.str, {f32(c.pos.x), f32(c.pos.y)}, {c.color.r, color.g, color.b, color.a}})
|
||||||
|
}
|
||||||
|
case ^mu.Command_Rect:
|
||||||
|
{
|
||||||
|
rect := c.rect
|
||||||
|
pos :[2]f32= {f32(rect.x), f32(rect.y)}
|
||||||
|
wh :[2]f32= {f32(rect.w), f32(rect.h)}
|
||||||
|
w, h := wh.x, wh.y
|
||||||
|
|
||||||
|
|
||||||
|
points : [4][2]f32 = {
|
||||||
|
{pos.x + w, pos.y},
|
||||||
|
{pos.x, pos.y},
|
||||||
|
{pos.x, pos.y + h},
|
||||||
|
{pos.x + w, pos.y + h},
|
||||||
|
}
|
||||||
|
|
||||||
|
for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p)
|
||||||
|
color := c.color
|
||||||
|
hex_color := e2_draw.make_hex_color({color.r, color.g, color.b, color.a})
|
||||||
|
e2_draw.solid_polygon_add(&draw.polygons, {q = b2.Rot{c = 1}}, &points[0], 4, 0, hex_color)
|
||||||
|
}
|
||||||
|
case ^mu.Command_Clip:
|
||||||
|
{
|
||||||
|
rect := c.rect
|
||||||
|
gl.Scissor(rect.x, state.height - (rect.y + rect.h), rect.w, rect.h)
|
||||||
|
}
|
||||||
|
case ^mu.Command_Icon:{
|
||||||
|
|
||||||
|
if c.id == .CHECK
|
||||||
|
{
|
||||||
|
pos :[2]f32= {f32(c.rect.x), f32(c.rect.y)}
|
||||||
|
|
||||||
|
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 = b2.Rot{c = 1}} , 0.1,{255, 255, 255, 255})
|
||||||
|
}else{
|
||||||
|
fmt.println(c.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
glfw.SwapBuffers(state.window)
|
glfw.SwapBuffers(state.window)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,9 +338,9 @@ is_key_released :: #force_inline proc(state: ^engine_state, key : i32) -> bool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
draw_flush :: proc(d: ^draw.Draw)
|
draw_flush :: proc(d: ^e2_draw.Draw)
|
||||||
{
|
{
|
||||||
draw.draw_flush(d)
|
e2_draw.draw_flush(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+28
-11
@@ -1,5 +1,6 @@
|
|||||||
package e2glyph
|
package e2glyph
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
/*
|
/*
|
||||||
Provides text rendering using glfw, stb_truetype for the engine
|
Provides text rendering using glfw, stb_truetype for the engine
|
||||||
|
|
||||||
@@ -52,11 +53,13 @@ GlyphState :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glyph_init :: proc(glyph: ^GlyphState, filepath : string) {
|
glyph_init :: proc(glyph: ^GlyphState, font_path : string = "") {
|
||||||
|
|
||||||
ok : bool
|
ok : bool
|
||||||
glyph.program_id, ok = gl.load_shaders_source(#load("./shaders/font_vert.glsl"), #load("./shaders/font_frag.glsl"), )
|
glyph.program_id, ok = gl.load_shaders_source(#load("./shaders/font_vert.glsl"), #load("./shaders/font_frag.glsl"), )
|
||||||
|
|
||||||
|
gl.UseProgram(glyph.program_id)
|
||||||
|
|
||||||
gl.CreateBuffers(1, &glyph.rect_instances_vbo)
|
gl.CreateBuffers(1, &glyph.rect_instances_vbo)
|
||||||
gl.CreateVertexArrays(1, &glyph.vao)
|
gl.CreateVertexArrays(1, &glyph.vao)
|
||||||
|
|
||||||
@@ -82,9 +85,18 @@ glyph_init :: proc(glyph: ^GlyphState, filepath : string) {
|
|||||||
gl.CreateTextures(gl.TEXTURE_RECTANGLE, 1, &glyph.atlas_texture)
|
gl.CreateTextures(gl.TEXTURE_RECTANGLE, 1, &glyph.atlas_texture)
|
||||||
gl.TextureStorage2D(glyph.atlas_texture, 1, gl.RGB8, glyph.atlas_width, glyph.atlas_height)
|
gl.TextureStorage2D(glyph.atlas_texture, 1, gl.RGB8, glyph.atlas_width, glyph.atlas_height)
|
||||||
|
|
||||||
font_data, _ := os.read_entire_file_from_path(filepath, context.allocator)
|
|
||||||
|
|
||||||
|
if !os.exists(font_path)
|
||||||
|
{
|
||||||
|
fmt.eprintln("Font not provided or not exist using default font")
|
||||||
|
font_data := #load("./mononoki-Regular.ttf", []byte)
|
||||||
stbtt.InitFont(&glyph.font_info, &font_data[0], 0)
|
stbtt.InitFont(&glyph.font_info, &font_data[0], 0)
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
font_data, _ := os.read_entire_file_from_path(font_path, context.allocator)
|
||||||
|
stbtt.InitFont(&glyph.font_info, &font_data[0], 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gl.UseProgram(0)
|
gl.UseProgram(0)
|
||||||
}
|
}
|
||||||
@@ -98,6 +110,7 @@ glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, co
|
|||||||
coverage_adjustment: f32 = 0.0
|
coverage_adjustment: f32 = 0.0
|
||||||
text_color: [4]f32 = {f32( color.r)/ 255.0 ,f32(color.g)/255.0, f32(color.b)/255.0, f32(color.a)/255.0}
|
text_color: [4]f32 = {f32( color.r)/ 255.0 ,f32(color.g)/255.0, f32(color.b)/255.0, f32(color.a)/255.0}
|
||||||
|
|
||||||
|
|
||||||
glyph_state.rect_buffer = make([dynamic]GlyphRectInstance, 0, 1000)
|
glyph_state.rect_buffer = make([dynamic]GlyphRectInstance, 0, 1000)
|
||||||
{
|
{
|
||||||
//put every glyph in text into rect_buffer
|
//put every glyph in text into rect_buffer
|
||||||
@@ -138,13 +151,15 @@ glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, co
|
|||||||
glyph_state.curr.y += math.round(line_height)
|
glyph_state.curr.y += math.round(line_height)
|
||||||
|
|
||||||
} else if c == '\t' {
|
} else if c == '\t' {
|
||||||
|
|
||||||
glyph_state.curr.x += 2 * glyph_state.font_size_pt
|
glyph_state.curr.x += 2 * glyph_state.font_size_pt
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
horizontal_filter_padding, subpixel_positioning_left_padding: i32 = 1, 1
|
horizontal_filter_padding, subpixel_positioning_left_padding: i32 = 1, 1
|
||||||
assert(codepoint <= 127)
|
if codepoint >= 127{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert(codepoint < 127)
|
||||||
glyph_atlas := glyph_state.atlas_items[codepoint]
|
glyph_atlas := glyph_state.atlas_items[codepoint]
|
||||||
|
|
||||||
if !glyph_atlas.filled
|
if !glyph_atlas.filled
|
||||||
@@ -283,17 +298,19 @@ glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, co
|
|||||||
gl.Enable(gl.BLEND)
|
gl.Enable(gl.BLEND)
|
||||||
gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC1_COLOR)
|
gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC1_COLOR)
|
||||||
|
|
||||||
gl.BindVertexArray(glyph_state.vao)
|
gl.UseProgram( glyph_state.program_id)
|
||||||
gl.UseProgram(glyph_state.program_id)
|
gl.BindVertexArray( glyph_state.vao)
|
||||||
gl.ProgramUniform2f(glyph_state.program_id, 0, f32(glyph_state.width) / 2.0, f32(glyph_state.height) / 2.0)
|
gl.ProgramUniform2f( glyph_state.program_id, 0, f32(glyph_state.width) / 2.0, f32(glyph_state.height) / 2.0)
|
||||||
gl.ProgramUniform1ui(glyph_state.program_id, 1, u32(coverage_adjustment))
|
gl.ProgramUniform1ui( glyph_state.program_id, 1, u32(coverage_adjustment))
|
||||||
gl.ProgramUniform1ui(glyph_state.program_id, 2, 0)
|
gl.ProgramUniform1ui( glyph_state.program_id, 2, 0)
|
||||||
gl.BindTextureUnit(0, glyph_state.atlas_texture)
|
gl.BindTextureUnit(0, glyph_state.atlas_texture)
|
||||||
gl.DrawArraysInstanced(gl.TRIANGLES, 0, 6, i32(len(glyph_state.rect_buffer)))
|
gl.DrawArraysInstanced(gl.TRIANGLES, 0, 6, i32(len(glyph_state.rect_buffer)))
|
||||||
|
|
||||||
|
gl.Disable(gl.BLEND)
|
||||||
|
|
||||||
gl.UseProgram(0)
|
|
||||||
gl.BindVertexArray(0)
|
//gl.UseProgram(0)
|
||||||
|
//gl.BindVertexArray(0)
|
||||||
|
|
||||||
gl.InvalidateBufferData(glyph_state.rect_instances_vbo)
|
gl.InvalidateBufferData(glyph_state.rect_instances_vbo)
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
+114
-24
@@ -1,15 +1,23 @@
|
|||||||
|
#+feature dynamic-literals
|
||||||
|
package edit2d
|
||||||
import im "shared:odin-imgui"
|
import im "shared:odin-imgui"
|
||||||
import mu "vendor:microui"
|
import mu "vendor:microui"
|
||||||
|
import e2_glyph "./glyph"
|
||||||
|
import "core:fmt"
|
||||||
import "vendor:glfw"
|
import "vendor:glfw"
|
||||||
|
import b2 "vendor:box2d"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This library will only account for box2d's entities editing
|
This library will only account for box2d's entities editing
|
||||||
This library will only account for box2d's entities editing
|
|
||||||
It only deals with one world_id, which means typically one level
|
It only deals with one world_id, which means typically one level
|
||||||
It only deals with one world_id, which means typically one level
|
|
||||||
All the interface follows a pattern
|
All the interface follows a pattern
|
||||||
All the interface follows a pattern
|
i.e. It takes interface_state pointer and returns a boolean indicating weather the world needs to be reloaded
|
||||||
i.e. It takes interface_state pointer and returns a boolean indicating weather the world needs to be reloaded
|
|
||||||
|
|
||||||
|
Interface should handle microui
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
EditMode :: enum
|
EditMode :: enum
|
||||||
@@ -41,6 +49,51 @@ interface_state :: struct
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
key_map : map[i32]mu.Key = {
|
||||||
|
glfw.KEY_LEFT_SHIFT = .SHIFT,
|
||||||
|
glfw.KEY_RIGHT_SHIFT = .SHIFT,
|
||||||
|
glfw.KEY_LEFT_CONTROL = .CTRL,
|
||||||
|
glfw.KEY_RIGHT = .CTRL,
|
||||||
|
glfw.KEY_LEFT_ALT = .ALT,
|
||||||
|
glfw.KEY_RIGHT_ALT = .ALT,
|
||||||
|
glfw.KEY_BACKSPACE = .BACKSPACE,
|
||||||
|
glfw.KEY_DELETE = .DELETE,
|
||||||
|
glfw.KEY_ENTER = .RETURN,
|
||||||
|
glfw.KEY_LEFT = .LEFT,
|
||||||
|
glfw.KEY_RIGHT = .RIGHT,
|
||||||
|
glfw.KEY_HOME = .HOME,
|
||||||
|
glfw.KEY_END = .END,
|
||||||
|
glfw.KEY_A = .A,
|
||||||
|
glfw.KEY_X = .X,
|
||||||
|
glfw.KEY_C = .C,
|
||||||
|
glfw.KEY_V = .V
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_map : map[i32]mu.Mouse = {
|
||||||
|
glfw.MOUSE_BUTTON_LEFT = .LEFT,
|
||||||
|
glfw.MOUSE_BUTTON_RIGHT = .RIGHT,
|
||||||
|
glfw.MOUSE_BUTTON_MIDDLE= .MIDDLE,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//interface_get_font
|
||||||
|
|
||||||
|
mui_text_width :: proc(font: mu.Font, str: string) -> i32
|
||||||
|
{
|
||||||
|
glyph := cast(^e2_glyph.GlyphState)font
|
||||||
|
return i32(len(str)) * i32(glyph.font_size_pt)
|
||||||
|
}
|
||||||
|
|
||||||
|
mui_text_height :: proc(font: mu.Font) -> i32
|
||||||
|
{
|
||||||
|
glyph := cast(^e2_glyph.GlyphState)font
|
||||||
|
return i32(glyph.font_size_pt)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface_get_default :: proc(interface: ^interface_state)
|
||||||
{
|
{
|
||||||
interface.selected_entity = 0
|
interface.selected_entity = 0
|
||||||
interface.vertex_index = new(i32)
|
interface.vertex_index = new(i32)
|
||||||
@@ -50,7 +103,8 @@ interface_get_default :: proc(interface: ^interface_state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface_draw_options :: proc(state: ^engine_state)
|
interface_draw_options :: proc(state: ^engine_state)
|
||||||
interface_draw_options :: proc(state: ^engine_state) {
|
{
|
||||||
|
debug_draw := &state.draw.debug_draw
|
||||||
|
|
||||||
im.SliderFloat("Zoom", &state.draw.cam.zoom, 0, 100)
|
im.SliderFloat("Zoom", &state.draw.cam.zoom, 0, 100)
|
||||||
im.Checkbox("Shapes", &debug_draw.drawShapes)
|
im.Checkbox("Shapes", &debug_draw.drawShapes)
|
||||||
@@ -70,6 +124,48 @@ interface_draw_options :: proc(state: ^engine_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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", {1700, 0, 250, 170})
|
||||||
|
{
|
||||||
|
for type in EditMode
|
||||||
|
{
|
||||||
|
b : bool = interface.edit_mode == type
|
||||||
|
if .CHANGE in mu.checkbox(&state.mu_ctx, fmt.tprint(type), &b) do interface.edit_mode = type
|
||||||
|
}
|
||||||
|
mu.end_window(&state.mu_ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mu_interface_draw_options :: proc(state: ^engine_state)
|
||||||
|
{
|
||||||
|
if mu.begin_window(&state.mu_ctx, "Options", {200, 150, 200, 400}){
|
||||||
|
debug_draw := &state.draw.debug_draw
|
||||||
|
|
||||||
|
mu.label(&state.mu_ctx, "Zoom")
|
||||||
|
mu.slider(&state.mu_ctx, &state.draw.cam.zoom,0, 100)
|
||||||
|
|
||||||
|
mu.checkbox(&state.mu_ctx, "Shapes", &debug_draw.drawShapes)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Joints", &debug_draw.drawJoints)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Joint Extras", &debug_draw.drawJointExtras)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Bounds", &debug_draw.drawBounds)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Contact Points", &debug_draw.drawContacts)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Contact Normals", &debug_draw.drawContactNormals)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Contact Inpulses", &debug_draw.drawContactImpulses)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Contact Features", &debug_draw.drawContactFeatures)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Friction Inpulses", &debug_draw.drawFrictionImpulses)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Mass ", &debug_draw.drawMass)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Body Names", &debug_draw.drawBodyNames)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Graph Colors", &debug_draw.drawGraphColors)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Islands ", &debug_draw.drawIslands)
|
||||||
|
|
||||||
|
mu.label(&state.mu_ctx, "Rotation")
|
||||||
|
mu.slider(&state.mu_ctx, &state.draw.cam.rotation, 0, 360)
|
||||||
|
|
||||||
|
mu.end_window(&state.mu_ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
interface_all :: proc(interface: ^interface_state) -> bool
|
interface_all :: proc(interface: ^interface_state) -> bool
|
||||||
{
|
{
|
||||||
ret := false
|
ret := false
|
||||||
@@ -79,27 +175,26 @@ interface_all :: proc(interface: ^interface_state) -> bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
state := interface.state
|
state := interface.state
|
||||||
if im.Begin("Edit Mode", nil)
|
mu.begin(&state.mu_ctx)
|
||||||
{
|
|
||||||
for type in EditMode
|
//test_window(&state.mu_ctx)
|
||||||
{
|
mu_interface_draw_options(interface.state)
|
||||||
if im.RadioButton(fmt.ctprint(type), interface.edit_mode == type)
|
mu_interface_game_mode(state, interface)
|
||||||
{
|
|
||||||
interface.edit_mode = type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
im.End()
|
|
||||||
if im.Begin("Box2d interface")
|
if im.Begin("Box2d interface")
|
||||||
{
|
{
|
||||||
if im.BeginTabBar("Tabs")
|
if im.BeginTabBar("Tabs")
|
||||||
{
|
{
|
||||||
|
|
||||||
if mu.begin_window(&state.mu_ctx, "B2d Interface", {1700, 150, 250, 250})
|
if mu.begin_window(&state.mu_ctx, "B2d Interface", {1700, 150, 250, 250})
|
||||||
if im.BeginTabItem("Entity", nil, {.Leading})
|
{
|
||||||
|
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
|
||||||
|
|
||||||
im.EndTabItem()
|
}
|
||||||
|
mu.end_window(&state.mu_ctx)
|
||||||
|
}
|
||||||
|
|
||||||
if im.BeginTabItem("Joints", nil, {})
|
if im.BeginTabItem("Joints", nil, {})
|
||||||
{
|
{
|
||||||
@@ -108,15 +203,10 @@ interface_all :: proc(interface: ^interface_state) -> bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
im.EndTabBar()
|
im.EndTabBar()
|
||||||
if im.BeginTabItem("Draw Options", nil, {})
|
|
||||||
{
|
|
||||||
interface_draw_options(interface.state)
|
|
||||||
im.EndTabItem()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mu.end(&state.mu_ctx)
|
mu.end(&state.mu_ctx)
|
||||||
|
im.End()
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+89
-2
@@ -2,6 +2,7 @@ package edit2d
|
|||||||
|
|
||||||
import b2 "vendor:box2d"
|
import b2 "vendor:box2d"
|
||||||
import im "shared:odin-imgui"
|
import im "shared:odin-imgui"
|
||||||
|
import mu "vendor:microui"
|
||||||
import "core:slice"
|
import "core:slice"
|
||||||
import draw "./draw"
|
import draw "./draw"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
@@ -122,6 +123,92 @@ interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_ent
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mu_interface_shape_def_editor :: proc(
|
||||||
|
state : ^engine_state,
|
||||||
|
def : ^engine_entity_def) -> bool
|
||||||
|
{
|
||||||
|
shape_def := &def.shape_def
|
||||||
|
|
||||||
|
mu.label(&state.mu_ctx, "Shape Type")
|
||||||
|
for type in b2.ShapeType
|
||||||
|
{
|
||||||
|
b := def.shape_type == type
|
||||||
|
if .CHANGE in mu.checkbox(&state.mu_ctx, fmt.tprint(type), &b) do def.shape_type = type
|
||||||
|
}
|
||||||
|
|
||||||
|
switch def.shape_type
|
||||||
|
{
|
||||||
|
case .circleShape:{
|
||||||
|
mu.label(&state.mu_ctx, "Radius")
|
||||||
|
mu.slider(&state.mu_ctx, &def.radius, 0, 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
case .polygonShape:{
|
||||||
|
mu.label(&state.mu_ctx, "Size")
|
||||||
|
mu.slider(&state.mu_ctx, &def.size[0], -500, 500)
|
||||||
|
mu.slider(&state.mu_ctx, &def.size[1], -500, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
case .capsuleShape:{
|
||||||
|
mu.label(&state.mu_ctx, "Center 1")
|
||||||
|
mu.slider(&state.mu_ctx, &def.centers[0][0], -100, 100)
|
||||||
|
mu.slider(&state.mu_ctx, &def.centers[0][1], -100, 100)
|
||||||
|
mu.label(&state.mu_ctx, "Center 2")
|
||||||
|
mu.slider(&state.mu_ctx, &def.centers[1][0], -100, 100)
|
||||||
|
mu.slider(&state.mu_ctx, &def.centers[1][1], -100, 100)
|
||||||
|
mu.label(&state.mu_ctx, "Radius")
|
||||||
|
mu.slider(&state.mu_ctx, &def.radius, 0, 40)
|
||||||
|
}
|
||||||
|
|
||||||
|
case .chainSegmentShape:{
|
||||||
|
mu.checkbox(&state.mu_ctx, "Is Loop", &def.is_loop)
|
||||||
|
}
|
||||||
|
case .segmentShape:{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mu.label(&state.mu_ctx, "Density")
|
||||||
|
mu.slider(&state.mu_ctx, &def.shape_def.density, 0, 100)
|
||||||
|
|
||||||
|
if .SUBMIT in mu.button(&state.mu_ctx, "Flip horizontally") do flip_points(def.vertices[:], .Horizontal)
|
||||||
|
if .SUBMIT in mu.button(&state.mu_ctx, "Flip Vertically ") do flip_points(def.vertices[:], .Vertical)
|
||||||
|
|
||||||
|
if .ACTIVE in mu.begin_treenode(&state.mu_ctx, "Events and contacts")
|
||||||
|
{
|
||||||
|
mu.checkbox(&state.mu_ctx, "Is sensor", &def.shape_def.isSensor)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Enable Sensor Events", &def.shape_def.enableSensorEvents)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Enable Contact Events", &def.shape_def.enableContactEvents)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Enable Hit Events", &def.shape_def.enableHitEvents)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Enable Presolve Events", &def.shape_def.enablePreSolveEvents)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Invoke contact Creation", &def.shape_def.invokeContactCreation)
|
||||||
|
mu.checkbox(&state.mu_ctx, "Update body mass ", &def.shape_def.updateBodyMass)
|
||||||
|
|
||||||
|
mu.end_treenode(&state.mu_ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
if .ACTIVE in mu.begin_treenode(&state.mu_ctx, "Material")
|
||||||
|
{
|
||||||
|
mu.label(&state.mu_ctx, "Friction")
|
||||||
|
mu.slider(&state.mu_ctx, &def.shape_def.material.friction, 0, 1)
|
||||||
|
|
||||||
|
mu.label(&state.mu_ctx, "Restitution")
|
||||||
|
mu.slider(&state.mu_ctx, &def.shape_def.material.restitution, 0, 1)
|
||||||
|
|
||||||
|
mu.label(&state.mu_ctx, "Rolling Resistance")
|
||||||
|
mu.slider(&state.mu_ctx, &def.shape_def.material.rollingResistance, 0, 1)
|
||||||
|
|
||||||
|
mu.label(&state.mu_ctx, "Tangent Speed")
|
||||||
|
mu.slider(&state.mu_ctx, &def.shape_def.material.tangentSpeed, 0, 1)
|
||||||
|
|
||||||
|
//if .ACTIVE in mu.begin_treenode(&state.mu_ctx, "Color")
|
||||||
|
|
||||||
|
mu.end_treenode(&state.mu_ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
|
interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
|
||||||
{
|
{
|
||||||
@@ -211,7 +298,6 @@ interface_shape_def_editor :: proc(def: ^engine_entity_def) -> bool
|
|||||||
im.Separator()
|
im.Separator()
|
||||||
im.TreePop()
|
im.TreePop()
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,8 +324,9 @@ interface_entity :: proc(interface: ^interface_state) -> bool
|
|||||||
|
|
||||||
if im.CollapsingHeader("Shape Edit")
|
if im.CollapsingHeader("Shape Edit")
|
||||||
{
|
{
|
||||||
interface_shape_def_editor(def)
|
//interface_shape_def_editor(def)
|
||||||
}
|
}
|
||||||
|
mu_interface_shape_def_editor(interface.state, def)
|
||||||
|
|
||||||
im.Separator()
|
im.Separator()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user