The prototype of Zen Zoom. Made on ubuntu, I guess.
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 

171 lines
4.0 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" };
class App {
int counter;
unsigned int width, height;
shader mshader;
shader clear_shader;
fbo mfbo;
static constexpr size_t number_of_lines = 6*50000;
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"),
mfbo(width, height) {
set_points();
//glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glPointSize(1.0);
std::string filename = filenames[3];
set_parameters(filename);
}
~App() {
}
void resize(int w, int h) {
}
void update() {
++counter;
iterate();
if(counter % 500 == 0) {
set_parameters(filenames[rand() % 4]);
set_points();
}
}
void draw() {
clear_shader.begin();
clear_shader.set_uniform("fade", .5f);
if( counter < 5 )
clear_shader.set_uniform("fade", 1.0f);
fade();
mshader.begin();
mshader.set_uniform("steps", counter);
glRotatef(0.5, std::sin(counter/1337.0), 1.0, 0.0);
scene();
}
void fade() {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
static const GLfloat quad[] = {
1.0, 1.0,
1.0, -1.0,
-1.0, -1.0,
-1.0, 1.0 };
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, &quad[0]);
// draw a cube
glDrawArrays(GL_QUADS, 0, 4);
// deactivate vertex arrays after drawing
glDisableClientState(GL_VERTEX_ARRAY);
}
void scene() {
glBlendFunc(GL_ONE, GL_ONE);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, &lines[0]);
// draw a cube
glDrawArrays(GL_POINTS, 0, number_of_vertices);
// deactivate vertex arrays after drawing
glDisableClientState(GL_VERTEX_ARRAY);
//save_screen();
}
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 / 500000.0;
}
}
void set_points(){
std::generate(lines.begin(), lines.end(), []() { return 2.0 * rand() / (double)RAND_MAX - 1.0; });
}
};
#endif // APP_H