A sky roads like game with interesting shaders
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.
 
 
 
 

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