From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/glx/antspotlight.c | 799 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 799 insertions(+) create mode 100644 hacks/glx/antspotlight.c (limited to 'hacks/glx/antspotlight.c') diff --git a/hacks/glx/antspotlight.c b/hacks/glx/antspotlight.c new file mode 100644 index 0000000..55bb80c --- /dev/null +++ b/hacks/glx/antspotlight.c @@ -0,0 +1,799 @@ +/* + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Copyright 2003 Blair Tennessy + */ + +#ifdef STANDALONE +#define DEFAULTS "*delay: 20000 \n" \ + "*showFPS: False \n" \ + "*useSHM: True \n" + +# define free_antspotlight 0 +# define release_antspotlight 0 +#include "xlockmore.h" +#else +#include "xlock.h" +#endif + +#ifdef HAVE_JWXYZ +# include "jwxyz.h" +#else +# include +# include +# include +#endif + +#ifdef HAVE_JWZGLES +# include "jwzgles.h" +#endif /* HAVE_JWZGLES */ + +#include "sphere.h" +#include "tube.h" +#include "rotator.h" +#include "gltrackball.h" + +ENTRYPOINT ModeSpecOpt antspotlight_opts = { + 0, NULL, 0, NULL, NULL +}; + +#ifdef USE_MODULES +ModStruct antspotlight_description = { + "antspotlight", "init_antspotlight", "draw_antspotlight", + (char *) NULL, "draw_antspotlight", "change_antspotlight", + (char *) NULL, &antspotlight_opts, 1000, 1, 1, 1, 4, 1.0, "", + "draws an ant scoping the screen", 0, NULL +}; +#endif + +#define Scale4Window 0.3 +#define Scale4Iconic 0.4 + +#define sqr(A) ((A)*(A)) + +#ifndef Pi +#define Pi M_PI +#endif + +#include "ants.h" +#include "grab-ximage.h" + +typedef struct { + GLXContext *glx_context; + rotator *rot; + trackball_state *trackball; + Bool button_down_p; + + GLfloat max_tx, max_ty; + int mono, wire, ticks; + GLuint screentexture; + + Ant *ant; + double boardsize; + GLfloat spot_direction[3]; + int mag; + + Bool mipmap_p; + Bool waiting_for_image_p; + +} antspotlightstruct; + +static antspotlightstruct *antspotlight = (antspotlightstruct *) NULL; + +#define NUM_SCENES 2 + +/* draw method for ant */ +static Bool draw_ant(ModeInfo *mi, antspotlightstruct *mp, + const GLfloat *Material, int mono, int shadow, + float ant_step, Bool (*sphere)(float), Bool (*cone)(float)) +{ + + float cos1 = cos(ant_step); + float cos2 = cos(ant_step + 2 * Pi / 3); + float cos3 = cos(ant_step + 4 * Pi / 3); + float sin1 = sin(ant_step); + float sin2 = sin(ant_step + 2 * Pi / 3); + float sin3 = sin(ant_step + 4 * Pi / 3); + +/* Apparently this is a performance killer on many systems... + glEnable(GL_POLYGON_SMOOTH); + */ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->mono ? MaterialGray5 : Material); + glEnable(GL_CULL_FACE); + glPushMatrix(); + glScalef(1, 1.3, 1); + if(!((*sphere)(0.18))) + return False; + glScalef(1, 1 / 1.3, 1); + glTranslatef(0.00, 0.30, 0.00); + if(!((*sphere)(0.2))) + return False; + + glTranslatef(-0.05, 0.17, 0.05); + glRotatef(-90, 1, 0, 0); + glRotatef(-25, 0, 1, 0); + if(!((*cone)(0.05))) + return False; + glTranslatef(0.00, 0.10, 0.00); + if(!((*cone)(0.05))) + return False; + glRotatef(25, 0, 1, 0); + glRotatef(90, 1, 0, 0); + + glScalef(1, 1.3, 1); + glTranslatef(0.15, -0.65, 0.05); + if(!((*sphere)(0.25))) + return False; + glScalef(1, 1 / 1.3, 1); + glPopMatrix(); + glDisable(GL_CULL_FACE); + + glDisable(GL_LIGHTING); + + /* ANTENNAS */ + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glBegin(GL_LINES); + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, 0.30, 0.00); + glColor3fv(MaterialGray); + glVertex3f(0.40, 0.70, 0.40); + mi->polygon_count++; + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, 0.30, 0.00); + glColor3fv(MaterialGray); + glVertex3f(0.40, 0.70, -0.40); + mi->polygon_count++; + glEnd(); + + if(!shadow) { + glBegin(GL_POINTS); + glColor3fv(mp->mono ? MaterialGray6 : MaterialGray5); + glVertex3f(0.40, 0.70, 0.40); + mi->polygon_count++; + glVertex3f(0.40, 0.70, -0.40); + mi->polygon_count++; + glEnd(); + } + + /* LEFT-FRONT ARM */ + glBegin(GL_LINE_STRIP); + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, 0.05, 0.18); + glVertex3f(0.35 + 0.05 * cos1, 0.15, 0.25); + mi->polygon_count++; + glColor3fv(MaterialGray); + glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45); + mi->polygon_count++; + glEnd(); + + /* LEFT-CENTER ARM */ + glBegin(GL_LINE_STRIP); + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, 0.00, 0.18); + glVertex3f(0.35 + 0.05 * cos2, 0.00, 0.25); + mi->polygon_count++; + glColor3fv(MaterialGray); + glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45); + mi->polygon_count++; + glEnd(); + + /* LEFT-BACK ARM */ + glBegin(GL_LINE_STRIP); + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, -0.05, 0.18); + glVertex3f(0.35 + 0.05 * cos3, -0.15, 0.25); + mi->polygon_count++; + glColor3fv(MaterialGray); + glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45); + mi->polygon_count++; + glEnd(); + + /* RIGHT-FRONT ARM */ + glBegin(GL_LINE_STRIP); + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, 0.05, -0.18); + glVertex3f(0.35 - 0.05 * sin1, 0.15, -0.25); + mi->polygon_count++; + glColor3fv(MaterialGray); + glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45); + mi->polygon_count++; + glEnd(); + + /* RIGHT-CENTER ARM */ + glBegin(GL_LINE_STRIP); + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, 0.00, -0.18); + glVertex3f(0.35 - 0.05 * sin2, 0.00, -0.25); + mi->polygon_count++; + glColor3fv(MaterialGray); + glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45); + mi->polygon_count++; + glEnd(); + + /* RIGHT-BACK ARM */ + glBegin(GL_LINE_STRIP); + glColor3fv(mp->mono ? MaterialGray5 : Material); + glVertex3f(0.00, -0.05, -0.18); + glVertex3f(0.35 - 0.05 * sin3, -0.15, -0.25); + mi->polygon_count++; + glColor3fv(MaterialGray); + glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45); + mi->polygon_count++; + glEnd(); + + if(!shadow) { + glBegin(GL_POINTS); + glColor3fv(MaterialGray5); + glVertex3f(-0.20 + 0.05 * cos1, 0.25 + 0.1 * sin1, 0.45); + glVertex3f(-0.20 + 0.05 * cos2, 0.00 + 0.1 * sin2, 0.45); + glVertex3f(-0.20 + 0.05 * cos3, -0.25 + 0.1 * sin3, 0.45); + glVertex3f(-0.20 - 0.05 * sin1, 0.25 + 0.1 * cos1, -0.45); + glVertex3f(-0.20 - 0.05 * sin2, 0.00 + 0.1 * cos2, -0.45); + glVertex3f(-0.20 - 0.05 * sin3, -0.25 + 0.1 * cos3, -0.45); + mi->polygon_count += 6; + glEnd(); + } + + glEnable(GL_LIGHTING); + + return True; +} + +/* filled sphere */ +static Bool mySphere(float radius) +{ +#if 0 + GLUquadricObj *quadObj; + + if((quadObj = gluNewQuadric()) == 0) + return False; + + gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL); + gluSphere(quadObj, radius, 16, 16); + gluDeleteQuadric(quadObj); +#else + glPushMatrix(); + glScalef (radius, radius, radius); + glRotatef (90, 1, 0, 0); + unit_sphere (16, 16, False); + glPopMatrix(); +#endif + return True; +} + +/* silhouette sphere */ +static Bool mySphere2(float radius) +{ +#if 0 + GLUquadricObj *quadObj; + + if((quadObj = gluNewQuadric()) == 0) + return False; + gluQuadricDrawStyle(quadObj, (GLenum) GLU_LINE); + gluSphere(quadObj, radius, 16, 8); + gluDeleteQuadric(quadObj); +#else + /* #### no GLU_LINE */ + glPushMatrix(); + glScalef (radius, radius, radius); + glRotatef (90, 1, 0, 0); + unit_sphere (16, 16, True); + glPopMatrix(); +#endif + return True; +} + +/* no cone */ +static Bool myCone2(float radius) { return True; } + +static void draw_board(ModeInfo *mi, antspotlightstruct *mp) +{ + int i, j; + double cutoff = Pi/3.0; + double center[3]; + double centertex[2]; + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, mp->screentexture); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray6); + + /* draw mesh */ + + /* center is roughly spotlight position */ + center[0] = mp->ant->position[0];/* + cos(ant->direction); */ + center[1] = 0.0; + center[2] = mp->ant->position[2];/* - 0.7*sin(ant->direction);*/ + + centertex[0] = (mp->boardsize/2.0+center[0]) * mp->max_tx / mp->boardsize; + centertex[1] = mp->max_ty - ((mp->boardsize/2.0+center[2]) * mp->max_ty / mp->boardsize); + +/* glPolygonMode(GL_FRONT, GL_LINE); */ +/* glDisable(GL_TEXTURE_2D); */ + + /* + the vertices determined here should correspond to the illuminated + board. ideally the code adapts vertex distribution to the + intensity and shape of the light. + + i should be finding the intersection of the cone of light and + the board-plane. + */ + for(i = -12; i < 12; ++i) { + + double theta1, theta2; + + glBegin(GL_TRIANGLE_STRIP); + glNormal3f(0.0, 1.0, 0.0); + + glTexCoord2f(centertex[0], centertex[1]); + glVertex3f(center[0], 0.01, center[2]); + + /* watch those constants */ + theta1 = mp->ant->direction + i*(cutoff/8); + theta2 = mp->ant->direction + (i+1)*(cutoff/8); + + for(j = 1; j <= 64; ++j) { + double point[3], tex[2]; + /* double fj = pow(1.05, j) - 1.0;*/ + double fj = j / 6.0; + point[0] = center[0] + fj*cos(theta1); + point[1] = 0.0; + point[2] = center[2] - fj*sin(theta1); + + tex[0] = (mp->boardsize/2.0+point[0]) * mp->max_tx / mp->boardsize; + tex[1] = (mp->boardsize/2.0+point[2]) * mp->max_ty / mp->boardsize; + + glTexCoord2f(tex[0], tex[1]); + glVertex3f(point[0], point[1], point[2]); + + point[0] = center[0] + fj*cos(theta2); + point[1] = 0.0; + point[2] = center[2] - fj*sin(theta2); + + tex[0] = (mp->boardsize/2.0+point[0]) * mp->max_tx / mp->boardsize; + tex[1] = (mp->boardsize/2.0+point[2]) * mp->max_ty / mp->boardsize; + + glTexCoord2f(tex[0], tex[1]); + glVertex3f(point[0], point[1], point[2]); + mi->polygon_count++; + } + + glEnd(); + } + + glDisable(GL_TEXTURE_2D); +} + +/* return euclidean distance between two points */ +static double distance(double x[3], double y[3]) +{ + double dx = x[0] - y[0]; + double dz = x[2] - y[2]; + return sqrt(dx*dx + dz*dz); +} + +/* determine a new goal */ +static void find_goal(antspotlightstruct *mp) +{ + do { + mp->ant->goal[0] = random()%((int)(mp->boardsize+0.5)-2) - mp->boardsize/2.0 + 1.0; + mp->ant->goal[1] = 0.0; + mp->ant->goal[2] = random()%((int)(mp->boardsize+0.5)-2) - mp->boardsize/2.0 + 1.0; + } + while(distance(mp->ant->position, mp->ant->goal) < 2.0); +} + +/* construct our ant */ +static void build_ant(antspotlightstruct *mp) +{ + mp->ant = (Ant *) malloc(sizeof (Ant)); + mp->ant->position[0] = 0.0; + mp->ant->position[1] = 0.0; + mp->ant->position[2] = 0.0; + mp->ant->direction = 0.0; + mp->ant->velocity = 0.02; + mp->ant->material = MaterialGray5; + mp->ant->step = 0; + find_goal(mp); +} + +#define EPSILON 0.01 + +static double sign(double d) +{ + return d < 0.0 ? -1.0 : 1.0; +} + +static double min(double a, double b) +{ + return a < b ? a : b; +} + +/* +static double max(double a, double b) +{ + return a > b ? a : b; +} +*/ + +/* find a new goal and reset steps */ +static void reset_ant(antspotlightstruct *mp) +{ + find_goal(mp); +} + +/* draw ant composed of skeleton and glass */ +static void show_ant(ModeInfo *mi, antspotlightstruct *mp) +{ + + glPushMatrix(); + + /* move into position */ + glTranslatef(mp->ant->position[0], 0.33, mp->ant->position[2]); + glRotatef(180.0 + mp->ant->direction*180.0/Pi, 0.0, 1.0, 0.0); + glRotatef(90.0, 0.0, 0.0, 1.0); + + /* draw skeleton */ + draw_ant(mi, mp, mp->ant->material, mp->mono, 0, mp->ant->step, mySphere2, myCone2); + + /* draw glass */ + if(!mp->wire && !mp->mono) { + glEnable(GL_BLEND); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGrayB); + glColor4fv(MaterialGrayB); + draw_ant(mi, mp, MaterialGrayB, mp->mono, 0, mp->ant->step, mySphere, myCone2); + glDisable(GL_BLEND); + } + + glPopMatrix(); +} + +static void draw_antspotlight_strip(ModeInfo *mi) +{ + antspotlightstruct *mp = &antspotlight[MI_SCREEN(mi)]; + + /* compute spotlight position and direction */ + GLfloat light1_position[4]; + + light1_position[0] = mp->ant->position[0] + 0.7*cos(mp->ant->direction); + light1_position[1] = 0.5; + light1_position[2] = mp->ant->position[2] - 0.7*sin(mp->ant->direction); + light1_position[3] = 1.0; + + mp->spot_direction[0] = cos(mp->ant->direction); + mp->spot_direction[1] = -0.5; + mp->spot_direction[2] = -sin(mp->ant->direction); + + glLightfv(GL_LIGHT2, GL_POSITION, light1_position); + glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, mp->spot_direction); + + glEnable(GL_LIGHT2); + glDisable(GL_LIGHT0); + glDisable(GL_LIGHT1); + + /* draw board */ + if(mp->wire) + ; + else + draw_board(mi, mp); + + glDisable(GL_LIGHT2); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + /* now modify ant */ + show_ant(mi, mp); + + /* near goal, bend path towards next step */ + if(distance(mp->ant->position, mp->ant->goal) < 0.2) { + reset_ant(mp); + } + + if(random()%100 == 0) { + reset_ant(mp); + } + + + /* move toward goal, correct ant direction if required */ + else { + + /* difference */ + double dx = mp->ant->goal[0] - mp->ant->position[0]; + double dz = -(mp->ant->goal[2] - mp->ant->position[2]); + double theta, ideal, dt; + + if(fabs(dx) > EPSILON) { + theta = atan(dz/dx); + if(dx < 0.0) + theta += Pi; + } + else + theta = dz > 0.0 ? (1.0/2.0)*Pi : (3.0/2.0)*Pi; + + if(theta < 0.0) + theta += 2*Pi; + + ideal = theta - mp->ant->direction; + if(ideal > Pi) + ideal -= 2*Pi; + + /* compute correction */ + dt = sign(ideal) * min(fabs(ideal), Pi/100.0); + mp->ant->direction += dt; + while(mp->ant->direction < 0.0) + mp->ant->direction += 2*Pi; + while(mp->ant->direction > 2*Pi) + mp->ant->direction -= 2*Pi; + } + + mp->ant->position[0] += mp->ant->velocity * cos(mp->ant->direction); + mp->ant->position[2] += mp->ant->velocity * sin(-mp->ant->direction); + mp->ant->step += 10*mp->ant->velocity; + while(mp->ant->step > 2*Pi) + mp->ant->step -= 2*Pi; +} + +ENTRYPOINT void reshape_antspotlight(ModeInfo * mi, int width, int height) +{ + double h = (GLfloat) height / (GLfloat) width; + int y = 0; + int size = 2; + + if (width > height * 5) { /* tiny window: show middle */ + height = width * 9/16; + y = -height/2; + h = height / (GLfloat) width; + } + + glViewport(0, y, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gluPerspective(45, 1/h, 1.0, 25.0); + + glMatrixMode(GL_MODELVIEW); + glLineWidth(size); + glPointSize(size); +} + +/* lighting variables */ +static const GLfloat front_shininess[] = {60.0}; +static const GLfloat front_specular[] = {0.8, 0.8, 0.8, 1.0}; +static const GLfloat ambient[] = {0.4, 0.4, 0.4, 1.0}; +/*static const GLfloat ambient2[] = {0.0, 0.0, 0.0, 0.0};*/ +static const GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0}; +static const GLfloat position0[] = {1.0, 5.0, 1.0, 0.0}; +static const GLfloat position1[] = {-1.0, -5.0, 1.0, 0.0}; +/*static const GLfloat lmodel_ambient[] = {0.8, 0.8, 0.8, 1.0};*/ +static const GLfloat lmodel_twoside[] = {GL_TRUE}; +static const GLfloat spotlight_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; +static const GLfloat spotlight_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; + +static void pinit(void) +{ + glClearDepth(1.0); + + /* setup twoside lighting */ + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_POSITION, position0); + glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT1, GL_POSITION, position1); + + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, spotlight_ambient); + glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + /* setup spotlight */ + glLightfv(GL_LIGHT2, GL_AMBIENT, spotlight_ambient); + glLightfv(GL_LIGHT2, GL_DIFFUSE, spotlight_diffuse); + glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, 0.1); + glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, 0.05); + glLightf(GL_LIGHT2, GL_QUADRATIC_ATTENUATION, 0.0); + glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 60.0); + glLightf(GL_LIGHT2, GL_SPOT_EXPONENT, 3.0); + + glEnable(GL_NORMALIZE); + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + + /* setup material properties */ + glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glShadeModel(GL_SMOOTH); +/* glShadeModel(GL_FLAT); */ + glEnable(GL_DEPTH_TEST); +} + +#define MAX_MAGNIFICATION 10 +#define max(a, b) a < b ? b : a +#define min(a, b) a < b ? a : b + +/* event handling */ +ENTRYPOINT Bool antspotlight_handle_event(ModeInfo *mi, XEvent *event) +{ + antspotlightstruct *mp = &antspotlight[MI_SCREEN(mi)]; + + if (gltrackball_event_handler (event, mp->trackball, + MI_WIDTH (mi), MI_HEIGHT (mi), + &mp->button_down_p)) + return True; + + if (event->xany.type == ButtonPress) + { + switch(event->xbutton.button) { + + case Button1: + mp->button_down_p = True; + gltrackball_start(mp->trackball, + event->xbutton.x, event->xbutton.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + return True; + + case Button4: + mp->mag = max(mp->mag-1, 1); + return True; + + case Button5: + mp->mag = min(mp->mag+1, MAX_MAGNIFICATION); + return True; + } + } + + return False; +} + +static void +image_loaded_cb (const char *filename, XRectangle *geometry, + int image_width, int image_height, + int texture_width, int texture_height, + void *closure) +{ + antspotlightstruct *mp = (antspotlightstruct *) closure; + + mp->max_tx = (GLfloat) image_width / texture_width; + mp->max_ty = (GLfloat) image_height / texture_height; + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + (mp->mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR)); + + mp->waiting_for_image_p = False; +} + + +/* get screenshot */ +static void get_snapshot(ModeInfo *modeinfo) +{ + antspotlightstruct *mp = &antspotlight[MI_SCREEN(modeinfo)]; + + if (MI_IS_WIREFRAME(modeinfo)) + return; + + mp->waiting_for_image_p = True; + mp->mipmap_p = True; + load_texture_async (modeinfo->xgwa.screen, modeinfo->window, + *mp->glx_context, 0, 0, mp->mipmap_p, + mp->screentexture, image_loaded_cb, mp); +} + + +ENTRYPOINT void init_antspotlight(ModeInfo *mi) +{ + double rot_speed = 0.3; + + antspotlightstruct *mp; + + MI_INIT(mi, antspotlight); + mp = &antspotlight[MI_SCREEN(mi)]; + mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True); + mp->trackball = gltrackball_init (False); + + if((mp->glx_context = init_GL(mi)) != NULL) { + reshape_antspotlight(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + glDrawBuffer(GL_BACK); + pinit(); + } + else + MI_CLEARWINDOW(mi); + + glGenTextures(1, &mp->screentexture); + glBindTexture(GL_TEXTURE_2D, mp->screentexture); + get_snapshot(mi); + + build_ant(mp); + mp->mono = MI_IS_MONO(mi); + mp->wire = MI_IS_WIREFRAME(mi); + mp->boardsize = 8.0; + mp->mag = 1; +} + +ENTRYPOINT void draw_antspotlight(ModeInfo * mi) +{ + antspotlightstruct *mp; + + Display *display = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + + if(!antspotlight) + return; + mp = &antspotlight[MI_SCREEN(mi)]; + + MI_IS_DRAWN(mi) = True; + + if(!mp->glx_context) + return; + + mi->polygon_count = 0; + + /* Just keep running before the texture has come in. */ + /* if (mp->waiting_for_image_p) return; */ + + glXMakeCurrent(display, window, *(mp->glx_context)); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(current_device_rotation(), 0, 0, 1); + + /* position camera */ + + /* follow focused ant */ + glTranslatef(0.0, 0.0, -6.0 - mp->mag); + glRotatef(35.0, 1.0, 0.0, 0.0); + gltrackball_rotate(mp->trackball); + glTranslatef(-mp->ant->position[0], mp->ant->position[1], -mp->ant->position[2]); + + /* stable position */ +/* glTranslatef(0.0, 0.0, -10.0 - mag); */ +/* gltrackball_rotate(mp->trackball); */ +/* glRotatef(40.0, 1.0, 0.0, 0.0); */ +/* glRotatef(20.0, 0.0, 1.0, 0.0); */ + + draw_antspotlight_strip(mi); + + ++mp->ticks; + + glPopMatrix(); + + if (MI_IS_FPS(mi)) do_fps (mi); + glFlush(); + + glXSwapBuffers(display, window); +} + +#ifndef STANDALONE +ENTRYPOINT void change_antspotlight(ModeInfo * mi) +{ + antspotlightstruct *mp = &antspotlight[MI_SCREEN(mi)]; + + if (!mp->glx_context) + return; + + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context)); + pinit(); +} +#endif /* !STANDALONE */ + +XSCREENSAVER_MODULE ("AntSpotlight", antspotlight) -- cgit v1.2.3-55-g7522