#ifndef GAME_GRAPHICS_H
#define GAME_GRAPHICS_H
#include "OpenGL.h"
#include "GLProgram.h"
#include "Dialog.h"
#include "GameSim.h"
#include "VoxelModel.h"
#include "Math.h"
#include "Camera.h"
#include "VertexArray.h"
#include "Cube.h"
#include "Scene.h"
#include "PolyVertex.h"
#define MODEL_COUNT 24
#define PLAYER_MODEL_COUNT 16
DECLARE_PROGRAM_UNIFORMS(PolyProgram)
DECLARE_UNIFORM(mat4, modelViewProjectionMatrix)
DECLARE_UNIFORM(mat4, shadowMapMVP)
DECLARE_UNIFORM(GLint, shadowMap)
DECLARE_UNIFORM(GLint, texture)
DECLARE_UNIFORM(float, time)
DECLARE_UNIFORM(float, shadowStrength)
DECLARE_UNIFORM(bool, mixNoise)
DECLARE_UNIFORM(vec4attrib, translation) // may not need
DECLARE_PROGRAM_UNIFORMS_END
DECLARE_PROGRAM_UNIFORMS(ShadowProgram)
DECLARE_UNIFORM(mat4, modelViewProjectionMatrix)
DECLARE_UNIFORM(float, time)
DECLARE_UNIFORM(vec4attrib, translation) // may not need
DECLARE_PROGRAM_UNIFORMS_END
class DrawableModels
{
public:
void loadVoxelModel(int index, const char* name, int x, int y, int w, int h, int d, bool direction, int scaling, bool asCubes = false, int yClamp0 = 0, int yClamp1 = 256);
VoxelModels m_models;
std::vector<VertexArray<PolyVertex> > m_modelsVertexArrays;
GLuint m_axisTextureIds[3];
};
// 64 256x256 tiles in a 2048x2048 texture
class GameGraphics
{
public:
GameGraphics();
~GameGraphics();
void resetVertexBuffers(const std::vector<Game::GameObjectList*>& a_objectLists);
void loadVoxelModel(VertexArray<PolyVertex>& vertexArray, const char* name, int x, int y, int w, int h, int d, bool direction, int scaling, bool asCubes = false, int yClamp0 = 0, int yClamp1 = 256);
void reloadShaders();
void initialize();
void shutdown();
void update(float a_elapsed, float a_aspect, const GameUi::DrawItems& a_uiItems, float a_playerPos[3], float a_cameraStyle[8], float a_light[8], float a_debugCamera[8]);
void preDraw(float a_time);
void prepareShadowContext();
void renderShadows();
void prepareScreenContext();
void renderScreen();
void prepareHUDContext();
void setEditModel(int modelIndex) { m_editModel = modelIndex; m_editModelDirty = true; }
void setEditLayer(float editLayer) { m_editLayer = editLayer; m_editModelDirty = true; }
void draw();
void drawObjectTypeList(const Game::GameObjectList& a_objs, int a_voxelModelIndex);
void drawObjectTypeListTiled(const Game::GameObjectList& a_objs, int a_voxelModelIndex, int zOff, int wid);
void drawScene();
void drawModelEditLayer();
void drawModelRotatingPreview();
void drawRotatingFrog();
void drawCaroselTest();
void drawHUD();
void drawAuxItems(const GameUi::DrawItems& a_uiItems);
void drawViews(const std::vector<GameUi::View*>& a_views);
void getEditObjectPixels(float editLayer, std::vector<uint32_t>& pixels, int& w, int& h, int& d);
void setEditObjectPixels(float editLayer, const std::vector<uint32_t>& pixels, int w, int h);
void getPalettePixels(std::vector<uint32_t>& pixels);
// Retrieved from GL viewport
uint32_t m_w = 0, m_h = 0;
private:
std::map<std::string,bool> m_options;
int m_editModel = MODEL_COUNT - 1;
float m_editLayer = 0.0;
float m_cameraX, m_cameraY;
float m_playerX, m_playerY, m_playerZ;
float m_time = 0.0;
// HUD
bool m_hudEnabled = true;
GLProgram m_hudProgram;
GLuint m_hudVertexArray;
GLuint m_hudVertexBuffer;
GLuint m_hudTexId = 0;
size_t m_hudItemCount = 0;
// Aux
GLuint m_auxVertexArray;
GLuint m_auxVertexBuffer;
void LoadPendingTexture(GameUi::TextureLoadJob& job);
// Shadows
bool m_shadowsEnabled = true;// true;//false;//true;
GLProgram m_shadowProgram;
GLuint m_shadowTexId = 0;
GLuint m_shadowFramebufferId = 0;
PolyProgram m_shadowUniforms;
// Polygons
GLProgram m_program;
GLuint m_defaultFramebufferId = 0;
Camera m_light;
Camera m_camera;
Camera m_debugCamera;
VertexArray<PolyVertex> m_staticPolyVertexArray;
VertexArray<PolyVertex> m_dynamicPolyVertexArray;
PolyProgram m_polyUniforms;
VertexArray<PolyVertex> m_editModelVertexArray1;
VertexArray<PolyVertex> m_editModelVertexArray2;
bool m_editModelDirty = true;
int modelIdx = 0;
VoxelModels m_models;
VertexArray<PolyVertex> m_modelsVertexArrays[MODEL_COUNT];
// a 2048x2048 image can contain 1024 voxel models which are 16x16x16
// or about 341 models when take in to account needing 3 textures for each axis
// if target 100 different models, need about 19 256x256 texture slots
// if plan to dynamically convert to PVR at runtime, then probably better to
// actually use smaller textures, but means needing to switch texture state
// when rendering
VoxelModels m_playerModels;
VertexArray<PolyVertex> m_playerModelsVertexArrays[PLAYER_MODEL_COUNT];
// Scene
Scene m_scene;
// move to DrawableModels class
uint32_t *m_model_x_axis = nullptr;
uint32_t *m_model_z_axis = nullptr;
void drawCuboid(float frustum[8][4]);
void drawSolidCuboid(float x, float y, float z, float w, float h, float d, uint32_t col, float scale);
VertexArray<PolyVertex> m_cuboidVertexList;
// For debugging
void drawCube(float x, float y, float z, float w, float h, float d, uint32_t color); // For debugging
};
#endif // GAME_GRAPHICS_H