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.
254 lines
6.6 KiB
254 lines
6.6 KiB
//
|
|
// App.h
|
|
// GLGameTemplate
|
|
//
|
|
// Created by Joshua Moerman on 5/4/12.
|
|
// Copyright (c) 2012 Vadovas. All rights reserved.
|
|
//
|
|
|
|
#ifndef GLGameTemplate_App_h
|
|
#define GLGameTemplate_App_h
|
|
|
|
#import <GLKit/GLKit.h>
|
|
|
|
#include <memory>
|
|
#include <cmath>
|
|
#include "shader.h"
|
|
#include "fbo.h"
|
|
#include "interpolator.h"
|
|
#include "statics.h"
|
|
|
|
#define kWindowWidth 1024
|
|
#define kWindowHeight 768
|
|
|
|
#define kFBOWidth 128
|
|
#define kFBOHeight 128
|
|
|
|
struct App {
|
|
constexpr static int preferred_frames_per_second(){ return 60; }
|
|
constexpr static bool multisample(){ return false; }
|
|
constexpr static bool depth(){ return true; }
|
|
|
|
constexpr static std::vector<std::string> get_attributes(){
|
|
std::vector<std::string> v;
|
|
v.push_back("position");
|
|
v.push_back("normal");
|
|
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];
|
|
}
|
|
|
|
constexpr static std::array<GLfloat, 16> from_carray(GLfloat const (& v)[16]){
|
|
std::array<GLfloat, 16> a;
|
|
for(int i = 0; i < 16; ++i) a[i] = v[i];
|
|
return a;
|
|
}
|
|
|
|
constexpr static std::array<GLfloat, 16> transpose(std::array<GLfloat, 16> const & v){
|
|
std::array<GLfloat, 16> a;
|
|
for(int i = 0; i < 4; ++i)
|
|
for(int j = 0; j < 4; ++j)
|
|
a[i + 4*j] = v[j + 4*i];
|
|
return a;
|
|
}
|
|
|
|
typedef std::array<GLfloat, 7> Vertex;
|
|
typedef std::array<Vertex, 8> Quad; //degenerate
|
|
|
|
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() {
|
|
}
|
|
|
|
void resize(float w, float h) {
|
|
aspect = std::abs(w/h);
|
|
}
|
|
|
|
void change_color(){
|
|
++color_scheme %= colors;
|
|
color_transformation.set_value(transpose(from_carray(color_transformations[color_scheme])));
|
|
}
|
|
|
|
void make_quads(){
|
|
quads.reserve(number_of_quads);
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
void update(float dt) {
|
|
time += dt;
|
|
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();
|
|
}
|
|
|
|
void draw() {
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
texture_shader.begin();
|
|
texture_shader.set_uniform("color_transformation", color_transformation, GL_FALSE);
|
|
texture(texture_shader, fbo2);
|
|
texture_shader.end();
|
|
}
|
|
|
|
void effects(J::fbo& read_fbo){
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
effect_shader.begin();
|
|
effect_shader.set_uniform("time", counter * counter * 0.00001f);
|
|
texture(effect_shader, read_fbo);
|
|
}
|
|
|
|
void scene(){
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
noise_shader.begin();
|
|
|
|
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);
|
|
}
|
|
|
|
void texture(J::shader const & tex_shader, J::fbo const & read_fbo) {
|
|
tex_shader.set_texture("tex", GL_TEXTURE_2D, read_fbo.texture_id, 0);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
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]);
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
}
|
|
};
|
|
|
|
#endif
|
|
|