186 lines
4.7 KiB
Objective-C
186 lines
4.7 KiB
Objective-C
//
|
|
// 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"
|
|
|
|
#include "myGL.h"
|
|
|
|
using namespace gl; // I know this is bad
|
|
#include "Game.h"
|
|
|
|
#define kWindowWidth 1024
|
|
#define kWindowHeight 768
|
|
|
|
#define kFBOWidth 128
|
|
#define kFBOHeight 128
|
|
|
|
constexpr static const char* attributes[] = {
|
|
"position",
|
|
"normal",
|
|
"color",
|
|
"tex_coord0"
|
|
};
|
|
|
|
struct App {
|
|
constexpr static int preferred_frames_per_second(){ return 60; }
|
|
constexpr static bool multisample(){ return false; }
|
|
constexpr static bool depth(){ return true; }
|
|
|
|
template <size_t N>
|
|
static std::vector<std::string> from_strarray(const char* const (& strs)[N]) {
|
|
std::vector<std::string> v(N);
|
|
for(auto i = 0; i < N; ++i){
|
|
v.push_back(strs[i]);
|
|
}
|
|
return v;
|
|
}
|
|
|
|
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];
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
|
|
Game game;
|
|
|
|
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"), from_strarray(attributes))
|
|
, texture_shader(getPath("textureShader", "vsh"), getPath("textureShader", "fsh"), from_strarray(attributes))
|
|
, effect_shader(getPath("effectShader", "vsh"), getPath("effectShader", "fsh"), from_strarray(attributes))
|
|
, fbo1(kFBOWidth, kFBOHeight)
|
|
, fbo2(kFBOWidth, kFBOHeight)
|
|
, color_transformation(transpose(from_carray(color_transformations[0])), 1.0)
|
|
, game()
|
|
{
|
|
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])));
|
|
|
|
// TEMPORARY:
|
|
game.position.y = -1.0;
|
|
game.speed.y = 0.0;
|
|
}
|
|
|
|
void update(float dt) {
|
|
time += dt;
|
|
game.update(dt);
|
|
|
|
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", time);
|
|
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();
|
|
noise_shader.set_uniform("time", time);
|
|
|
|
GLKMatrix4 p1 = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(80.0f), aspect, 0.01f, 20.0f);
|
|
GLKMatrix4 p2 = GLKMatrix4MakeLookAt(0.0, 0.0, game.position.z + 2.0, 0.0, -2.0, game.position.z - 7.0, 0.0, 1.0, 0.0);
|
|
GLKMatrix4 projectionMatrix = GLKMatrix4Multiply(p1, p2);
|
|
|
|
game.draw(projectionMatrix, noise_shader);
|
|
}
|
|
|
|
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
|