RtB/LOGIC

156 lines
5.8 KiB
Plaintext

This file describes the program logic and organization. It holds a focus on data types and classes.
,,,,,,,,,,,,,,,,,,,,,,,,
Program Organization
````````````````````````
To begin with, RtB is governed by a state machine, individual states, and sub-states (modal dialogs/windows). The state machine, as run by the main loop, is as follows:
1. Check states for destroy/clean-up flags
a. destroy all states with said flags
2. For each Event,
a. send down the event to each state's onEvent(event)
1. if State eats event, continue to the next Event
3. For each State,
a. call onThink, if State blocks, break
4. For each State,
a. call onDraw, if State blocks, break
Alternatively..
[ State Machine ]
[ governs State ]
[ event + think ] --- creates RenderSet
|
[ Render System ] <-----+
[ renders all ]
[ "RenderSet"s ]
The State Machine governs all event handling and logic, while the Render System governs all rendering. Within the Render System, you have RenderSets which, in turn, have RenderObjects:
RenderSet {
char *name; // (or std::string) ex. "Voxel Models"
int mode; // bitflag, 0 = normal, 1 = hide
std::vector <RenderObjects>;
GLuint program; // Shader Program to use
}
What we want for Render Objects:
World Objects:
Rendering of textured plane (flat image)
Rendering of full textured 3d model
Rendering of textured voxel model
UI Objects:
Textured plane (flat dialog, texture of text)
RenderSets should be contained in a RenderScene, which would be something akin to:
RenderScene {
char *name; // (or std::string) ex. "Game"
RenderCamera *camera; // ptr to RenderCamera object
GLuint context; // framebuffer object to render the scene to
std::vector<RenderSet> sets;
}
During the render call, the current RenderCamera defines both the position and orientation of the view.
RenderCamera {
char *name;
Vec3 x, y, z; // OR should it be a quaternion?
int mode; // perspective, orthogonal
GLuint target; // framebuffer target?
RenderView view; // alt to ^
}
RenderView {
GLuint program; // shader program to render with
GLuint target; // fbo/texture target
unsigned int w, h; // width and height of view (also of texture!)
int x, y; // x and y, in terms of render start on screen
}
RenderScenes are, potentially, contained in a layered system, of which there are the following categories in order of rendering:
1. Terrain Layer (terrain, obv.)
2. Game Layer (models, tokens, etc.)
3. Game Overlay (hp, arrows, etc.)
4. Dialogs (mini character sheets, etc.)
5. Windows (character sheets)
6. UI (menu access, etc.)
7. Notification (modal dialog boxes, usually d/c, quit, etc.)
These render layers could be implemented as such:
* Basic array with enums for each layer
* std Vector
* Double-linked list
These layers simply provide an ordering to rendering.
In brief:
RenderObject defines a specific object in the world
RenderSet defines a common group of RenderObjects to be rendered
RenderCamera defines the positions and orientations we render
RenderScene defines the world to be rendered and where to render to
So sort of:
RenderScene
RenderCamera
ptr to RenderView
RenderSet(s)
RenderObject(s)
RenderView
The Render call would be:
* for each RenderScene
* for each RenderCamera
- camera = RenderCamera
* for each RenderSet
- set render output to camera's fbo target
* for each RenderObject
- if out of view, continue
- get MVP from camera, apply, and render
* for each RenderView
- render FBO to screen, additive? multiply?
,,,,,,,,,,,,,,,,,,,,,,,,
File Transmit Logic
````````````````````````
This section defines how File and Data transfer logic works.
First, file transmission is governed by the Server, who hosts the Campaign.
All files possess identifier IDs, as established by the Server.
DataFile {
std::string name; // e.g., "token1.png"
std::string id; // e.g., "a88bok4mp1323kd90ubv"
int type; // Type of binary data, DATA_IMAGE, DATA_SOUND, DATA_MESH, etc.
byte *data; // The binary data
size_t length; // length, in bytes, of binary data
};
DataFile(s) are transferred using a non-blocking push-pull method. When a client connects, the client receives a list of required DataFile ids. For every DataFile required, the client sends a DataFile request message consisting of either a blank checksum indicating no file, or the current checksum that the client has. If the checksum is blank or does not match the server's, the server will send the client the requested FileData. Each file will be checked and requested one at a time.
The message syntax for NetData is:
FILE_REQUEST:DataFile id:checksum
To which the server can respond:
FILE_ERROR:DataFile id
Somehow the server could not find the corresponding DataFile
FILE_SEND:DataFile id:count of bytes:bytes
sends bytes of DataFile to client. if count of bytes is 0, file is complete
FILE_OK:DataFile id
indicates checksum matches
,,,,,,,,,,,,,,,,,,,,,,,,
Terrain/Map Mesh
````````````````````````
Map terrain consists of two components:
* The base Mesh, which can be grid, hexagonal, etc.
* A terrain height modifier
The terrain modifier is a std::vector of Vec3(s). Each Vec3 indicates a height "displacement" that affects the base Mesh. In this way, height modifier(heightmap?) are separate from the underlying terrain Mesh, allowing users to switch between grid-based or hexagonal tile settings.
The method for modifying the base Mesh is to (multiply?) the "Y" of nearby Mesh vectors based on the distance to/from a near-by heightmap
The final Mesh (LiveMesh?) is used to draw the grid outlines(if selected), and to map another Mesh(or Texture?) onto it.