diff --git a/scripts/modules/sdl_render.js b/scripts/modules/sdl_render.js index c8ed7a7b..50c22177 100644 --- a/scripts/modules/sdl_render.js +++ b/scripts/modules/sdl_render.js @@ -31,7 +31,7 @@ render.initialize = function(config) prosperon.window = prosperon.engine_start({width:500,height:500}) console.log(prosperon.window) - context = prosperon.window.make_renderer("vulkan") + context = prosperon.window.make_renderer("metal") } // img here is the engine surface @@ -65,12 +65,81 @@ render.clip = function(rect) render.circle = function(pos, radius, color = Color.white) { + if (radius <= 0) return // nothing to draw + var cx = pos[0], cy = pos[1] + var x = 0, y = radius + var d = 3 - (radius << 1) // decision parameter + + context.draw_color(color) + + while (x <= y) { + context.point([ + [cx + x, cy + y], [cx - x, cy + y], + [cx + x, cy - y], [cx - x, cy - y], + [cx + y, cy + x], [cx - y, cy + x], + [cx + y, cy - x], [cx - y, cy - x] + ]) + + if (d < 0) d += (x << 2) + 6 + else { + d += ((x - y) << 2) + 10 + y-- + } + x++ + } } render.ellipse = function(pos, radiuses, color = Color.white) { + var rx = radiuses[0], ry = radiuses[1] + if (rx <= 0 || ry <= 0) return // nothing to draw + var cx = pos[0], cy = pos[1] + + var rx_sq = rx * rx, ry_sq = ry * ry + var two_rx_sq = rx_sq << 1, two_ry_sq = ry_sq << 1 + + var x = 0, y = ry + var px = 0, py = two_rx_sq * y + + context.draw_color(color) + + // Region 1 + var p = ry_sq - rx_sq * ry + (0.25 * rx_sq) + while (px < py) { + context.point([ + [cx + x, cy + y], [cx - x, cy + y], + [cx + x, cy - y], [cx - x, cy - y] + ]) + + x++ + px += two_ry_sq + if (p < 0) p += ry_sq + px + else { + y-- + py -= two_rx_sq + p += ry_sq + px - py + } + } + + // Region 2 + p = ry_sq * (x + 0.5) * (x + 0.5) + rx_sq * (y - 1) * (y - 1) - rx_sq * ry_sq + while (y >= 0) { + context.point([ + [cx + x, cy + y], [cx - x, cy + y], + [cx + x, cy - y], [cx - x, cy - y] + ]) + + y-- + py -= two_rx_sq + if (p > 0) p += rx_sq - py + else { + x++ + px += two_ry_sq + p += rx_sq - py + px + } + } } render.line = function(points, color = Color.white) @@ -87,7 +156,8 @@ render.point = function(pos, color = Color.white) render.rectangle = function(rect, color = Color.white) { - + context.draw_color(color) + context.rects([rect]) } render.geometry = function(mesh, pipeline) diff --git a/source/jsffi.c b/source/jsffi.c index 5bf896be..2b5d8caf 100644 --- a/source/jsffi.c +++ b/source/jsffi.c @@ -2840,32 +2840,37 @@ JSC_CCALL(renderer_point, SDL_RenderPoint(r, p.x, p.y); ) -// Function to translate a list of 2D points -void Translate2DPoints(HMM_Vec2 *points, int count, HMM_Vec3 position, HMM_Quat rotation, HMM_Vec3 scale) { - // Precompute the 2D rotation matrix from the quaternion - float xx = rotation.x * rotation.x; - float yy = rotation.y * rotation.y; - float zz = rotation.z * rotation.z; - float xy = rotation.x * rotation.y; - float zw = rotation.z * rotation.w; +JSC_CCALL(renderer_rects, + renderer_ctx *ctx = js2renderer_ctx(js, self); + SDL_Renderer *r = ctx->sdl; - // Extract 2D affine rotation and scaling - float m00 = (1.0f - 2.0f * (yy + zz)) * scale.x; // Row 1, Column 1 - float m01 = (2.0f * (xy + zw)) * scale.y; // Row 1, Column 2 - float m10 = (2.0f * (xy - zw)) * scale.x; // Row 2, Column 1 - float m11 = (1.0f - 2.0f * (xx + zz)) * scale.y; // Row 2, Column 2 + /* array-of-rectangles case */ + if (JS_IsArray(js, argv[0])) { + int len = js_arrlen(js, argv[0]); + if (len <= 0) return JS_UNDEFINED; - // Translation components (ignore the z position) - float tx = position.x; - float ty = position.y; + SDL_FRect rects[len]; - // Transform each point - for (int i = 0; i < count; ++i) { - HMM_Vec2 p = points[i]; - points[i].x = m00 * p.x + m01 * p.y + tx; - points[i].y = m10 * p.x + m11 * p.y + ty; + for (int i = 0; i < len; ++i) { + JSValue val = JS_GetPropertyUint32(js, argv[0], i); + rect w = js2rect(js, val); + JS_FreeValue(js, val); + w = renderer_worldrect_to_screen(ctx, w); + rects[i] = w; } -} + + if (!SDL_RenderFillRects(r, rects, len)) + return JS_ThrowReferenceError(js, "SDL_RenderFillRects: %s", SDL_GetError()); + return JS_UNDEFINED; + } + + /* single-rect path */ + rect w = js2rect(js, argv[0]); + w = renderer_worldrect_to_screen(ctx, w); + if (!SDL_RenderFillRects(r, &w, 1)) + return JS_ThrowReferenceError(js, "SDL_RenderFillRects: %s", SDL_GetError()); +) + // Should take a single struct with pos, color, uv, and indices arrays JSC_CCALL(renderer_geometry, @@ -3098,6 +3103,7 @@ static const JSCFunctionListEntry js_renderer_ctx_funcs[] = { MIST_FUNC_DEF(renderer, line, 1), MIST_FUNC_DEF(renderer, point, 1), MIST_FUNC_DEF(renderer, texture, 2), + MIST_FUNC_DEF(renderer, rects, 1), MIST_FUNC_DEF(renderer, geometry, 2), MIST_FUNC_DEF(renderer, load_texture, 1), MIST_FUNC_DEF(renderer, get_image, 1), diff --git a/tests/camera.js b/tests/camera.js index e5fa9be0..4e20940f 100644 --- a/tests/camera.js +++ b/tests/camera.js @@ -41,7 +41,10 @@ function loop() render.camera(hudcam) render.line([[0,0],[100,50]]) render.point([100,100]) - render.image("button_grey", [100,100]) + render.circle([200,200],40) + render.ellipse([300,300],[20,40]) + render.rectangle({x:150,y:150,width:50,height:50}) + //render.image("button_grey", [100,100]) // draw.rectangle({x:50,y:-50,width:50,height:50}) render.present() $_.delay(loop, 1/60)