cakefoot/src/Cakefoot.cpp

184 lines
6.2 KiB
C++

/* >> Cakefoot << */
#if defined(__ANDROID__) || defined(ANDROID)
#include <android/asset_manager_jni.h>
#endif
#include "Cakefoot.hpp"
Cakefoot::Cakefoot()
{
#ifdef __ANDROID__
SDL_SetHint(SDL_HINT_ORIENTATIONS, "Portrait");
#endif
start_button.scale(0.5f);
start_button.on_state_change([&](bool state, int count){
if (state)
{
std::ostringstream message;
message << "Hello, " << state << " World! " << count;
sb::Log::log(message);
start_button.press(1);
}
});
/* subscribe to command events */
delegate().subscribe(&Cakefoot::respond, this);
delegate().subscribe(&Cakefoot::respond, this, SDL_MOUSEMOTION);
delegate().subscribe(&Cakefoot::respond, this, SDL_MOUSEBUTTONDOWN);
/* loading GL context for 3D */
load_gl_context();
/* Load a pointer cursor from the system library that will be freed automatically */
poke = std::shared_ptr<SDL_Cursor>(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND), SDL_FreeCursor);
}
void Cakefoot::load_gl_context()
{
super::load_gl_context();
/* Generate a vertex array object ID, bind it as current (requirement of OpenGL) */
vao.generate();
vao.bind();
/* Generate ID for the vertex buffer object that will hold all vertex data. Using one buffer for all attributes, data
* will be copied in one after the other. */
vbo.generate();
vbo.bind();
/* Load shader program */
GLuint vertex_shader = load_shader("src/shaders/shader.vert", GL_VERTEX_SHADER);
GLuint fragment_shader = load_shader("src/shaders/shader.frag", GL_FRAGMENT_SHADER);
shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
sb::Plane::position->bind(0, shader_program, "vertex_position");
sb::Plane::uv->bind(1, shader_program, "vertex_uv");
sb::Plane::color->bind(2, shader_program, "vertex_color");
sb::Log::gl_errors("after loading shaders");
/* Fill VBO with attribute data */
vbo.allocate(start_button.size(), GL_STATIC_DRAW);
vbo.add(*sb::Plane::position);
vbo.add(*sb::Plane::uv);
vbo.add(*sb::Plane::color);
sb::Log::gl_errors("after filling VBO");
/* link shaders */
link_shader(shader_program);
glUseProgram(shader_program);
sb::Log::gl_errors("after linking");
/* store uniform locations after linking */
uniform["mvp"] = glGetUniformLocation(shader_program, "mvp");
uniform["time"] = glGetUniformLocation(shader_program, "time");
uniform["effect"] = glGetUniformLocation(shader_program, "effect");
uniform["uv transformation"] = glGetUniformLocation(shader_program, "uv_transformation");
uniform["coordinate bound"] = glGetUniformLocation(shader_program, "coordinate_bound");
uniform["model texture"] = glGetUniformLocation(shader_program, "model_texture");
uniform["texture enabled"] = glGetUniformLocation(shader_program, "texture_enabled");
/* enable alpha rendering */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
sb::Log::gl_errors("after uniform locations");
}
void Cakefoot::respond(SDL_Event& event)
{
/* Mouse interface */
if (event.type == SDL_MOUSEMOTION || event.type == SDL_MOUSEBUTTONDOWN)
{
/* Get mouse coordinates in pixel resolution and NDC */
glm::vec2 mouse_pixel = event.type == SDL_MOUSEBUTTONDOWN ? glm::vec2{event.button.x, event.button.y} :
glm::vec2{event.motion.x, event.motion.y};
glm::vec2 mouse_ndc {
float(mouse_pixel.x) / window_box().width() * 2.0f - 1.0f, (1.0f - float(mouse_pixel.y) / window_box().height()) * 2.0f - 1.0f
};
/* Collide with start button */
bool over_start_button = start_button.collide(mouse_ndc);
/* Check for press */
if (over_start_button)
{
/* Set cursor to pokey finger */
if (SDL_GetCursor() != poke.get())
{
SDL_SetCursor(poke.get());
}
/* Respond to a click */
if (event.type == SDL_MOUSEBUTTONDOWN)
{
/* Reset cursor to default arrow */
// SDL_SetCursor(SDL_GetDefaultCursor());
start_button.press(0);
}
}
else if (SDL_GetCursor() == poke.get())
{
SDL_SetCursor(SDL_GetDefaultCursor());
}
}
else if (sb::Delegate::compare(event, "reset"))
{
sb::Log::log("Goodbye, World!");
}
}
void Cakefoot::destroy_texture(GLuint* texture_id)
{
/* not sure why SDL_Log works here but SDL_LogDebug and SDL_LogInfo don't */
std::ostringstream message;
message << "destroying texture ID " << *texture_id;
sb::Log::log(message);
glDeleteTextures(1, texture_id);
}
void Cakefoot::update()
{
sb::Log::gl_errors("at beginning of update");
/* Time in seconds the game has running for */
float time_seconds = SDL_GetTicks() / 1000.0f;
glDisable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* flat shader uniforms: time, texture ID, disabled HSV blend, scroll on */
glActiveTexture(GL_TEXTURE0);
glUniform1f(uniform["time"], time_seconds);
glUniformMatrix4fv(uniform["mvp"], 1, GL_FALSE, &glm::mat4(1)[0][0]);
/* calculate the transformation matrix for displaying pudding in viewport */
model = glm::rotate(model, 0.0f, Y_UNIT_NORMAL_3D);
projection = glm::perspective(glm::radians(40.0f * 1 / window_box().aspect()), window_box().aspect(), 0.1f, 100.0f);
mvp = projection * VIEW_MATRIX * model;
/* uniforms */
// glUniformMatrix4fv(uniform["mvp"], 1, GL_FALSE, &mvp[0][0]);
/* draw pudding model */
// glEnable(GL_DEPTH_TEST);
/* draws bg vertices and texture */
// cake_model.enable();
start_button.draw(uniform["mvp"], uniform["texture enabled"]);
// glDrawArrays(GL_TRIANGLES, 0, cake_model.attributes("position")->count());
/* Display */
SDL_GL_SwapWindow(window());
sb::Log::gl_errors("at end of update");
}
int main()
{
Cakefoot game = Cakefoot();
game.run();
game.quit();
return 0;
}