Created
April 28, 2020 22:24
-
-
Save i2pi/14418b84d7e3542215e39d74a7680335 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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