Skip to content

Instantly share code, notes, and snippets.

@i2pi
Created April 28, 2020 22:24
Show Gist options
  • Save i2pi/14418b84d7e3542215e39d74a7680335 to your computer and use it in GitHub Desktop.
Save i2pi/14418b84d7e3542215e39d74a7680335 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
#include "gl.h"
#define PI 3.14159265359
uint8_t *pixels = NULL;
int w, h;
GLuint texId;
char *filename;
typedef uint32_t ahsvT;
unsigned int mask_0(unsigned long intern) { return intern & 0x000000ff; }
unsigned int mask_1(unsigned long intern) { return intern & 0x0000ff00; }
unsigned int mask_2(unsigned long intern) { return intern & 0x00ff0000; }
unsigned int mask_3(unsigned long intern) { return intern & 0xff000000; }
unsigned int mask_02(unsigned long intern) { return intern & 0x00ff00ff; }
unsigned int mask_13(unsigned long intern) { return intern & 0xff00ff00; }
unsigned int mask_123(unsigned long intern) { return intern & 0xffffff00; }
unsigned int mask_023(unsigned long intern) { return intern & 0xffff00ff; }
unsigned int mask_013(unsigned long intern) { return intern & 0xff00ffff; }
unsigned int mask_012(unsigned long intern) { return intern & 0x00ffffff; }
unsigned long set_0(unsigned long intern, int i)
{ return (intern = mask_123(intern) | (i & 0x000000ff)); }
unsigned long set_1(unsigned long intern, int i)
{ return (intern = mask_023(intern) | (i & 0x0000ff00)); }
unsigned long set_2(unsigned long intern, int i)
{ return (intern = mask_013(intern) | (i & 0x00ff0000)); }
unsigned long set_3(unsigned long intern, int i)
{ return (intern = mask_012(intern) | (i & 0xff000000)); }
unsigned long set_02(unsigned long intern, int i)
{ return (intern = mask_13(intern) | (i & 0x00ff00ff)); }
unsigned long set_13(unsigned long intern, int i)
{ return (intern = mask_02(intern) | (i & 0xff00ff00)); }
unsigned long set_a(unsigned long intern, unsigned int i)
{ return set_3(intern, i << 24); }
unsigned long set_r(unsigned long intern, unsigned int i)
{ return set_2(intern, i << 16); }
unsigned long set_g(unsigned long intern, unsigned int i)
{ return set_1(intern, i << 8); }
unsigned long set_b(unsigned long intern, unsigned int i)
{ return set_0(intern, i); }
unsigned int get_a(unsigned long intern) { return mask_3(intern) >> 24; }
unsigned int get_r(unsigned long intern) { return mask_2(intern) >> 16; }
unsigned int get_g(unsigned long intern) { return mask_1(intern) >> 8; }
unsigned int get_b(unsigned long intern) { return mask_0(intern); }
unsigned long set_h(unsigned long intern, unsigned int i)
{ return set_2(intern, i << 16); }
unsigned long set_s(unsigned long intern, unsigned int i)
{ return set_1(intern, i << 8); }
unsigned long set_v(unsigned long intern, unsigned int i)
{ return set_0(intern, i); }
unsigned int get_h(unsigned long intern) { return mask_2(intern) >> 16; }
unsigned int get_s(unsigned long intern) { return mask_1(intern) >> 8; }
unsigned int get_v(unsigned long intern) { return mask_0(intern); }
inline ahsvT toHSV(uint32_t rgb) {
ahsvT hsv = 0x0;
int max, med, min;
int r = get_r(rgb);
int g = get_g(rgb);
int b = get_b(rgb);
hsv = set_a(hsv, get_a(rgb));
// split colors
if (r>=g) { // r > g
if (r>=b) { // r > g,b
if (g>=b) { // r > g > b
max = r;
med = g;
min = b;
r = 0;
}
else { // r > b > g
max = r;
med = b;
min = g;
r = 5;
}
}
else { // b > r > g
max = b;
med = r;
min = g;
r = 4;
}
}
else { // g > r
if (g>=b) { // g > r,b
if (r>=b) { // g > r > b
max = g;
med = r;
min = b;
r = 1;
}
else { // g > b > r
max = g;
med = b;
min = r;
r = 2;
}
}
else { // b > g > r
max = b;
med = g;
min = r;
r = 3;
}
}
hsv = set_v(hsv, max);
// colors are split into max,med,min and base h.
if (min != max) {
hsv = set_s(hsv, 255 - ((min<<8)/max));
med = max - (max * (max-med))/(max-min);
min = (med<<8)/max; // 0..256
if (r&1)
min = 256-min;
hsv = set_h(hsv, ((r<<8)+min)/6);
}
return hsv;
}
inline uint32_t toRGB(ahsvT hsv) {
uint32_t rgb = 0x0;
int max,med,min,h;
int r = 0x0, g = 0x0, b = 0x0;
rgb = set_a(rgb, get_a(hsv));
h = 6*get_h(hsv);
max = get_v(hsv);
min = (max*(256-get_s(hsv)))>>8;
med = (((h&255)+1)*max)>>8;
if (h&256) med = max-med;
med = max-(((max-med)*(get_s(hsv)+1))>>8);
h>>=8;
switch(h) {
case 0: r=max; g=med; b=min; break;
case 1: r=med; g=max; b=min; break;
case 2: r=min; g=max; b=med; break;
case 3: r=min; g=med; b=max; break;
case 4: r=med; g=min; b=max; break;
case 5: r=max; g=min; b=med; break;
}
rgb = set_r(rgb, r);
rgb = set_g(rgb, g);
rgb = set_b(rgb, b);
return rgb;
}
GLuint create_texture (int w, int h, uint8_t *pixels, GLenum format) {
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, format, GL_UNSIGNED_BYTE, pixels);
return (id);
}
void read_ppm (char *filename) {
FILE *fp;
fp = fopen (filename, "r");
if (!fp) {
fprintf (stderr, "Failed to open %s\n", filename);
exit (-1);
}
fscanf (fp, "P6\n%d %d\n255\n", &w, &h);
printf ("Image size: %d x %d\n", w, h);
pixels = (uint8_t *) malloc (w * h * 3);
if (!pixels) {
fprintf (stderr, "Failed to allocate pixel store %d x %d\n", w, h);
exit (-1);
}
fread(pixels, 3, w*h, fp);
fclose(fp);
}
float cos_random() {
float x;
x = random() / (float) RAND_MAX;
x = 2.0 * (x - 0.5);
x = 2.0 * ((acos(x) / PI) - 0.5);
return (x);
}
int clamp_byte(int x) {
if (x < 0) return (0);
if (x > 255) return (255);
return (x);
}
void hsv_shift(int8_t h_shift, int8_t s_shift, int8_t v_shift) {
uint32_t *frame;
int w, h;
int x, y;
GLuint id = 7;
w = gui_state.w;
h = gui_state.h;
frame = (uint32_t *) malloc (w * h * 4);
glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void *) frame);
for (y=0; y<h; y++)
for (x=0; x<w; x++) {
int H, S, V;
uint32_t hsv, new;
hsv = toHSV(frame[(y*w) + x]);
H = get_h(hsv);
S = get_s(hsv);
V = get_v(hsv);
H += h_shift;
if (H > 255) H = H - 255; else
if (H < 255) H = H + 255;
S = clamp_byte(S + s_shift);
V = clamp_byte(V + v_shift);
new = 0x0;
new = set_h(new, H);
new = set_s(new, S);
new = set_v(new, V);
frame[(y*w) + x] = toRGB(new);
}
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
glClearColor(0.5, 0.5, 0.5, 1);
glClearDepth(-1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, id);
glBegin(GL_QUADS);
glColor4f(1,1,1,1);
glTexCoord2d(0.0,0.0);
glVertex2d(0.0,0.0);
glTexCoord2d(0.0,1.0);
glVertex2d(0.0,1.0);
glTexCoord2d(1.0,1.0);
glVertex2d(1.0,1.0);
glTexCoord2d(1.0,0.0);
glVertex2d(1.0,0.0);
glEnd();
free(frame);
}
void add_noise(float amount, float color_amount) {
uint32_t *frame;
int w, h;
int x, y;
GLuint id = 7;
w = gui_state.w;
h = gui_state.h;
frame = (uint32_t *) malloc (w * h * 4);
glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void *) frame);
for (y=0; y<h; y++)
for (x=0; x<w; x++) {
int r,g,b, noise, rn, gn, bn;
r = (frame[(y*w) + x] & 0x00ff0000) >> 16;
g = (frame[(y*w) + x] & 0x0000ff00) >> 8;
b = (frame[(y*w) + x] & 0x000000ff) >> 0;
noise = 127 * amount * cos_random();
rn = 127 * color_amount * cos_random();
gn = 127 * color_amount * cos_random();
bn = 127 * color_amount * cos_random();
r = clamp_byte (r + noise + rn);
g = clamp_byte (g + noise + gn);
b = clamp_byte (b + noise + bn);
frame[(y*w) + x] = (r << 16) | (g << 8) | (b << 0) | (0xff << 24);
}
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
glClearColor(0.5, 0.5, 0.5, 1);
glClearDepth(-1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, id);
glBegin(GL_QUADS);
glColor4f(1,1,1,1);
glTexCoord2d(0.0,0.0);
glVertex2d(0.0,0.0);
glTexCoord2d(0.0,1.0);
glVertex2d(0.0,1.0);
glTexCoord2d(1.0,1.0);
glVertex2d(1.0,1.0);
glTexCoord2d(1.0,0.0);
glVertex2d(1.0,0.0);
glEnd();
free(frame);
}
void spherical(float amount) {
uint32_t *frame;
int w, h;
float x, y, z, s;
GLuint id = 7;
w = gui_state.w;
h = gui_state.h;
frame = (uint32_t *) malloc (w * h * 4);
glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void *) frame);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
glClearColor(0.5, 0.5, 0.5, 1);
glClearDepth(-1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 1.0, 0.1, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, id);
glBegin(GL_QUADS);
s = 0.1;
for (x=0; x<1.0; x+=s)
for (y=0; y<1.0; y+=s) {
float X, Y, S;
float Z = 2.2;
X = 2.0 * (x - 0.5);
Y = 2.0 * (y - 0.5);
S = s * 2.0;
glNormal3f(0,0,1);
glTexCoord2f(x,y);
z = -Z + amount * sqrt((x-0.5)*(x-0.5) + (y-0.5)*(y-0.5));
glVertex3f(X,Y, z);
glNormal3f(0,0,1);
glTexCoord2f(x,y+s);
z = -Z + amount * sqrt((x-0.5)*(x-0.5) + (y+s-0.5)*(y+s-0.5));
glVertex3f(X,Y+S, z);
glNormal3f(0,0,1);
glTexCoord2f(x+s, y+s);
z = -Z + amount * sqrt((x+s-0.5)*(x+s-0.5) + (y+s-0.5)*(y+s-0.5));
glVertex3f(X+S,Y+S, z);
glNormal3f(0,0,1);
glTexCoord2f(x+s,y);
z = -Z + amount * sqrt((x+s-0.5)*(x+s-0.5) + (y-0.5)*(y-0.5));
glVertex3f(X+S,Y, z);
}
glEnd();
free(frame);
}
void spherical_blur(float amount) {
uint32_t *frame;
int w, h;
int x, y;
GLuint id = 7;
w = gui_state.w;
h = gui_state.h;
frame = (uint32_t *) malloc (w * h * 4);
glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void *) frame);
for (y=1; y<(h-1); y++)
for (x=1; x<(w-1); x++) {
int r,g,b;
float X = x / (float) w;
float Y = y / (float) h;
float z = sqrt((X-0.5)*(X-0.5) + (Y-0.5)*(Y-0.5));
float A, B;
A = amount * z / 8.0;
B = 1.0 - (amount * z);
r = A*( ((frame[((y-1)*w) + x - 1] & 0x00ff0000) >> 16) +
((frame[((y-1)*w) + x + 0] & 0x00ff0000) >> 16) +
((frame[((y-1)*w) + x + 1] & 0x00ff0000) >> 16) +
((frame[((y+0)*w) + x - 1] & 0x00ff0000) >> 16) +
((frame[((y+0)*w) + x + 1] & 0x00ff0000) >> 16) +
((frame[((y+1)*w) + x - 1] & 0x00ff0000) >> 16) +
((frame[((y+1)*w) + x + 0] & 0x00ff0000) >> 16) +
((frame[((y+1)*w) + x + 1] & 0x00ff0000) >> 16) ) +
B * ((frame[((y+0)*w) + x + 0] & 0x00ff0000) >> 16) ;
g = A*( ((frame[((y-1)*w) + x - 1] & 0x0000ff00) >> 8) +
((frame[((y-1)*w) + x + 0] & 0x0000ff00) >> 8) +
((frame[((y-1)*w) + x + 1] & 0x0000ff00) >> 8) +
((frame[((y+0)*w) + x - 1] & 0x0000ff00) >> 8) +
((frame[((y+0)*w) + x + 1] & 0x0000ff00) >> 8) +
((frame[((y+1)*w) + x - 1] & 0x0000ff00) >> 8) +
((frame[((y+1)*w) + x + 0] & 0x0000ff00) >> 8) +
((frame[((y+1)*w) + x + 1] & 0x0000ff00) >> 8) ) +
B * ((frame[((y+0)*w) + x + 0] & 0x0000ff00) >> 8) ;
b = A*( ((frame[((y-1)*w) + x - 1] & 0x000000ff) >> 0) +
((frame[((y-1)*w) + x + 0] & 0x000000ff) >> 0) +
((frame[((y-1)*w) + x + 1] & 0x000000ff) >> 0) +
((frame[((y+0)*w) + x - 1] & 0x000000ff) >> 0) +
((frame[((y+0)*w) + x + 1] & 0x000000ff) >> 0) +
((frame[((y+1)*w) + x - 1] & 0x000000ff) >> 0) +
((frame[((y+1)*w) + x + 0] & 0x000000ff) >> 0) +
((frame[((y+1)*w) + x + 1] & 0x000000ff) >> 0) ) +
B * ((frame[((y+0)*w) + x + 0] & 0x000000ff) >> 0) ;
frame[(y*w) + x] = (r << 16) | (g << 8) | (b << 0) | (0xff << 24);
}
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
glClearColor(0.5, 0.5, 0.5, 1);
glClearDepth(-1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, id);
glBegin(GL_QUADS);
glColor4f(1,1,1,1);
glTexCoord2d(0.0,0.0);
glVertex2d(0.0,0.0);
glTexCoord2d(0.0,1.0);
glVertex2d(0.0,1.0);
glTexCoord2d(1.0,1.0);
glVertex2d(1.0,1.0);
glTexCoord2d(1.0,0.0);
glVertex2d(1.0,0.0);
glEnd();
free(frame);
}
void blur(float amount) {
uint32_t *frame;
int w, h;
int x, y;
GLuint id = 7;
float a;
a = amount / 8.0;
w = gui_state.w;
h = gui_state.h;
frame = (uint32_t *) malloc (w * h * 4);
glReadPixels(0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void *) frame);
for (y=1; y<(h-1); y++)
for (x=1; x<(w-1); x++) {
int r,g,b;
r = a*( ((frame[((y-1)*w) + x - 1] & 0x00ff0000) >> 16) +
((frame[((y-1)*w) + x + 0] & 0x00ff0000) >> 16) +
((frame[((y-1)*w) + x + 1] & 0x00ff0000) >> 16) +
((frame[((y+0)*w) + x - 1] & 0x00ff0000) >> 16) +
((frame[((y+0)*w) + x + 1] & 0x00ff0000) >> 16) +
((frame[((y+1)*w) + x - 1] & 0x00ff0000) >> 16) +
((frame[((y+1)*w) + x + 0] & 0x00ff0000) >> 16) +
((frame[((y+1)*w) + x + 1] & 0x00ff0000) >> 16) ) +
(1-amount) *
((frame[((y+0)*w) + x + 0] & 0x00ff0000) >> 16) ;
g = a*( ((frame[((y-1)*w) + x - 1] & 0x0000ff00) >> 8) +
((frame[((y-1)*w) + x + 0] & 0x0000ff00) >> 8) +
((frame[((y-1)*w) + x + 1] & 0x0000ff00) >> 8) +
((frame[((y+0)*w) + x - 1] & 0x0000ff00) >> 8) +
((frame[((y+0)*w) + x + 1] & 0x0000ff00) >> 8) +
((frame[((y+1)*w) + x - 1] & 0x0000ff00) >> 8) +
((frame[((y+1)*w) + x + 0] & 0x0000ff00) >> 8) +
((frame[((y+1)*w) + x + 1] & 0x0000ff00) >> 8) ) +
(1-amount) *
((frame[((y+0)*w) + x + 0] & 0x0000ff00) >> 8) ;
b = a*( ((frame[((y-1)*w) + x - 1] & 0x000000ff) >> 0) +
((frame[((y-1)*w) + x + 0] & 0x000000ff) >> 0) +
((frame[((y-1)*w) + x + 1] & 0x000000ff) >> 0) +
((frame[((y+0)*w) + x - 1] & 0x000000ff) >> 0) +
((frame[((y+0)*w) + x + 1] & 0x000000ff) >> 0) +
((frame[((y+1)*w) + x - 1] & 0x000000ff) >> 0) +
((frame[((y+1)*w) + x + 0] & 0x000000ff) >> 0) +
((frame[((y+1)*w) + x + 1] & 0x000000ff) >> 0) ) +
(1-amount) *
((frame[((y+0)*w) + x + 0] & 0x000000ff) >> 0) ;
frame[(y*w) + x] = (r << 16) | (g << 8) | (b << 0) | (0xff << 24);
}
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
glClearColor(0.5, 0.5, 0.5, 1);
glClearDepth(-1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, id);
glBegin(GL_QUADS);
glColor4f(1,1,1,1);
glTexCoord2d(0.0,0.0);
glVertex2d(0.0,0.0);
glTexCoord2d(0.0,1.0);
glVertex2d(0.0,1.0);
glTexCoord2d(1.0,1.0);
glVertex2d(1.0,1.0);
glTexCoord2d(1.0,0.0);
glVertex2d(1.0,0.0);
glEnd();
free(frame);
}
void save_frame_ppm (char *filename) {
FILE *fp;
uint8_t *pixels;
int w, h;
fp = fopen (filename, "w");
w = gui_state.w;
h = gui_state.h;
pixels = (uint8_t *) malloc (w * h * 3);
if (!pixels) {
fprintf (stderr, "Failed to allocate pixel store %d x %d\n", w, h);
exit (-1);
}
glReadPixels(0,0, w, h, GL_RGB, GL_UNSIGNED_BYTE, (void*) pixels);
fprintf (fp, "P6\n%d %d\n255\n", w, h);
fwrite(pixels, 3, w*h, fp);
fclose(fp);
}
void photo(void) {
static char loaded_image = 0;
static double T = 0.0;
int i,j;
float z = 0;
float x, y, s;
GLenum lights[] = {GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5};
T += 0.001;
if (!loaded_image) {
texId = create_texture(w,h,pixels, GL_RGB);
loaded_image = 1;
}
glClearColor(1,1,1,1);
glClearDepth(0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
GLfloat mat_shininess[] = { 50.0 };
GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_diffuse[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat mat_emission[] = { 0.6, 0.6, 0.6, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_SMOOTH);
// Generate off-white spotlights
for (i=0; i<4; i++) {
GLfloat direction[] = { 0, 0, -1 };
GLfloat light_position[] = { 0.0, 0.0, 300.0, 300.0 };
GLfloat light_color[] = {1,1,1,1};
glEnable(lights[i]);
for (j=0; j<3; j++) light_color[j] = 0.6 + 0.3*cos_random();
glLightfv(lights[i], GL_SPECULAR, light_color);
for (j=0; j<3; j++) light_color[j] = 0.3 + 0.2*cos_random();
glLightfv(lights[i], GL_DIFFUSE, light_color);
light_position[3] = 600 + 250*cos_random();
light_position[0] = 1000*cos_random();
light_position[1] = 1000*cos_random();
glLightfv(lights[i], GL_POSITION, light_position);
glLightfv(lights[i], GL_SPOT_DIRECTION, direction);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40+40*cos_random(),1.0,-1000,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Add backing plane
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glBegin(GL_QUADS);
s = 0.01;
z = -1000;
float D = 10;
for (x=0; x<1.0; x+=s)
for (y=0; y<1.0; y+=s) {
float X, Y, S;
X = D * (x - 0.5);
Y = D * (y - 0.5);
S = s * D;
glColor4f(1,1,1,1);
glNormal3f(0,0,1);
glVertex3f(X,Y, z);
glNormal3f(0,0,1);
glVertex3f(X,Y+S, z);
glNormal3f(0,0,1);
glVertex3f(X+S,Y+S, z);
glNormal3f(0,0,1);
glVertex3f(X+S,Y, z);
}
glEnd();
// Rotate the image
{
float a;
a = 360 * cos_random();
glRotatef(a, 0, 0, 1);
a = 40 * cos_random();
glRotatef(a, 1, 0, 0);
a = 40 * cos_random();
glRotatef(a, 0, 1, 0);
}
// Translate the image
{
float x, y;
x = cos_random() * 0.2;
y = cos_random() * 0.2;
glTranslatef(x,y,0);
}
// Draw the image
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glBindTexture(GL_TEXTURE_2D, texId);
glBegin(GL_QUADS);
s = 0.001;
z = 0;
for (x=0; x<1.0; x+=s)
for (y=0; y<1.0; y+=s) {
float X, Y, S;
X = 2.0 * (x - 0.5);
Y = 2.0 * (y - 0.5);
S = s * 2.0;
glNormal3f(0,0,1);
glTexCoord2f(x,y);
glVertex3f(X,Y, z);
glNormal3f(0,0,1);
glTexCoord2f(x,y+s);
glVertex3f(X,Y+S, z);
glNormal3f(0,0,1);
glTexCoord2f(x+s, y+s);
glVertex3f(X+S,Y+S, z);
glNormal3f(0,0,1);
glTexCoord2f(x+s,y);
glVertex3f(X+S,Y, z);
}
glEnd();
add_noise (0.3, 0.2);
blur(0.2);
spherical(0.5*cos_random());
for (i=0; i<5; i++) spherical_blur(1.7);
hsv_shift(10 * cos_random(),
40 * cos_random(),
80 * cos_random());
add_noise (0.1, 0.05);
{
// save a screenshot
char new_filename[256];
snprintf (new_filename, 256, "photo_%s_%011d.ppm", filename, random());
save_frame_ppm (new_filename);
}
glutSwapBuffers();
}
int main (int argc, char **argv) {
filename = argv[1];
read_ppm(filename);
start_gl(argc, argv, photo);
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment