Changed the style of projection displays from lines to filled surfaces, to

make it easier to discern where is up and where is down.

- solidify/gui_util.h, solidify/gui_util.c (hpoint, vpoint, alpha, aa_line):
  draw horizontal or vertical lines with anti-aliases beginning and end
- solidify/level.c (draw_xz, draw_zy): instead of drawing thin lines for z
  and z0, show a filled surface of the difference
This commit is contained in:
Werner Almesberger 2010-09-28 19:49:49 -03:00
parent fd7b7223ab
commit 46704e6b0e
3 changed files with 104 additions and 28 deletions

View File

@ -11,11 +11,77 @@
*/
#include <stdint.h>
#include <math.h>
#include <assert.h>
#include <gtk/gtk.h>
#include "gui_util.h"
void hpoint(guchar *rgbbuf, int x, int y, int sx, uint8_t c[3])
{
guchar *p = rgbbuf+(y*sx+x)*3;
p[0] = c[0];
p[1] = c[1];
p[2] = c[2];
}
void vpoint(guchar *rgbbuf, int y, int x, int sx, uint8_t c[3])
{
guchar *p = rgbbuf+(y*sx+x)*3;
p[0] = c[0];
p[1] = c[1];
p[2] = c[2];
}
static void alpha(guchar *rgbbuf, int f, int i, int sx, uint8_t c[3], double w,
void (*point)(guchar *rgbbuf, int f, int i, int sx, uint8_t c[3]))
{
uint8_t ct[3];
int n;
assert(w >= 0);
assert(w <= 1);
for (n = 0; n != 3; n++)
ct[n] = round(c[n]*w);
point(rgbbuf, f, i, sx, ct);
}
void aa_line(guchar *rgbbuf, int i, double fa, double fb, int max, int sx,
uint8_t c[3],
void (*point)(guchar *rgbbuf, int f, int i, int sx, uint8_t c[3]))
{
int f0, f1;
int from, to, n;
assert(max > 0);
assert(fb >= fa);
f0 = floor(fa);
f1 = ceil(fb);
if (f0 > max || f1 < 0)
return;
if (f0 == f1) {
if (f0 >= 0 && f1 <= max)
point(rgbbuf, f0, i, sx, c);
return;
}
if (f0 >= 0)
alpha(rgbbuf, f0, i, sx, c, 1-(fa-f0), point);
if (f1 <= max)
alpha(rgbbuf, f1, i, sx, c, 1-(f1-fb), point);
from = f0+1 > 0 ? f0+1 : 0;
to = f1-1 < max ? f1-1: max;
for (n = from; n <= to; n++)
point(rgbbuf, n, i, sx, c);
}
void draw_circle(GdkDrawable *da, GdkGC *gc, int x, int y, int r)
{
gdk_draw_arc(da, gc, FALSE, x-r, y-r, 2*r, 2*r, 0, 360*64);

View File

@ -13,9 +13,17 @@
#ifndef GUI_UTIL_H
#define GUI_UTIL_H
#include <stdint.h>
#include <gtk/gtk.h>
void hpoint(guchar *rgbbuf, int x, int y, int sx, uint8_t c[3]);
void vpoint(guchar *rgbbuf, int y, int x, int sx, uint8_t c[3]);
void aa_line(guchar *rgbbuf, int i, double fa, double fb, int max, int sx,
uint8_t c[3],
void (*point)(guchar *rgbbuf, int f, int i, int sx, uint8_t c[3]));
void draw_circle(GdkDrawable *da, GdkGC *gc, int x, int y, int r);
#endif /* !GUI_UTIL_H */

View File

@ -94,7 +94,9 @@ static void draw_image(GtkWidget *widget, struct face *f, int osd)
static void draw_xz(GtkWidget *widget, struct face *f, int y)
{
int x, z, z0;
int zm = f->a->max_z;
int x, z;
double z0;
guchar *rgbbuf, *p;
rgbbuf = p = calloc(f->sx*f->sz, 3);
@ -105,19 +107,18 @@ static void draw_xz(GtkWidget *widget, struct face *f, int y)
if (y != -1)
for (x = 0; x != f->sx ; x++) {
z = get(f->a, x+f->a->min_x, y+f->a->min_y);
if (z != UNDEF) {
p = rgbbuf+3*(x+f->sx*(f->sz-z+f->a->min_z-1));
p[0] = 0xff;
p[1] = 0xff;
p[2] = 0xff;
}
z0 = round(face_z0(f, x, y));
/* @@@ anti-alias */
if (z0 >= f->a->min_z && z0 <= f->a->max_z) {
p = rgbbuf+3*(x+f->sx*(f->sz-z0+f->a->min_z-1));
p[0] = 0x80;
p[1] = 0xc0;
p[2] = 0xff;
z0 = face_z0(f, x, y);
if (z == UNDEF || z == z0) {
aa_line(rgbbuf, x, zm-z0, zm-z0, zm, f->sx,
(uint8_t *) "\0\0\xff", vpoint);
continue;
}
if (z > z0) {
aa_line(rgbbuf, x, zm-z, zm-z0, zm, f->sx,
(uint8_t *) "\0\xff\0", vpoint);
} else {
aa_line(rgbbuf, x, zm-z0, zm-z, zm, f->sx,
(uint8_t *) "\xff\0\0", vpoint);
}
}
gdk_draw_rgb_image(widget->window,
@ -130,7 +131,9 @@ static void draw_xz(GtkWidget *widget, struct face *f, int y)
static void draw_zy(GtkWidget *widget, struct face *f, int x)
{
int y, z, z0;
int zm = f->a->max_z;
int y, z;
double z0;
guchar *rgbbuf, *p;
rgbbuf = p = calloc(f->sy*f->sz, 3);
@ -140,20 +143,19 @@ static void draw_zy(GtkWidget *widget, struct face *f, int x)
}
if (x != -1)
for (y = 0; y != f->sy ; y++) {
z = get(f->a, x+f->a->min_x, y+f->a->min_y);
if (z != UNDEF) {
p = rgbbuf+3*(f->a->max_z-z+f->sz*(f->sy-y-1));
p[0] = 0xff;
p[1] = 0xff;
p[2] = 0xff;
z = get(f->a, x+f->a->min_x, f->a->max_y-y);
z0 = face_z0(f, x, f->sy-y-1);
if (z == UNDEF || z == z0) {
aa_line(rgbbuf, y, zm-z0, zm-z0, zm, f->sz,
(uint8_t *) "\0\0\xff", hpoint);
continue;
}
z0 = round(face_z0(f, x, y));
/* @@@ anti-alias */
if (z0 >= f->a->min_z && z0 <= f->a->max_z) {
p = rgbbuf+3*(f->a->max_z-z0+f->sz*(f->sy-y-1));
p[0] = 0x80;
p[1] = 0xc0;
p[2] = 0xff;
if (z > z0) {
aa_line(rgbbuf, y, zm-z, zm-z0, zm, f->sz,
(uint8_t *) "\0\xff\0", hpoint);
} else {
aa_line(rgbbuf, y, zm-z0, zm-z, zm, f->sz,
(uint8_t *) "\xff\0\0", hpoint);
}
}
gdk_draw_rgb_image(widget->window,