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

master
kts 2015-03-02 19:58:35 -08:00
parent 685c28891e
commit a567769fcf
14 changed files with 410 additions and 198 deletions

1
GUI
View File

@ -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)

27
ORDER 100644
View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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