You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
5.5 KiB
213 lines
5.5 KiB
#ifndef APP_H
|
|
#define APP_H
|
|
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <cmath>
|
|
#include <array>
|
|
#include <ratio>
|
|
|
|
#include "stfu/stf.hpp"
|
|
#include "pngwriter/pngwriter.h"
|
|
|
|
#include "shader.h"
|
|
#include "fbo.h"
|
|
|
|
static const std::string filenames[] = {
|
|
"resources/attractor_2011-04-28_10-30-35-2.stf",
|
|
"resources/attractor_2011-04-28_10-05-11-1.stf",
|
|
"resources/attractor_2011-04-29_04-34-41-9.stf",
|
|
"resources/attractor_2011-04-29_15-19-03-9.stf" };
|
|
|
|
static const GLfloat quad[] = {
|
|
1.0, 1.0,
|
|
1.0, -1.0,
|
|
-1.0, -1.0,
|
|
-1.0, 1.0 };
|
|
|
|
static const GLfloat tex_quad[] = {
|
|
1.0, 1.0,
|
|
1.0, 0.0,
|
|
0.0, 0.0,
|
|
0.0, 1.0 };
|
|
|
|
class App {
|
|
int counter;
|
|
unsigned int width, height;
|
|
|
|
shader mshader;
|
|
shader clear_shader;
|
|
shader texture_shader;
|
|
shader blur_shader;
|
|
fbo fbo1;
|
|
fbo fbo2;
|
|
|
|
static constexpr size_t number_of_lines = 40000;
|
|
static constexpr size_t number_of_vertices = 2*number_of_lines;
|
|
std::array<GLfloat, 3*number_of_vertices> lines;
|
|
std::array<GLfloat, 7> parameters;
|
|
std::array<GLfloat, 7> random_parameters;
|
|
|
|
public:
|
|
App(unsigned int w, unsigned int h) :
|
|
counter(0),
|
|
width(w),
|
|
height(h),
|
|
mshader("resources/myTeaShader.vert", "resources/myTeaShader.frag"),
|
|
clear_shader("resources/myClearShader.vert", "resources/myClearShader.frag"),
|
|
texture_shader("resources/myTextureShader.vert", "resources/myTextureShader.frag"),
|
|
blur_shader("resources/myHBlurShader.vert", "resources/myHBlurShader.frag"),
|
|
fbo1(width, height),
|
|
fbo2(width, height),
|
|
lines(),
|
|
parameters(),
|
|
random_parameters() {
|
|
|
|
set_points();
|
|
//glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_BLEND);
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
std::string filename = filenames[3];
|
|
set_parameters(filename);
|
|
}
|
|
|
|
~App() {
|
|
}
|
|
|
|
void resize(int w, int h) {
|
|
std::cout << w << "x" << h << std::endl;
|
|
}
|
|
|
|
void update() {
|
|
++counter;
|
|
iterate();
|
|
|
|
if(counter % 5000 == 0) {
|
|
set_parameters(filenames[rand() % 4]);
|
|
set_points();
|
|
}
|
|
}
|
|
|
|
void draw() {
|
|
fbo & read_fbo = (counter % 2) ? fbo1 : fbo2;
|
|
fbo & draw_fbo = (counter % 2) ? fbo2 : fbo1;
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
|
draw_fbo.begin();
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
blur_shader.begin();
|
|
blur_shader.set_uniform("offset", (float) cos(counter) / width, (float) sin(counter) / height);
|
|
if(true){
|
|
blur_shader.set_uniform("fade", 0.75f);
|
|
blur_shader.set_uniform("inter", 0.55f);
|
|
} else {
|
|
blur_shader.set_uniform("fade", 0.96f);
|
|
blur_shader.set_uniform("inter", 0.9f);
|
|
}
|
|
texture(blur_shader, read_fbo);
|
|
mshader.begin();
|
|
glBlendFunc(GL_ONE, GL_ONE);
|
|
scene();
|
|
draw_fbo.end();
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
texture_shader.begin();
|
|
texture(texture_shader, draw_fbo);
|
|
|
|
//if(counter % 4 == 0)
|
|
// save_screen();
|
|
}
|
|
|
|
void fade() {
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glVertexPointer(2, GL_FLOAT, 0, &quad[0]);
|
|
glDrawArrays(GL_QUADS, 0, 4);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void texture(shader const & tex_shader, fbo const & read_fbo) {
|
|
tex_shader.set_texture("tex", GL_TEXTURE_2D, read_fbo.texture_id, 0);
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glVertexPointer(2, GL_FLOAT, 0, &quad[0]);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, &tex_quad[0]);
|
|
glDrawArrays(GL_QUADS, 0, 4);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void scene() {
|
|
mshader.set_uniform("steps", counter/10);
|
|
glRotatef(0.09, std::sin(counter/13370.0), 1.0, 0.0);
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glVertexPointer(3, GL_FLOAT, 0, &lines[0]);
|
|
glPointSize(1.0);
|
|
glDrawArrays(GL_POINTS, 0, number_of_vertices);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void iterate() {
|
|
for(size_t i = 0; i < number_of_lines; ++i) {
|
|
GLfloat* vectorNew = &lines[3*2*i];
|
|
GLfloat* vectorOld = &lines[3*2*i+3];
|
|
if(counter % 2) std::swap(vectorNew, vectorOld);
|
|
|
|
vectorNew[0] = parameters[0]*(vectorOld[2] + parameters[1]);
|
|
vectorNew[1] = parameters[2]*(vectorOld[0] + parameters[3]);
|
|
vectorNew[2] = parameters[4]*(vectorOld[1] + parameters[5]);
|
|
|
|
const double dist = vectorNew[0]*vectorNew[0] + vectorNew[1]*vectorNew[1] + vectorNew[2]*vectorNew[2];
|
|
|
|
if(dist > parameters[6]*parameters[6]) {
|
|
const double sqrtDist = std::sqrt(dist);
|
|
const double p = 1.0 - parameters[6] * (static_cast<int>(sqrtDist / parameters[6]) + 1.0) / sqrtDist;
|
|
vectorNew[0] *= p;
|
|
vectorNew[1] *= p;
|
|
vectorNew[2] *= p;
|
|
}
|
|
}
|
|
|
|
for(size_t i = 0; i < 7; ++i){
|
|
parameters[i] += random_parameters[i];
|
|
}
|
|
}
|
|
|
|
void save_screen(){
|
|
unsigned char data[width*height*6];
|
|
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_SHORT, data);
|
|
|
|
char filename[256];
|
|
sprintf(filename, "render/shot_%08d.png", counter);
|
|
|
|
pngwriter png(width, height, &data[0], filename);
|
|
png.close();
|
|
}
|
|
|
|
void set_parameters(std::string filename){
|
|
stfu::node file;
|
|
file.read(filename.c_str());
|
|
for(unsigned int i = 0; i < 7; ++i) {
|
|
stfu::node const attractorParameters = file.getChild("AttractorKernel").getChild("parameters");
|
|
parameters[i] = atof(attractorParameters.getValue(i).c_str());
|
|
random_parameters[i] = (rand() / (double)RAND_MAX - 0.5) * counter / 5000000.0;
|
|
}
|
|
}
|
|
|
|
void set_points(){
|
|
std::generate(lines.begin(), lines.end(), []() { return 2.0 * rand() / (double)RAND_MAX - 1.0; });
|
|
}
|
|
};
|
|
|
|
#endif // APP_H
|
|
|