|
@ -14,148 +14,241 @@ |
|
|
#include <memory> |
|
|
#include <memory> |
|
|
#include <cmath> |
|
|
#include <cmath> |
|
|
#include "shader.h" |
|
|
#include "shader.h" |
|
|
|
|
|
#include "fbo.h" |
|
|
|
|
|
#include "interpolator.h" |
|
|
|
|
|
#include "statics.h" |
|
|
|
|
|
|
|
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i)) |
|
|
#define kWindowWidth 1024 |
|
|
|
|
|
#define kWindowHeight 768 |
|
|
|
|
|
|
|
|
struct App { |
|
|
#define kFBOWidth 128 |
|
|
std::unique_ptr<J::shader> program; |
|
|
#define kFBOHeight 128 |
|
|
|
|
|
|
|
|
GLKMatrix4 modelViewProjectionMatrix; |
|
|
|
|
|
GLKMatrix3 normalMatrix; |
|
|
|
|
|
float rotation; |
|
|
|
|
|
float aspect; |
|
|
|
|
|
|
|
|
|
|
|
GLuint vertexArray; |
|
|
struct App { |
|
|
GLuint vertexBuffer; |
|
|
constexpr static int preferred_frames_per_second(){ return 60; } |
|
|
|
|
|
constexpr static bool multisample(){ return false; } |
|
|
App() |
|
|
constexpr static bool depth(){ return true; } |
|
|
: program(nullptr) |
|
|
|
|
|
, modelViewProjectionMatrix({{0}}) |
|
|
|
|
|
, normalMatrix({{0}}) |
|
|
|
|
|
, rotation(0) |
|
|
|
|
|
, aspect(0.75) |
|
|
|
|
|
, vertexArray(0) |
|
|
|
|
|
, vertexBuffer(0) |
|
|
|
|
|
{ |
|
|
|
|
|
std::cout << "APP CONSTRUCTED" << std::endl; |
|
|
|
|
|
glEnable(GL_DEPTH_TEST); |
|
|
|
|
|
|
|
|
|
|
|
// shader
|
|
|
constexpr static std::vector<std::string> get_attributes(){ |
|
|
NSString * vshader_file = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; |
|
|
|
|
|
NSString * fshader_file = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; |
|
|
|
|
|
std::vector<std::string> v; |
|
|
std::vector<std::string> v; |
|
|
v.emplace_back("position"); |
|
|
v.push_back("position"); |
|
|
v.emplace_back("normal"); |
|
|
v.push_back("normal"); |
|
|
program.reset(new J::shader([vshader_file UTF8String], [fshader_file UTF8String], std::move(v))); |
|
|
v.push_back("color"); |
|
|
|
|
|
v.push_back("tex_coord0"); |
|
|
|
|
|
return v; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
constexpr static std::string getPath(std::string name, std::string kind){ |
|
|
|
|
|
return [[[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:name.c_str()] ofType:[NSString stringWithUTF8String:kind.c_str()]] UTF8String]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// vertex-buffer
|
|
|
constexpr static std::array<GLfloat, 16> from_carray(GLfloat const (& v)[16]){ |
|
|
glGenVertexArraysOES(1, &vertexArray); |
|
|
std::array<GLfloat, 16> a; |
|
|
glBindVertexArrayOES(vertexArray); |
|
|
for(int i = 0; i < 16; ++i) a[i] = v[i]; |
|
|
|
|
|
return a; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
glGenBuffers(1, &vertexBuffer); |
|
|
constexpr static std::array<GLfloat, 16> transpose(std::array<GLfloat, 16> const & v){ |
|
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); |
|
|
std::array<GLfloat, 16> a; |
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW); |
|
|
for(int i = 0; i < 4; ++i) |
|
|
|
|
|
for(int j = 0; j < 4; ++j) |
|
|
|
|
|
a[i + 4*j] = v[j + 4*i]; |
|
|
|
|
|
return a; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
glEnableVertexAttribArray(GLKVertexAttribPosition); |
|
|
typedef std::array<GLfloat, 7> Vertex; |
|
|
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); |
|
|
typedef std::array<Vertex, 8> Quad; //degenerate
|
|
|
glEnableVertexAttribArray(GLKVertexAttribNormal); |
|
|
|
|
|
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12)); |
|
|
|
|
|
|
|
|
|
|
|
glBindVertexArrayOES(0); |
|
|
int counter; |
|
|
|
|
|
float time; |
|
|
|
|
|
unsigned int width, height; |
|
|
|
|
|
float aspect; |
|
|
|
|
|
unsigned int color_scheme; |
|
|
|
|
|
|
|
|
|
|
|
J::shader noise_shader; |
|
|
|
|
|
J::shader texture_shader; |
|
|
|
|
|
J::shader effect_shader; |
|
|
|
|
|
J::fbo fbo1; |
|
|
|
|
|
J::fbo fbo2; |
|
|
|
|
|
|
|
|
|
|
|
J::interpolator<std::array<GLfloat, 16>> color_transformation; |
|
|
|
|
|
|
|
|
|
|
|
std::vector<Quad> quads; |
|
|
|
|
|
|
|
|
|
|
|
App(float w, float h) |
|
|
|
|
|
: counter(0) |
|
|
|
|
|
, time(0) |
|
|
|
|
|
, width(w) |
|
|
|
|
|
, height(h) |
|
|
|
|
|
, aspect(w/h) |
|
|
|
|
|
, color_scheme(0) |
|
|
|
|
|
, noise_shader(getPath("teaShader", "vsh"), getPath("teaShader", "fsh"), get_attributes()) |
|
|
|
|
|
, texture_shader(getPath("textureShader", "vsh"), getPath("textureShader", "fsh"), get_attributes()) |
|
|
|
|
|
, effect_shader(getPath("effectShader", "vsh"), getPath("effectShader", "fsh"), get_attributes()) |
|
|
|
|
|
, fbo1(kFBOWidth, kFBOHeight) |
|
|
|
|
|
, fbo2(kFBOWidth, kFBOHeight) |
|
|
|
|
|
, color_transformation(transpose(from_carray(color_transformations[0])), 1.0) |
|
|
|
|
|
{ |
|
|
|
|
|
make_quads(); |
|
|
|
|
|
glEnable(GL_DEPTH_TEST); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
~App(){ |
|
|
~App() { |
|
|
glDeleteBuffers(1, &vertexBuffer); |
|
|
|
|
|
glDeleteVertexArraysOES(1, &vertexArray); |
|
|
|
|
|
std::cout << "APP DESTRUCTED" << std::endl; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void resize(float width, float height){ |
|
|
void resize(float w, float h) { |
|
|
aspect = std::abs(width/height); |
|
|
aspect = std::abs(w/h); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void update(float dt){ |
|
|
void change_color(){ |
|
|
// projection matrix (perspective)
|
|
|
++color_scheme %= colors; |
|
|
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); |
|
|
color_transformation.set_value(transpose(from_carray(color_transformations[color_scheme]))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// model matrix (rotation)
|
|
|
void make_quads(){ |
|
|
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); |
|
|
quads.reserve(number_of_quads); |
|
|
baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, rotation, 0.0f, 1.0f, 0.0f); |
|
|
for(int yy = 0; yy < level_height; ++yy){ |
|
|
|
|
|
for(int xx = 0; xx < level_width; ++xx){ |
|
|
|
|
|
if(level[xx + level_width*yy] == 0) continue; |
|
|
|
|
|
const double size = 1.0; |
|
|
|
|
|
|
|
|
|
|
|
double x = xx - (int)level_width/2; |
|
|
|
|
|
double z = -5.0 -level_height + yy; |
|
|
|
|
|
double y = -1.0; |
|
|
|
|
|
|
|
|
|
|
|
Quad q; |
|
|
|
|
|
|
|
|
|
|
|
// deg.
|
|
|
|
|
|
q[0][0] = x - size*0.5; |
|
|
|
|
|
q[0][1] = y; |
|
|
|
|
|
q[0][2] = z - size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
q[1][0] = x - size*0.5; |
|
|
|
|
|
q[1][1] = y; |
|
|
|
|
|
q[1][2] = z - size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
// real quad
|
|
|
|
|
|
q[2][0] = x - size*0.5; |
|
|
|
|
|
q[2][1] = y; |
|
|
|
|
|
q[2][2] = z - size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
q[3][0] = x - size*0.5; |
|
|
|
|
|
q[3][1] = y; |
|
|
|
|
|
q[3][2] = z + size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
q[4][0] = x + size*0.5; |
|
|
|
|
|
q[4][1] = y; |
|
|
|
|
|
q[4][2] = z - size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
q[5][0] = x + size*0.5; |
|
|
|
|
|
q[5][1] = y; |
|
|
|
|
|
q[5][2] = z + size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
// deg.
|
|
|
|
|
|
q[6][0] = x + size*0.5; |
|
|
|
|
|
q[6][1] = y; |
|
|
|
|
|
q[6][2] = z + size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
q[7][0] = x + size*0.5; |
|
|
|
|
|
q[7][1] = y; |
|
|
|
|
|
q[7][2] = z + size*0.5; |
|
|
|
|
|
|
|
|
|
|
|
//double r = rand() / (double) RAND_MAX;
|
|
|
|
|
|
//double g = rand() / (double) RAND_MAX;
|
|
|
|
|
|
//double b = rand() / (double) RAND_MAX;
|
|
|
|
|
|
|
|
|
|
|
|
for(auto& v : q){ |
|
|
|
|
|
v[3] = (x + 2.0) / 5.0; |
|
|
|
|
|
v[4] = 0.5; |
|
|
|
|
|
v[5] = (yy < level_height && yy > level_height - 7)? 1.0 : 0.0; |
|
|
|
|
|
v[6] = 1.0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
quads.push_back(q); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f); |
|
|
void update(float dt) { |
|
|
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, rotation, 1.0f, 1.0f, 1.0f); |
|
|
time += dt; |
|
|
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix); |
|
|
for(auto& q : quads){ |
|
|
|
|
|
for(auto& v : q){ |
|
|
|
|
|
v[2] += dt * 7.0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(q[0][2] > 10.0) { |
|
|
|
|
|
for(auto& v : q){ |
|
|
|
|
|
v[2] -= level_height; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
color_transformation.interpolate(dt); |
|
|
|
|
|
|
|
|
|
|
|
// Update the FBO's here
|
|
|
|
|
|
// (can't be done in draw, because of apple's fbo shizzle)
|
|
|
|
|
|
fbo1.begin(); |
|
|
|
|
|
scene(); |
|
|
|
|
|
fbo1.end(); |
|
|
|
|
|
|
|
|
|
|
|
fbo2.begin(); |
|
|
|
|
|
effects(fbo1); |
|
|
|
|
|
fbo2.end(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// setting stuff for later use in the shader
|
|
|
void draw() { |
|
|
normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); |
|
|
glClearColor(0.0, 0.0, 0.0, 0.0); |
|
|
modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); |
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
|
|
|
|
|
|
// time update
|
|
|
texture_shader.begin(); |
|
|
rotation += dt * 0.5f; |
|
|
texture_shader.set_uniform("color_transformation", color_transformation, GL_FALSE); |
|
|
|
|
|
texture(texture_shader, fbo2); |
|
|
|
|
|
texture_shader.end(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void draw(){ |
|
|
void effects(J::fbo& read_fbo){ |
|
|
// clear
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0); |
|
|
float red = rand() / (float)RAND_MAX; |
|
|
|
|
|
glClearColor(red, 0.65f, 0.65f, 1.0f); |
|
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
|
|
|
|
|
|
// bind and set up
|
|
|
effect_shader.begin(); |
|
|
glBindVertexArrayOES(vertexArray); |
|
|
effect_shader.set_uniform("time", counter * counter * 0.00001f); |
|
|
|
|
|
texture(effect_shader, read_fbo); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
program->begin(); |
|
|
void scene(){ |
|
|
program->set_uniform("modelViewProjectionMatrix", modelViewProjectionMatrix.m, 0); |
|
|
glClearColor(0.0, 0.0, 0.0, 0.0); |
|
|
program->set_uniform("normalMatrix", normalMatrix.m, 0); |
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
|
|
|
|
|
|
|
|
// draw
|
|
|
noise_shader.begin(); |
|
|
glDrawArrays(GL_TRIANGLES, 0, 36); |
|
|
|
|
|
|
|
|
GLKMatrix4 p1 = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(80.0f), aspect, 0.01f, 20.0f); |
|
|
|
|
|
GLKMatrix4 p2 = GLKMatrix4MakeLookAt(0.0, 0.0, 9.0, 0.0, -2.0, 0.0, 0.0, 1.0, 0.0); |
|
|
|
|
|
GLKMatrix4 projectionMatrix = GLKMatrix4Multiply(p1, p2); |
|
|
|
|
|
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity; |
|
|
|
|
|
GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); |
|
|
|
|
|
GLKMatrix3 normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); |
|
|
|
|
|
noise_shader.set_uniform("modelViewProjectionMatrix", modelViewProjectionMatrix.m, 0); |
|
|
|
|
|
noise_shader.set_uniform("normalMatrix", normalMatrix.m, 0); |
|
|
|
|
|
|
|
|
|
|
|
noise_shader.set_uniform("time", time); |
|
|
|
|
|
noise_shader.set_attribute("position", 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &quads[0][0][0]); |
|
|
|
|
|
noise_shader.set_attribute("color", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &quads[0][0][3]); |
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, quads.size()*8); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
constexpr GLfloat gCubeVertexData[216] = { |
|
|
void texture(J::shader const & tex_shader, J::fbo const & read_fbo) { |
|
|
// Data layout for each line below is:
|
|
|
tex_shader.set_texture("tex", GL_TEXTURE_2D, read_fbo.texture_id, 0); |
|
|
// positionX, positionY, positionZ, normalX, normalY, normalZ,
|
|
|
|
|
|
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
|
|
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
|
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, |
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
|
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, |
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
|
|
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, |
|
|
|
|
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, |
|
|
tex_shader.set_attribute("position", 2, GL_FLOAT, GL_FALSE, 0, &quad[0]); |
|
|
|
|
|
tex_shader.set_attribute("tex_coord0", 2, GL_FLOAT, GL_FALSE, 0, &tex_quad[0]); |
|
|
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, |
|
|
|
|
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, |
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
|
|
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, |
|
|
} |
|
|
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, |
|
|
|
|
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, |
|
|
|
|
|
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, |
|
|
|
|
|
|
|
|
|
|
|
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, |
|
|
|
|
|
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, |
|
|
|
|
|
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, |
|
|
|
|
|
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, |
|
|
|
|
|
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, |
|
|
|
|
|
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, |
|
|
|
|
|
|
|
|
|
|
|
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, |
|
|
|
|
|
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, |
|
|
|
|
|
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, |
|
|
|
|
|
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, |
|
|
|
|
|
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, |
|
|
|
|
|
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, |
|
|
|
|
|
|
|
|
|
|
|
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
|
|
|
|
|
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
|
|
|
|
|
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
|
|
|
|
|
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
|
|
|
|
|
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
|
|
|
|
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, |
|
|
|
|
|
|
|
|
|
|
|
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, |
|
|
|
|
|
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, |
|
|
|
|
|
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, |
|
|
|
|
|
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, |
|
|
|
|
|
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, |
|
|
|
|
|
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f |
|
|
|
|
|
}; |
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|