X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fblinkbox.c;h=c057943f5344066893eb6704aad6e98e83b211eb;hp=bbd1e599f0326a1bc1239a123fa8df4d36111518;hb=e4fa2ac140f7bc56571373a7b7eb585fa4500e38;hpb=96a411663168b0ba5432b407a83be55f3df0c802 diff --git a/hacks/glx/blinkbox.c b/hacks/glx/blinkbox.c index bbd1e599..c057943f 100644 --- a/hacks/glx/blinkbox.c +++ b/hacks/glx/blinkbox.c @@ -5,7 +5,7 @@ * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or + * software for any purpose. It is provided "as is" without express or * implied warranty. */ @@ -18,10 +18,22 @@ extern XtAppContext app; #define HACK_DRAW draw_ball #define HACK_RESHAPE reshape_ball #define sws_opts xlockmore_opts - #define MAX_COUNT 20 +#define ALPHA_AMT 0.05 + +/* this should be between 1 and 4 */ +#define DEF_WH "1" +#define DEF_DISSOLVE "False" +#define DEF_FADE "True" -#define DEFAULTS "*delay: 30000 \n" \ +#define DEFAULTS "*delay: 30000 \n" \ + "*wireframe: False \n" \ + "*boxsize: " DEF_WH "\n" \ + "*dissolve: " DEF_DISSOLVE "\n" \ + "*fade: " DEF_FADE "\n" \ + +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) #include "xlockmore.h" #include "sphere.h" @@ -42,6 +54,8 @@ typedef struct{ int counter; GLfloat color[3]; GLfloat rot[4]; + int des_count; + int alpha_count; }Side; struct Bounding_box { @@ -56,28 +70,51 @@ struct Ball { int d; } ball = {0,0,0,1}; +struct { + GLfloat wh; /*width Height*/ + GLfloat d; /*depth*/ +} bscale = {1, 0.25}; + static GLuint ballList; static GLuint boxList; Tdpos mo = { 1.0, 1.0, 1.0}; /*motion*/ Tdpos moh= {-1.0,-1.5,-1.5}; /*hold motion value*/ -GLfloat bscale[3] = {1,1,0.25}; -GLfloat bpos[3]; +Tdpos bpos= {1.0, 1.0, 1.0}; /*sides*/ -static Side lside = {0, {0, 0, 0,}, MAX_COUNT, {1.0, 0.0, 0.0},{90,0,1,0}};/*Red*/ -static Side rside = {0, {0, 0, 0,}, MAX_COUNT, {0.0, 1.0, 0.0},{90,0,1,0}};/*Green*/ -static Side tside = {0, {0, 0, 0,}, MAX_COUNT, {0.0, 0.0, 1.0},{90,1,0,0}};/*Blue*/ -static Side bside = {0, {0, 0, 0,}, MAX_COUNT, {1.0, 0.5, 0.0},{90,1,0,0}};/*Orange*/ -static Side fside = {0, {0, 0, 0,}, MAX_COUNT, {1.0, 1.0, 0.0},{90,0,0,1}};/*Yellow*/ -static Side aside = {0, {0, 0, 0,}, MAX_COUNT, {0.5, 0.0, 1.0},{90,0,0,1}};/*Purple*/ +static Side lside = {0, {0, 0, 0,}, MAX_COUNT, {1.0, 0.0, 0.0},{90,0,1,0},1,1};/*Red*/ +static Side rside = {0, {0, 0, 0,}, MAX_COUNT, {0.0, 1.0, 0.0},{90,0,1,0},1,1};/*Green*/ +static Side tside = {0, {0, 0, 0,}, MAX_COUNT, {0.0, 0.0, 1.0},{90,1,0,0},1,1};/*Blue*/ +static Side bside = {0, {0, 0, 0,}, MAX_COUNT, {1.0, 0.5, 0.0},{90,1,0,0},1,1};/*Orange*/ +static Side fside = {0, {0, 0, 0,}, MAX_COUNT, {1.0, 1.0, 0.0},{90,0,0,1},1,1};/*Yellow*/ +static Side aside = {0, {0, 0, 0,}, MAX_COUNT, {0.5, 0.0, 1.0},{90,0,0,1},1,1};/*Purple*/ Side *sp; /* lights */ static float LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; static float LightPosition[]= { 20.0f, 100.0f, 20.0f, 1.0f }; -ModeSpecOpt sws_opts = {0,NULL,0,NULL,NULL}; +static Bool do_dissolve; +static Bool do_fade; +static GLfloat des_amt = 1; + +static XrmOptionDescRec opts[] = { + { "-boxsize", ".boxsize", XrmoptionSepArg, 0 }, + { "-dissolve", ".dissolve", XrmoptionNoArg, "True" }, + { "+dissolve", ".dissolve", XrmoptionNoArg, "False" }, + { "-fade", ".fade", XrmoptionNoArg, "True" }, + { "+fade", ".fade", XrmoptionNoArg, "False" } + +}; + +static argtype vars[] = { + {(caddr_t *) &bscale.wh, "boxsize", "Boxsize", DEF_WH, t_Float}, + {(caddr_t *) &do_dissolve, "dissolve", "Dissolve", DEF_DISSOLVE, t_Bool}, + {(caddr_t *) &do_fade, "fade", "Fade", DEF_FADE, t_Bool}, +}; + +ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL}; void swap(GLfloat *a, GLfloat *b) @@ -87,7 +124,7 @@ swap(GLfloat *a, GLfloat *b) *b = t; } -float +float get_rand(void) { GLfloat j = 1+(random() % 2); @@ -106,7 +143,7 @@ swap_mov(GLfloat *a, GLfloat *b) *a = j; } -void +void cp_b_pos(Tdpos *s_pos){ s_pos->x = ball.x; s_pos->y = ball.y; @@ -116,15 +153,19 @@ cp_b_pos(Tdpos *s_pos){ void hit_side(void) { - if ((ball.x - ball.d) <= bbox.bottom.x){ + if ((ball.x - ball.d) <= bbox.bottom.x){ lside.hit = 1; - lside.counter = MAX_COUNT; + lside.counter = MAX_COUNT; + lside.des_count = 1; + lside.alpha_count = 0; cp_b_pos(&lside.pos); swap_mov(&mo.x,&moh.x); }else - if ((ball.x + ball.d) >= bbox.top.x){ + if ((ball.x + ball.d) >= bbox.top.x){ rside.hit = 1; rside.counter = MAX_COUNT; + rside.des_count = 1; + rside.alpha_count = 0; cp_b_pos(&rside.pos); swap_mov(&mo.x,&moh.x); } @@ -135,13 +176,17 @@ hit_top_bottom(void) { if ((ball.y - ball.d) <= bbox.bottom.y){ bside.hit = 1; - bside.counter = MAX_COUNT; + bside.counter = MAX_COUNT; + bside.des_count = 1; + bside.alpha_count = 0; cp_b_pos(&bside.pos); swap_mov(&mo.y,&moh.y); }else if ((ball.y + ball.d) >= bbox.top.y){ tside.hit = 1; tside.counter = MAX_COUNT; + tside.des_count = 1; + tside.alpha_count = 0; cp_b_pos(&tside.pos); swap_mov(&mo.y,&moh.y); } @@ -149,16 +194,20 @@ hit_top_bottom(void) void hit_front_back(void) -{ +{ if ((ball.z - ball.d) <= bbox.bottom.z){ aside.hit = 1; aside.counter = MAX_COUNT; + aside.des_count = 1; + aside.alpha_count = 0; cp_b_pos(&aside.pos); swap_mov(&mo.z,&moh.z); }else if((ball.z + ball.d) >= bbox.top.z){ fside.hit = 1; fside.counter = MAX_COUNT; + fside.des_count = 1; + fside.alpha_count = 0; cp_b_pos(&fside.pos); swap_mov(&mo.z,&moh.z); } @@ -183,11 +232,11 @@ reshape_ball (ModeInfo *mi, int width, int height) } void -unit_cube(void) +unit_cube(int wire) { - glBegin(GL_QUADS); + glBegin((wire)?GL_LINE_LOOP:GL_QUADS); glNormal3f( 0.0f, -1.0f, 0.0f); - glVertex3f(-1.0f, -1.0f, -1.0f); + glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); @@ -200,7 +249,7 @@ unit_cube(void) glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); - glVertex3f( 1.0f, -1.0f, -1.0f); + glVertex3f( 1.0f, -1.0f, -1.0f); glNormal3f( 1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); @@ -216,50 +265,75 @@ unit_cube(void) glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); - glEnd(); + glEnd(); } -void +void init_ball (ModeInfo *mi) -{ +{ #define SPHERE_SLICES 32 /* how densely to render spheres */ #define SPHERE_STACKS 16 + int wire = MI_IS_WIREFRAME(mi); + sp = malloc(sizeof(*sp)); if(sp == NULL){ fprintf(stderr,"Could not allocate memory\n"); exit(1); } + if( (bscale.wh < 1) || + (bscale.wh > 4) ) { + fprintf(stderr,"Boxsize out of range. Using default\n"); + bscale.wh = 1; + } + if (do_dissolve){ + des_amt = bscale.wh / MAX_COUNT; + } init_GL(mi); reshape_ball(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); ballList = glGenLists(1); glNewList(ballList, GL_COMPILE); - unit_sphere (SPHERE_STACKS, SPHERE_SLICES, False); + unit_sphere (SPHERE_STACKS, SPHERE_SLICES, wire); glEndList (); boxList = glGenLists(1); glNewList(boxList, GL_COMPILE); - unit_cube(); + unit_cube(wire); glEndList(); + if (wire) return; + glEnable(GL_COLOR_MATERIAL); - glShadeModel(GL_SMOOTH); + glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); - glClearDepth(1.0f); - glEnable(GL_DEPTH_TEST); + glClearDepth(1.0f); + glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_LIGHTING); glClearDepth(1); glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); glEnable(GL_LIGHT1); + if (do_fade){ + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + } +} + +void +CheckBoxPos(GLfloat bot_x, GLfloat top_x, GLfloat bot_y, GLfloat top_y) +{ + /*Make sure it's inside of the bounding box*/ + bpos.x = ((bpos.x - bscale.wh) < bot_x) ? bot_x + bscale.wh : bpos.x; + bpos.x = ((bpos.x + bscale.wh) > top_x) ? top_x - bscale.wh : bpos.x; + bpos.y = ((bpos.y - bscale.wh) < bot_y) ? bot_y + bscale.wh : bpos.y; + bpos.y = ((bpos.y + bscale.wh) > top_y) ? top_y - bscale.wh : bpos.y; } void draw_ball (ModeInfo *mi) -{ +{ Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); - /*int dem = 1;*/ int i = 0; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -271,6 +345,7 @@ draw_ball (ModeInfo *mi) glRotated(0.25,0,1,0); glRotated(0.25,1,0,0); + glColor3f(1,1,1); glPushMatrix(); glTranslatef(ball.x += mo.x, @@ -284,60 +359,83 @@ draw_ball (ModeInfo *mi) switch(i){ case 0:{ sp = &lside; - bpos[0] = lside.pos.z*-1; - bpos[1] = lside.pos.y; - bpos[2] = bbox.bottom.x - bscale[3]; + bpos.x = lside.pos.z*-1; + bpos.y = lside.pos.y; + bpos.z = bbox.bottom.x - bscale.d; + if (sp->hit) + CheckBoxPos(bbox.bottom.z,bbox.top.z,bbox.bottom.y,bbox.top.y); break; } case 1:{ sp = &rside; - bpos[0] = rside.pos.z*-1; - bpos[1] = rside.pos.y; - bpos[2] = bbox.top.x + bscale[3]; + bpos.x = rside.pos.z*-1; + bpos.y = rside.pos.y; + bpos.z = bbox.top.x + bscale.d; + if (sp->hit) + CheckBoxPos(bbox.bottom.z,bbox.top.z,bbox.bottom.y,bbox.top.y); break; } case 2:{ sp = &tside; - bpos[0] = tside.pos.x; - bpos[1] = tside.pos.z; - bpos[2] = bbox.bottom.y - bscale[3]; + bpos.x = tside.pos.x; + bpos.y = tside.pos.z; + bpos.z = bbox.bottom.y - bscale.d; + if (sp->hit) + CheckBoxPos(bbox.bottom.x,bbox.top.x,bbox.bottom.z,bbox.top.z); break; } case 3:{ sp = &bside; - bpos[0] = bside.pos.x; - bpos[1] = bside.pos.z; - bpos[2] = bbox.top.y + bscale[3]; + bpos.x = bside.pos.x; + bpos.y = bside.pos.z; + bpos.z = bbox.top.y + bscale.d; + if (sp->hit) + CheckBoxPos(bbox.bottom.x,bbox.top.x,bbox.bottom.z,bbox.top.z); break; } case 4:{ sp = &fside; - bpos[0] = fside.pos.y; - bpos[1] = fside.pos.x*-1; - bpos[2] = bbox.top.z + bscale[3]; + bpos.x = fside.pos.y; + bpos.y = fside.pos.x*-1; + bpos.z = bbox.top.z + bscale.d; + if (sp->hit) + CheckBoxPos(bbox.bottom.y,bbox.top.y,bbox.bottom.x,bbox.top.x); break; } case 5:{ sp = &aside; - bpos[0] = aside.pos.y; - bpos[1] = aside.pos.x*-1; - bpos[2] = bbox.bottom.z + bscale[3]; + bpos.x = aside.pos.y; + bpos.y = aside.pos.x*-1; + bpos.z = bbox.bottom.z + bscale.d; + if (sp->hit) + CheckBoxPos(bbox.bottom.y,bbox.top.y,bbox.bottom.x,bbox.top.x); break; } } if(sp->hit){ - glColor3fv(sp->color); - glPushMatrix(); - glRotatef(sp->rot[0],sp->rot[1],sp->rot[2],sp->rot[3]); - glTranslatef(bpos[0],bpos[1],bpos[2]); - /*dem = (MAX_COUNT-(sp->counter+1));*/ - /*glScalef(bscale[0]/dem,bscale[1]/dem,bscale[2]);*/ - glScalef(bscale[0],bscale[1],bscale[2]); - glCallList(boxList); - glPopMatrix(); - sp->counter--; - if(!sp->counter) - sp->hit = 0; + if(do_fade){ + glColor4f(sp->color[0],sp->color[1],sp->color[2],1-(ALPHA_AMT * sp->alpha_count)); + }else{ + glColor3fv(sp->color); + } + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + glPushMatrix(); + glRotatef(sp->rot[0],sp->rot[1],sp->rot[2],sp->rot[3]); + glTranslatef(bpos.x,bpos.y,bpos.z); + if (do_dissolve) { + glScalef(bscale.wh-(des_amt*sp->des_count),bscale.wh-(des_amt*sp->des_count),bscale.d); + }else{ + glScalef(bscale.wh,bscale.wh,bscale.d); + } + glCallList(boxList); + glPopMatrix(); + sp->counter--; + sp->des_count++; + sp->alpha_count++; + if(!sp->counter) + { + sp->hit = 0; + } } i++; }