Particles II, which uses BWindowScreen
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21411 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -7,3 +7,5 @@ SubInclude HAIKU_TOP src tests kits game direct_window_test ;
|
||||
SubInclude HAIKU_TOP src tests kits game direct_window_info_test ;
|
||||
SubInclude HAIKU_TOP src tests kits game page_flipper ;
|
||||
SubInclude HAIKU_TOP src tests kits game chart ;
|
||||
SubInclude HAIKU_TOP src tests kits game ParticlesII ;
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
SubDir HAIKU_TOP src tests kits game ParticlesII ;
|
||||
|
||||
SimpleTest ParticlesII
|
||||
: particlesII.cpp
|
||||
: game be root
|
||||
;
|
||||
|
||||
@@ -0,0 +1,645 @@
|
||||
#include <Application.h>
|
||||
#include <WindowScreen.h>
|
||||
#include <Screen.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <SupportDefs.h> // min_c() and max_c()
|
||||
|
||||
#ifdef DEBUGGING
|
||||
#define PRINT(x) printf x
|
||||
#else
|
||||
#define PRINT(x)
|
||||
#endif
|
||||
|
||||
// macros
|
||||
#define set_pixel(x,y,color) (frame_buffer[x + (line_length*y)] = color)
|
||||
#define get_pixel(x,y) (frame_buffer[x + (line_length*y)])
|
||||
|
||||
class NApplication : public BApplication {
|
||||
public:
|
||||
NApplication();
|
||||
bool is_quitting; // So that the WindowScreen knows what
|
||||
// to do when disconnected.
|
||||
private:
|
||||
bool QuitRequested();
|
||||
void ReadyToRun();
|
||||
};
|
||||
|
||||
class NWindowScreen : public BWindowScreen {
|
||||
public:
|
||||
NWindowScreen(status_t*);
|
||||
private:
|
||||
void ScreenConnected(bool);
|
||||
long MyCode();
|
||||
static long Entry(void*);
|
||||
// handy stuff
|
||||
void set_frame_rate(float fps) {frame_pause = (bigtime_t)((1000 * 1000)/fps);}
|
||||
// special for demos
|
||||
enum {
|
||||
// used for star->last_draw
|
||||
INVALID = 0x7fffffff
|
||||
};
|
||||
typedef struct {
|
||||
float init_velocity;
|
||||
float gravity;
|
||||
double cos_z_theta;
|
||||
int32 y;
|
||||
int32 x;
|
||||
int32 timeval;
|
||||
uint32 last_draw;
|
||||
int32 lx,ly;
|
||||
} particle;
|
||||
uint32 particle_count;
|
||||
particle *particle_list;
|
||||
// simple raster functions
|
||||
void draw_line(int x1, int y1, int x2, int y2, int color);
|
||||
void draw_rect(int x, int y, int w, int h, int color);
|
||||
void fill_rect(int x, int y, int w, int h, int color);
|
||||
void draw_ellipse(int cx, int cy, int wide, int deep, int color);
|
||||
void fill_ellipse(int x, int y, int xradius, int yradius, int color);
|
||||
void ellipse_points(int x, int y, int x_offset, int y_offset, int color);
|
||||
void ellipse_fill_points(int x, int y, int x_offset, int y_offset, int color);
|
||||
thread_id tid;
|
||||
sem_id sem;
|
||||
area_id area;
|
||||
uint8* save_buffer;
|
||||
uint8* frame_buffer;
|
||||
ulong line_length;
|
||||
bigtime_t frame_pause; // time between frames
|
||||
int width,height;
|
||||
int COLORS;
|
||||
bool thread_is_locked; // small hack to allow to quit the
|
||||
// app from ScreenConnected()
|
||||
};
|
||||
|
||||
main()
|
||||
{
|
||||
NApplication app;
|
||||
}
|
||||
|
||||
NApplication::NApplication()
|
||||
:BApplication("application/x-vnd.Prok-DemoTemplate")
|
||||
{
|
||||
Run(); // see you in ReadyToRun()
|
||||
}
|
||||
|
||||
void NApplication::ReadyToRun()
|
||||
{
|
||||
PRINT(("ReadyToRun()\n"));
|
||||
status_t ret = B_ERROR;
|
||||
is_quitting = false;
|
||||
NWindowScreen *ws = new NWindowScreen(&ret);
|
||||
PRINT(("WindowScreen ctor returned. ret = %s\n", strerror(ret)));
|
||||
// exit if constructing the WindowScreen failed.
|
||||
if((ws == NULL) || (ret < B_OK) || !ws->CanControlFrameBuffer())
|
||||
{
|
||||
//printf("the window screen was NULL, or there was an error\n");
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
else
|
||||
PRINT(("everything's just peachy. done with ReadyToRun().\n"));
|
||||
}
|
||||
|
||||
bool NApplication::QuitRequested()
|
||||
{
|
||||
PRINT(("QuitRequested()\n"));
|
||||
status_t ret;
|
||||
is_quitting = true;
|
||||
wait_for_thread(find_thread("rendering thread"), &ret); // wait for the render thread to finish
|
||||
return true;
|
||||
}
|
||||
|
||||
NWindowScreen::NWindowScreen(status_t *ret)
|
||||
: BWindowScreen("Example", B_8_BIT_640x480, ret), width(640), height(480), COLORS(256)
|
||||
{
|
||||
PRINT(("WindowScreen ctor.\n"));
|
||||
thread_is_locked = true;
|
||||
tid = 0;
|
||||
if(*ret == B_OK)
|
||||
{
|
||||
PRINT(("creating blocking sem and save_buffer area.\n"));
|
||||
// this semaphore controls the access to the WindowScreen
|
||||
sem = create_sem(0,"WindowScreen Access");
|
||||
// this area is used to save the whole framebuffer when
|
||||
// switching workspaces. (better than malloc()).
|
||||
area = create_area("save", (void**)&save_buffer, B_ANY_ADDRESS, 640*480, B_NO_LOCK, B_READ_AREA|B_WRITE_AREA);
|
||||
// exit if an error occured.
|
||||
if((sem < B_OK) || (area < B_OK))
|
||||
{
|
||||
PRINT(("create_area() or create_sem() failed\n"));
|
||||
*ret = B_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT(("calling Show().\n"));
|
||||
Show(); // let's go. See you in ScreenConnected.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT(("BWindowScreen base class ctor returned failure\n"));
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
}
|
||||
// set the frame rate
|
||||
set_frame_rate(30.);
|
||||
}
|
||||
|
||||
void NWindowScreen::ScreenConnected(bool connected)
|
||||
{
|
||||
PRINT(("ScreenConnected()\n"));
|
||||
fflush(stdout);
|
||||
if(connected)
|
||||
{
|
||||
if(SetSpace(B_8_BIT_640x480) < B_OK)
|
||||
{
|
||||
SetFrameBuffer(640,480);
|
||||
PRINT(("SetSpace() failed\n"));
|
||||
// properly set the framebuffer. exit if an error occurs.
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
// get the framebuffer-related info, each time the
|
||||
// WindowScreen is connected (multiple monitor)
|
||||
frame_buffer = (uint8*)(CardInfo()->frame_buffer);
|
||||
line_length = FrameBufferInfo()->bytes_per_row;
|
||||
if(tid == 0)
|
||||
{
|
||||
// clean the framebuffer
|
||||
PRINT(("zeroing the framebuffer\n"));
|
||||
memset(frame_buffer,0,480*line_length);
|
||||
// spawn the rendering thread. exit if an error occurs.
|
||||
PRINT(("spawning the render thread.\n"));
|
||||
if(resume_thread((tid = spawn_thread(Entry,"rendering thread", B_URGENT_DISPLAY_PRIORITY,this))) < B_OK)
|
||||
{
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y=0;y<480;y++)
|
||||
{
|
||||
// restore the framebuffer when switching back from
|
||||
// another workspace.
|
||||
memcpy(frame_buffer+y*line_length,save_buffer+640*y,640);
|
||||
}
|
||||
}
|
||||
// set our color list.
|
||||
rgb_color palette[256];
|
||||
rgb_color c1;
|
||||
for(int i=0,j=0;i<256;i++,j++)
|
||||
{
|
||||
if(i<64)
|
||||
{
|
||||
c1.red = j*4; // greys
|
||||
c1.green = j*4;
|
||||
c1.blue = j*4;
|
||||
c1.alpha = 255;
|
||||
}
|
||||
if((i>=64) && (i<128))
|
||||
{
|
||||
c1.red = j*4; // reds
|
||||
c1.green = 0;
|
||||
c1.blue = 0;
|
||||
c1.alpha = 255;
|
||||
}
|
||||
if((i>=128) && (i<192))
|
||||
{
|
||||
c1.red = 0; // greens
|
||||
c1.green = j*4;
|
||||
c1.blue = 0;
|
||||
c1.alpha = 255;
|
||||
}
|
||||
if((i>=192) && (i<256))
|
||||
{
|
||||
c1.red = 0; // blues
|
||||
c1.green = 0;
|
||||
c1.blue = j*4;
|
||||
c1.alpha = 255;
|
||||
}
|
||||
if(j == 64)
|
||||
j=0;
|
||||
palette[i]=c1;
|
||||
}
|
||||
SetColorList(palette);
|
||||
|
||||
// allow the rendering thread to run.
|
||||
thread_is_locked = false;
|
||||
release_sem(sem);
|
||||
}
|
||||
else /* !connected */
|
||||
{
|
||||
// block the rendering thread.
|
||||
if(!thread_is_locked)
|
||||
{
|
||||
acquire_sem(sem);
|
||||
thread_is_locked = true;
|
||||
}
|
||||
// kill the rendering and clean up when quitting
|
||||
if((((NApplication*)be_app)->is_quitting))
|
||||
{
|
||||
status_t ret;
|
||||
kill_thread(tid);
|
||||
wait_for_thread(tid,&ret);
|
||||
delete_sem(sem);
|
||||
delete_area(area);
|
||||
free(particle_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the color list black so that the screen doesn't seem
|
||||
// to freeze while saving the framebuffer
|
||||
rgb_color c={0,0,0,255};
|
||||
rgb_color palette[256];
|
||||
// build the palette
|
||||
for(int i=0;i<256;i++)
|
||||
palette[i] = c;
|
||||
// set the palette
|
||||
SetColorList(palette);
|
||||
// save the framebuffer
|
||||
for(int y=0;y<480;y++)
|
||||
memcpy(save_buffer+640*y,frame_buffer+y*line_length,640);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long NWindowScreen::Entry(void* p) {
|
||||
return ((NWindowScreen*)p)->MyCode();
|
||||
}
|
||||
|
||||
long NWindowScreen::MyCode()
|
||||
{
|
||||
bigtime_t trgt = system_time() + frame_pause;
|
||||
srandom(system_time());
|
||||
// beforehand stuff
|
||||
particle_count = 1024*2;
|
||||
particle_list = (particle *)malloc(sizeof(particle)*particle_count);
|
||||
for (uint32 i=0; i<particle_count; i++)
|
||||
{
|
||||
uint32 rand_max = 0xffffffff;
|
||||
particle_list[i].init_velocity = -((double)((rand_max>>1)+(random()%(rand_max>>1)))/rand_max)*3.333; // magic number
|
||||
particle_list[i].gravity = -(((double)((rand_max>>1)+(random()%(rand_max>>1)))/rand_max))*0.599; // more magic
|
||||
|
||||
// make the particle initialy invisible and fixed, but at a random moment in time
|
||||
particle_list[i].lx = 0;
|
||||
particle_list[i].ly = 0;
|
||||
particle_list[i].last_draw = INVALID;
|
||||
particle_list[i].timeval = random() & 64;
|
||||
particle_list[i].x = 0; // this gets figured out at drawtime
|
||||
particle_list[i].y = 0; // same here
|
||||
particle_list[i].cos_z_theta = cos(random() % 360); // grab an angle
|
||||
}
|
||||
|
||||
|
||||
// the loop o' fun
|
||||
while(!(((NApplication*)be_app)->is_quitting))
|
||||
{
|
||||
// try to sync with the vertical retrace
|
||||
if(BScreen(this).WaitForRetrace() != B_OK)
|
||||
{
|
||||
// snoze for a bit so that other threads can be happy.
|
||||
// We are realtime priority you know
|
||||
if(system_time() < trgt)
|
||||
snooze(trgt - system_time());
|
||||
trgt = system_time() + frame_pause;
|
||||
}
|
||||
|
||||
// gain access to the framebuffer before writing to it.
|
||||
acquire_sem(sem); // block until we're allowed to own the framebuffer
|
||||
|
||||
///////////////////////////////
|
||||
// do neat stuff here //
|
||||
//////////////////////////////
|
||||
PRINT(("rendering a frame.\n"));
|
||||
|
||||
|
||||
// eye candy VII - particles! - my own cookin
|
||||
particle *s;
|
||||
int32 x, y, cx,cy;
|
||||
set_frame_rate(60.); // woo. ntsc
|
||||
// calculate the center
|
||||
cx = width/2;
|
||||
cy = height/2;
|
||||
|
||||
// palette test
|
||||
//set_frame_rate(0.1);
|
||||
//for(int i=0;i<256;i++)
|
||||
// draw_line(i,0,i,height, i);
|
||||
|
||||
PRINT(("Starting particle drawing loop\n"));
|
||||
s = particle_list;
|
||||
for (uint32 i=0; i<particle_count; i++)
|
||||
{
|
||||
PRINT(("drawing particle %d\r", i));
|
||||
|
||||
// save the old position
|
||||
s->lx = s->x;
|
||||
s->ly = s->y;
|
||||
|
||||
PRINT(("cx=%d, cy=%d\n", cx,cy));
|
||||
|
||||
// move the particle
|
||||
// find y and x
|
||||
// (s->gravity/2)*(s->timeval*s->timeval) * 1.85 is magic
|
||||
y = s->y = (int32)(cy + (int32)((s->gravity/2)*(s->timeval*s->timeval)*1.94) + ((s->init_velocity - (s->gravity*s->timeval)) * s->timeval));
|
||||
x = s->x = (int32)(cx + (int32)(s->timeval * s->cos_z_theta)); // 3d rotation
|
||||
|
||||
// interate timeval
|
||||
s->timeval++;
|
||||
|
||||
// sanity check
|
||||
if(x <= 0)
|
||||
goto erase_and_reset;
|
||||
if(x > width)
|
||||
goto erase_and_reset;
|
||||
if(y < 0)
|
||||
goto erase; // invisible + erase last position
|
||||
if(y > height)
|
||||
goto erase_and_reset;
|
||||
|
||||
// erase the previous position, if necessary
|
||||
if (s->last_draw != INVALID)
|
||||
set_pixel(s->lx,s->ly,0);
|
||||
|
||||
// if it's visible, then draw it.
|
||||
set_pixel(s->x,s->y, 169);
|
||||
s->last_draw = 1;
|
||||
goto loop;
|
||||
|
||||
erase_and_reset:
|
||||
if((s->lx <= width) && (s->lx >= 0) && (s->ly <= height) && (s->ly >= 0))
|
||||
set_pixel(s->lx, s->ly,0);
|
||||
s->x = 0;
|
||||
s->y = 0;
|
||||
s->lx = 0;
|
||||
s->ly = 0;
|
||||
s->timeval = 0;
|
||||
s->last_draw = INVALID;
|
||||
goto loop;
|
||||
|
||||
erase:
|
||||
// erase it.
|
||||
if(s->last_draw != INVALID)
|
||||
set_pixel(s->lx, s->ly,0);
|
||||
s->lx = s->x;
|
||||
s->ly = s->y;
|
||||
s->last_draw = INVALID;
|
||||
loop:
|
||||
s++;
|
||||
//printf("end draw loop\n");
|
||||
}
|
||||
PRINT(("frame done\n"));
|
||||
|
||||
//////////////////////////////////
|
||||
// stop doing neat stuff //
|
||||
/////////////////////////////////
|
||||
|
||||
// release the semaphore while waiting. gotta release it
|
||||
// at some point or nasty things will happen!
|
||||
release_sem(sem);
|
||||
// loop for another frame!
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Misc - a place for demos to put their convenience functions
|
||||
//////////////////////////////
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// My Silly Raster Lib
|
||||
//////////////////////////////
|
||||
|
||||
/*
|
||||
|
||||
Functions:
|
||||
void draw_line(int x1, int y1, int x2, int y2, int color);
|
||||
void draw_rect(int x, int y, int w, int h, int color);
|
||||
void fill_rect(int x, int y, int w, int h, int color);
|
||||
void draw_ellipse(int x, int y, int xradius, int yradius, int color);
|
||||
void fill_ellipse(int x, int y, int xradius, int yradius, int color);
|
||||
|
||||
*/
|
||||
|
||||
void NWindowScreen::draw_line(int x1, int y1, int x2, int y2, int color)
|
||||
{
|
||||
// Simple Bresenham's line drawing algorithm
|
||||
int d,x,y,ax,ay,sx,sy,dx,dy;
|
||||
|
||||
#define ABS(x) (((x)<0) ? -(x) : (x))
|
||||
#define SGN(x) (((x)<0) ? -1 : 1)
|
||||
|
||||
dx=x2-x1; ax=ABS(dx)<<1; sx=SGN(dx);
|
||||
dy=y2-y1; ay=ABS(dy)<<1; sy=SGN(dy);
|
||||
|
||||
x=x1;
|
||||
y=y1;
|
||||
if(ax>ay)
|
||||
{
|
||||
d=ay-(ax>>1);
|
||||
for(;;)
|
||||
{
|
||||
set_pixel(x,y,color);
|
||||
if(x==x2) return;
|
||||
if(d>=0)
|
||||
{
|
||||
y+=sy;
|
||||
d-=ax;
|
||||
}
|
||||
x+=sx;
|
||||
d+=ay;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
d=ax-(ay>>1);
|
||||
for(;;)
|
||||
{
|
||||
set_pixel(x,y,color);
|
||||
if(y==y2) return;
|
||||
if(d>=0)
|
||||
{
|
||||
x+=sx;
|
||||
d-=ay;
|
||||
}
|
||||
y+=sy;
|
||||
d+=ax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NWindowScreen::draw_rect(int x, int y, int w, int h, int color)
|
||||
{
|
||||
draw_line(x,y,x+w,y,color);
|
||||
draw_line(x,y,x,y+h,color);
|
||||
draw_line(x,y+h,x+w,y+h,color);
|
||||
draw_line(x+w,y,x+w,y+h,color);
|
||||
}
|
||||
|
||||
void NWindowScreen::fill_rect(int x, int y, int w, int h, int color)
|
||||
{
|
||||
for(int i=0;i<w;i++)
|
||||
for(int j=0;j<h;j++)
|
||||
set_pixel(i,j,color);
|
||||
}
|
||||
|
||||
void NWindowScreen::draw_ellipse(int cx, int cy, int wide, int deep, int color)
|
||||
{
|
||||
// if we're asked to draw a really small ellipse, put a single pixel in the buffer
|
||||
// and bail
|
||||
if((wide < 1) || (deep < 1))
|
||||
{
|
||||
set_pixel(cx,cy,color);
|
||||
return;
|
||||
}
|
||||
|
||||
// MidPoint Ellipse algorithm.
|
||||
// page 90 of Computer Graphics Principles and Practice 2nd edition (I highly recommend this book)
|
||||
int16 x, y;
|
||||
int16 wide_squared, deep_squared;
|
||||
double d;
|
||||
|
||||
x = 0;
|
||||
y = deep;
|
||||
wide_squared = wide * wide;
|
||||
deep_squared = deep * deep;
|
||||
d = deep_squared - (wide_squared*deep) + (wide_squared/4);
|
||||
|
||||
ellipse_points(x, y, cx, cy, color);
|
||||
while((wide_squared*(y - 0.5)) > (deep_squared*(x + 1)))
|
||||
{
|
||||
if(d < 0)
|
||||
d += deep_squared*(2*x + 3);
|
||||
else
|
||||
{
|
||||
d += deep_squared*(2*x + 3) + wide_squared*(-2*y + 2);
|
||||
y--;
|
||||
}
|
||||
x++;
|
||||
ellipse_points(x, y, cx, cy, color);
|
||||
}
|
||||
|
||||
d = deep_squared*((x+0.5)*(x+0.5)) + wide_squared*((y-1)*(y-1)) - deep_squared*wide_squared;
|
||||
while(y > 0)
|
||||
{
|
||||
if(d < 0)
|
||||
{
|
||||
d += deep_squared*(2*x + 2) + wide_squared*(-2*y + 3);
|
||||
x++;
|
||||
}
|
||||
else
|
||||
d += wide_squared*(-2*y + 3);
|
||||
y--;
|
||||
ellipse_points(x, y, cx, cy, color);
|
||||
}
|
||||
}
|
||||
|
||||
void NWindowScreen::fill_ellipse(int cx, int cy, int wide, int deep, int color)
|
||||
{
|
||||
// if we're asked to draw a really small ellipse, put a single pixel in the buffer
|
||||
// and bail
|
||||
if((wide < 1) || (deep < 1))
|
||||
{
|
||||
set_pixel(cx,cy,color);
|
||||
return;
|
||||
}
|
||||
|
||||
// MidPoint Ellipse algorithm.
|
||||
// page 90 of Computer Graphics Principles and Practice 2nd edition (I highly recommend this book)
|
||||
int16 x, y;
|
||||
int16 wide_squared, deep_squared;
|
||||
double d;
|
||||
|
||||
x = 0;
|
||||
y = deep;
|
||||
wide_squared = wide * wide;
|
||||
deep_squared = deep * deep;
|
||||
d = deep_squared - (wide_squared*deep) + (wide_squared/4);
|
||||
|
||||
ellipse_fill_points(x, y, cx, cy, color);
|
||||
while((wide_squared*(y - 0.5)) > (deep_squared*(x + 1)))
|
||||
{
|
||||
if(d < 0)
|
||||
d += deep_squared*(2*x + 3);
|
||||
else
|
||||
{
|
||||
d += deep_squared*(2*x + 3) + wide_squared*(-2*y + 2);
|
||||
y--;
|
||||
}
|
||||
x++;
|
||||
ellipse_fill_points(x, y, cx, cy, color);
|
||||
}
|
||||
|
||||
d = deep_squared*((x+0.5)*(x+0.5)) + wide_squared*((y-1)*(y-1)) - deep_squared*wide_squared;
|
||||
while(y > 0)
|
||||
{
|
||||
if(d < 0)
|
||||
{
|
||||
d += deep_squared*(2*x + 2) + wide_squared*(-2*y + 3);
|
||||
x++;
|
||||
}
|
||||
else
|
||||
d += wide_squared*(-2*y + 3);
|
||||
y--;
|
||||
ellipse_fill_points(x, y, cx, cy, color);
|
||||
}
|
||||
}
|
||||
|
||||
void NWindowScreen::ellipse_points(int x, int y, int x_offset, int y_offset, int color)
|
||||
{
|
||||
// fill four pixels for every iteration in draw_ellipse
|
||||
|
||||
// the x_offset and y_offset values are needed since the midpoint ellipse algorithm
|
||||
// assumes the midpoint to be at the origin
|
||||
// do a sanity check before each set_pixel, that way we clip to the edges
|
||||
|
||||
int xCoord, yCoord;
|
||||
|
||||
xCoord = x_offset + x;
|
||||
yCoord = y_offset + y;
|
||||
if((xCoord > 0) && (yCoord > 0) && (xCoord < width) && (yCoord < height))
|
||||
set_pixel(xCoord,yCoord,color);
|
||||
xCoord = x_offset - x;
|
||||
if((xCoord > 0) && (yCoord > 0) && (xCoord < width) && (yCoord < height))
|
||||
set_pixel(xCoord,yCoord,color);
|
||||
xCoord = x_offset + x;
|
||||
yCoord = y_offset - y;
|
||||
if((xCoord > 0) && (yCoord > 0) && (xCoord < width) && (yCoord < height))
|
||||
set_pixel(xCoord,yCoord,color);
|
||||
xCoord = x_offset - x;
|
||||
if((xCoord > 0) && (yCoord > 0) && (xCoord < width) && (yCoord < height))
|
||||
set_pixel(xCoord,yCoord,color);
|
||||
}
|
||||
|
||||
void NWindowScreen::ellipse_fill_points(int x, int y, int x_offset, int y_offset, int color)
|
||||
{
|
||||
// put lines between two pixels twice. once for y positive, the other for y negative (symmetry)
|
||||
// for every iteration in fill_ellipse
|
||||
|
||||
// the x_offset and y_offset values are needed since the midpoint ellipse algorithm
|
||||
// assumes the midpoint to be at the origin
|
||||
// do a sanity check before each set_pixel, that way we clip to the edges
|
||||
|
||||
int xCoord1, yCoord1;
|
||||
int xCoord2, yCoord2;
|
||||
|
||||
xCoord1 = x_offset - x;
|
||||
yCoord1 = y_offset + y;
|
||||
xCoord2 = x_offset + x;
|
||||
yCoord2 = y_offset + y;
|
||||
if((xCoord1 > 0) && (yCoord1 > 0) && (xCoord1 < width) && (yCoord1 < height))
|
||||
if((xCoord2 > 0) && (yCoord2 > 0) && (xCoord2 < width) && (yCoord2 < height))
|
||||
draw_line(xCoord1,yCoord1,xCoord2,yCoord2,color);
|
||||
|
||||
xCoord1 = x_offset - x;
|
||||
yCoord1 = y_offset - y;
|
||||
xCoord2 = x_offset + x;
|
||||
yCoord2 = y_offset - y;
|
||||
if((xCoord1 > 0) && (yCoord1 > 0) && (xCoord1 < width) && (yCoord1 < height))
|
||||
if((xCoord2 > 0) && (yCoord2 > 0) && (xCoord2 < width) && (yCoord2 < height))
|
||||
draw_line(xCoord1,yCoord1,xCoord2,yCoord2,color);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user