Skip to content

Commit

Permalink
with rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
eclecticc committed Sep 11, 2011
1 parent ac68d52 commit 9e94bbb
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 13 deletions.
53 changes: 43 additions & 10 deletions sosg/sosg.c
Expand Up @@ -18,19 +18,25 @@
#include <stdlib.h>

#define TICK_INTERVAL 16
#define PI 3.141592653589793
#define ROTATION_INTERVAL PI/(120.0*(1000.0/TICK_INTERVAL))

typedef struct sosg_struct {
int w;
int h;
int texres[2];
float radius;
float height;
float center[2];
float rotation;
float drotation;
Uint32 time;
SDL_Surface *screen;
GLuint texture;
GLuint program;
GLuint vertex;
GLuint fragment;
GLuint lrotation;
} sosg_t;

static SDL_Surface *load_image(const char *filename)
Expand Down Expand Up @@ -132,6 +138,9 @@ static int load_shaders(sosg_t *data)
glUniform2f(loc, data->center[0]/(float)data->w, data->center[1]/(float)data->h);
loc = glGetUniformLocation(data->program, "ratio");
glUniform1f(loc, (float)data->w/(float)data->h);
loc = glGetUniformLocation(data->program, "texres");
glUniform2f(loc, 1.0/(float)data->texres[0], 1.0/(float)data->texres[1]);
data->lrotation = glGetUniformLocation(data->program, "rotation");

return 0;
}
Expand All @@ -145,6 +154,7 @@ static int setup(sosg_t *data)
}

data->time = SDL_GetTicks();
SDL_EnableKeyRepeat(250, TICK_INTERVAL);

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

Expand Down Expand Up @@ -176,28 +186,47 @@ static void timer_update(sosg_t *data)
SDL_Delay(data->time - now);
}

data->time = now + TICK_INTERVAL;
while (data->time <= now) {
data->time += TICK_INTERVAL;
}
}

static int handle_events(sosg_t *data)
{
SDL_Event event;
SDL_WaitEvent(&event);

switch (event.type) {
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {

while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
return -1;
case SDLK_LEFT:
data->drotation += ROTATION_INTERVAL;
break;
case SDLK_RIGHT:
data->drotation -= ROTATION_INTERVAL;
break;
case SDLK_p:
data->drotation = 0.0;
default:
break;
}
break;
case SDL_QUIT:
return -1;
}
break;
case SDL_QUIT:
return -1;
default:
break;
}
}

return 0;
}

static void update(sosg_t *data)
{
glUniform1f(data->lrotation, data->rotation);

// Clear the screen before drawing
glClear(GL_COLOR_BUFFER_BIT);

Expand Down Expand Up @@ -239,6 +268,7 @@ int main(int argc, char *argv[])
data->height = 370.0;
data->center[0] = 431.0;
data->center[1] = 210.0;
data->rotation = PI;

if (setup(data)) {
return 1;
Expand All @@ -253,6 +283,8 @@ int main(int argc, char *argv[])
}

data->texture = load_texture(surface);
data->texres[0] = surface->w;
data->texres[1] = surface->h;
SDL_FreeSurface(surface);
} else {
printf("SDL could not load %s: %s\n", filename, SDL_GetError());
Expand All @@ -268,6 +300,7 @@ int main(int argc, char *argv[])
while (handle_events(data) != -1) {
update(data);
timer_update(data);
data->rotation += data->drotation;
}

// Now we can delete the OpenGL texture and close down SDL
Expand Down
18 changes: 15 additions & 3 deletions sosg/sosg.frag
Expand Up @@ -2,7 +2,9 @@ uniform sampler2D tex;
uniform float radius;
uniform float height;
uniform float ratio;
uniform float rotation;
uniform vec2 center;
uniform vec2 texres;

#define SIN_PI_4 0.7071067811865475
#define PI2 6.283185307179586
Expand All @@ -11,15 +13,25 @@ uniform vec2 center;

void main(void)
{
vec4 color = vec4(0.0);
vec2 offset = (gl_TexCoord[0].st - center)*vec2(ratio, 1.0);
float d = length(offset);
if (d > radius) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragColor = color;
} else {
// Map equirectangular to the Snow Globe fisheye
float h = d*SIN_PI_4/radius;
float theta = asin(height*h)+asin(h);
float phi = atan(offset[0],offset[1]);
vec2 fisheye = vec2((PI-phi)/PI2, theta/PI_2);
gl_FragColor = texture2D(tex, fisheye);
vec2 fisheye = vec2((rotation-phi)/PI2, theta/PI_2);

// A really naive filter to reduce sparkling
color += texture2D(tex, fisheye + vec2(-texres[0], 0.0));
color += texture2D(tex, fisheye + vec2(texres[0], 0.0));
color += texture2D(tex, fisheye);
color += texture2D(tex, fisheye + vec2(0.0, texres[1]));
color += texture2D(tex, fisheye + vec2(0.0, -texres[1]));
color /= 5.0;
gl_FragColor = color;
}
}

0 comments on commit 9e94bbb

Please sign in to comment.