Core now uses a state stack. States may be pushed on the stack with Core::pushState(State*) and popped off with Core::popState(). Pushing a state will trigger the old state's onCede(), push the state onto the stack, then call the new state's onInit(if DID_INIT is not set) then onRise(). Popping a state will trigger the top state's onCede and the previous state(if it exists)'s onRise. Core::doProcess now has a delta tickrate accumulator that ensures the world is processed at Core::tick_rate. Rendering is not capped to this tickrate, as doRender is called outside of the Event handling and state processing. Finally, functionality that was in Core for testing is now in TestState - it pushed onto the stack during Core::initSystem
parent
685c28891e
commit
a567769fcf
1
GUI
1
GUI
|
@ -26,6 +26,7 @@ Live Game/Editor Design
|
|||
--------
|
||||
As the campaign master, at the top of the screen(top-right?) you can press on map editor controls to bring up the editing toolbar. This toolbar has:
|
||||
* Toggle terrain modifier (mountain icon)
|
||||
* Switch between map layers
|
||||
* Create map token (icon of a tree with a star?)
|
||||
* maybe "add token to <layer>"
|
||||
* Create new token (icon of token with a star or something on the top-right)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
Program Order
|
||||
````````````````
|
||||
This file is improperly named.
|
||||
|
||||
Regardless, this file is intended to outline some organization of the program and how Events are passed and handled between sections of the program.
|
||||
|
||||
Core
|
||||
accumulator loop {
|
||||
* handle Events
|
||||
* handle System events (resize, etc.)
|
||||
* handle User Input
|
||||
- first, send to Gui() subsystem to:
|
||||
- check for mouse/touch events that collide with an element
|
||||
- second, send to top-most State for processing
|
||||
* handle Net
|
||||
* receive data
|
||||
- handle low-level things such as ping, disconnect, etc.
|
||||
- high-level things are added to cache for further processing by top-most State
|
||||
* send data
|
||||
- handle low-level responses if needed
|
||||
- send out high-level commands
|
||||
* process top State
|
||||
}
|
||||
* render
|
||||
* renderScene to FBO
|
||||
* GUI renderScene to same FBO
|
||||
|
|
@ -14,7 +14,7 @@ CXXFLAGS+=$(DEBUG) -Wall `sdl2-config --cflags` -I../../src -I../../src/states -
|
|||
LDFLAGS+= -Wall -L../../../sdl/$(LIB_DIR) -Wl,-rpath=$(LIB_DIR)/ -lSDL2 -lpthread -Wl,--no-undefined -lm -ldl -pthread -lrt -Wl,-Bstatic -lGLEW -Wl,-Bdynamic -lGL
|
||||
VPATH=../../src
|
||||
BINARY=RtB$(BITS)
|
||||
OBJ=main.o Asset.o AssetCache.o AssetManager.o Core.o fio.o checksum.o Log.o Quat.o Mat4.o Vec.o Mesh.o Program.o RenderScene.o RenderSet.o RenderObject.o RenderCamera.o RenderView.o states/MenuState.o
|
||||
OBJ=main.o Asset.o AssetCache.o AssetManager.o Core.o fio.o checksum.o Log.o Quat.o Mat4.o Vec.o Mesh.o Program.o RenderScene.o RenderSet.o RenderObject.o RenderCamera.o RenderView.o states/TestState.o states/MenuState.o
|
||||
OBJ_DIR=obj
|
||||
|
||||
$(BINARY): $(patsubst %,$(OBJ_DIR)/%,$(OBJ))
|
||||
|
|
|
@ -17,6 +17,8 @@ Files may be added to the Cache through the following manners:
|
|||
Beyond the File Cache, there is the Live Cache. This cache is the current list of loaded Assets. These Live Caches are generally loaded from and saved to a Campaign.
|
||||
|
||||
================================================================ */
|
||||
#ifndef ASSETMANAGER_HPP
|
||||
#define ASSETMANAGER_HPP
|
||||
#include "AssetCache.hpp"
|
||||
#include "Asset.hpp"
|
||||
#include "fio.hpp"
|
||||
|
@ -41,4 +43,5 @@ class AssetManager {
|
|||
Asset null_asset; // Special null asset to return from loadAsset if it could not be found
|
||||
std::vector<AssetCache*> caches; // Caches
|
||||
AssetCache live_cache; // Cache of loaded assets
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
|
263
src/Core.cpp
263
src/Core.cpp
|
@ -9,7 +9,9 @@ Core is somewhat like a service locator, but with larger engine capabilities - i
|
|||
#include "RenderCamera.hpp"
|
||||
#include "RenderSet.hpp"
|
||||
#include "RenderObject.hpp"
|
||||
#include "State.hpp"
|
||||
#include "MenuState.hpp"
|
||||
#include "TestState.hpp"
|
||||
|
||||
Core core;
|
||||
|
||||
|
@ -22,6 +24,29 @@ Core::Core() {
|
|||
}
|
||||
Core::~Core() {
|
||||
}
|
||||
int Core::pushState(State *state) {
|
||||
if (states.size() > 0) {
|
||||
states.back()->onCede();
|
||||
}
|
||||
states.push_back(state);
|
||||
if (!(state->flags & State::DID_INIT)) {
|
||||
state->onInit();
|
||||
}
|
||||
state->onRise();
|
||||
return 0;
|
||||
}
|
||||
int Core::popState() {
|
||||
if (states.size() > 0) {
|
||||
State *state = states.back();
|
||||
state->onCede();
|
||||
delete state; // FIXME: this should be handled elsewhere, as popping should not necessarily destroy the state
|
||||
}
|
||||
states.pop_back();
|
||||
if (states.size() > 0) {
|
||||
states.back()->onCede();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int Core::initSystem() {
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC) != 0) {
|
||||
LOG(LOG_ERROR) << FUNC_NAME << " " << SDL_GetError();
|
||||
|
@ -74,10 +99,6 @@ int Core::initSystem() {
|
|||
// enable back-face culling
|
||||
//glEnable(GL_CULL_FACE);
|
||||
LOG(LOG_INFO) << "OpenGL Renderer: " << glGetString(GL_RENDERER) << "\nOpenGL Version: " << glGetString(GL_VERSION) << "\nGLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
// FIXME: temporary location for adding cameras/etc. for testing
|
||||
// Create our basic RenderScene
|
||||
scene = new RenderScene();
|
||||
// TEMP: this should be assigned elsewhere.
|
||||
asset_manager = new AssetManager();
|
||||
// TODO: load APP cache as first cache (using ApkAssetCache in the case of Android)
|
||||
#ifdef __ANDROID__
|
||||
|
@ -98,120 +119,18 @@ int Core::initSystem() {
|
|||
// TODO: load USER cache as second
|
||||
// TODO: add others via user pref?
|
||||
|
||||
// TEMP: our framebuffer rendering program
|
||||
Program *program = new Program();
|
||||
// FIXME: check for GLSL version and automagically load the appropriate shader file
|
||||
#ifdef HAVE_OPENGLES
|
||||
Asset *shader_asset = asset_manager->loadFile("shaders/fb_fs.100.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/fb_vs.100.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
// TEMP: our model rendering program
|
||||
Program *program_model = new Program();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_fs.100.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_vs.100.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shdaer!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program_model->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
Asset *shader_asset = asset_manager->loadFile("shaders/fb_fs.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/fb_vs.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
// TEMP: our model rendering program
|
||||
Program *program_model = new Program();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_fs.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_vs.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program_model->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
RenderCamera *camera = new RenderCamera();
|
||||
camera->setRenderView(new RenderView(v_width, v_height));
|
||||
camera->updateProjection(v_width, v_height);
|
||||
camera->setPitch(80.0f);
|
||||
camera->setPosition(0, 30, 0);
|
||||
camera->doRefresh();
|
||||
|
||||
scene->addCamera(camera);
|
||||
|
||||
program->attachTexture(0, camera->getRenderView()->getTex());
|
||||
|
||||
(camera->getRenderView()->setProgram(program));
|
||||
|
||||
RenderSet *sert = new RenderSet();
|
||||
sert->setProgram(program_model);
|
||||
|
||||
Asset *asset_mesh;
|
||||
|
||||
RenderObject *objerct = new RenderObject();
|
||||
asset_mesh = asset_manager->loadFile("models/cube.obj");
|
||||
Mesh *mersh = new Mesh(asset_mesh->getData(), asset_mesh->getDataLength());
|
||||
asset_mesh->unloadData();
|
||||
mersh->buildMesh();
|
||||
objerct->setMesh(mersh);
|
||||
sert->addObject(objerct);
|
||||
|
||||
objerct = new RenderObject();
|
||||
asset_mesh = asset_manager->loadFile("models/chest.obj");
|
||||
mersh = new Mesh(asset_mesh->getData(), asset_mesh->getDataLength());
|
||||
asset_mesh->unloadData();
|
||||
mersh->buildMesh();
|
||||
objerct->setMesh(mersh);
|
||||
objerct->setTranslation(-5.0f, 0.0f, 5.0f);
|
||||
objerct->calcMatrix();
|
||||
sert->addObject(objerct);
|
||||
|
||||
scene->addSet(sert);
|
||||
|
||||
// FIXME: temporary location for adding cameras/etc. for testing
|
||||
// Create our basic RenderScene
|
||||
scene = new RenderScene();
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
tick_rate = 10;
|
||||
tick_current = tick_last = SDL_GetTicks();
|
||||
tick_delta = 0;
|
||||
tick_accumulator = tick_rate;
|
||||
|
||||
pushState(new TestState());
|
||||
|
||||
flags |= IS_RUNNING;
|
||||
return 0;
|
||||
}
|
||||
|
@ -231,81 +150,41 @@ int Core::closeSystem() {
|
|||
*/
|
||||
void Core::doProcess() {
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
flags &= ~IS_RUNNING;
|
||||
} else if (event.type == SDL_WINDOWEVENT) {
|
||||
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
v_width = event.window.data1;
|
||||
v_height = event.window.data2;
|
||||
LOG(LOG_INFO) << "Resized to " << v_width << "x" << v_height;
|
||||
RenderCamera *r_camera;
|
||||
RenderView *r_view;
|
||||
std::vector<RenderCamera*>::iterator camera_it, camera_end;
|
||||
for (camera_it = scene->getCameras()->begin(), camera_end = scene->getCameras()->end(); camera_it != camera_end; ++camera_it) {
|
||||
r_camera = *camera_it;
|
||||
if ((r_view = r_camera->getRenderView()) == NULL) continue;
|
||||
r_camera->updateProjection(v_width, v_height);
|
||||
r_view->setView(v_width, v_height);
|
||||
tick_last = tick_current;
|
||||
tick_current = SDL_GetTicks();
|
||||
tick_delta = tick_current - tick_last;
|
||||
tick_accumulator += tick_delta;
|
||||
while (tick_accumulator >= tick_rate) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
flags &= ~IS_RUNNING;
|
||||
} else if (event.type == SDL_WINDOWEVENT) {
|
||||
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
v_width = event.window.data1;
|
||||
v_height = event.window.data2;
|
||||
LOG(LOG_INFO) << "Resized to " << v_width << "x" << v_height;
|
||||
RenderCamera *r_camera;
|
||||
RenderView *r_view;
|
||||
std::vector<RenderCamera*>::iterator camera_it, camera_end;
|
||||
for (camera_it = scene->getCameras()->begin(), camera_end = scene->getCameras()->end(); camera_it != camera_end; ++camera_it) {
|
||||
r_camera = *camera_it;
|
||||
if ((r_view = r_camera->getRenderView()) == NULL) continue;
|
||||
r_camera->updateProjection(v_width, v_height);
|
||||
r_view->setView(v_width, v_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (event.type == SDL_MULTIGESTURE) {
|
||||
LOG(LOG_INFO) << "gesture: " << event.mgesture.x << "x" << event.mgesture.y << ", rot:" << event.mgesture.dTheta << ", pinch:" << event.mgesture.dDist << ", fingers:" << event.mgesture.numFingers;
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
camera_pos.y -= event.mgesture.dDist*256.0f;
|
||||
camera->setPosition(camera_pos.x, camera_pos.y, camera_pos.z);
|
||||
float yaw = camera->getYaw();
|
||||
camera->setYaw(yaw - (event.mgesture.dTheta*128.0f));
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_FINGERMOTION) {
|
||||
LOG(LOG_INFO) << "finger: " << event.tfinger.fingerId << " " << event.tfinger.x << "x" << event.tfinger.y << " " << event.tfinger.dx << "x" << event.tfinger.dy;
|
||||
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
float x = event.tfinger.dx * v_width/16;
|
||||
float y = event.tfinger.dy * v_height/16;
|
||||
|
||||
// This is weird.
|
||||
float yaw = camera->getYaw() * M_PI / 180.0f;
|
||||
float ax = (-x * cosf(yaw)) + (y * sinf(yaw));
|
||||
float ay = (y * cosf(yaw)) - (-x * sinf(yaw));
|
||||
|
||||
camera->setPosition(camera_pos.x+ax, camera_pos.y, camera_pos.z+ay);
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_MOUSEMOTION) {
|
||||
if (event.motion.which == SDL_TOUCH_MOUSEID) continue;
|
||||
LOG(LOG_INFO) << "mouse motion: " << event.motion.xrel << "x" << event.motion.yrel << " ";
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
if (event.motion.state & SDL_BUTTON_MMASK) {
|
||||
camera->setYaw(camera->getYaw() - event.motion.xrel);
|
||||
} else if (event.motion.state & SDL_BUTTON_RMASK) {
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
float x = (float)event.motion.xrel / (v_width/50);
|
||||
float y = (float)event.motion.yrel / (v_height/50);
|
||||
// This is weird. (again)
|
||||
float yaw = camera->getYaw() * M_PI / 180.0f;
|
||||
float ax = (-x * cosf(yaw)) + (y * sinf(yaw));
|
||||
float ay = (y * cosf(yaw)) - (-x * sinf(yaw));
|
||||
camera->setPosition(camera_pos.x+ax, camera_pos.y, camera_pos.z+ay);
|
||||
}
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_MOUSEWHEEL) {
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
camera_pos.y -= event.wheel.y;
|
||||
camera->setPosition(camera_pos.x, camera_pos.y, camera_pos.z);
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_KEYUP) {
|
||||
if (event.key.keysym.sym == SDLK_SPACE) {
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
if (camera->getRenderMode() == 0) {
|
||||
camera->setRenderMode(1);
|
||||
} else {
|
||||
camera->setRenderMode(0);
|
||||
} else {
|
||||
if (states.size() > 0) {
|
||||
State *state = states.back();
|
||||
state->onEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (states.size() > 0) {
|
||||
State *state = states.back();
|
||||
state->doProcess(tick_rate);
|
||||
}
|
||||
tick_accumulator -= tick_rate;
|
||||
}
|
||||
doRender();
|
||||
}
|
||||
|
@ -342,9 +221,19 @@ void Core::doRender() {
|
|||
// And update!
|
||||
SDL_GL_SwapWindow(v_window);
|
||||
}
|
||||
RenderScene* Core::getScene() {
|
||||
// TODO: Should there be a RenderSceneNull class?
|
||||
return scene;
|
||||
}
|
||||
SDL_Window* Core::getWindow() {
|
||||
return v_window;
|
||||
}
|
||||
int Core::getWidth() {
|
||||
return v_width;
|
||||
}
|
||||
int Core::getHeight() {
|
||||
return v_height;
|
||||
}
|
||||
AssetManager* Core::getAssetManager() {
|
||||
return asset_manager;
|
||||
}
|
||||
|
|
10
src/Core.hpp
10
src/Core.hpp
|
@ -26,6 +26,10 @@ class Core {
|
|||
// Audio* getAudio();
|
||||
// Net* getNet();
|
||||
// Gui* getGui();
|
||||
int pushState(State *state);
|
||||
int popState();
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
unsigned int flags; // Core state flags
|
||||
private:
|
||||
SDL_Window *v_window; // Our window
|
||||
|
@ -39,6 +43,12 @@ class Core {
|
|||
std::vector<State*> states; // our record of states
|
||||
// Audio *audio_service;
|
||||
// Net *net_service;
|
||||
//
|
||||
unsigned int tick_rate; // our tickrate
|
||||
unsigned int tick_accumulator;// our tickrate accumulator
|
||||
unsigned int tick_last; // our last tickstamp
|
||||
unsigned int tick_current; // our current tickstamp
|
||||
unsigned int tick_delta; // delta between current and last
|
||||
};
|
||||
extern Core core;
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@ RenderCamera::RenderCamera() {
|
|||
pitch = yaw = 0;
|
||||
render_mode = 0;
|
||||
flags = 0;
|
||||
render_flags = CLEAR_DEPTH | CLEAR_COLOR;
|
||||
width = height = 1;
|
||||
render_view = NULL;
|
||||
}
|
||||
|
@ -97,6 +98,9 @@ void RenderCamera::setYaw(float yaw_) {
|
|||
yaw = yaw_;
|
||||
flags |= DIRTY;
|
||||
}
|
||||
void RenderCamera::setRenderFlags(int r_flags) {
|
||||
render_flags = r_flags;
|
||||
}
|
||||
/* ======== Getter functions ======== */
|
||||
RenderView* RenderCamera::getRenderView() {
|
||||
return render_view;
|
||||
|
@ -119,3 +123,6 @@ Mat4 RenderCamera::getModelview() {
|
|||
int RenderCamera::getRenderMode() {
|
||||
return render_mode;
|
||||
}
|
||||
int RenderCamera::getRenderFlags() {
|
||||
return render_flags;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@ class RenderCamera {
|
|||
enum Flags {
|
||||
DIRTY = (1 << 1)
|
||||
};
|
||||
enum RenderFlags {
|
||||
CLEAR_COLOR = (1 << 1), // clear the render FBO's color when this camera is rendered with
|
||||
CLEAR_DEPTH = (1 << 2) // clear the render FBO's depth
|
||||
};
|
||||
int setRenderView(RenderView *view);
|
||||
RenderView* getRenderView();
|
||||
void updateProjection(int width, int height);
|
||||
|
@ -36,7 +40,9 @@ class RenderCamera {
|
|||
void setYaw(float yaw);
|
||||
float getSize();
|
||||
Mat4 getModelview();
|
||||
private:
|
||||
void setRenderFlags(int r_flags);
|
||||
int getRenderFlags();
|
||||
protected:
|
||||
int render_mode; // 0 = perspective, 1 = orthogonal
|
||||
Vec3 position; // The camera's coordinates in 3D space
|
||||
float pitch, yaw; // The camera's basic orientation
|
||||
|
@ -48,5 +54,6 @@ class RenderCamera {
|
|||
Mat4 p_matrix; // Our camera's projection matrix
|
||||
Mat4 mv_matrix; // modelview matrix
|
||||
int flags; // set flags, such as DIRTY
|
||||
int render_flags; // set flags for rendering
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -66,7 +66,8 @@ int RenderScene::doRender() {
|
|||
if ((view = camera->getRenderView()) == NULL) continue; // bail if camera has no rendering target
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, view->fbo);
|
||||
glViewport(0, 0, view->w, view->h);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
if (camera->render_flags & RenderCamera::CLEAR_DEPTH) glClear(GL_DEPTH_BUFFER_BIT);
|
||||
if (camera->render_flags & RenderCamera::CLEAR_COLOR) glClear(GL_COLOR_BUFFER_BIT);
|
||||
// Iterate over the scene's render sets
|
||||
std::vector<RenderSet*>::iterator set_it, set_end;
|
||||
for (set_it = sets.begin(), set_end = sets.end(); set_it != set_end; ++set_it) {
|
||||
|
|
|
@ -7,17 +7,40 @@ A State is, as indicated by the name, a collection of data and functionality tha
|
|||
================================================================ */
|
||||
#ifndef STATE_HPP
|
||||
#define STATE_HPP
|
||||
#include "SDL.h"
|
||||
#include <vector>
|
||||
class State {
|
||||
friend class Core;
|
||||
public:
|
||||
State() {};
|
||||
~State() {};
|
||||
State() { flags = 0; };
|
||||
virtual ~State() {};
|
||||
protected:
|
||||
virtual float doProcess(float delta) { return 0.0f; };
|
||||
/* doProcess
|
||||
This function is called from Core and is where the processing logic of the State should go. It takes a parameter that is the number of ticks that have passed. This value is equal to core.tick_rate as the processing loop is managed within an accumulator.
|
||||
*/
|
||||
virtual int doProcess(unsigned int ticks) { return 0; };
|
||||
/* onEvent
|
||||
onEvent receives most SDL_Event events that are sent to Core.
|
||||
*/
|
||||
virtual int onEvent(SDL_Event event) { return 0; };
|
||||
/* onInit
|
||||
A strangely named function that does what would normally be accomplished in the constructor. The reason for the separation is in the (probably rare) case that the State is created before the system is ready for it. onInit is called only once during Core::pushState, whereafter Core will set the DID_INIT flag on the state
|
||||
It is assumed that the data initialized here could be completely cleared when the State deconstructor is called.
|
||||
*/
|
||||
virtual int onInit() { return 0; };
|
||||
/* onCede
|
||||
onCede is called when the State is to give up control/resources. This should be a recoverable process that onRise() can undo. This is triggered when a new State is pushed on Core or when Core requests due to the program entering the background
|
||||
*/
|
||||
virtual int onCede() { return 0; };
|
||||
/* onRise
|
||||
onRise is called when the State is supposed to reinitialize control/resources that it gave up during onCede. This is triggered when a State higher on the stack than this one is Core::popState()'d or when Core requests due to the program entering the foreground
|
||||
*/
|
||||
virtual int onRise() { return 0; };
|
||||
std::vector<State*> state; // state(s) of this state
|
||||
enum Flags {
|
||||
DID_INIT = (1 << 1),
|
||||
};
|
||||
int flags;
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -7,8 +7,11 @@ MenuState::~MenuState() {
|
|||
|
||||
}
|
||||
/* ======== State functions ======== */
|
||||
float MenuState::doProcess(float delta) {
|
||||
return 0.0f;
|
||||
int MenuState::doProcess(unsigned int ticks) {
|
||||
return 0;
|
||||
}
|
||||
int MenuState::onEvent(SDL_Event event) {
|
||||
return 0;
|
||||
}
|
||||
int MenuState::onCede() {
|
||||
return 0;
|
||||
|
@ -16,4 +19,6 @@ int MenuState::onCede() {
|
|||
int MenuState::onRise() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MenuState::onInit() {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,9 @@ class MenuState : public State {
|
|||
MenuState();
|
||||
~MenuState();
|
||||
protected:
|
||||
virtual float doProcess(float delta);
|
||||
virtual int doProcess(unsigned int ticks);
|
||||
virtual int onEvent(SDL_Event event);
|
||||
virtual int onInit();
|
||||
virtual int onCede();
|
||||
virtual int onRise();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
#include "TestState.hpp"
|
||||
#include "Core.hpp"
|
||||
#include "Log.hpp"
|
||||
#include "RenderCamera.hpp"
|
||||
#include "RenderSet.hpp"
|
||||
#include "RenderObject.hpp"
|
||||
#include "Program.hpp"
|
||||
#include "Mesh.hpp"
|
||||
/* ======== Construction and Destruction ======== */
|
||||
TestState::TestState() {
|
||||
scene = NULL;
|
||||
}
|
||||
TestState::~TestState() {
|
||||
|
||||
}
|
||||
/* ======== State functions ======== */
|
||||
int TestState::doProcess(unsigned int delta) {
|
||||
return 0;
|
||||
}
|
||||
int TestState::onEvent(SDL_Event event) {
|
||||
if (event.type == SDL_MULTIGESTURE) {
|
||||
LOG(LOG_INFO) << "gesture: " << event.mgesture.x << "x" << event.mgesture.y << ", rot:" << event.mgesture.dTheta << ", pinch:" << event.mgesture.dDist << ", fingers:" << event.mgesture.numFingers;
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
camera_pos.y -= event.mgesture.dDist*256.0f;
|
||||
camera->setPosition(camera_pos.x, camera_pos.y, camera_pos.z);
|
||||
float yaw = camera->getYaw();
|
||||
camera->setYaw(yaw - (event.mgesture.dTheta*128.0f));
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_FINGERMOTION) {
|
||||
LOG(LOG_INFO) << "finger: " << event.tfinger.fingerId << " " << event.tfinger.x << "x" << event.tfinger.y << " " << event.tfinger.dx << "x" << event.tfinger.dy;
|
||||
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
int width = core.getWidth();
|
||||
int height = core.getHeight();
|
||||
float x = event.tfinger.dx * width/16;
|
||||
float y = event.tfinger.dy * height/16;
|
||||
|
||||
// This is weird.
|
||||
float yaw = camera->getYaw() * M_PI / 180.0f;
|
||||
float ax = (-x * cosf(yaw)) + (y * sinf(yaw));
|
||||
float ay = (y * cosf(yaw)) - (-x * sinf(yaw));
|
||||
|
||||
camera->setPosition(camera_pos.x+ax, camera_pos.y, camera_pos.z+ay);
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_MOUSEMOTION && event.motion.which != SDL_TOUCH_MOUSEID) {
|
||||
LOG(LOG_INFO) << "mouse motion: " << event.motion.xrel << "x" << event.motion.yrel << " ";
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
if (event.motion.state & SDL_BUTTON_MMASK) {
|
||||
camera->setYaw(camera->getYaw() - event.motion.xrel);
|
||||
} else if (event.motion.state & SDL_BUTTON_RMASK) {
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
int width = core.getWidth();
|
||||
int height = core.getHeight();
|
||||
float x = (float)event.motion.xrel / (width/50);
|
||||
float y = (float)event.motion.yrel / (height/50);
|
||||
// This is weird. (again)
|
||||
float yaw = camera->getYaw() * M_PI / 180.0f;
|
||||
float ax = (-x * cosf(yaw)) + (y * sinf(yaw));
|
||||
float ay = (y * cosf(yaw)) - (-x * sinf(yaw));
|
||||
camera->setPosition(camera_pos.x+ax, camera_pos.y, camera_pos.z+ay);
|
||||
}
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_MOUSEWHEEL) {
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
Vec3 camera_pos = camera->getPosition();
|
||||
camera_pos.y -= event.wheel.y;
|
||||
camera->setPosition(camera_pos.x, camera_pos.y, camera_pos.z);
|
||||
camera->doRefresh();
|
||||
} else if (event.type == SDL_KEYUP) {
|
||||
if (event.key.keysym.sym == SDLK_SPACE) {
|
||||
RenderCamera *camera = scene->getCamera(1);
|
||||
if (camera->getRenderMode() == 0) {
|
||||
camera->setRenderMode(1);
|
||||
} else {
|
||||
camera->setRenderMode(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int TestState::onRise() {
|
||||
scene = core.getScene();
|
||||
asset_manager = core.getAssetManager();
|
||||
return 0;
|
||||
}
|
||||
int TestState::onCede() {
|
||||
return 0;
|
||||
}
|
||||
int TestState::onInit() {
|
||||
// Get our services
|
||||
asset_manager = core.getAssetManager();
|
||||
// TEMP: our framebuffer rendering program
|
||||
Program *program = new Program();
|
||||
// FIXME: check for GLSL version and automagically load the appropriate shader file
|
||||
#ifdef HAVE_OPENGLES
|
||||
Asset *shader_asset = asset_manager->loadFile("shaders/fb_fs.100.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/fb_vs.100.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
// TEMP: our model rendering program
|
||||
Program *program_model = new Program();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_fs.100.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_vs.100.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shdaer!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program_model->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
Asset *shader_asset = asset_manager->loadFile("shaders/fb_fs.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/fb_vs.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
// TEMP: our model rendering program
|
||||
Program *program_model = new Program();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_fs.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_vs.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program_model->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
scene = core.getScene();
|
||||
int width = core.getWidth();
|
||||
int height = core.getHeight();
|
||||
|
||||
RenderCamera *camera = new RenderCamera();
|
||||
camera->setRenderView(new RenderView(width, height));
|
||||
camera->updateProjection(width, height);
|
||||
camera->setPitch(80.0f);
|
||||
camera->setPosition(0, 30, 0);
|
||||
camera->doRefresh();
|
||||
|
||||
scene->addCamera(camera);
|
||||
|
||||
program->attachTexture(0, camera->getRenderView()->getTex());
|
||||
|
||||
(camera->getRenderView()->setProgram(program));
|
||||
|
||||
RenderSet *sert = new RenderSet();
|
||||
sert->setProgram(program_model);
|
||||
|
||||
Asset *asset_mesh;
|
||||
|
||||
RenderObject *objerct = new RenderObject();
|
||||
asset_mesh = asset_manager->loadFile("models/cube.obj");
|
||||
Mesh *mersh = new Mesh(asset_mesh->getData(), asset_mesh->getDataLength());
|
||||
asset_mesh->unloadData();
|
||||
mersh->buildMesh();
|
||||
objerct->setMesh(mersh);
|
||||
sert->addObject(objerct);
|
||||
|
||||
objerct = new RenderObject();
|
||||
asset_mesh = asset_manager->loadFile("models/chest.obj");
|
||||
mersh = new Mesh(asset_mesh->getData(), asset_mesh->getDataLength());
|
||||
asset_mesh->unloadData();
|
||||
mersh->buildMesh();
|
||||
objerct->setMesh(mersh);
|
||||
objerct->setTranslation(-5.0f, 0.0f, 5.0f);
|
||||
objerct->calcMatrix();
|
||||
sert->addObject(objerct);
|
||||
|
||||
scene->addSet(sert);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* ================================================================
|
||||
TestState
|
||||
----------------
|
||||
TestState.cpp/TestState.hpp provide the Main Test state that the program first attempts to open.
|
||||
================================================================ */
|
||||
#ifndef TESTSTATE_HPP
|
||||
#define TESTSTATE_HPP
|
||||
#include "State.hpp"
|
||||
#include "RenderScene.hpp"
|
||||
#include "AssetManager.hpp"
|
||||
class TestState : public State {
|
||||
friend class Core;
|
||||
public:
|
||||
TestState();
|
||||
~TestState();
|
||||
protected:
|
||||
virtual int onInit();
|
||||
virtual int doProcess(unsigned int ticks);
|
||||
virtual int onEvent(SDL_Event event);
|
||||
virtual int onRise();
|
||||
virtual int onCede();
|
||||
private:
|
||||
RenderScene *scene;
|
||||
AssetManager *asset_manager;
|
||||
};
|
||||
#endif
|
Loading…
Reference in New Issue