первое движение
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#ifndef FIGURE_DRAW_H
|
||||
#define FIGURE_ANFIGURE_DRAW_HIMATE_H
|
||||
#define FIGURE_DRAW_H
|
||||
|
||||
#include "window.h"
|
||||
|
||||
|
||||
0
wayland/src/figure-draw.asm
Normal file
0
wayland/src/figure-draw.asm
Normal file
109
wayland/src/figure-draw.c
Normal file
109
wayland/src/figure-draw.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "figure-draw.h"
|
||||
|
||||
/* C implementation of the drawing routine. The .asm file simply forwards to this
|
||||
* function so we keep the symbol present in an assembly file. */
|
||||
void figure_draw(struct window_draw_info* draw_info, float border_thickness, uint32_t border_color, uint32_t fill_color)
|
||||
{
|
||||
if (!draw_info || !draw_info->data)
|
||||
return;
|
||||
|
||||
int w = draw_info->width;
|
||||
int h = draw_info->height;
|
||||
uint32_t *pixels = (uint32_t *)draw_info->data;
|
||||
|
||||
struct figure_animation_info fig = draw_info->figure;
|
||||
|
||||
/* center in pixels */
|
||||
float cx = fig.position.x * (float)w;
|
||||
float cy = fig.position.y * (float)h;
|
||||
float r = fig.radius * (float)w; /* normalized to width */
|
||||
float r2 = r * r;
|
||||
float border = border_thickness;
|
||||
if (border < 0.0f) border = 0.0f;
|
||||
|
||||
/* bounding box */
|
||||
int minx = (int)floorf(cx - r);
|
||||
int maxx = (int)ceilf(cx + r);
|
||||
int miny = (int)floorf(cy - r);
|
||||
int maxy = (int)ceilf(cy + r);
|
||||
/* make sure we don't go out of bounds */
|
||||
if (miny < 0) miny = 0;
|
||||
if (minx < 0) minx = 0;
|
||||
if (maxy >= h) maxy = h - 1;
|
||||
if (maxx >= w) maxx = w - 1;
|
||||
|
||||
/* We'll compute pixel centers at (x + 0.5f, y + 0.5f) */
|
||||
for (int y = miny; y <= maxy; ++y)
|
||||
{
|
||||
float py = (float)y + 0.5f;
|
||||
for (int x = minx; x <= maxx; ++x)
|
||||
{
|
||||
float px = (float)x + 0.5f;
|
||||
int draw = 0;
|
||||
int border_pixel = 0;
|
||||
switch (fig.type)
|
||||
{
|
||||
case FIGURE_CIRCLE:
|
||||
{
|
||||
float dx = px - cx;
|
||||
float dy = py - cy;
|
||||
float d2 = dx*dx + dy*dy;
|
||||
if (d2 <= r2)
|
||||
{
|
||||
draw = 1;
|
||||
if (d2 >= (r - border)*(r - border))
|
||||
border_pixel = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FIGURE_SQUARE:
|
||||
{
|
||||
float dx = fabsf(px - cx);
|
||||
float dy = fabsf(py - cy);
|
||||
if (dx <= r && dy <= r)
|
||||
{
|
||||
draw = 1;
|
||||
if (fmaxf(dx, dy) >= r - border)
|
||||
border_pixel = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FIGURE_TRIANGLE:
|
||||
{
|
||||
/* Equilateral triangle centered at cx,cy. Apex up. *
|
||||
* Vertices: A=(cx, cy - r), B=(cx + r*0.866, cy + r*0.5), C=(cx - r*0.866, cy + r*0.5) */
|
||||
float v1x = r * 0.8660254037844386f;
|
||||
float v1y = r * 0.5f;
|
||||
float ax = cx; float ay = cy - r;
|
||||
float bx = cx + v1x; float by = cy + v1y;
|
||||
float cx2 = cx - v1x; float cy2 = by;
|
||||
|
||||
/* barycentric tests: point inside triangle if all cross products have same sign */
|
||||
float s1 = (px - bx)*(ay - by) - (ax - bx)*(py - by);
|
||||
float s2 = (px - cx2)*(by - cy2) - (bx - cx2)*(py - cy2);
|
||||
float s3 = (px - ax)*(cy2 - ay) - (cx2 - ax)*(py - ay);
|
||||
int neg = (s1 < 0) + (s2 < 0) + (s3 < 0);
|
||||
int pos = (s1 > 0) + (s2 > 0) + (s3 > 0);
|
||||
if (neg == 0 || pos == 0)
|
||||
{
|
||||
draw = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (draw)
|
||||
{
|
||||
uint32_t col = border_pixel ? border_color : fill_color;
|
||||
pixels[y * w + x] = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* C symbol exported to be called by minimal assembly wrapper */
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "window.h"
|
||||
#include "registry.h"
|
||||
#include "figure-draw.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
#include <wayland-client.h>
|
||||
#include <stddef.h>
|
||||
@@ -128,9 +129,12 @@ static void draw(struct wayland_window *win)
|
||||
{
|
||||
uint32_t *row = (uint32_t *)(bytes + y * stride);
|
||||
for (int32_t x = 0; x < (int32_t)draw_info->width; ++x)
|
||||
row[x] = color;
|
||||
row[x] = 0xFF000000; /* background black */
|
||||
}
|
||||
|
||||
/* Draw figure into buffer. border thickness in pixels = 3.0f */
|
||||
figure_draw(&win->draw_info, 3.0f, 0xFFFFFFFF, color);
|
||||
|
||||
wl_surface_attach(win->wl_surface, win->buffer, 0, 0);
|
||||
wl_surface_damage_buffer(win->wl_surface, 0, 0, draw_info->width, draw_info->height);
|
||||
wl_surface_commit(win->wl_surface);
|
||||
|
||||
Reference in New Issue
Block a user