efficient opengl rendering

This commit is contained in:
John Alanbrook 2023-05-16 06:31:13 +00:00
parent 0b6566ff8b
commit d662d9e2fa
20 changed files with 459 additions and 422 deletions

View file

@ -24,12 +24,40 @@
cpSpace *space = NULL;
float phys2d_gravity = -50.f;
float dbg_color[3] = {0.836f, 1.f, 0.45f};
float trigger_color[3] = {0.278f, 0.953f, 1.f};
float disabled_color[3] = {0.58f, 0.58f, 0.58f};
float dynamic_color[3] = {255 / 255, 70 / 255, 46 / 255};
float kinematic_color[3] = {255 / 255, 206 / 255, 71 / 255};
float static_color[3] = {0.22f, 0.271f, 1.f};
struct rgba color_white = {255,255,255,255};
struct rgba color_black = {0,0,0,255};
struct rgba dbg_color = {
.r = 0.836*255,
.g = 255,
.b = 0.45*255,
.a = 255
};
struct rgba trigger_color = {
.r = 0.278*255,
.g = 0.953*255,
.b = 255,
.a = 255
};
struct rgba disabled_color = {
.r = 0.58*255,
.g = 0.58*255,
.b = 0.58*255,
.a = 255
};
struct rgba dynamic_color = {
.r = 255,
.g = 70,
.b = 46,
.a = 255
};
struct rgba kinematic_color = {255, 206, 71, 255};
struct rgba static_color = {
.r = 0.22*255,
.g = 0.271*255,
.b = 255,
.a = 255
};
unsigned int category_masks[32];
@ -37,20 +65,6 @@ void set_cat_mask(int cat, unsigned int mask) {
category_masks[cat] = mask;
}
void color2float(struct color color, float *fcolor) {
fcolor[0] = (float)color.r / 255;
fcolor[1] = (float)color.g / 255;
fcolor[2] = (float)color.b / 255;
}
struct color float2color(float *fcolor) {
struct color new;
new.r = fcolor[0] * 255;
new.b = fcolor[1] * 255;
new.g = fcolor[2] * 255;
return new;
}
cpShape *phys2d_query_pos(cpVect pos) {
cpShapeFilter filter;
filter.group = CP_NO_GROUP;
@ -153,7 +167,7 @@ int cpshape_enabled(cpShape *c) {
return 1;
}
float *shape_outline_color(cpShape *shape) {
struct rgba shape_outline_color(cpShape *shape) {
switch (cpBodyGetType(cpShapeGetBody(shape))) {
case CP_BODY_TYPE_DYNAMIC:
return dynamic_color;
@ -168,7 +182,7 @@ float *shape_outline_color(cpShape *shape) {
return static_color;
}
float *shape_color(cpShape *shape) {
struct rgba shape_color(cpShape *shape) {
if (!cpshape_enabled(shape)) return disabled_color;
if (cpShapeGetSensor(shape)) return trigger_color;
@ -176,13 +190,8 @@ float *shape_color(cpShape *shape) {
return dbg_color;
}
struct color shape_color_s(cpShape *shape) {
float *c = shape_color(shape);
struct color col;
col.r = c[0] * 255;
col.g = c[1] * 255;
col.b = c[2] * 255;
return col;
struct rgba shape_color_s(cpShape *shape) {
return shape_color(shape);
}
void phys2d_init() {
@ -416,7 +425,7 @@ void phys2d_applypoly(struct phys2d_poly *poly) {
cpSpaceReindexShapesForBody(space, cpShapeGetBody(poly->shape.shape));
}
void phys2d_dbgdrawpoly(struct phys2d_poly *poly) {
float *color = shape_color(poly->shape.shape);
struct rgba color = shape_color(poly->shape.shape);
if (arrlen(poly->points) >= 3) {
int n = cpPolyShapeGetCount(poly->shape.shape);
@ -549,7 +558,7 @@ void phys2d_dbgdrawedge(struct phys2d_edge *edge) {
drawpoints[i] = bodytransformpoint(cpShapeGetBody(edge->shapes[0]), drawpoints[i]);
}
draw_edge(drawpoints, arrlen(edge->points), shape_color_s(edge->shapes[0]), edge->thickness * 2);
draw_edge(drawpoints, arrlen(edge->points), shape_color_s(edge->shapes[0]), edge->thickness * 2, 0,0);
draw_points(drawpoints, arrlen(edge->points), 2, kinematic_color);
}

View file

@ -10,12 +10,24 @@ extern float phys2d_gravity;
extern int physOn;
extern cpSpace *space;
extern float dbg_color[3];
extern float trigger_color[3];
extern float disabled_color[3];
extern float dynamic_color[3];
extern float kinematic_color[3];
extern float static_color[3];
struct rgba {
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
extern struct rgba color_white;
extern struct rgba color_black;
extern struct rgba dbg_color;
extern struct rgba trigger_color;
extern struct rgba disabled_color;
extern struct rgba dynamic_color;
extern struct rgba kinematic_color;
extern struct rgba static_color;
struct phys2d_shape {
cpShape *shape;
@ -126,15 +138,7 @@ int shape_is_enabled(struct phys2d_shape *shape);
void shape_set_sensor(struct phys2d_shape *shape, int sensor);
int shape_get_sensor(struct phys2d_shape *shape);
struct color {
unsigned char r;
unsigned char g;
unsigned char b;
};
void color2float(struct color, float *fcolor);
struct color float2color(float *fcolor);
struct color shape_color_s(cpShape *shape);
struct rgba shape_color_s(cpShape *shape);
void shape_gui(struct phys2d_shape *shape);
void phys2d_setup_handlers(int go);

View file

@ -16,28 +16,42 @@
#include "font.h"
static sg_shader point_shader;
static sg_pipeline point_pipe;
static sg_bindings point_bind;
struct point_vertex {
cpVect pos;
struct rgba color;
float radius;
};
static int point_c = 0;
static sg_pipeline grid_pipe;
static sg_bindings grid_bind;
static sg_shader grid_shader;
static int grid_c = 0;
static sg_pipeline rect_pipe;
static sg_bindings rect_bind;
static sg_shader rect_shader;
static int rect_c = 0;
static sg_pipeline poly_pipe;
static sg_bindings poly_bind;
static sg_shader poly_shader;
static int poly_c = 0;
static int poly_v = 0;
static int poly_vc = 7;
struct poly_vertex {
float pos[2];
float uv[2];
struct rgba color;
};
static sg_pipeline circle_pipe;
static sg_bindings circle_bind;
static sg_shader csg;
static int circle_count = 0;
static int circle_vert_c = 7;
struct circle_vertex {
float pos[2];
float radius;
struct rgba color;
};
void debug_flush()
{
@ -48,18 +62,18 @@ void debug_flush()
sg_draw(0,4,circle_count);
circle_count = 0;
sg_apply_pipeline(rect_pipe);
sg_apply_bindings(&rect_bind);
sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection));
sg_draw(0,rect_c*2,1);
rect_c = 0;
sg_apply_pipeline(poly_pipe);
sg_apply_bindings(&poly_bind);
sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection));
sg_draw(0,poly_c,1);
poly_c = 0;
poly_v = 0;
sg_apply_pipeline(point_pipe);
sg_apply_bindings(&point_bind);
sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection));
sg_draw(0,point_c,1);
point_c = 0;
}
static sg_shader_uniform_block_desc projection_ubo = {
@ -69,8 +83,41 @@ static sg_shader_uniform_block_desc projection_ubo = {
}
};
sg_blend_state blend_trans = {
.enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
.src_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
};
void debugdraw_init()
{
point_shader = sg_make_shader(&(sg_shader_desc){
.vs.source = slurp_text("shaders/point_v.glsl"),
.fs.source = slurp_text("shaders/point_f.glsl"),
.vs.uniform_blocks[0] = projection_ubo
});
point_pipe = sg_make_pipeline(&(sg_pipeline_desc){
.shader = point_shader,
.layout = {
.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT2, /* pos */
[1].format = SG_VERTEXFORMAT_UBYTE4N, /* color */
[2].format = SG_VERTEXFORMAT_FLOAT /* radius */
}
},
.primitive_type = SG_PRIMITIVETYPE_POINTS,
.colors[0].blend = blend_trans
});
point_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(struct point_vertex)*5000,
.usage = SG_USAGE_STREAM
});
csg = sg_make_shader(&(sg_shader_desc){
.vs.source = slurp_text("shaders/circlevert.glsl"),
.fs.source = slurp_text("shaders/circlefrag.glsl"),
@ -83,21 +130,15 @@ void debugdraw_init()
.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT2,
[0].buffer_index = 1,
[1].format = SG_VERTEXFORMAT_FLOAT3,
[2].format = SG_VERTEXFORMAT_FLOAT2,
[3].format = SG_VERTEXFORMAT_FLOAT
[1].format = SG_VERTEXFORMAT_FLOAT2,
[2].format = SG_VERTEXFORMAT_FLOAT,
[3].format = SG_VERTEXFORMAT_UBYTE4N
},
.buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE,
},
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
.cull_mode = SG_CULLMODE_BACK,
.colors[0].blend = {
.enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
.src_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
},
.colors[0].blend = blend_trans,
.label = "circle pipeline"
});
@ -118,7 +159,6 @@ void debugdraw_init()
.usage = SG_USAGE_IMMUTABLE,
});
grid_shader = sg_make_shader(&(sg_shader_desc){
.vs.source = slurp_text("shaders/gridvert.glsl"),
.fs.source = slurp_text("shaders/gridfrag.glsl"),
@ -127,88 +167,55 @@ void debugdraw_init()
.size = sizeof(float)*2,
.uniforms = { [0] = { .name = "offset", .type = SG_UNIFORMTYPE_FLOAT2 } } },
.fs.uniform_blocks[0] = {
.size = sizeof(float)*5,
.size = sizeof(float)*6,
.uniforms = {
[0] = { .name = "thickness", .type = SG_UNIFORMTYPE_FLOAT },
[1] = { .name = "span", .type = SG_UNIFORMTYPE_FLOAT },
[2] = { .name = "color", .type = SG_UNIFORMTYPE_FLOAT3 },
[2] = { .name = "color", .type = SG_UNIFORMTYPE_FLOAT4 },
}
},
});
grid_pipe = sg_make_pipeline(&(sg_pipeline_desc){
.shader = grid_shader,
.layout = {
.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT2
[0].format = SG_VERTEXFORMAT_FLOAT2, /* pos */
}
},
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
// .cull_mode = SG_CULLMODE_BACK,
// .cull_mode = sg_cullmode_back,
.label = "grid pipeline",
.colors[0] = {
.blend = {
.enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.op_rgb = SG_BLENDOP_ADD,
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.op_alpha = SG_BLENDOP_ADD
},
},
.colors[0].blend = blend_trans,
});
grid_bind.vertex_buffers[0] = circle_bind.vertex_buffers[1];
rect_shader = sg_make_shader(&(sg_shader_desc){
.vs.source = slurp_text("shaders/linevert.glsl"),
.fs.source = slurp_text("shaders/linefrag.glsl"),
.vs.uniform_blocks[0] = projection_ubo
});
rect_pipe = sg_make_pipeline(&(sg_pipeline_desc){
.shader = rect_shader,
.layout = {
.attrs = { [0].format = SG_VERTEXFORMAT_FLOAT2 }
},
.primitive_type = SG_PRIMITIVETYPE_LINES
});
rect_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(float)*2*10000,
.usage = SG_USAGE_STREAM
});
poly_shader = sg_make_shader(&(sg_shader_desc){
.vs.source = slurp_text("shaders/poly_v.glsl"),
.fs.source = slurp_text("shaders/poly_f.glsl"),
.vs.uniform_blocks[0] = projection_ubo,
.vs.uniform_blocks[0] = projection_ubo
});
poly_pipe = sg_make_pipeline(&(sg_pipeline_desc){
.shader = poly_shader,
.layout = {
.attrs = { [0].format = SG_VERTEXFORMAT_FLOAT2,
[1].format = SG_VERTEXFORMAT_FLOAT2,
[2].format = SG_VERTEXFORMAT_FLOAT3
.attrs = { [0].format = SG_VERTEXFORMAT_FLOAT2, /* pos */
[1].format = SG_VERTEXFORMAT_FLOAT2, /* uv */
[2].format = SG_VERTEXFORMAT_UBYTE4N /* color rgba */
}
},
.index_type = SG_INDEXTYPE_UINT32
.index_type = SG_INDEXTYPE_UINT32,
.colors[0].blend = blend_trans,
});
poly_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(float)*poly_vc*1000,
.size = sizeof(struct poly_vertex)*1000,
.usage = SG_USAGE_STREAM,
.type = SG_BUFFERTYPE_VERTEXBUFFER,
});
/* poly_bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(float)*1000,
.usage = SG_USAGE_STREAM,
});
*/
poly_bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(uint32_t)*6*1000,
.usage = SG_USAGE_STREAM,
@ -216,7 +223,7 @@ void debugdraw_init()
});
}
void draw_line(cpVect s, cpVect e, float *color)
void draw_line(cpVect s, cpVect e, struct rgba color)
{
cpVect verts[2] = {s, e};
draw_poly(verts, 2, color);
@ -287,156 +294,11 @@ void inflatepoints(cpVect *r, cpVect *p, float d, int n)
r[i+1] = inflatepoint(p[i],p[i+1],p[i+2], d);
}
void draw_edge(cpVect *points, int n, struct color color, int thickness)
void draw_edge(cpVect *points, int n, struct rgba color, int thickness, int closed, int flags)
{
return;
static_assert(sizeof(cpVect) == 2*sizeof(float));
float col[3] = {(float)color.r/255, (float)color.g/255, (float)color.b/255};
/* TODO: Should be dashed, and filled. Use a texture. */
parsl_position par_v[n];
for (int i = 0; i < n; i++) {
par_v[i].x = points[i].x;
par_v[i].y = points[i].y;
}
uint16_t spine_lens[] = {n};
parsl_context *par_ctx = parsl_create_context((parsl_config){
.thickness = thickness
});
parsl_mesh *mesh = parsl_mesh_from_lines(par_ctx, (parsl_spine_list){
.num_vertices = n,
.num_spines = 1,
.vertices = points,
.spine_lengths = spine_lens,
});
sg_range pt = {
.ptr = mesh->positions,
.size = sizeof(float)*2*mesh->num_vertices
};
for (int i = 0; i < mesh->num_triangles*3; i++)
mesh->triangle_indices[i] += poly_v;
float mesh_colors[3*mesh->num_vertices];
for (int i = 0; i < 3*mesh->num_vertices; i+=3)
for (int j = 0; j < 3; j++)
mesh_colors[i+j] = col[j];
sg_range it = {
.ptr = mesh->triangle_indices,
.size = sizeof(uint32_t)*mesh->num_triangles*3
};
sg_range ct = {
.ptr = mesh_colors,
.size = sizeof(float)*mesh->num_vertices*3
};
sg_append_buffer(poly_bind.vertex_buffers[0], &pt);
sg_append_buffer(poly_bind.index_buffer, &it);
sg_append_buffer(poly_bind.vertex_buffers[1], &ct);
poly_c += mesh->num_triangles*3;
poly_v += mesh->num_vertices;
parsl_destroy_context(par_ctx);
}
void draw_circle(int x, int y, float radius, int pixels, float *color, int fill)
{
float cv[circle_vert_c];
cv[0] = color[0];
cv[1] = color[1];
cv[2] = color[2];
cv[3] = x;
cv[4] = y;
cv[5] = radius;
cv[6] = fill;
sg_append_buffer(circle_bind.vertex_buffers[0], SG_RANGE_REF(cv));
circle_count++;
}
void draw_rect(int x, int y, int w, int h, float *color)
{
float hw = w / 2.f;
float hh = h / 2.f;
cpVect verts[4] = {
{ .x = x-hw, .y = y-hh },
{ .x = x+hw, .y = y-hh },
{ .x = x+hw, .y = y+hh },
{ .x = x-hw, .y = y+hh }
};
draw_poly(verts, 4, color);
}
void draw_box(struct cpVect c, struct cpVect wh, struct color color)
{
float col[3] = {(float)color.r/255, (float)color.g/255, (float)color.b/255};
draw_rect(c.x, c.y, wh.x, wh.y, col);
}
void draw_arrow(struct cpVect start, struct cpVect end, struct color color, int capsize)
{
float col[3] = {(float)color.r/255, (float)color.g/255, (float)color.b/255};
draw_line(start, end, col);
draw_cppoint(end, capsize, color);
}
void draw_grid(int width, int span)
{
cpVect offset = cam_pos();
offset = cpvmult(offset, 1/cam_zoom());
offset.x -= mainwin->width/2;
offset.y -= mainwin->height/2;
sg_apply_pipeline(grid_pipe);
sg_apply_bindings(&grid_bind);
float col[3] = { 0.3, 0.5, 0.8};
float fubo[5];
fubo[0] = width;
fubo[1] = span;
fubo[2] = col;
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
sg_apply_uniforms(SG_SHADERSTAGE_VS, 1, SG_RANGE_REF(offset));
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(fubo));
sg_draw(0,4,1);
}
void draw_point(int x, int y, float r, float *color)
{
draw_circle(x,y,r,r,color,1);
}
void draw_cppoint(struct cpVect point, float r, struct color color)
{
float col[3] = {(float)color.r/255, (float)color.g/255, (float)color.b/255};
draw_point(point.x, point.y, r, col);
}
void draw_points(struct cpVect *points, int n, float size, float *color)
{
for (int i = 0; i < n; i++)
draw_point(points[i].x, points[i].y, size, color);
}
void draw_poly(cpVect *points, int n, float *color)
{
/* todo: should be dashed, and filled. use a texture. */
/* draw polygon outline */
parsl_position par_v[n];
for (int i = 0; i < n; i++) {
@ -456,7 +318,7 @@ void draw_poly(cpVect *points, int n, float *color)
.num_spines = 1,
.vertices = par_v,
.spine_lengths = spine_lens,
.closed = true
.closed = closed
});
for (int i = 0; i < mesh->num_triangles*3; i++)
@ -467,21 +329,19 @@ void draw_poly(cpVect *points, int n, float *color)
.size = sizeof(uint32_t)*mesh->num_triangles*3
};
float vertices[poly_vc*mesh->num_vertices];
struct poly_vertex vertices[mesh->num_vertices];
for (int i = 0, vert = 0; i < mesh->num_vertices; i++, vert+=poly_vc) {
vertices[vert] = mesh->positions[i].x;
vertices[vert+1] = mesh->positions[i].y;
vertices[vert+2] = mesh->annotations[i].u_along_curve;
vertices[vert+3] = mesh->annotations[i].v_across_curve;
vertices[vert+4] = color[0];
vertices[vert+5] = color[1];
vertices[vert+6] = color[2];
for (int i = 0; i < mesh->num_vertices; i++) {
vertices[i].pos[0] = mesh->positions[i].x;
vertices[i].pos[1] = mesh->positions[i].y;
vertices[i].uv[0] = mesh->annotations[i].u_along_curve;
vertices[i].uv[1] = mesh->annotations[i].v_across_curve;
vertices[i].color = color;
}
sg_range vvt = {
.ptr = vertices,
.size = sizeof(float)*poly_vc*mesh->num_vertices
.size = sizeof(struct poly_vertex)*mesh->num_vertices
};
sg_append_buffer(poly_bind.vertex_buffers[0], &vvt);
@ -491,8 +351,142 @@ void draw_poly(cpVect *points, int n, float *color)
poly_v += mesh->num_vertices;
parsl_destroy_context(par_ctx);
}
return;
void draw_circle(int x, int y, float radius, int pixels, struct rgba color, int fill)
{
struct circle_vertex cv;
cv.pos[0] = x;
cv.pos[1] = y;
cv.radius = radius;
cv.color = color;
sg_append_buffer(circle_bind.vertex_buffers[0], SG_RANGE_REF(cv));
circle_count++;
}
void draw_rect(int x, int y, int w, int h, struct rgba color)
{
float hw = w / 2.f;
float hh = h / 2.f;
cpVect verts[4] = {
{ .x = x-hw, .y = y-hh },
{ .x = x+hw, .y = y-hh },
{ .x = x+hw, .y = y+hh },
{ .x = x-hw, .y = y+hh }
};
draw_poly(verts, 4, color);
}
void draw_box(struct cpVect c, struct cpVect wh, struct rgba color)
{
draw_rect(c.x, c.y, wh.x, wh.y, color);
}
void draw_arrow(struct cpVect start, struct cpVect end, struct rgba color, int capsize)
{
draw_line(start, end, color);
draw_cppoint(end, capsize, color);
}
void draw_grid(int width, int span, struct rgba color)
{
cpVect offset = cam_pos();
offset = cpvmult(offset, 1/cam_zoom());
offset.x -= mainwin->width/2;
offset.y -= mainwin->height/2;
sg_apply_pipeline(grid_pipe);
sg_apply_bindings(&grid_bind);
float col[4] = { color.r/255.0 ,color.g/255.0 ,color.b/255.0 ,color.a/255.0 };
float fubo[6];
fubo[0] = 1;
fubo[1] = span;
memcpy(&fubo[2], col, sizeof(float)*4);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection));
sg_apply_uniforms(SG_SHADERSTAGE_VS, 1, SG_RANGE_REF(offset));
sg_apply_uniforms(SG_SHADERSTAGE_FS, 0, SG_RANGE_REF(fubo));
sg_draw(0,4,1);
}
void draw_point(int x, int y, float r, struct rgba color)
{
struct point_vertex p;
p.pos.x = x;
p.pos.y = y;
p.color = color;
p.radius = r;
sg_range pt = {
.ptr = &p,
.size = sizeof(p)
};
sg_append_buffer(point_bind.vertex_buffers[0], &pt);
point_c++;
}
void draw_cppoint(struct cpVect point, float r, struct rgba color)
{
draw_point(point.x, point.y, r, color);
}
void draw_points(struct cpVect *points, int n, float size, struct rgba color)
{
for (int i = 0; i < n; i++)
draw_point(points[i].x, points[i].y, size, color);
}
void draw_poly(cpVect *points, int n, struct rgba color)
{
draw_edge(points,n,color,1,1,0);
color.a = 40;
/* Find polygon mesh */
int tric = n - 2;
if (n < 1) return;
uint32_t tridxs[tric*3];
for (int i = 2, ti = 0; i < n; i++, ti+=3) {
tridxs[ti] = 0;
tridxs[ti+1] = i-1;
tridxs[ti+2] = i;
}
for (int i = 0; i < tric*3; i++)
tridxs[i] += poly_v;
sg_range trip = {
.ptr = tridxs,
.size = sizeof(uint32_t)*3*tric
};
struct poly_vertex polyverts[n];
for (int i = 0; i < n; i++) {
polyverts[i].pos[0] = points[i].x;
polyverts[i].pos[1] = points[i].y;
polyverts[i].uv[0] = 0.0;
polyverts[i].uv[1] = 0.0;
polyverts[i].color = color;
}
sg_range ppp = {
.ptr = polyverts,
.size = sizeof(struct poly_vertex)*n
};
sg_append_buffer(poly_bind.vertex_buffers[0], &ppp);
sg_append_buffer(poly_bind.index_buffer, &trip);
poly_c += tric*3;
poly_v += n;
}
void debugdraw_flush()

View file

@ -2,20 +2,20 @@
#define DEBUGDRAW_H
#include <chipmunk/chipmunk.h>
struct color;
struct rgba;
void debugdraw_init();
void draw_line(cpVect s, cpVect e, float *color);
void draw_edge(struct cpVect *points, int n, struct color color, int thickness);
void draw_points(struct cpVect *points, int n, float size, float *color);
void draw_arrow(struct cpVect start, struct cpVect end, struct color, int capsize);
void draw_circle(int x, int y, float radius, int pixels, float *color, int fill);
void draw_grid(int width, int span);
void draw_rect(int x, int y, int w, int h, float *color);
void draw_box(struct cpVect c, struct cpVect wh, struct color color);
void draw_point(int x, int y, float r, float *color);
void draw_cppoint(struct cpVect point, float r, struct color color);
void draw_poly(cpVect *points, int n, float *color);
void draw_line(cpVect s, cpVect e, struct rgba color);
void draw_edge(struct cpVect *points, int n, struct rgba color, int thickness, int closed, int flags);
void draw_points(struct cpVect *points, int n, float size, struct rgba color);
void draw_arrow(struct cpVect start, struct cpVect end, struct rgba, int capsize);
void draw_circle(int x, int y, float radius, int pixels, struct rgba color, int fill);
void draw_grid(int width, int span, struct rgba color);
void draw_rect(int x, int y, int w, int h, struct rgba color);
void draw_box(struct cpVect c, struct cpVect wh, struct rgba color);
void draw_point(int x, int y, float r, struct rgba color);
void draw_cppoint(struct cpVect point, float r, struct rgba color);
void draw_poly(cpVect *points, int n, struct rgba color);
void debug_flush();

View file

@ -116,11 +116,14 @@ int js_arrlen(JSValue v) {
JS_ToInt32(js, &len, JS_GetPropertyStr(js, v, "length"));
return len;
}
struct color js2color(JSValue v) {
struct color color = {0, 0, 0};
color.r = js2int(js_arridx(v, 0));
color.g = js2int(js_arridx(v, 1));
color.b = js2int(js_arridx(v, 2));
struct rgba js2color(JSValue v) {
struct rgba color = {
.r = js2int(js_arridx(v, 0)),
.g = js2int(js_arridx(v, 1)),
.b = js2int(js_arridx(v, 2)),
.a = 255
};
return color;
}
@ -189,8 +192,7 @@ JSValue duk_gui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *a
cpVect pos = js2vec2(argv[1]);
float size = js2number(argv[2]);
const float white[3] = {1.f, 1.f, 1.f};
renderText(s, &pos, size, white, 500, -1);
renderText(s, &pos, size, color_white, 500, -1);
JS_FreeCString(js, s);
return JS_NULL;
}
@ -200,10 +202,9 @@ JSValue duk_ui_text(JSContext *js, JSValueConst this, int argc, JSValueConst *ar
cpVect pos = js2vec2(argv[1]);
float size = js2number(argv[2]);
struct color c = js2color(argv[3]);
const float col[3] = {(float)c.r / 255, (float)c.g / 255, (float)c.b / 255};
struct rgba c = js2color(argv[3]);
int wrap = js2int(argv[4]);
JSValue ret = JS_NewInt64(js, renderText(s, &pos, size, col, wrap, -1));
JSValue ret = JS_NewInt64(js, renderText(s, &pos, size, c, wrap, -1));
JS_FreeCString(js, s);
return ret;
}
@ -213,11 +214,10 @@ JSValue duk_cursor_text(JSContext *js, JSValueConst this, int argc, JSValueConst
cpVect pos = js2vec2(argv[1]);
float size = js2number(argv[2]);
struct color c = js2color(argv[3]);
const float col[3] = {(float)c.r / 255, (float)c.g / 255, (float)c.b / 255};
struct rgba c = js2color(argv[3]);
int wrap = js2int(argv[5]);
int cursor = js2int(argv[4]);
renderText(s, &pos, size, col, wrap, cursor);
renderText(s, &pos, size, c, wrap, cursor);
JS_FreeCString(js, s);
return JS_NULL;
}
@ -598,11 +598,11 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 16:
color2float(js2color(argv[1]), dbg_color);
dbg_color = js2color(argv[1]);
break;
case 17:
color2float(js2color(argv[1]), trigger_color);
trigger_color = js2color(argv[1]);
break;
case 18:
@ -719,7 +719,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
return JS_NULL;
case 47:
draw_grid(js2int(argv[1]), js2int(argv[2]));
draw_grid(js2int(argv[1]), js2int(argv[2]), color_white);
return JS_NULL;
case 48:
@ -853,7 +853,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
return JS_NULL;
case 83:
draw_edge(js2cpvec2arr(argv[1]), 2, js2color(argv[2]), 1);
draw_edge(js2cpvec2arr(argv[1]), 2, js2color(argv[2]), 1, 0, 0);
return JS_NULL;
case 84:
@ -909,7 +909,7 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
break;
case 96:
color2float(js2color(argv[2]), id2sprite(js2int(argv[1]))->color);
// id2sprite(js2int(argv[1]))->color = js2color(argv[2]);
break;
case 97:

View file

@ -3,6 +3,7 @@
#include "quickjs/quickjs.h"
#include <chipmunk/chipmunk.h>
#include "2dphysics.h"
void ffi_load();
@ -12,7 +13,7 @@ cpVect js2vec2(JSValue v);
JSValue bitmask2js(cpBitmask mask);
cpBitmask js2bitmask(JSValue v);
struct color js2color(JSValue v);
struct rgba js2color(JSValue v);
double js2number(JSValue v);
JSValue num2js(double g);
JSValue int2js(int i);

View file

@ -9,6 +9,8 @@
#include <stdlib.h>
#include <string.h>
#include <window.h>
#include <chipmunk/chipmunk.h>
#include "2dphysics.h"
#include "openglrender.h"
@ -18,6 +20,7 @@
struct sFont *font;
#define max_chars 40000
unsigned char *slurp_file(const char *filename) {
FILE *f = fopen(filename, "rb");
@ -36,7 +39,11 @@ unsigned char *slurp_file(const char *filename) {
char *slurp_text(const char *filename) {
FILE *f = fopen(filename, "r'");
if (!f) return NULL;
if (!f) {
YughWarn("File %s doesn't exist.", filename);
return NULL;
}
char *buf;
long int fsize;
@ -64,10 +71,15 @@ int slurp_write(const char *txt, const char *filename) {
static sg_shader fontshader;
static sg_bindings bind_text;
static sg_pipeline pipe_text;
struct text_vert {
cpVect pos;
cpVect wh;
struct uv_n uv;
struct uv_n st;
struct rgba color;
};
static float text_buffer[16 * 40000];
static uint16_t text_idx_buffer[6 * 40000];
static float color_buffer[3 * 40000];
static struct text_vert text_buffer[max_chars];
void font_init(struct shader *textshader) {
fontshader = sg_make_shader(&(sg_shader_desc){
@ -85,35 +97,37 @@ void font_init(struct shader *textshader) {
.shader = fontshader,
.layout = {
.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT2,
[0].buffer_index = 0,
[1].format = SG_VERTEXFORMAT_FLOAT2,
[1].buffer_index = 0,
[2].format = SG_VERTEXFORMAT_FLOAT3,
[2].buffer_index = 1,
[0].format = SG_VERTEXFORMAT_FLOAT2, /* verts */
[0].buffer_index = 1,
[1].format = SG_VERTEXFORMAT_FLOAT2, /* pos */
[2].format = SG_VERTEXFORMAT_FLOAT2, /* width and height */
[3].format = SG_VERTEXFORMAT_USHORT2N, /* uv pos */
[4].format = SG_VERTEXFORMAT_USHORT2N, /* uv width and height */
[5].format = SG_VERTEXFORMAT_UBYTE4N, /* color */
},
.buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE
},
.label = "text pipeline",
.index_type = SG_INDEXTYPE_UINT16});
.primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP,
});
float text_verts[8] = {
0,0,
0,1,
1,0,
1,1
};
bind_text.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
.data = SG_RANGE(text_verts),
.usage = SG_USAGE_IMMUTABLE
});
bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(float) * 16 * 40000,
.size = sizeof(struct text_vert)*max_chars,
.type = SG_BUFFERTYPE_VERTEXBUFFER,
.usage = SG_USAGE_STREAM,
.label = "text buffer"});
bind_text.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(float) * 3 * 4 * 40000,
.type = SG_BUFFERTYPE_VERTEXBUFFER,
.usage = SG_USAGE_STREAM,
.label = "text color buffer"});
bind_text.index_buffer = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(uint16_t) * 6 * 40000,
.type = SG_BUFFERTYPE_INDEXBUFFER,
.usage = SG_USAGE_STREAM,
.label = "text index buffer"});
font = MakeFont("LessPerfectDOSVGA.ttf", 16);
bind_text.fs_images[0] = font->texID;
}
@ -205,66 +219,31 @@ void text_flush() {
sg_range verts;
verts.ptr = text_buffer;
verts.size = sizeof(float) * 16 * curchar;
verts.size = sizeof(struct text_vert) * curchar;
sg_update_buffer(bind_text.vertex_buffers[0], &verts);
sg_range idxs;
idxs.ptr = text_idx_buffer;
idxs.size = sizeof(uint16_t) * 6 * curchar;
sg_update_buffer(bind_text.index_buffer, &idxs);
sg_range c = {
.ptr = color_buffer,
.size = sizeof(float) * 3 * 4 * curchar};
sg_update_buffer(bind_text.vertex_buffers[1], &c);
sg_draw(0, 6 * curchar, 1);
sg_draw(0, 4, curchar);
curchar = 0;
}
void fill_charverts(float *verts, float cursor[2], float scale, struct Character c, float *offset) {
float w = c.Size[0] * scale;
float h = c.Size[1] * scale;
float xpos = cursor[0] + (c.Bearing[0] + offset[0]) * scale;
float ypos = cursor[1] - (c.Bearing[1] + offset[1]) * scale;
float v[16] = {
xpos, ypos, c.rect.s0, c.rect.t1,
xpos + w, ypos, c.rect.s1, c.rect.t1,
xpos, ypos + h, c.rect.s0, c.rect.t0,
xpos + w, ypos + h, c.rect.s1, c.rect.t0};
memcpy(verts, v, sizeof(float) * 16);
}
static int drawcaret = 0;
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, float color[3]) {
float shadowcolor[3] = {0.f, 0.f, 0.f};
float shadowcursor[2];
float verts[16];
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct rgba color) {
float offset[2] = {-1, 1};
fill_charverts(verts, cursor, scale, c, offset);
struct text_vert vert;
/* Check if the vertex is off screen */
if (verts[5] < -window_i(0)->width / 2.f || verts[9] < -window_i(0)->height / 2.f || verts[0] > window_i(0)->width / 2.f || verts[1] > window_i(0)->height / 2.f)
return;
vert.wh.x = c.Size[0] * scale;
vert.wh.y = c.Size[1] * scale;
vert.pos.x = cursor[0] - (c.Bearing[0] + offset[0]) * scale;
vert.pos.y = cursor[1] - (c.Bearing[1] + offset[1]) * scale;
vert.uv.u = c.rect.s0*USHRT_MAX;
vert.uv.v = c.rect.t0*USHRT_MAX;
vert.st.u = (c.rect.s1-c.rect.s0)*USHRT_MAX;
vert.st.v = (c.rect.t1-c.rect.t0)*USHRT_MAX;
vert.color = color;
uint16_t pts[6] = {
0, 1, 2,
2, 1, 3};
for (int i = 0; i < 6; i++)
pts[i] += curchar * 4;
memcpy(text_buffer + (16 * curchar), verts, sizeof(verts));
for (int i = 0; i < 4; i++)
memcpy(color_buffer + (12 * curchar) + (3 * i), color, sizeof(color));
memcpy(text_idx_buffer + (6 * curchar), pts, sizeof(pts));
memcpy(text_buffer + curchar, &vert, sizeof(struct text_vert));
curchar++;
return;
@ -291,17 +270,13 @@ void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, float c
fill_charverts(verts, cursor, scale, c, offset);
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
*/
offset[0] = offset[1] = 0;
fill_charverts(verts, cursor, scale, c, offset);
sg_update_buffer(bind_text.vertex_buffers[0], SG_RANGE_REF(verts));
}
void text_settype(struct sFont *mfont) {
font = mfont;
}
int renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3], float lw, int caret) {
int renderText(const char *text, mfloat_t pos[2], float scale, struct rgba color, float lw, int caret) {
int len = strlen(text);
drawcaret = caret;
@ -312,7 +287,7 @@ int renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3]
const unsigned char *line, *wordstart, *drawstart;
line = drawstart = (unsigned char *)text;
float *usecolor = color;
struct rgba usecolor = color;
while (*line != '\0') {
if (isblank(*line)) {

View file

@ -4,6 +4,7 @@
#include "mathc.h"
#include "sokol/sokol_gfx.h"
#include "texture.h"
#include "2dphysics.h"
struct shader;
struct window;
@ -25,9 +26,9 @@ struct sFont {
void font_init(struct shader *s);
struct sFont *MakeFont(const char *fontfile, int height);
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, float color[3]);
void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct rgba color);
void text_settype(struct sFont *font);
int renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3], float lw, int caret);
int renderText(const char *text, mfloat_t pos[2], float scale, struct rgba color, float lw, int caret);
// void text_frame();
void text_flush();

View file

@ -321,7 +321,12 @@ void gameobject_draw_debug(int go) {
if (!g || !g->body) return;
cpVect pos = cpBodyGetPosition(g->body);
float color[3] = {0.76f, 0.38f, 1.f};
struct rgba color = {
.r = 0.76*255,
.b = 0.38*255,
.g = 255,
.a = 255
};
draw_point(pos.x, pos.y, 3.f, color);
cpBodyEachShape(g->body, body_draw_shapes_dbg, NULL);
}

View file

@ -291,7 +291,7 @@ void openglRender(struct window *window) {
if (debugDrawPhysics)
gameobject_draw_debugs();
float c[3] = {0.3,0.5,0.7};
struct rgba c = {100,130,200,255};
draw_circle(100,100,40,2,c,0);
call_debugs();
debug_flush();

View file

@ -4,4 +4,15 @@
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
struct uv_n {
unsigned short u;
unsigned short v;
};
struct st_n {
struct uv_n s;
struct uv_n t;
};
#endif

View file

@ -4,7 +4,7 @@ in vec2 coords;
out vec4 color;
in float radius;
in vec3 fcolor;
in vec4 fcolor;
in vec2 pos;
void main()
@ -19,9 +19,9 @@ void main()
float dist = sqrt(dot(coords, coords));
if (dist >= R2 && dist <= R1)
color = vec4(fcolor, 1.f);
color = fcolor;
else if (dist < R2)
color = vec4(fcolor, 0.1f);
color = vec4(fcolor.xyz, 0.1f);
else
discard;
}

View file

@ -1,14 +1,14 @@
#version 330 core
layout (location = 0) in vec2 vertex;
layout (location = 1) in vec3 acolor;
layout (location = 2) in vec2 apos;
layout (location = 3) in float aradius;
layout (location = 1) in vec2 apos;
layout (location = 2) in float aradius;
layout (location = 3) in vec4 acolor;
//layout (location = 4) in float afill;
out vec2 coords;
out float radius;
out vec3 fcolor;
out vec4 fcolor;
uniform mat4 proj;

View file

@ -2,15 +2,16 @@
out vec4 frag_color;
in vec2 apos;
vec2 bpos;
uniform float thickness; /* thickness in pixels */
uniform float span;
uniform vec3 color;
uniform vec4 color;
void main(void)
{
float t = thickness / span;
t /= 2.0;
vec2 bpos;
bpos.x = mod(apos.x, span) / span;
bpos.y = mod(apos.y, span) / span;
bpos.x -= t;
@ -23,5 +24,5 @@ void main(void)
comp += t;
frag_color = vec4(color, 1.0);
frag_color = color;
}

View file

@ -0,0 +1,13 @@
#version 330 core
in vec4 fcolor;
out vec4 color;
void main()
{
float d = length(gl_PointCoord - vec2(0.5,0.5));
if (d >= 0.47)
discard;
color = fcolor;
}

View file

@ -0,0 +1,16 @@
#version 330 core
layout (location = 0) in vec2 apos;
layout (location = 1) in vec4 acolor;
layout (location = 2) in float radius;
uniform mat4 proj;
out vec4 fcolor;
void main()
{
gl_Position = proj * vec4(apos, 0.0, 1.0);
fcolor = acolor;
gl_PointSize = radius;
}

View file

@ -1,10 +1,10 @@
#version 330 core
out vec4 fcolor;
in vec3 color;
in vec4 color;
in vec2 uv;
void main()
{
fcolor = vec4(color,1.0);
fcolor = color;
}

View file

@ -1,9 +1,9 @@
#version 330 core
in vec2 apos;
in vec2 auv;
in vec3 acolor;
in vec4 acolor;
out vec3 color;
out vec4 color;
out vec2 uv;
uniform mat4 proj;

View file

@ -1,6 +1,6 @@
#version 330 core
in vec2 TexCoords;
in vec3 fColor;
in vec4 fColor;
out vec4 color;
@ -8,8 +8,11 @@ uniform sampler2D text;
void main()
{
color = vec4(fColor.xyz, texture(text, TexCoords).r);
float lettera = texture(text,TexCoords).r;
// color = vec4(1.f, 1.f, 1.f, texture(text, TexCoords).r);
if (color.a <= 0.1f)
if (lettera <= 0.1f)
discard;
color = vec4(fColor.xyz, lettera * fColor.a);
}

View file

@ -1,17 +1,21 @@
#version 330 core
layout (location = 0) in vec2 vertex;
layout (location = 1) in vec2 rect;
layout (location = 2) in vec3 vColor;
layout (location = 0) in vec2 vert;
layout (location = 1) in vec2 pos;
layout (location = 2) in vec2 wh;
layout (location = 3) in vec2 uv;
layout (location = 4) in vec2 st;
layout (location = 5) in vec4 vColor;
out vec2 TexCoords;
out vec3 fColor;
out vec4 fColor;
uniform mat4 projection;
void main()
{
gl_Position = projection * vec4(vertex, 0.0, 1.0);
TexCoords = rect;
gl_Position = projection * vec4(pos + (vert * wh), 0.0, 1.0);
TexCoords = uv + vec2(vert.x*st.x, st.y - vert.y*st.y);
fColor = vColor;
}