Initial commit

This commit is contained in:
2026-04-03 00:22:39 -05:00
commit eca1e8c458
945 changed files with 218160 additions and 0 deletions

137
Include/ZBuild.hpp Normal file
View File

@@ -0,0 +1,137 @@
/*
ZBuild.hpp
Author: James Russell <jcrussell@762studios.com>
Purpose: This is the build file that is used to set overall build configuration
when building ZEngine projects. This needs to be on the build path for
all ZEngine projects.
Changelog
2011/12/11 - creation (jcrussell)
*/
#pragma once
#ifndef _ZBUILD_HPP
#define _ZBUILD_HPP
//Current version of ZEngine (overall, not individual lib versions)
#define ZENGINE_CURRENT_VERSION "0.6.0"
//These should be modified for the game in question
#ifndef COMPANY_NAME
#define COMPANY_NAME "762Studios"
#endif
#ifndef GAME_NAME
#define GAME_NAME "762Game"
#endif
/*
The following flags can be enabled / disabled based off of compile type. Usually enabled as a 1 or 0, but
some will have additional options.
--- ZRendererUtil ---
#define ZASSERT_RENDERERUTIL - Enables run-time asserts for renderer util project debugging
--- ZRenderer ---
#define ZASSERT_RENDERER - Enables run-time asserts for renderer project debugging
#define ZGL_CHECKGL - Enables the CHECKGL function call to check graphics library state after library calls
--- ZUtil ---
#define ZALLOC_CHECK_ALLOC - Indicates that ZAlloc should record allocations
#define ZALLOC_EXTRA_SPAMMY - Indicates that ZAlloc should log all allocations
#define ZASSERT_DISABLE - Disables run-time asserts for debugging purposes
#define ZASSERT_UTIL_ENABLE - Enables run-time asserts for util project debugging
#define ZLOG_LEVEL - Defined as one of ZLOG_LEVEL_NONE, ZLOG_LEVEL_ERROR, ZLOG_LEVEL_WARNING, ZLOG_LEVEL_DETAILED, or ZLOG_LEVEL_EVERYTHING
#define ZSTL_CHECK_INTEGRITY - Causes ZSTL containers to check integrity after function calls (uses ZASSERT)
#define ZSTL_CHECK_NAME - Causes ZName to ensure no hash collision has occurred
#define ZSTL_DISABLE_RUNTIME_CHECKS - Causes ZSTL containers to no longer do runtime bounds and error checking (ballsy)
*/
//Engine Debug version engine flags
#ifdef _DEBUGENG
#define ZALLOC_CHECK_ALLOC 1
#define ZALLOC_EXTRA_SPAMMY 0
#define ZASSERT_ENABLE 1
#define ZASSERT_UTIL_ENABLE 1
#define ZASSERT_RENDERER_ENABLE 1
#define ZRENDERER_CHECKGL 1
#define ZLOG_LEVEL ZLOG_LEVEL_SPAM
#define ZSTL_CHECK_INTEGRITY 1
#define ZSTL_CHECK_NAME 1
#define ZSTL_DISABLE_RUNTIME_CHECKS 0
#endif //_DEBUGENG
//Debug version engine flags
#ifdef _DEBUG
#define ZALLOC_CHECK_ALLOC 1
#define ZALLOC_EXTRA_SPAMMY 0
#define ZASSERT_ENABLE 1
#define ZASSERT_UTIL_ENABLE 1
#define ZASSERT_RENDERER_ENABLE 0
#define ZLOG_LEVEL ZLOG_LEVEL_INFO
#define ZRENDERER_CHECKGL 1
#define ZSTL_CHECK_INTEGRITY 1
#define ZSTL_CHECK_NAME 1
#define ZSTL_DISABLE_RUNTIME_CHECKS 0
#endif //_DEBUG
//Dev version engine flags
#ifdef _DEV
#define ZALLOC_CHECK_ALLOC 0
#define ZALLOC_EXTRA_SPAMMY 0
#define ZASSERT_ENABLE 1
#define ZASSERT_UTIL_ENABLE 0
#define ZASSERT_RENDERER_ENABLE 0
#define ZRENDERER_CHECKGL 0
#define ZLOG_LEVEL ZLOG_LEVEL_WARNING
#define ZSTL_CHECK_INTEGRITY 0
#define ZSTL_CHECK_NAME 0
#define ZSTL_DISABLE_RUNTIME_CHECKS 0
#endif //_DEV
//Release version engine flags
#ifdef _RELEASE
#define ZALLOC_CHECK_ALLOC 0
#define ZALLOC_EXTRA_SPAMMY 0
#define ZASSERT_ENABLE 0
#define ZASSERT_UTIL_ENABLE 0
#define ZASSERT_RENDERER_ENABLE 0
#define ZRENDERER_CHECKGL 0
#define ZLOG_LEVEL ZLOG_LEVEL_WARNING
#define ZSTL_CHECK_INTEGRITY 0
#define ZSTL_CHECK_NAME 0
#define ZSTL_DISABLE_RUNTIME_CHECKS 1
#endif //_RELEASE
#endif

29
Include/ZNet/ZNet.hpp Normal file
View File

@@ -0,0 +1,29 @@
/*
ZNet.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/4/2013
Purpose:
ZNet main include
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNET_HPP
#define _ZNET_HPP
#include <ZNet/ZNetConsts.hpp>
#include <ZNet/ZNetHost.hpp>
#include <ZNet/ZNetServer.hpp>
#include <ZNet/ZNetClient.hpp>
#include <ZNet/ZNetPacket.hpp>
#include <ZNet/ZNetPeer.hpp>
#endif

View File

@@ -0,0 +1,57 @@
/*
ZNetBandwidthMeter.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 7/10/2013
Purpose:
** NOT PART OF PUBLIC SDK **
This class is not part of the public SDK; its fields and methods are not present
in the documentation and cannot be guaranteed in future revisions.
** NOT PART OF PUBLIC SDK **
Bandwidth metering using a simple token bucket algorithm. A single value is
metered, so a incoming / outgoing each need an instance.
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETBANDWIDTHMETER_HPP
#define _ZNETBANDWIDTHMETER_HPP
#include <pstdint.h>
class ZNetBandwidthMeter
{
public:
/* Sets the new bandwidth limit */
void SetLimit(uint32_t newLimit);
/* Resets the meter for reuse. Takes the current time */
void Reset(uint64_t newStartTime);
/* Try to allocate a given number of bytes */
bool TryAllocate(uint32_t bytes);
/* Update the token bucket */
void Update(uint64_t newTime);
/* Get the bandwidth limit */
uint32_t GetLimit() const { return limit; }
/* Get the available instantaneous bandwidth */
uint32_t GetAvailable() const { return tokens; }
private: //Should be POD basically
uint64_t lastTime; //The last time this was updated
uint32_t limit; //The bandwidth limit, in bytes per second
uint32_t tokens; //The available bandwidth within this 1 second timeframe
};
#endif

View File

@@ -0,0 +1,98 @@
/*
ZNetClient.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 7/11/2013
Purpose:
ZNetClient -- extends ZNetHost to provide a client
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETCLIENT_HPP
#define _ZNETCLIENT_HPP
#include <ZNet/ZNetHost.hpp>
#include <ZNet/ZNetPeer.hpp>
class ZNetClient : public ZNetHost
{
public:
ZNetClient();
~ZNetClient();
/*
ZNetClient::Update()
Implements ZNetHost::Update().
This should be called to read incoming network data and send outgoing traffic. Events
are only generated by calling Update().
@return (int) - Less than 0: error. 0: OK
*/
int Update();
/*
ZNetClient::Connect()
Initiates a connection to the given host. This method is asynchronous, so an event is
generated. However, if this returns false, then no events will be generated because
an error has occurred locally.
*/
bool Connect(SST_Socket socket, SST_NetAddress* addr, uint32_t nrChannels, uint32_t userData);
/*
ZNetClient::SendPacket()
Sends a packet to the server via a certain channel. Use ZNetPacket::Release()
when the packet is no longer needed.
@param packet - The packet to broadcast
@param channelId - The channel ID
*/
void SendPacket(ZNetPacket* packet, uint32_t channelId);
/*
ZNetClient::Disconnect()
Begins a graceful disconnect. Update() should be called until an event of type DISCONNECT occurs,
or a timeout happens. If a timeout is reached, Reset() should be used.
*/
void Disconnect();
/*
ZNetClient::Reset()
Disconnects from the server, but does not inform him/her that the disconnect has occurred.
This should only be used when a graceful disconnect does not work or when aborting
the client. No local event is generated, so any cleanup must be done immediately.
*/
void Reset();
/*
ZNetClient::GetServer()
Gets the ZNetPeer object that represents the server. If the client is
not connected, then this returns NULL.
*/
ZNetPeer* GetServer() const;
bool IsConnected() const { return connectedFlag; }
private:
ZNetPeer server;
bool connectedFlag;
/* Handle a raw packet sent by the server */
void HandlePacket(const uint8_t* data, uint32_t dataSize);
};
#endif

View File

@@ -0,0 +1,44 @@
/*
ZNetConsts.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/5/2013
Purpose:
ZNet symbolic constants
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETCONSTS_HPP
#define _ZNETCONSTS_HPP
#define ZNET_MTU_IPV4SAFE 512 //Like ZNET_MTU_IPV4, but with slightly less space, allowing for 64 bytes of IP overhead via optional sections
#define ZNET_MTU_IPV4 548 //Minimum maximum reassembly buffer size of 576 minus 28 bytes of overhead for UDPv4
#define ZNET_MTU_ETHERNET 1500
#define ZNET_MTU_IPV6 1280
#define ZNET_MTU_IPV6SAFE 1232 //IPv6 required 1280 minus 48 for UDPv6+IPv6 header
#define ZNET_MAX_SERVER_SOCKETS 4 //Maximum number of sockets a server may listen on
//Flags for ZNetPacket::Initialize()
#define ZNET_TRANSIENT 0x00000000u //< Default value. The packet is unreliable, but transient, so the newest copy is presented and older version discarded.
#define ZNET_RELIABLE 0x00000001u //< This packet will be reliable.
//Peer state
enum ZNetConnectionState
{
STATE_UNCONNECTED, //No connection(s) established
STATE_HANDSHAKE, //Machine has attempted connection, awaiting handshake
STATE_CONNECTED, //Machine is connected actively to a remote machine
STATE_SERVING //Clients connected, actively serving them
};
#endif

View File

@@ -0,0 +1,45 @@
/*
ZNetEvent.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/5/2013
Purpose:
ZNet event structure
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETEVENT_HPP
#define _ZNETEVENT_HPP
class ZNetPeer;
struct ZNetPacket;
enum ZNetEventType
{
ZNETEVENT_NONE, //No event
ZNETEVENT_CONNECT, //A new incoming connection was made
ZNETEVENT_DISCONNECT, //A graceful disconnection occurred
ZNETEVENT_TIMEOUT, //A timeout occurred
ZNETEVENT_DATA //Data was received
};
//Event when connected
struct ZNetEvent
{
ZNetPeer* remote; //The remote host
ZNetPacket* packet; //The packet data
uint32_t userdata; //The user data (if applicable)
ZNetEventType type; //The type
};
#endif

184
Include/ZNet/ZNetHost.hpp Normal file
View File

@@ -0,0 +1,184 @@
/*
ZNetHost.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 7/10/2013
Purpose:
ZNet base class for shared client/server data
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETHOST_HPP
#define _ZNETHOST_HPP
#include <ZNet/ZNetBandwidthMeter.hpp>
#include <ZNet/ZNetEvent.hpp>
#include <ZSTL/ZList.hpp>
struct ZNetPacket;
class ZNetHost
{
public:
ZNetHost();
virtual ~ZNetHost() { }
/*
ZNetHost::Update()
Fetches and sends data as necessary to perform the given role. See the
documentation for the specific class. Generally, you need to call this
each frame.
@return (int) - Less than 0: error. 0: OK
*/
virtual int Update() = 0;
/*
ZNetHost::CreatePacket()
Creates a packet and copies the given initialization data (if any).
@param initData - Data to copy to the new packet, or NULL for uninitialized packet.
@param dataSize - The size of the packet's payload
@param flags - The flags. No flags defined, so must be 0
*/
ZNetPacket* CreatePacket(const void* initData, uint32_t dataSize, uint32_t flags);
/*
ZNetHost::HasEvent()
Returns true if there are queued events. The next call to GetNextEvent()
is guaranteed to succeed.
@return (bool) - True if at least one event is pending
*/
bool HasEvent() { return events.Size() > 0; }
/*
ZNetHost::GetNextEvent()
Attempt to fetch the next event form the queue and returns
whether one was fetched or not.
@param eventReturn - Pointer to ZNetEvent structure to receive event data
@return (bool) - True if an event was returned, false if none was available (and eventReturn is not modified)
*/
bool GetNextEvent(ZNetEvent* eventReturn);
//======================================================================
// TRIVIAL GETTER / SETTER
//======================================================================
/*
ZNetHost::SetIncomingBandwidth()
Sets the desired incoming bandwidth cap.
Note that this is a request made of the remote host; malicious hosts can still
attempt DoS attacks by sending far above this limit.
@param bwIn - The target incoming bandwidth, measured in bytes per second.
*/
void SetIncomingBandwidth(uint32_t bwIn) { inBW.SetLimit(bwIn); }
/*
ZNetHost::SetOutgoingBandwidth()
Sets the desired outgoing bandwidth cap.
@param bwOut - The target outgoing bandwidth, measured in bytes per second.
*/
void SetOutgoingBandwidth(uint32_t bwOut) { outBW.SetLimit(bwOut); }
/*
ZNetHost::SetDropChance()
** DEBUG ONLY **
Sets the chance that a packet will be intentionally dropped. This is used to
simulate high packet loss networks; it should not be used in production. As
such, the percent chance defaults to 0. Values over 100 are treated as 100%.
@param _dropChance - The percent chance to drop. The value should be 0-99.
*/
void SetDropChance(uint32_t _dropChance) { dropChance = _dropChance; }
/*
ZNetHost::SetMTU()
Sets the MTU used by ZNet. ZNet will not send raw packets larger than this;
they will be fragmented into multiple calls into libsst-net. This typically less
the MTU on the adapter, since the "path MTU" is minimum of all nodes between the
two endpoints. The minimum MTU is clamped to 256 bytes.
*/
void SetMTU(uint32_t _mtu) { mtu = _mtu; if(mtu<256) mtu = 256; }
/*
ZNetHost::GetIncomingBandwidth()
Gets the incoming bandwidth, in bytes per second.
@return (uint32_t) - The incoming bandwidth
*/
uint32_t GetIncomingBandwidth() const { return inBW.GetLimit(); }
/*
ZNetHost::GetOutgoingBandwidth()
Gets the outgoing bandwidth, in bytes per second.
@return (uint32_t) - The outgoing bandwidth
*/
uint32_t GetOutgoingBandwidth() const { return outBW.GetLimit(); }
/*
ZNetHost::GetDropChance()
** DEBUG ONLY **
Gets the chance to drop intentionally drop a packet. This should
be zero unless testing network code.
@return (uint32_t) - The chance to drop a packet.
*/
uint32_t GetDropChance() const { return dropChance; }
/*
ZNetHost::GetMTU()
Gets the ZNet maximum transmission unit.
*/
uint32_t GetMTU() const { return mtu; }
protected: //These are used by ZNetServer/ZNetClient
void Reset(uint64_t time);
void AddEvent(const ZNetEvent* newEvent) { events.PushBack(*newEvent); }
//Send all channel data to peer
bool SendToPeer(ZNetPeer* peer);
void TrySendPing(bool isReply, uint32_t givenToken, ZNetPeer* peer);
void TrySendConnResp(uint32_t flags, uint32_t code);
ZNetBandwidthMeter inBW;
ZNetBandwidthMeter outBW;
private:
ZList<ZNetEvent> events;
uint32_t mtu; //< Maximum (wire) size packet
uint32_t dropChance; //< Chance to drop a packet
};
#endif

View File

@@ -0,0 +1,46 @@
/*
ZNetPacket.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/4/2013
Purpose:
ZNet packet class, represents a packet
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETPACKET_HPP
#define _ZNETPACKET_HPP
#include <pstdint.h>
/*
ZNetPacket defines a logical packet that is to be sent or has been received. The data is appended
at the end of the structure, so getting the address requires pointer manipulation. It does
not represent the wire format of what is sent, since packets may be merged.
*/
struct ZNetPacket
{
uint32_t dataSize; //< Size of the packet (logically)
uint32_t flags; //< The flags. ZNET_TRANSIENT, ZNET_RELIABLE, etc.
int32_t refCount; //< Reference count
uint8_t* GetData() { return (uint8_t*) ((uintptr_t)this + sizeof(ZNetPacket)); }
void AddReference() { refCount++; }
void ReleaseReference()
{
refCount--;
if(refCount == 0)
free(this);
}
};
#endif

View File

@@ -0,0 +1,165 @@
/*
ZNetPacketChannel.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/14/2013
Purpose:
** NOT PART OF PUBLIC SDK **
This class is not part of the public SDK; its fields and methods are not present
in the documentation and cannot be guaranteed in future revisions.
** NOT PART OF PUBLIC SDK **
Queue of incoming and outgoing packets.
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETPACKETCHANNEL_HPP
#define _ZNETPACKETCHANNEL_HPP
#include <ZSTL/ZList.hpp>
#include <ZNet/ZNetConsts.hpp>
struct ZNetPacket;
class ZNetHost;
namespace ZNetPrivate { struct ZNetMessageContainer; } //urgh
class ZNetPacketChannel
{
public:
struct ZNetQueuedPacket
{
uint64_t timeSent; //< Time this packet was sent (or 0 for never)
ZNetPacket* packet; //< Logical packet data (payload)
uint32_t subsequence; //< For data packets, this is the number of bytes successfully acked on the remote end
uint32_t command; //< Logical packet command such as ZNETCMD_CONNECT, ZNETCMD_DATA, ...
uint16_t sequence; //< Logical packet sequence
};
ZNetPacketChannel() :
packetCount(0), overflowLimit(1024), localAck(0), remoteAck(0), nextSequenceNumber(1), critical(false)
{
}
void SetOverflowThreshold(uint32_t _overflowLimit) { overflowLimit = _overflowLimit; }
/*
ZNetPacketChannel::QueueForSending()
Attempts to queue a new packet to the channel. If the overflow limit is reached,
this returns false and the client should be disconnected.
*/
bool QueueForSending(ZNetPacket* packet, uint32_t command);
bool QueueForReceiving();
/*
ZNetPacketChannel::SetChannelId()
Sets the channel's ID value for use in outgoing packets.
*/
void SetChannelId(uint32_t chId) { channelId = chId; }
/*
ZNetPacketChannel::FillBuffer()
Fills a buffer with as many packets as the buffer can hold. If all packets
have been added, this returns true. If there was not enough space to hold
all of the packets, this returns false and the index to resume at is provided.
@param buffer - Input buffer pointer
@param bufferSize - The size of the buffer pointed to by buffer[]
@param packetStartIndex - The starting index. Should start at 0, and use the value returned in restartIndexReturn to resume
@param restartIndexReturn - The index to resume packet storage.
@param bytesWritten - The number of bytes written
*/
bool FillBuffer(uint8_t* buffer, uint32_t bufferSize, uint32_t packetStartIndex, uint32_t* restartIndexReturn, uint32_t* bytesWritten);
/*
ZNetPacketChannel::Deinitialize()
*/
void Deinitialize();
/*
ZNetPacketChannel::UpdateRemoteAck()
Updates the remote ack counter and dequeues packets as necessary.
@param newHighest - The new highest sequence number
@param pingAdjust - Set to the current ping value, this value is adjusted by the RTT on a per-packet basis
*/
void UpdateRemoteAck(uint16_t newHighest, int32_t* pingAdjust);
/*
ZNetPacketChannel::UpdateLocalAck()
Updates the local sequence counter for this time period.
*/
void UpdateLocalAck(uint16_t seq);
/*
ZNetPacketChannel::QueueLocally()
Queue a received packet for local consumption. Since packets have an ordering and they may be received out of
order (e.g. send 1, 2, 3 may be processed as 2, 1, 3), this allows ZNet to reorder them and generate the
appropriate sequence of events.
*/
bool QueueLocally(const ZNetPacketChannel::ZNetQueuedPacket* container);
/*
ZNetPacketChannel::QueueData()
Queue a received data packet. This has one of three effects:
1) Full data packet received (e.g. short packet), so it just acts like QueueLocally()
2) Fragmented data packet, did not exist before now -- creates a reassembly buffer.
3) Fragmented data packet, did exist -- adds to reassembly and check if reassembly is complete. If it is, QueueLocally().
*/
bool QueueData(ZNetPrivate::ZNetMessageContainer* data);
void ProcessLocalAcks();
void SetHost(ZNetHost* _host) { host = _host; }
ZNetHost* GetHost() const { return host; }
uint16_t GetLocalAck() { return localAck; }
//Return the highest sequence number for this channel. This is one less than the "next", intuitively.
uint16_t GetHighestSent() { return nextSequenceNumber == 0 ? UINT16_MAX : nextSequenceNumber; }
private:
struct ZNetDataReassemblyPacket
{
ZNetPacket* packet; //< Logical packet data (not yet fully assembled)
uint32_t subsequence; //< Highest contiguous amount of data received
uint16_t sequence; //< The sequence number of this packet
};
ZList<ZNetQueuedPacket> packets; //List of packets we've sent (or will send) but have not yet been acknowledged
ZList<ZNetDataReassemblyPacket> reassembly;
ZList<ZNetQueuedPacket> assembled;
ZList<uint16_t> sequencesFound; //The sequence numbers found this time around (sorted)
ZNetHost* host; //Owner (used for memory allocations)
uint32_t packetCount; //ZList::Size() is O(n), keep track manually
uint32_t overflowLimit; //When this many outgoing packets are unacknowledged,
uint32_t channelId; //This channel's ID value for outgoing packets
uint16_t localAck; //Local acknowledge counter (i.e. highest number of incoming packets we've confirmed)
uint16_t remoteAck; //Remote acknowledge counter (i.e. highest number the remote host has told us it has confirmed)
uint16_t nextSequenceNumber; //Next outgoing sequence number
bool critical; //Is the remote host in a critical state?
};
#endif

143
Include/ZNet/ZNetPeer.hpp Normal file
View File

@@ -0,0 +1,143 @@
/*
ZNetPeer.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/5/2013
Purpose:
ZNet peer class, representing a remote host
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETPEER_HPP
#define _ZNETPEER_HPP
#include <SST/SST_Net.h>
#include <ZNet/ZNetConsts.hpp>
#include <ZNet/ZNetPacketChannel.hpp>
class ZNetPeer;
class ZNetServer;
class ZNetPeer
{
public:
ZNetPeer();
~ZNetPeer() { Deinitialize(); }
/*
ZNetPeer::SetUserData()
Sets the user data for this peer. This value is not
modified or inspected by ZNet. It defaults to NULL.
@param ud - The user data
*/
void SetUserData(void* ud) { userdata = ud; }
/*
ZNetPeer:GetUserData()
Gets the user data for this peer.
@return (void*) - The user data
*/
void* GetUserData() { return userdata; }
/*
ZNetPeer::GetNetAddress()
Gets the network address that this remote host uses.
@return (const SST_NetAddress*) - The remote host's network address
*/
const SST_NetAddress* GetNetAddress() const { return &addr; }
/*
ZNetPeer::GetState()
Gets the remote host's state. TODO: Is this necessary for public API?
@return (ZNetConnectionState) - The connection state
*/
ZNetConnectionState GetState() const { return state; }
/*
ZNetPeer::GetSocket()
Gets the socket that was is used to send/receive from the remote host.
*/
SST_Socket GetSocket() const { return socketCopy; }
/*
ZNetPeer::GetPing()
Gets the approximate ping. Note that the ping value is only updated
when a packet is received, so during a disconnect event, this would not
be accurate. Use GetLastReceived() to find the time since the last packet.
@return (int32_t) - The last known ping value. If < 0, then the ping is unknown.
*/
int32_t GetPing() { return ping; }
/*
Gets the timestamp at which the last valid packet was received. Applications
can use this as a sort of "health" meter for the link and decide how to change
things such as client predictions during times of high latency. A value of 0
indicates that no valid packet has yet been received. To compare timestamps,
use SST_OS_GetMilliTime(). Note that only *valid* packets are considered; so
hosts sending incompatible data are not considered.
@return (uint64_t) - The timestamp of the last valid packet.
*/
uint64_t GetLastReceived() { return lastValidIncoming; }
private:
/* Initialize the peer */
bool Initialize(ZNetHost* _host, const SST_NetAddress* newAddr, SST_Socket s, uint32_t nrChannels);
void Deinitialize();
void SetState(ZNetConnectionState s) { state = s; }
void SetLastReceived(uint64_t ts) { lastValidIncoming = ts; }
void SetPing(int32_t _ping) { ping = _ping; }
uint32_t GetNumberChannels() const { return nrChannels; }
ZNetPacketChannel* GetPacketChannel(uint32_t chId);
//Process all received packets' sequence number to come up with a
//new sequence number to tell the remote server that we've received.
void ProcessLocalAcks();
void SendAcksForAllChannels();
friend class ZNetHost;
friend class ZNetClient;
friend class ZNetServer;
SST_NetAddress addr; //Remote address
uint64_t lastValidIncoming; //Last time a valid packet was received
uint64_t lastOutgoingAck; //Last time an outgoing ACK was sent, or 0 for never.
SST_Socket socketCopy; //Copy of the socket that was used connect to this peer
ZNetPacketChannel* channels; //The packet channels
void* userdata; //User data
uint32_t nrChannels; //Size of channels[] array
int32_t ping; //Estimated ping
ZNetConnectionState state; //Connection state
};
#endif

240
Include/ZNet/ZNetServer.hpp Normal file
View File

@@ -0,0 +1,240 @@
/*
ZNetServer.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 7/10/2013
Purpose:
ZNetServer -- extends ZNetHost to provide a server
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETSERVER_HPP
#define _ZNETSERVER_HPP
#include <ZNet/ZNetHost.hpp>
#include <ZNet/ZNetConsts.hpp>
#include <ZSTL/ZHashMap.hpp>
#include <SST/SST_Net.h>
typedef uint32_t (*ZNetConnectCallback)(const SST_NetAddress* addr, uint32_t userdata, void* callbackParam);
class ZNetServer : public ZNetHost
{
public:
ZNetServer();
~ZNetServer();
/*
ZNetServer::Initialize()
Initializes the ZNetServer instance.
*/
bool Initialize(uint32_t peerCount, uint32_t channelCount);
/*
ZNetServer::AddSocket()
Adds a socket for ZNet to listen on. ZNet may listen on multiple
sockets, but once a socket is added, it cannot be removed. This
limit may be lifted. Only up to ZNET_MAX_SERVER_SOCKETS can be
added.
@param s - The socket to listen on.
@return (bool) - True if successful, false otherwise
*/
bool AddSocket(SST_Socket s);
/*
ZNetServer::Update()
Checks sockets and packet queues for incoming/outgoing traffic. Use GetEvent() to
fetch events generated.
@return (int) - Less than 0: error. 0: OK
*/
int Update();
/*
ZNetServer::SendPacket()
Sends a packet to a peer via a certain channel. Use ZNetPacket::Release()
when the packet is no longer needed.
@param packet - The packet to broadcast
@param peer - The remote host to send to
@param channelId - The channel ID
*/
void SendPacket(ZNetPacket* packet, ZNetPeer* peer, uint8_t channelId);
/*
ZNetServer::BroadcastPacket()
Sends a packet to all peers via a certain channel. Use ZNetPacket::Release()
when the packet is no longer needed.
@param packet - The packet to broadcast
@param channelId - The channel ID
*/
void BroadcastPacket(ZNetPacket* packet, uint8_t channelId);
/*
ZNetServer::DisconnectPeer()
Gracefully disconnects a peer. The peer is sent a message letting him/her
that he/she has been disconnected and awaiting confirmation. The reason code
parameter is sent to the peer.
@param peer - The peer to signal a disconnect to
@param reasonCode - The application-specific reason code. This is not interpreted by ZNet in any way.
*/
void DisconnectPeer(ZNetPeer* peer, uint32_t reasonCode);
/*
ZNetServer::ResetPeer()
Disconnects the peer, but does not inform him/her that the disconnect has occurred.
This should only be used when a graceful disconnect does not work or when aborting
the server. No local event is generated, so any cleanup of the peer must be done
immediately.
@param packet - The packet to broadcast
@param channelId - The channel ID
*/
void ResetPeer(ZNetPeer* peer);
/*
ZNetServer::NextPeer()
Gets the next peer in list of peers. The ordering is completely arbitrary and should not be
relied on, thus you should only pass NULL or the return value from an earlier NextPeer() call.
This can be used to iterate through the list of peers:
ZNetPeer* p = Server->NextPeer(NULL);
while(p)
{
DoSomethingWithPeer(p);
p = Server->NextPeer(p);
}
@param thisPeer - The peer to get the next of, or NULL to start.
@return (ZNetPeer*) - The next peer, or NULL if reached the end.
*/
ZNetPeer* NextPeer(ZNetPeer* thisPeer);
//======================================================================
// TRIVIAL GETTER / SETTER
//======================================================================
/*
ZNetServer::SetListenFlag()
Sets the listen flag. When true, the server reports incoming connections
for normal processing. When false, the server does not report incoming connections
and automatically rejects them.
@param _listenFlag - The new value for the listen flag
*/
void SetListenFlag(bool _listenFlag) { listenFlag = _listenFlag; }
/*
ZNetServer::SetConnectCallback()
Sets the connection callback. When non-NULL, the server calls this function when
a connection attempt is made. Returning 0 indicates the client should be accepted,
while any other value indicates that the client should be rejected. If no function
is present, the server automatically accepts the client. This should be used to
implement ban lists.
@param fn - The new callback function, or NULL to disable it
*/
void SetConnectCallback(ZNetConnectCallback fn) { connectCallback = fn; }
/*
ZNetServer::SetCallbackParam()
Sets the parameter that is passed to the callback. It defaults to NULL.
@param param - The callback parameter
*/
void SetCallbackParam(void* param) { callbackParam = param; }
/*
ZNetServer::GetListenFlag()
Gets the listen flag. See ZNetServer::SetListenFlag() for a description of the
listen flag.
@return (bool) - The value of the listen flag
*/
bool GetListenFlag() const { return listenFlag; }
/*
ZNetServer::GetMaximumClientCount()
Gets the maximum number of clients that may be simultaneously connected.
@return (uint32_t) - The maximum number of clients
*/
uint32_t GetMaximumClientCount() const { return maxClients; }
/*
ZNetServer::GetClientCount()
Gets the number of clients who are currently connected.
@return (uint32_t) - The number of clients who are connected.
*/
uint32_t GetClientCount() const { return clientCount; }
/*
ZNetServer::GetConnectCallback()
Gets the currently installed callback function, or NULL if none is
present.
@return (ZNetConnectCallback) - The connect callback
*/
ZNetConnectCallback GetConnectCallback() { return connectCallback; }
/*
ZNetServer::GetCallbackParam()
Gets the parameter that is passed to the callback function. This
defaults to NULL.
@return (void*) - The callback parameter
*/
void* GetCallbackParam() { return callbackParam; }
private:
ZNetPeer* peers; //< The number of peers
SST_Socket sockets[ZNET_MAX_SERVER_SOCKETS]; //< The sockets that ZNet can listen on
ZNetConnectCallback connectCallback;
void* callbackParam;
uint32_t channelCount; //< The number of channels
uint32_t maxClients; //< The maximum number of clients
uint32_t clientCount; //< The current number of clients
bool listenFlag; //< The listen flag
void HandlePacket(SST_Socket s, const SST_NetAddress* addr, const uint8_t* data, uint32_t length);
void TrySendConnResp(SST_Socket s, const SST_NetAddress* addr, uint32_t reasonCode, uint32_t flags);
ZNetPeer* PeerForAddress(const SST_NetAddress* addr) const;
ZNetPeer* FindEmptyPeerSlot();
};
#endif

49
Include/ZNet/ZNetUtil.hpp Normal file
View File

@@ -0,0 +1,49 @@
/*
ZNetUtil.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/5/2013
Purpose:
ZNet utility functions
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZNETUTIL_HPP
#define _ZNETUTIL_HPP
#include <ZUtil/ZBinaryBufferReader.hpp>
#include <ZUtil/ZBinaryBufferWriter.hpp>
#include <ZNet/ZNetPacket.hpp>
namespace ZNetUtil
{
/*
ZNetUtil::ReaderForPacket
Constructs a ZBinaryBufferReader for the given packet to read it.
@param packet - The packet to read
@return (ZBinaryBufferReader) - The reader class
*/
inline ZBinaryBufferReader ReaderForPacket(ZNetPacket* packet) { return ZBinaryBufferReader(packet->data, packet->dataSize, ZNET_BYTEORDER); }
/*
ZNetUtil::WriterForPacket
Constructs a ZBinaryBufferWriter for the given packet to read it.
@param packet - The packet to read
@return (ZBinaryBufferWriter) - The writer class
*/
inline ZBinaryBufferWriter WriterForPacket(ZNetPacket* packet) { return ZBinaryBufferWriter(packet->data, packet->dataSize, ZNET_BYTEORDER); }
}
#endif

View File

@@ -0,0 +1,288 @@
/*
ZDataBuffer.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 3/20/2011
Purpose:
Interface for graphics device buffered memory, used for uniform buffers, vertex buffers, and
index buffers.
Note that ZDataBuffer is a ZRendererResource, and should be used as such.
License:
TODO
*/
#pragma once
#ifndef _ZDATABUFFER_HPP
#define _ZDATABUFFER_HPP
#include <ZRenderer/ZRendererResource.hpp>
#include <ZSTL/ZArray.hpp>
//Forward Declarations
class ZDataBuffer;
//The type of data buffer
enum ZDataBufferType
{
ZDBT_VERTEX, //Contains Vertex Data
ZDBT_INDEX, //Contains Index Data
ZDBT_UNIFORM, //Contains Uniform (Constant) Data
ZDBT_SIZE
};
//The usage type of the data buffer
enum ZDataBufferUsage
{
ZDBU_STATIC, //Static Buffer (never or rarely updated)
ZDBU_DYNAMIC, //Dynamic Buffer (updated frequently)
ZDBU_STREAMING, //Streaming Buffer (updated every frame)
ZDBU_SIZE
};
//The data type in a stream
enum ZDataBufferStreamType
{
ZDBST_FLOAT32, //32-bit floating point
ZDBST_FLOAT64, //64-bit floating point
ZDBST_INT8, //8-bit integer, signed
ZDBST_INT16, //16-bit integer, signed
ZDBST_INT32, //32-bit integer, signed
ZDBST_UINT8, //8-bit integer, unsigned
ZDBST_UINT16, //16-bit integer, unsigned
ZDBST_UINT32, //32-bit integer, unsigned
ZDBST_SIZE
};
//The data type in a block
enum ZDataBufferBlockType
{
ZDBBT_UNIFORM, //Uniform Data
ZDBBT_INDEX8, //8-bit index data
ZDBBT_INDEX16, //16-bit index data
ZDBBT_INDEX32, //32-bit index data
ZDBBT_SIZE
};
//Struct for stream definitions
struct ZDataBufferStream
{
ZDataBuffer* Buffer; //Parent buffer that contains this stream
size_t ElementSize; //Size of an element in terms of data type (e.g., 2 for vec2, 3 for vec3, etc.)
size_t Offset; //Offset (in bytes) that this stream starts from beginning of data buffer
size_t Stride; //Distance (in bytes) between elements of this stream
ZDataBufferStreamType Type; //Type of data in each element of this stream (this gives us size of each unit of data)
bool Normalize; //true: fixed point value converted to [0,1] or [-1,1] range; false: typecasted.
};
//Struct for block definitions
struct ZDataBufferBlock
{
ZDataBufferBlockType Type; //Type of data contained by this block
size_t Offset; //Offset (in bytes) into the buffer where this block begins
size_t Size; //Size (in bytes) of the block
ZDataBuffer* Buffer; //Parent buffer that contains this block data
};
//Wrapper class for data buffers
class ZDataBuffer : public ZRendererResource
{
private:
DISABLE_COPY_AND_ASSIGN(ZDataBuffer);
public:
//Default Constructor
ZDataBuffer() : ZRendererResource() { }
//Virtual Destructor
virtual ~ZDataBuffer() { }
/*
virtual public ZDataBuffer::DefineBlock
Defines a block of data present in the buffer. Examples of blocks include
index blocks and uniform buffer storage blocks.
@param _type - the type of block (index or uniform)
@param _size - the size of the block (in bytes)
@return (const ZDataBufferBlock*) - the data buffer block created
@context (all)
*/
virtual const ZDataBufferBlock* DefineBlock(ZDataBufferBlockType _type,
size_t _size
) = 0;
/*
virtual public ZDataBuffer::DefineStream
Defines a stream that is present in this buffer. Examples of streams include
the position stream (vertex coordinates), the color stream, the normal stream,
and uv coordinate streams. Other streams can be defined so as to be usable by
shader programs.
@param _type - The type of stream.
@param _elemCount - The number of elements in the stream, e.g., 3D position has an element
count of 3, 2D position has an element count of 2, etc...
@param _offset - The offset into the buffer (in bytes) where this stream begins
@param _stride - The stride between beginnings of consecutive elements (in bytes), or 0 for packed elements
@param _normalize - If true, fixed point data should be normalized (i.e. changed to [0,1] or [-1,1] if unsigned/signed), otherwise
it is converted similar to a C typecast, i.e. 'float value = (float)fixedValue'
@return (const ZDataBufferStream*) - the data buffer stream created
@context (all)
*/
virtual const ZDataBufferStream* DefineStream(ZDataBufferStreamType _type,
size_t _elemCount,
size_t _offset,
size_t _stride,
bool _normalize
) = 0;
/*
virtual public ZDataBuffer::Fill
Fills the buffer with data, as specified. This is equivalent to calling
'MapBuffer', filling the buffer, and calling 'UnmapBuffer'.
@param _data - the data to fill the buffer with
@param _offset - offset into the buffer to start copying to
@param _byteCount - number of bytes to copy from _data
@return (bool) - true if this update was successful, false if the buffer is 'locked' or 'contended'
@context (all)
*/
virtual bool Fill(const void* _data,
size_t _offset,
size_t _byteCount
) = 0;
/*
virtual public ZDataBuffer::GetBlock
Gets the pointer to a block previously defined using DefineBlock().
@param index - The block's index. The first block created with DefineBlock() is 0, the second is 1, and so on.
@return ( const ZDataBufferBlock*) - block definition
@context (all)
*/
virtual const ZDataBufferBlock* GetBlock(size_t index) = 0;
/*
virtual public ZDataBuffer::GetStream
Gets the pointer to a stream previously defined using DefineStream().
@param index - The stream's index. The first stream created with DefineStream() is 0, the second is 1, and so on.
@return (const ZDataBufferStream*) - stream definition
@context (all)
*/
virtual const ZDataBufferStream* GetStream(size_t index) = 0;
/*
virtual public ZDataBuffer::GetBlockCount
Gets the number of blocks that have been defined so far.
@return (size_t) - The number of blocks defined with DefineBlock()
@context (all)
*/
virtual size_t GetBlockCount() const = 0;
/*
virtual public ZDataBuffer::GetStreamCount
Gets the number of streams that have been defined so far.
@return (size_t) - The number of blocks defined with DefineStream()
@context (all)
*/
virtual size_t GetStreamCount() const = 0;
/*
virtual public ZDataBuffer::GetSize
Gets the size of this data buffer.
@return (size_t) - the size (in bytes) of this buffer
@context (all)
*/
virtual size_t GetSize() = 0;
/*
virtual public ZDataBuffer::GetType
Gets the type of this data buffer.
@return (ZDataBufferType) - the buffer type
@context (all)
*/
virtual ZDataBufferType GetType() = 0;
/*
virtual public ZDataBuffer::GetUsage
Gets the usage of this data buffer.
@return (ZDataBufferUsage) - the usage type
@context (all)
*/
virtual ZDataBufferUsage GetUsage() = 0;
/*
virtual public ZDataBuffer::Map
Maps the data buffer into user memory and marks this resource as locked until 'UnmapBuffer' is called.
If the discard parameter is set to true, this tells the implementation that the data
that is currently present in the buffer is not required, and this may result in a faster
return, especially in the case of static usage buffers. If the current data is needed
(discard is false), static usage buffers must wait for the render thread to get the data
from the graphics memory. Dynamic and streaming usage buffers typically suffer no
performance penalty regardless of the value of the discard parameter, though this may
vary based on implementation.
@param _discard - hint to the implementation that the data in the buffer can be discarded
@return (void*) - pointer to the buffer in mapped memory, NULL if this buffer is 'locked' or 'contended'
@context (all)
*/
virtual void* Map(bool _discard = false) = 0;
/*
virtual public ZDataBuffer::UndefBlocks
Undefines all currently set blocks. This will invalidate existing block
definition structures returned from DefineBlock.
@return (void)
@context (all)
*/
virtual void UndefBlocks() = 0;
/*
virtual public ZDataBuffer::UndefStreams
Undefines all currently set streams. This will invalidate existing stream
definition structures returned from DefineStream.
@return (void)
@context (all)
*/
virtual void UndefStreams() = 0;
/*
virtual public ZDataBuffer::Unmap
Unmaps a previously mapped data buffer and unlocks the data buffer.
@return (void)
@context (all)
*/
virtual void Unmap() = 0;
};
#endif

View File

@@ -0,0 +1,130 @@
/*
ZDataBufferBase.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 3/20/2011
Purpose:
The ZDataBufferBase class is meant to be used by implementations that are
required to handle threading and concurrency problems that are not solved by
the graphics library.
License:
TODO
*/
#pragma once
#ifndef _ZDATABUFFERBASE_HPP
#define _ZDATABUFFERBASE_HPP
#include <ZRenderer/ZDataBuffer.hpp>
/*
Base class implementation for the Data Buffer.
*/
class ZDataBufferBase : public ZDataBuffer
{
protected:
//Default Constructor
ZDataBufferBase(ZDataBufferType _type, ZDataBufferUsage _usage, size_t _size);
//Type of the Data Buffer
ZDataBufferType Type;
//Usage setting for the Data Buffer
ZDataBufferUsage Usage;
//Size (in bytes) of the Data Buffer
size_t Size;
//Array of DataBufferBlocks held by this DataBuffer
ZArray<ZDataBufferBlock*> Blocks;
//Array of DataBufferStreams held by this DataBuffer
ZArray<ZDataBufferStream*> Streams;
//Backing buffer, used to double-buffer the graphics device buffer
void* MemBuffer;
//Flag indicating this buffer was mapped or filled
bool bIsDirty;
//Gets the buffer data from graphics memory
virtual void GetDeviceData(void* _buffer) = 0;
//Gets the next block offset we should use from the subclass
virtual size_t GetNextBlockOffset(size_t _size) = 0;
//Resets the block offset to zero
virtual void ResetBlockOffset() = 0;
public:
//Destructor
virtual ~ZDataBufferBase();
/*
public ZDataBufferBase::GetMemBufferResetDirty
Gets the backing memory buffer for this device. This will return
NULL if the buffer has not been modified since the last call to
this function, and in the case it has been modified, a call to this
resets the 'dirty' flag for the buffer.
@return (void*) - the backing memory buffer, NULL if not modified
@context (renderer)
*/
void* GetMemBufferResetDirty();
//Subclass Implementation
virtual const ZDataBufferBlock* DefineBlock(ZDataBufferBlockType _type,
size_t _size
);
//Subclass Implementation
virtual const ZDataBufferStream* DefineStream(ZDataBufferStreamType _type,
size_t _elemCount,
size_t _offset,
size_t _stride,
bool _normalize
);
//Subclass Implementation
virtual bool Fill(const void* _data, size_t _offset, size_t _byteCount);
//Subclass Implementation
virtual const ZDataBufferBlock* GetBlock(size_t index) { return Blocks[index]; }
//Subclass Implementation
virtual const ZDataBufferStream* GetStream(size_t index) { return Streams[index]; }
//Subclass Implementation
virtual size_t GetBlockCount() const { return Blocks.Size(); }
//Subclass Implementation
virtual size_t GetStreamCount() const { return Streams.Size(); }
//Subclass Implementation
virtual size_t GetSize();
//Subclass Implementation
virtual ZDataBufferType GetType();
//Subclass Implementation
virtual ZDataBufferUsage GetUsage();
//Subclass Implementation
virtual void* Map( bool _discard = false );
//Subclass Implementation
virtual void UndefBlocks();
//Subclass Implementation
virtual void UndefStreams();
//Subclass Implementation
virtual void Unmap();
};
#endif

View File

@@ -0,0 +1,91 @@
/*
ZDimensionTexture.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
'Dimension' (1D, 2D, 3D) Texture Interface.
License:
TODO
*/
#pragma once
#ifndef _ZDIMENSIONTEXTURE_HPP
#define _ZDIMENSIONTEXTURE_HPP
#include <ZUtil/ZBitmap.hpp>
#include <ZRenderer/ZTexture.hpp>
//Two dimensional texture interface class
class ZDimensionTexture : public ZTexture
{
public:
//Virtual Destructor
virtual ~ZDimensionTexture() { }
/*
virtual public ZDimensionTexture::Fill
Fills this texture with the data given in the bitmap data structure.
@param _data - the bitmap data
@return (bool) - true if able to fill the texture, false if unable (contested or locked)
@context (all)
*/
virtual bool Fill(const void* _data) = 0;
/*
virtual public ZDimensionTexture::GetBitmap
Function to get the image metadata for a texture as a ZBitmap. Does not get the
bitmap data field in the ZBitmap instance, which is set to NULL.
@return (const ZBitmapFormat) - bitmap format
@context (all)
*/
virtual const ZBitmapFormat GetBitmapFormat() = 0;
/*
virtual public ZDimensionTexture::Map
Maps this texture into memory and locks this texture until 'UnmapTexture' is called.
The bitmap parameter is a description of how the data is laid out in memory.
If the discard parameter is set to true, this tells the implementation that the data
that is currently present in the texture is not required, and this may result in a faster
return.
@param _discard - hint to the implementation that the data in the texture can be discarded
@return (void*) - pointer to the mapped buffer
@context (all)
*/
virtual void* Map( bool _discard) = 0;
/*
virtual public ZDimensionTexture::Unmap
Unmaps a previously mapped texture and unlocks the texture.
@return (void)
@context (all)
*/
virtual void Unmap() = 0;
//Not Implemented
virtual ZTextureType GetType() = 0;
//Not Implemented
virtual ZTextureUsage GetUsage() = 0;
//Not Implemented
virtual bool IsMipmapped() = 0;
};
#endif

View File

@@ -0,0 +1,110 @@
/*
ZDimensionTextureBase.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
Base implementation of a dimension (1D, 2D, 3D) texture.
License:
TODO
*/
#pragma once
#ifndef _ZDIMENSIONTEXTUREBASE_HPP
#define _ZDIMENSIONTEXTUREBASE_HPP
#include <ZRenderer/ZDimensionTexture.hpp>
class ZDimensionTextureBase : public ZDimensionTexture
{
protected:
//Type of texture
ZTextureType Type;
//Format of texture
ZTextureFormat Format;
//Usage type of texture
ZTextureUsage Usage;
//Bitmap format (including memory buffer, if needed)
ZBitmap Bitmap;
//Flag indicating this is a mipmapped texture
bool bIsMipmapped;
//Flag indicating the texture data has been modified
bool bIsDirty;
//Gets the texture data from graphics memory
virtual void GetDeviceData(void* _buffer) = 0;
/*
Parameterized Constructor.
@param _type - the texture type
@param _format - the texture internal storage format
@param _usage - the texture usage hint
@param _bitmap - the bitmap for this texture (or side of texture, in case of cube map)
@param _generateMipmaps - flag indicating we should generate mipmaps for this texture
*/
ZDimensionTextureBase(ZTextureType _type, ZTextureFormat _format, ZTextureUsage _usage, const ZBitmap& _bitmap, bool _generateMipmaps);
public:
//Virtual Destructor
virtual ~ZDimensionTextureBase();
/*
public ZDimensionTextureBase::GetBitmapResetDirty
Gets the bitmap data for this dimension texture. This will return
NULL if the texture has not been modified since the last call to
this function, and in the case it has been modified, a call to this
resets the 'dirty' flag for the render target.
@return (ZBitmap*) - bitmap data, NULL if not dirty
@context (all)
*/
ZBitmap* GetBitmapResetDirty();
uint32_t GetWidth() { return Bitmap.GetWidth(); }
uint32_t GetHeight() { return Bitmap.GetHeight(); }
uint32_t GetDepth() { return Bitmap.GetDepth(); }
/*****************************/
/* ZDimensionTexture Methods */
/*****************************/
//Subclass Implementation
virtual bool Fill(const void* _data);
//Subclass Implementation
virtual const ZBitmapFormat GetBitmapFormat();
//Subclass Implementation
virtual void* Map(bool _discard);
//Subclass Implementation
virtual void Unmap();
/********************/
/* ZTexture Methods */
/********************/
//Subclass Implementation
virtual ZTextureType GetType();
//Subclass Implementation
virtual ZTextureUsage GetUsage();
//Subclass Implementation
virtual bool IsMipmapped();
};
#endif

View File

@@ -0,0 +1,62 @@
/*
ZDrawParams.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/17/2012
Purpose:
TODO
License:
TODO
*/
#pragma once
#ifndef _ZDRAWPARAMS_HPP
#define _ZDRAWPARAMS_HPP
#include <ZRenderer/ZRendererBuild.hpp>
//Draw Parameters Types
enum ZDrawParamsType
{
ZDPT_SHADER, //Shader Parameter Binding Structure
ZDPT_VERTEX, //Vertex Parameter Binding Structure
ZDPT_INDEX, //Index Parameter Binding Structure
ZDPT_SIZE
};
class ZDrawParams
{
public:
//Virtual Destructor
virtual ~ZDrawParams() { }
/*
virtual public ZDrawParams::MarkResourcesContended
Marks all resources bound in this draw parameters structure to be
contended by the renderer.
@return (void)
@context (renderer)
*/
virtual void MarkResourcesContended() = 0;
/*
virtual public ZDrawParams::ReleaseResourceContention
Releases resource contention from the renderer.
@return (void)
@context (renderer)
*/
virtual void ReleaseResourceContention() = 0;
};
#endif

View File

@@ -0,0 +1,138 @@
/*
ZFramebufferRenderTarget.h
Author: James Russell <jcrussell@762studios.com>
Purpose: Interface which defines a FrameBuffer, which is a render target that contains
a set of Textures or RenderBuffers which can be used for off-screen rendering.
Changelog
2011/04/03 - creation (jcrussell)
*/
#pragma once
#ifndef _ZFRAMEBUFFERRENDERTARGET_HPP
#define _ZFRAMEBUFFERRENDERTARGET_HPP
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZRenderTarget.hpp>
#include <ZRenderer/ZTexture.hpp>
#include <ZRenderer/ZRenderBuffer.hpp>
//The maximum number of color buffers supported on a single frame buffer render target
#ifndef ZFBRT_MAX_COLOR_BUFFERS
#define ZFBRT_MAX_COLOR_BUFFERS (16)
#endif
//Frame Buffer Render Target, used for off-screen rendering
class ZFramebufferRenderTarget : public ZRenderTarget
{
public:
/*
public ZFramebufferRenderTarget::AttachColorBuffer
Attach a texture to this frame buffer render target as a color buffer. All textures
set as color buffers must be of the same dimension, and their dimensions must match
that of GetWidth() and GetHeight().
@param _buffer - the texture to bind to this render target
@param _index - the index to bind this color buffer to
@return (bool) - true if able to attach buffer, false if resource contended
@context (all)
*/
virtual bool AttachColorTexture(ZPtr<ZTexture> _texture, size_t _index) = 0;
/*
virtual public ZFramebufferRenderTarget::AttachDepthTexture
Attaches a texture to this frame buffer render target as a depth buffer. The texture
set as the depth buffer must be of the same dimension as the color buffers, and it's
dimension must match that of GetWidth() and GetHeight().
A frame buffer render target cannot have a texture attached as a depth buffer as well
as a render buffer attached for the same purpose.
@param _texture - the texture to bind
@return (bool) - true if able to attach, false otherwise
@context (all)
*/
virtual bool AttachDepthTexture(ZPtr<ZTexture> _texture) = 0;
/*
virtual public ZFramebufferRenderTarget::AttachRenderBuffer
Attaches a render buffer to this frame buffer render target. The type of attachment
is determined by render buffer type.
A render buffer cannot be attached if another buffer is already attached that would
perform it's function, i.e., it is not possible to attach a depth buffer when a
depth texture is in place, and it is not possible to attach a stencil buffer
when a depth buffer is acting as depth and stencil buffer.
@param _buffer - the render buffer to attach
@return (bool) - true if able to attach buffer, false if resource contended
@context (all)
*/
virtual bool AttachRenderBuffer(ZPtr<ZRenderBuffer> _buffer) = 0;
/*
virtual public ZFramebufferRenderTarget::IsComplete
Checks to see if this FrameBuffer is in a 'complete' status and can be used. A
'complete' frame buffer requires at least one color buffer (bound at index 0) and
one depth buffer, and the buffers should be bound by the graphics library to the
frame buffer object.
@return (bool) - true if complete, false otherwise
@context (all)
*/
virtual bool IsComplete() = 0;
/*
virtual public ZFramebufferRenderTarget::RemoveColorBuffers
Removes the current set of color buffers attached to this frame buffer render target.
@return (bool) - true if able to remove buffers, false if resource contended
@context (all)
*/
virtual bool RemoveColorBuffers() = 0;
/*
virtual public ZFramebufferRenderTarget::RemoveDepthBuffer
Removes the current set depth buffers attached to this frame buffer render target.
@return (bool) - true if able to remove buffer, false if resource contended
@context (all)
*/
virtual bool RemoveDepthBuffer() = 0;
/*
virtual public ZFramebufferRenderTarget::RemoveStencilBuffer
Removes the current set stencil buffer attached to this frame buffer render target.
@return (bool) - true if able to remove buffer, false if resource contended
@context (all)
*/
virtual bool RemoveStencilBuffer() = 0;
//Not Implemented
virtual const ZRenderTargetClearFlags& GetClearFlags() = 0;
//Not Implemented
virtual size_t GetHeight() = 0;
//Not Implemented
virtual ZRenderTargetType GetType() = 0;
//Not Implemented
virtual size_t GetWidth() = 0;
//Not Implemented
virtual bool SetClearFlags(const ZRenderTargetClearFlags& _flags) = 0;
};
#endif

View File

@@ -0,0 +1,150 @@
/*
ZFramebufferRenderTargetBase.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 08/07/2011
Purpose:
Base class implementation of the ZFramebufferRenderTarget interface.
License:
TODO
*/
#pragma once
#ifndef _ZFRAMEBUFFERRENDERTARGETBASE_HPP
#define _ZFRAMEBUFFERRENDERTARGETBASE_HPP
#include <ZRenderer/ZFramebufferRenderTarget.hpp>
#include <ZRenderer/ZTexture.hpp>
#include <ZRenderer/ZRenderBuffer.hpp>
//Buffer Data Struct, used to indicate buffer state
struct ZFramebufferRenderTargetBufferState
{
//Our set of attached Color Buffers
ZPtr<ZTexture> ColorBuffers[ZFBRT_MAX_COLOR_BUFFERS];
//Our attached depth texture
ZPtr<ZTexture> DepthTexture;
//Our attached depth buffer
ZPtr<ZRenderBuffer> DepthBuffer;
//Our attached stencil buffer
ZPtr<ZRenderBuffer> StencilBuffer;
//Indicates we are in a usable state
bool bIsComplete;
ZFramebufferRenderTargetBufferState()
: bIsComplete(false) { }
};
//Base class implementation of a frame buffer render target
class ZFramebufferRenderTargetBase : public ZFramebufferRenderTarget
{
private:
DISABLE_COPY_AND_ASSIGN(ZFramebufferRenderTargetBase);
protected:
//The 'clear' flags
ZRenderTargetClearFlags Flags;
//Width of the FBRT
size_t Width;
//Height of the FBRT
size_t Height;
//Flag indicating state has changed
bool bIsDirty;
//Buffer State for this frame buffer render target
ZFramebufferRenderTargetBufferState BufferState;
/*
Constructor.
@param _width - the width (in pixels / texels) of the FBRT
@param _height - the height (in pixels / texels) of the FBRT
*/
ZFramebufferRenderTargetBase(size_t _width, size_t _height);
public:
//Virtual Destructor
virtual ~ZFramebufferRenderTargetBase() { }
/*
public ZFramebufferRenderTargetBase::GetBufferState
Gets the buffer state for this frame buffer render target.
@return (ZFramebufferRenderTargetBufferState*) - the buffer state
@context (all)
*/
ZFramebufferRenderTargetBufferState* GetBufferState();
/*
public ZFramebufferRenderTargetBase::GetBufferStateResetDirty
Gets the backing buffer state for this render target. This will return
NULL if the buffer state has not been modified since the last call to
this function, and in the case it has been modified, a call to this
resets the 'dirty' flag for the render target.
@return (ZFramebufferRenderTargetBufferState*) - buffer state, NULL if not modified
@context (all)
*/
ZFramebufferRenderTargetBufferState* GetBufferStateResetDirty();
/*************************/
/* ZRenderTarget Methods */
/*************************/
//Subclass Implementation
virtual const ZRenderTargetClearFlags& GetClearFlags();
//Subclass Implementation
virtual size_t GetHeight();
//Subclass Implementation
virtual ZRenderTargetType GetType();
//Subclass Implementation
virtual size_t GetWidth();
//Subclass Implementation
virtual bool SetClearFlags(const ZRenderTargetClearFlags& _flags);
/************************************/
/* ZFramebufferRenderTarget Methods */
/************************************/
//Subclass Implementation
virtual bool AttachColorTexture(ZPtr<ZTexture> _texture, size_t _index);
//Subclass Implementation
virtual bool AttachDepthTexture(ZPtr<ZTexture> _texture);
//Subclass Implementation
virtual bool AttachRenderBuffer(ZPtr<ZRenderBuffer> _buffer);
//Subclass Implementation
virtual bool IsComplete();
//Subclass Implementation
virtual bool RemoveColorBuffers();
//Subclass Implementation
virtual bool RemoveDepthBuffer();
//Subclass Implementation
virtual bool RemoveStencilBuffer();
};
#endif

View File

@@ -0,0 +1,163 @@
/*
ZIndexParams.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
TODO
License:
TODO
*/
#pragma once
#ifndef _ZINDEXPARAMS_HPP
#define _ZINDEXPARAMS_HPP
#include <ZRenderer/ZDrawParams.hpp>
#include <ZSTL/ZSTL.hpp>
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZDataBuffer.hpp>
typedef enum ZIndexPrimitiveType {
ZIPT_TRIANGLES, //Unrelated triangles, n/3 primitives are drawn
ZIPT_TRISTRIP, //Triangle Strip, n-2 primitives are drawn
ZIPT_LINES, //Unrelated lines, n/2 primitives are drawn
ZIPT_LINESTRIP, //Line Strip, n-1 primitives are drawn
ZIPT_POINTS, //Point list, n primitives are drawn
} ZIndexPrimitiveType;
class ZIndexParams : public ZDrawParams
{
private:
//This is the bound index buffer and block
ZPtr<ZDataBuffer> IndexBuffer;
ZPair<ZDataBuffer*, const ZDataBufferBlock*> Binding;
ZIndexPrimitiveType primType;
size_t nrPrims;
size_t offset;
public:
/*
Default Constructor.
*/
ZIndexParams();
/*
public ZIndexParams::ClearBlock
Clears the current block definition and index buffer.
@return (void)
@context (all)
*/
void ClearIndexBlock();
/*
public ZIndexParams::SetBlock
Sets the index buffer and index block that will be being used.
@param _indexBuffer - data buffer containing index data
@param _block - the index block
@return (void)
@context (all)
*/
void SetIndexBlock(ZPtr<ZDataBuffer> _indexBuffer, const ZDataBufferBlock* _block);
/*
public ZIndexParams::SetPrimitiveDrawCount
Sets the number of primitives that will be drawn. This is not the number
of indices used in total. For example, 300 indices with triangles will draw
100 triangles, so the primitive draw count should be 100.
The special value of '0' is interpreted as "draw as many as possible".
@param count - The number of primitives
@return (void)
@context (all)
*/
void SetPrimitiveDrawCount(size_t _count) { nrPrims = _count; }
/*
public ZIndexParams::GetPrimitiveDrawCount
Gets the number of primitives that will be drawn.
@return (size_t) - The number of primitives
@context (all)
*/
size_t GetPrimitiveDrawCount() const { return nrPrims; }
/*
public ZIndexParams::SetDrawOffset
Sets starting point for drawing, measured in whole indices (not bytes). For example,
if you had a stream that contained { 1, 3, 5, 7 } and you wanted to draw
starting at '3', then you would use an offset of 1 -- regardless of the
type of index (8, 16, 32-bit).
@param _offset - The offset measured in whole indices
@return (void)
@context (all)
*/
void SetDrawOffset(size_t _offset) { offset = _offset; }
/*
public ZIndexParams::GetDrawOffset
Gets starting point for drawing, measured in whole indices (not bytes)
@return (size_t) - The offset
@context (all)
*/
size_t GetDrawOffset() const { return offset; }
/*
public ZIndexParams::SetPrimitiveType
Sets primitive type to draw.
@param _type - The primitive type
@return (void)
@context (all)
*/
void SetPrimitiveType(ZIndexPrimitiveType _type) { primType = _type; }
/*
public ZIndexParams::GetPrimitiveType
Gets the type of primitive being rendered
@return (ZIndexPrimitiveType) - The primitive type
@context (all)
*/
ZIndexPrimitiveType GetPrimitiveType() { return primType; }
/*
The following methods are used by the renderer to get the values needed when
binding shader parameter values to pass to the shader program, to mark
all bound resources as contended, and release contention.
*/
const ZPair<ZDataBuffer*, const ZDataBufferBlock*>* GetIndexBlock();
ZDataBuffer* GetIndexBuffer();
//Subclass Override
virtual void MarkResourcesContended();
//Subclass Override
virtual void ReleaseResourceContention();
};
#endif

View File

@@ -0,0 +1,98 @@
/*
ZOpenGLDataBuffer.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 3/20/2011
Purpose:
OpenGL implementation of the ZDataBuffer interfaces.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLDATABUFFER_HPP
#define _ZOPENGLDATABUFFER_HPP
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZDataBufferBase.hpp>
//Forward Declarations
class ZOpenGLRenderer;
/*
OpenGL Data Buffer.
*/
class ZOpenGLDataBuffer : public ZDataBufferBase
{
protected:
//Renderer associated with this buffer
ZOpenGLRenderer *Renderer;
//The current offset to use
size_t NextOffset;
//Offset Alignment Requirement
static int OffsetAlignment;
//Gets the buffer data from the graphics device as part of a thread request
static void GetDeviceData_( ZThread *_renderThread, void *_dataBuffer );
//Subclass Override
virtual void GetDeviceData(void* _buffer);
//Subclass Override
virtual size_t GetNextBlockOffset(size_t _size);
//Subclass Override
virtual void ResetBlockOffset();
public:
//OpenGL Handle to the Buffer
GLuint GLHandle;
//Gets a GLenum based off of type
GLenum GetGLType()
{
switch (Type)
{
case ZDBT_UNIFORM: return GL_UNIFORM_BUFFER;
case ZDBT_VERTEX: return GL_ARRAY_BUFFER;
case ZDBT_INDEX: return GL_ELEMENT_ARRAY_BUFFER;
default: return GL_INVALID_ENUM;
}
}
//Gets a GLenum based off of usage
GLenum GetGLUsage()
{
switch(Usage)
{
case ZDBU_STATIC: return GL_STATIC_DRAW;
case ZDBU_DYNAMIC: return GL_DYNAMIC_DRAW;
case ZDBU_STREAMING: return GL_STREAM_DRAW;
default: return GL_INVALID_ENUM;
}
}
/*
Constructor.
@param _renderer - the current renderer
@param _type - the type of buffer this is
@param _usage - the usage type of this buffer
@param _size - the size (in bytes) of the data buffer
*/
ZOpenGLDataBuffer(ZOpenGLRenderer *_renderer, ZDataBufferType _type, ZDataBufferUsage _usage, size_t _size);
/*
Destructor.
*/
virtual ~ZOpenGLDataBuffer();
};
#endif

View File

@@ -0,0 +1,262 @@
/*
ZOpenGLDimensionTexture.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
OpenGL implementation of a 'dimensional' (1D, 2D, 3D) texture.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLDIMENSIONTEXTURE_HPP
#define _ZOPENGLDIMENSIONTEXTURE_HPP
#include <SST/SST_GLAPI.h>
#include <ZRenderer/ZDimensionTextureBase.hpp>
//Forward Declarations
class ZOpenGLRenderer;
//OpenGL implementation of the two dimensional texture interface
class ZOpenGLDimensionTexture : public ZDimensionTextureBase
{
private:
DISABLE_COPY_AND_ASSIGN(ZOpenGLDimensionTexture);
protected:
//Gets the texture data from the graphics device as part of a thread request
static void GetDeviceData_( ZThread *_renderThread, void *_dataBuffer );
//Subclass Implementation
virtual void GetDeviceData(void* _buffer);
public:
//Renderer associated with this texture
ZOpenGLRenderer *Renderer;
//The OpenGL handle to the loaded texture
GLuint GLHandle;
//Gets the OpenGL 'target' parameter for this texture type
GLenum GetGLTarget()
{
switch(Type)
{
case ZTT_TEXTURE1D: return GL_TEXTURE_1D;
case ZTT_TEXTURE2D: return GL_TEXTURE_2D;
case ZTT_TEXTURE3D: return GL_TEXTURE_3D;
case ZTT_TEXTURE_CUBE: /* Invalid Here */
default: return GL_INVALID_ENUM;
}
}
//Gets the OpenGL 'internalFormat' parameter for this texture format (used for glTexImage*D)
GLenum GetGLInternalFormat()
{
switch (Format)
{
case ZTF_R8: return GL_R8;
case ZTF_R8_SNORM: return GL_R8_SNORM;
case ZTF_R8I: return GL_R8I;
case ZTF_R8UI: return GL_R8UI;
case ZTF_R16: return GL_R16;
case ZTF_R16_SNORM: return GL_R16_SNORM;
case ZTF_R16I: return GL_R16I;
case ZTF_R16UI: return GL_R16UI;
case ZTF_R16F: return GL_R16F;
case ZTF_R32I: return GL_R32I;
case ZTF_R32UI: return GL_R32UI;
case ZTF_R32F: return GL_R32F;
case ZTF_RG8: return GL_RG8;
case ZTF_RG8_SNORM: return GL_RG8_SNORM;
case ZTF_RG8I: return GL_RG8I;
case ZTF_RG8UI: return GL_RG8UI;
case ZTF_RG16: return GL_RG16;
case ZTF_RG16_SNORM: return GL_RG16_SNORM;
case ZTF_RG16I: return GL_RG16I;
case ZTF_RG16UI: return GL_RG16UI;
case ZTF_RG16F: return GL_RG16F;
case ZTF_RG32I: return GL_RG32I;
case ZTF_RG32UI: return GL_RG32UI;
case ZTF_RG32F: return GL_RG32F;
case ZTF_RGB8: return GL_RGB8;
case ZTF_RGB8_SNORM: return GL_RGB8_SNORM;
case ZTF_RGB8I: return GL_RGB8I;
case ZTF_RGB8UI: return GL_RGB8UI;
case ZTF_RGB16: return GL_RGB16;
case ZTF_RGB16_SNORM: return GL_RGB16_SNORM;
case ZTF_RGB16I: return GL_RGB16I;
case ZTF_RGB16UI: return GL_RGB16UI;
case ZTF_RGB16F: return GL_RGB16F;
case ZTF_RGB32I: return GL_RGB32I;
case ZTF_RGB32UI: return GL_RGB32UI;
case ZTF_RGB32F: return GL_RGB32F;
case ZTF_RGBA8: return GL_RGBA8;
case ZTF_RGBA8_SNORM: return GL_RGBA8_SNORM;
case ZTF_RGBA8I: return GL_RGBA8I;
case ZTF_RGBA8UI: return GL_RGBA8UI;
case ZTF_RGBA16: return GL_RGBA16;
case ZTF_RGBA16_SNORM: return GL_RGBA16_SNORM;
case ZTF_RGBA16I: return GL_RGBA16I;
case ZTF_RGBA16UI: return GL_RGBA16UI;
case ZTF_RGBA16F: return GL_RGBA16F;
case ZTF_RGBA32I: return GL_RGBA32I;
case ZTF_RGBA32UI: return GL_RGBA32UI;
case ZTF_RGBA32F: return GL_RGBA32F;
case ZTF_DEPTH16: return GL_DEPTH_COMPONENT16;
case ZTF_DEPTH24: return GL_DEPTH_COMPONENT24;
case ZTF_DEPTH32: return GL_DEPTH_COMPONENT32;
case ZTF_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
default: return GL_INVALID_ENUM;
}
}
//Gets the OpenGL 'format' parameter for this texture's bitmap format (used for glTexImage*D)
GLenum GetGLFormat()
{
switch (Bitmap.GetFormat())
{
case ZBF_R8:
case ZBF_R8I:
case ZBF_R16:
case ZBF_R16I:
case ZBF_R32:
case ZBF_R32I:
case ZBF_R32F: return GL_RED;
case ZBF_RG8:
case ZBF_RG8I:
case ZBF_RG16:
case ZBF_RG16I:
case ZBF_RG32:
case ZBF_RG32I:
case ZBF_RG32F: return GL_RG;
case ZBF_RGB8:
case ZBF_RGB8I:
case ZBF_RGB16:
case ZBF_RGB16I:
case ZBF_RGB32:
case ZBF_RGB32I:
case ZBF_RGB32F: return GL_RGB;
case ZBF_RGBA8:
case ZBF_RGBA8I:
case ZBF_RGBA16:
case ZBF_RGBA16I:
case ZBF_RGBA32:
case ZBF_RGBA32I:
case ZBF_RGBA32F: return GL_RGBA;
case ZBF_BGR8:
case ZBF_BGR8I:
case ZBF_BGR16:
case ZBF_BGR16I:
case ZBF_BGR32:
case ZBF_BGR32I:
case ZBF_BGR32F: return GL_BGR;
case ZBF_BGRA8:
case ZBF_BGRA8I:
case ZBF_BGRA16:
case ZBF_BGRA16I:
case ZBF_BGRA32:
case ZBF_BGRA32I:
case ZBF_BGRA32F: return GL_BGRA;
case ZBF_DEPTH32: return GL_DEPTH_COMPONENT;
default: return GL_INVALID_ENUM;
}
}
//Gets the OpenGL 'type' parameter for this texture's bitmap format (used for glTexImage*D calls)
GLenum GetGLType()
{
switch (Bitmap.GetFormat())
{
case ZBF_R8:
case ZBF_RG8:
case ZBF_RGB8:
case ZBF_RGBA8:
case ZBF_BGR8:
case ZBF_BGRA8: return GL_UNSIGNED_BYTE;
case ZBF_R8I:
case ZBF_RG8I:
case ZBF_RGB8I:
case ZBF_RGBA8I:
case ZBF_BGR8I:
case ZBF_BGRA8I: return GL_BYTE;
case ZBF_R16:
case ZBF_RG16:
case ZBF_RGB16:
case ZBF_RGBA16:
case ZBF_BGR16:
case ZBF_BGRA16: return GL_UNSIGNED_SHORT;
case ZBF_R16I:
case ZBF_RG16I:
case ZBF_RGB16I:
case ZBF_RGBA16I:
case ZBF_BGR16I:
case ZBF_BGRA16I: return GL_SHORT;
case ZBF_R32:
case ZBF_RG32:
case ZBF_RGB32:
case ZBF_RGBA32:
case ZBF_BGR32:
case ZBF_BGRA32: return GL_UNSIGNED_INT;
case ZBF_R32I:
case ZBF_RG32I:
case ZBF_RGB32I:
case ZBF_RGBA32I:
case ZBF_BGR32I:
case ZBF_BGRA32I: return GL_INT;
case ZBF_R32F:
case ZBF_RG32F:
case ZBF_RGB32F:
case ZBF_RGBA32F:
case ZBF_BGR32F:
case ZBF_BGRA32F: return GL_FLOAT;
case ZBF_DEPTH32: return GL_UNSIGNED_INT;
default: return GL_INVALID_ENUM;
}
}
/*
Constructor.
@param _renderer - the current renderer instance
@param _type - the type of texture
@param _format - the format of the texture
@param _usage - the usage type of texture
@param _bitmap - the bitmap for this texture (or side, in case of cube map)
@param _generateMipmaps - flag indicating we should generate mipmaps
*/
ZOpenGLDimensionTexture(ZOpenGLRenderer* _renderer, ZTextureType _type, ZTextureFormat _format, ZTextureUsage _usage, const ZBitmap& _bitmap, bool _generateMipmaps);
//Virtual destructor
virtual ~ZOpenGLDimensionTexture();
};
#endif

View File

@@ -0,0 +1,53 @@
/*
ZOpenGLFrameBufferRenderTarget.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 07/24/2011
Purpose:
OpenGL implementation of the ZFramebufferRenderTargetBase class.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLFRAMEBUFFERRENDERTARGET_HPP
#define _ZOPENGLFRAMEBUFFERRENDERTARGET_HPP
//Forward Declarations
class ZOpenGLRenderer;
#include <ZRenderer/ZFramebufferRenderTargetBase.hpp>
#include <SST/SST_GLAPI.h>
class ZOpenGLFramebufferRenderTarget : public ZFramebufferRenderTargetBase
{
protected:
//Renderer Instance
ZOpenGLRenderer* Renderer;
public:
//The OpenGL handle to the FBO
GLuint GLHandle;
/*
Constructor.
@param _renderer - the current renderer
@param _width - the width this frame buffer render target be be
@param _height - the height this frame buffer render target will be
*/
ZOpenGLFramebufferRenderTarget(ZOpenGLRenderer *_renderer, size_t _width, size_t _height);
/*
Destructor.
*/
~ZOpenGLFramebufferRenderTarget();
};
#endif

View File

@@ -0,0 +1,84 @@
/*
ZOpenGLRenderBuffer.hpp
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Purpose:
Implementation of the render buffer interface for OpenGL renderers.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLRENDERBUFFER_HPP
#define _ZOPENGLRENDERBUFFER_HPP
//Forward Declaration
class ZOpenGLRenderer;
#include <SST/SST_GLAPI.h>
#include <ZRenderer/ZRenderBuffer.hpp>
class ZOpenGLRenderBuffer : public ZRenderBuffer
{
protected:
//Renderer Instance
ZOpenGLRenderer* Renderer;
//The type of render buffer
ZRenderBufferType Type;
//Width of the render buffer
size_t Width;
//Height of the render buffer
size_t Height;
public:
//Gets the GL storage type
inline GLenum GetGLType()
{
switch(Type)
{
case ZRBT_DEPTH16: return GL_DEPTH_COMPONENT16;
case ZRBT_DEPTH24: return GL_DEPTH_COMPONENT24;
case ZRBT_DEPTH32: return GL_DEPTH_COMPONENT32;
case ZRBT_STENCIL8: return GL_STENCIL_INDEX8;
case ZRBT_DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
default: return GL_INVALID_ENUM;
}
}
//The OpenGL handle to the render buffer
GLuint GLHandle;
/*
Constructor.
@param _renderer - the current renderer instance
@param _type - the type of render buffer this will be
@param _width - with of the render buffer
@param _height - height of the render buffer
*/
ZOpenGLRenderBuffer( ZOpenGLRenderer *_renderer, ZRenderBufferType _type, size_t _width, size_t _height);
//Destructor
virtual ~ZOpenGLRenderBuffer();
//Subclass Implementation
virtual size_t GetHeight();
//Subclass Implementation
virtual ZRenderBufferType GetType();
//Subclass Implementation
virtual size_t GetWidth();
};
#endif

View File

@@ -0,0 +1,197 @@
/*
ZOpenGLRenderer.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 3/27/2011
Purpose:
OpenGL implementation of the Renderer. Currently requires OpenGL 3.3.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLRENDERER_HPP
#define _ZOPENGLRENDERER_HPP
#include <SST/SST_GLAPI.h>
#include <SST/SST_WMOpenGL.h>
#include <ZRenderer/ZRendererBase.hpp>
#include <ZRenderer/ZOpenGLDataBuffer.hpp>
#include <ZRenderer/ZOpenGLShader.hpp>
#include <ZRenderer/ZOpenGLShaderProgram.hpp>
#include <ZRenderer/ZOpenGLDimensionTexture.hpp>
#include <ZRenderer/ZOpenGLSampler.hpp>
#include <ZRenderer/ZOpenGLFrameBufferRenderTarget.hpp>
#include <ZRenderer/ZOpenGLRenderBuffer.hpp>
#include <ZRenderer/ZOpenGLWindowRenderTarget.hpp>
#include <ZRenderer/ZOpenGLVertexParams.hpp>
//CHECKGL function, which checks for OpenGL Error conditions and asserts when they are found
void CheckGL();
//CHECKGL macro for debug mode
#if ZRENDERER_CHECKGL
#define CHECKGL() (CheckGL())
#else
#define CHECKGL()
#endif
//Enumeration for various OpenGL resource types
enum ZOpenGLResourceType
{
ZOGLRT_BUFFER, //OpenGL Buffer Object
ZOGLRT_SHADER, //OpenGL Shader Object
ZOGLRT_SHADER_PROGRAM, //OpenGL Shader Program Object
ZOGLRT_TEXTURE, //OpenGL Texture Object
ZOGLRT_SAMPLER, //OpenGL Sampler Object
ZOGLRT_FRAME_BUFFER, //OpenGL Frame Buffer Object
ZOGLRT_RENDER_BUFFER, //OpenGL Render Buffer Object
ZOGLRT_VERTEX_ARRAY, //OpenGL Vertex Array Object
ZOGLRT_SIZE
};
/*
OpenGL Renderer implementation class.
*/
class ZOpenGLRenderer : public ZRendererBase
{
private:
DISABLE_COPY_AND_ASSIGN(ZOpenGLRenderer);
//Resource Generation Thread Request
class ResourceGenerationThreadRequest : public ZThreadRequest
{
public:
//Default Constructor
ResourceGenerationThreadRequest() : ZThreadRequest(true) { }
//Concurrency control lock for resource generation and cleanup
ZMutex ResourceMutex;
//Indicator that we have a pending resource request
bool bPendingResourceRequest;
//Resource Generation Requests
ZArray< ZPtr<ZOpenGLDataBuffer> > DataBufferGenerateRequests;
ZArray< ZPtr<ZOpenGLShader> > ShaderGenerateRequests;
ZArray< ZPtr<ZOpenGLShaderProgram> > ShaderProgramGenerateRequests;
ZArray< ZPtr<ZOpenGLDimensionTexture> > DimensionTextureGenerateRequests;
ZArray<ZPtr<ZOpenGLSampler> > SamplerGenerateRequests;
ZArray< ZPtr<ZOpenGLFramebufferRenderTarget> > FrameBufferGenerateRequests;
ZArray< ZPtr<ZOpenGLRenderBuffer> > RenderBufferGenerateRequests;
ZArray< ZPtr<ZOpenGLVertexParams> > VertexParamsGenerateRequests;
//Resource Delete Requests
ZArray< ZPair<ZOpenGLResourceType, GLuint> > ResourceDeleteRequests;
//Subclass Implementation
virtual void Execute( ZThread *_threadObj );
};
protected:
//The initialization window
SST_Window InitializationWindow;
//The OpenGL Context for this renderer
SST_OpenGLContext GLContext;
//Indicates we own the GLContext
bool bOwnsContext;
//The Current Render State
ZRenderState *CurrentRenderState;
//Resource Request Object
ZPtr<ResourceGenerationThreadRequest> ResourceThreadRequest;
//Subclass Override
virtual bool init();
//Subclass Override
virtual void initThread();
//Subclass Override
virtual void shutdown();
//Subclass Override
virtual void shutdownThread();
//Subclass Override
virtual void Draw(ZArray<ZDrawData*,
ZArrayAllocator< ZDrawData*, ZRB_DEFAULT_DRAWDATA_BUFFER_SIZE> >& _renderList,
ZRenderTarget* _renderTarget);
public:
/*
Constructor.
Initializes this renderer with the given OpenGL context.
The provided window handle is only used for binding to a window so that OpenGL values can be obtained. In order
to render to the provided window, a ZWindowRenderTarget will need to be created using that window handle after
the renderer has finished initializing.
@param _glContext - the OpenGL context to initialize this renderer with
@param _window - window to initialize this renderer with
@param _ownContext - indicates whether this renderer 'owns' the context and should clean up when destructed
*/
ZOpenGLRenderer(SST_OpenGLContext _glContext, SST_Window _window, bool _ownContext);
/*
Destructor.
*/
~ZOpenGLRenderer();
/*
public ZOpenGLRenderer::DeleteResource
This will ask the renderer thread to clean up a previously generated OpenGL resource.
@param _type - the type of resource
@param _handle - the handle to the resource
@return (void)
@context (all)
*/
void DeleteResource(ZOpenGLResourceType _type, GLuint _handle);
//////////////////////////
/* Logistics Operations */
//////////////////////////
//Subclass Override
virtual ZPtr<ZDataBuffer> CreateDataBuffer(ZDataBufferType _type,
ZDataBufferUsage _usage,
size_t _size);
//Subclass Override
virtual ZPtr<ZDrawParams> CreateDrawParams(ZDrawParamsType _type);
//Subclass Override
virtual ZPtr<ZFramebufferRenderTarget> CreateFrameBufferRenderTarget(size_t _width, size_t _height);
//Subclass Override
virtual ZPtr<ZRenderBuffer> CreateRenderBuffer(ZRenderBufferType _type, size_t _width, size_t _height);
//Subclass Override
virtual ZPtr<ZSampler> CreateSampler();
//Subclass Override
virtual ZPtr<ZShader> CreateShader(ZShaderType _type);
//Subclass Override
virtual ZPtr<ZShaderProgram> CreateShaderProgram();
//Subclass Override
virtual ZPtr<ZTexture> CreateTexture(ZTextureType _type, ZTextureFormat _format, ZTextureUsage _usage, const ZBitmap& _bitmap, bool _generateMipmaps);
//Subclass Override
virtual ZPtr<ZRenderTarget> CreateWindowRenderTarget(SST_Window _window,
size_t _screenIndex);
};
#endif

View File

@@ -0,0 +1,162 @@
/*
ZOpenGLSampler.hpp
Author: James Russell <jcrussell@762studios.com>,
Chris Ertel <crertel@762studios.com>
Created: 7/1/2012
Purpose:
OpenGL implementation of the ZSampler interface class.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLSAMPLER_HPP
#define _ZOPENGLSAMPLER_HPP
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZSamplerBase.hpp>
#include <SST/SST_GLAPI.h>
//Forward Declarations
class ZOpenGLRenderer;
struct ZOpenGLSamplerState
{
GLenum SWrapMode; //Wrapping mode for S
GLenum TWrapMode; //Wrapping mode for T (unused for 1D)
GLenum RWrapMode; //Wrapping mode for R (unused for 1D, 2D)
GLenum MinFilter; //Minification Filter (including mip filter)
GLenum MagFilter; //Magnification Filter
float MaxAnisotropy; //Maximum Anisotropy (< 2.0 has no effect)
float MinLOD; //Minimum LOD
float MaxLOD; //Maximum LOD
float LODBias; //LOD Bias
float BorderColor[4]; //RGBA Border Color
GLenum CompareMode; //Sampler Comparison Mode
GLenum CompareFunc; //Sampler Comparison Function
};
//OpenGL implementation of the ZSampler interface class
class ZOpenGLSampler : public ZSamplerBase
{
private:
DISABLE_COPY_AND_ASSIGN(ZOpenGLSampler);
protected:
//The current renderer
ZOpenGLRenderer* Renderer;
//Sampler State
ZOpenGLSamplerState OpenGLSamplerState;
public:
//OpenGL Handle for the Sampler object
GLuint GLHandle;
//Gets the OpenGL Sampler State
const ZOpenGLSamplerState& GetGLSamplerState()
{
switch (State.SWrapMode)
{
case ZSWM_CLAMP_EDGE: OpenGLSamplerState.SWrapMode = GL_CLAMP_TO_EDGE; break;
case ZSWM_CLAMP_BORDER: OpenGLSamplerState.SWrapMode = GL_CLAMP_TO_BORDER; break;
case ZSWM_MIRROR_REPEAT: OpenGLSamplerState.SWrapMode = GL_MIRRORED_REPEAT; break;
case ZSWM_REPEAT: OpenGLSamplerState.SWrapMode = GL_REPEAT; break;
default: OpenGLSamplerState.SWrapMode = GL_INVALID_ENUM; break;
}
switch (State.TWrapMode)
{
case ZSWM_CLAMP_EDGE: OpenGLSamplerState.TWrapMode = GL_CLAMP_TO_EDGE; break;
case ZSWM_CLAMP_BORDER: OpenGLSamplerState.TWrapMode = GL_CLAMP_TO_BORDER; break;
case ZSWM_MIRROR_REPEAT: OpenGLSamplerState.TWrapMode = GL_MIRRORED_REPEAT; break;
case ZSWM_REPEAT: OpenGLSamplerState.TWrapMode = GL_REPEAT; break;
default: OpenGLSamplerState.TWrapMode = GL_INVALID_ENUM; break;
}
switch (State.RWrapMode)
{
case ZSWM_CLAMP_EDGE: OpenGLSamplerState.RWrapMode = GL_CLAMP_TO_EDGE; break;
case ZSWM_CLAMP_BORDER: OpenGLSamplerState.RWrapMode = GL_CLAMP_TO_BORDER; break;
case ZSWM_MIRROR_REPEAT: OpenGLSamplerState.RWrapMode = GL_MIRRORED_REPEAT; break;
case ZSWM_REPEAT: OpenGLSamplerState.RWrapMode = GL_REPEAT; break;
default: OpenGLSamplerState.RWrapMode = GL_INVALID_ENUM; break;
}
switch(State.MagFilter)
{
case ZSMAGF_NEAREST: OpenGLSamplerState.MagFilter = GL_NEAREST; break;
case ZSMAGF_LINEAR: OpenGLSamplerState.MagFilter = GL_LINEAR; break;
default: OpenGLSamplerState.MagFilter = GL_INVALID_ENUM; break;
}
switch(State.MinFilter)
{
case ZSMINF_NEAREST: OpenGLSamplerState.MinFilter = GL_NEAREST; break;
case ZSMINF_NEAREST_MIP_NEAREST: OpenGLSamplerState.MinFilter = GL_NEAREST_MIPMAP_NEAREST; break;
case ZSMINF_NEAREST_MIP_LINEAR: OpenGLSamplerState.MinFilter = GL_NEAREST_MIPMAP_LINEAR; break;
case ZSMINF_LINEAR: OpenGLSamplerState.MinFilter = GL_LINEAR; break;
case ZSMINF_LINEAR_MIP_NEAREST: OpenGLSamplerState.MinFilter = GL_LINEAR_MIPMAP_NEAREST; break;
case ZSMINF_LINEAR_MIP_LINEAR: OpenGLSamplerState.MinFilter = GL_LINEAR_MIPMAP_LINEAR; break;
default: OpenGLSamplerState.MinFilter = GL_INVALID_ENUM; break;
}
OpenGLSamplerState.MaxAnisotropy = State.MaxAnisotropy;
OpenGLSamplerState.MinLOD = State.MinLOD;
OpenGLSamplerState.MaxLOD = State.MaxLOD;
OpenGLSamplerState.LODBias = State.LODBias;
OpenGLSamplerState.BorderColor[0] = State.BorderColor[0];
OpenGLSamplerState.BorderColor[1] = State.BorderColor[1];
OpenGLSamplerState.BorderColor[2] = State.BorderColor[2];
OpenGLSamplerState.BorderColor[3] = State.BorderColor[3];
switch(State.CompareMode)
{
case ZSCM_NONE: OpenGLSamplerState.CompareMode = GL_NONE; break;
case ZSCM_COMPARE_REF_TO_TEXTURE: OpenGLSamplerState.CompareMode = GL_COMPARE_REF_TO_TEXTURE; break;
default: OpenGLSamplerState.CompareMode = GL_INVALID_ENUM; break;
}
switch(State.CompareFunc)
{
case ZSCF_NEVER: OpenGLSamplerState.CompareFunc = GL_NEVER; break;
case ZSCF_ALWAYS: OpenGLSamplerState.CompareFunc = GL_ALWAYS; break;
case ZSCF_EQUAL: OpenGLSamplerState.CompareFunc = GL_EQUAL; break;
case ZSCF_NOT_EQUAL: OpenGLSamplerState.CompareFunc = GL_NOTEQUAL; break;
case ZSCF_LESS: OpenGLSamplerState.CompareFunc = GL_LESS; break;
case ZSCF_LESS_EQUAL: OpenGLSamplerState.CompareFunc = GL_LEQUAL; break;
case ZSCF_GREATER: OpenGLSamplerState.CompareFunc = GL_GREATER; break;
case ZSCF_GREATER_EQUAL: OpenGLSamplerState.CompareFunc = GL_GEQUAL; break;
default: OpenGLSamplerState.CompareFunc = GL_INVALID_ENUM; break;
}
return OpenGLSamplerState;
}
/*
Default Constructor.
*/
ZOpenGLSampler(ZOpenGLRenderer* _renderer);
/*
Destructor.
*/
~ZOpenGLSampler();
};
#endif

View File

@@ -0,0 +1,66 @@
/*
ZOpenGLShader.hpp
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 04/20/2011
Purpose:
OpenGL implementation of the shader interface.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLSHADER_HPP
#define _ZOPENGLSHADER_HPP
#include <ZRenderer/ZShaderBase.hpp>
#include <ZUtil/ZUtil.hpp>
#include <SST/SST_GLAPI.h>
//Forward Declarations
class ZOpenGLRenderer;
/*
OpenGL Shader Implementation.
*/
class ZOpenGLShader : public ZShaderBase
{
private:
DISABLE_COPY_AND_ASSIGN(ZOpenGLShader);
protected:
//The renderer that created us
ZOpenGLRenderer* Renderer;
//Method used to compile the shader
static void Compile_(ZThread* _thread, void* _shader);
public:
//OpenGL Shader Handle
GLuint GLHandle;
/*
Constructor.
@param _renderer - the current renderer instance
@param _type - the type of shader
*/
ZOpenGLShader(ZOpenGLRenderer* _renderer, ZShaderType _type);
/*
Destructor.
*/
virtual ~ZOpenGLShader();
//Subclass Override
virtual bool Compile();
};
#endif

View File

@@ -0,0 +1,69 @@
/*
ZOpenGLShaderProgram.h
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 04/03/2011
Purpose:
TODO
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLSHADERPROGRAM_HPP
#define _ZOPENGLSHADERPROGRAM_HPP
#include <ZRenderer/ZShaderProgramBase.hpp>
#include <ZRenderer/ZOpenGLShader.hpp>
#include <SST/SST_GLAPI.h>
//Forward Declarations
class ZOpenGLRenderer;
//Struct we use to track opengl handles for uniform blocks and block members
struct ZOpenGLUniformBlockData
{
GLuint BlockIndex; //OpenGL Index for UniformBlocks[i]
ZArray<GLuint> MemberIndices; //OpenGL Index for UniformBlocks[i].Members[i]
};
//OpenGL Implementation of ZShaderProgram
class ZOpenGLShaderProgram : public ZShaderProgramBase
{
protected:
//Parent renderer
ZOpenGLRenderer* Renderer;
//Static method used to link a shader program
static void Link_(ZThread* _thread, void* _shaderProgram);
public:
//Handle to the program in OpenGL
GLuint GLHandle;
//Our set of uniform indices, sampler indices, and stream indices
ZArray<ZOpenGLUniformBlockData> OpenGLUniformBlockData;
ZArray<GLuint> OpenGLSamplerData;
ZArray<GLuint> OpenGLStreamData;
/*
Constructor.
@param _renderer - the current renderer
*/
ZOpenGLShaderProgram(ZOpenGLRenderer* _renderer);
//Virtual destructor
virtual ~ZOpenGLShaderProgram();
//Subclass Implementation
virtual bool Link();
};
#endif

View File

@@ -0,0 +1,92 @@
/*
ZOpenGLTextureRenderTarget.h
Author: Chris Ertel (cre1)
Purpose: TODO
Changelog
2011/05/22 - creation (cre1)
*/
#pragma once
#ifndef _ZOPENGLTEXTURERENDERTARGET_H
#define _ZOPENGLTEXTURERENDERTARGET_H
#include <ZRendering/ZTextureRenderTarget.h>
#include <ZRendering/ZOpenGLRenderer.h>
#include <GLee/GLee.h>
class ZOpenGLTexture;
class ZOpenGLTextureRenderTarget;
class ZOpenGLTextureRenderTargetLoadRequest : public ZThreadRequest
{
private:
ZOpenGLTextureRenderTarget *Target;
public:
ZOpenGLTextureRenderTargetLoadRequest(ZOpenGLTextureRenderTarget *_target);
void Execute(ZThread *_renderer);
};
class ZOpenGLTextureRenderTarget : public ZTextureRenderTarget
{
friend class ZOpenGLTextureRenderTargetLoadRequest;
protected:
//The OpenGL Texture
// ZOpenGLTexture Tex;
//The glhandle to the FrameBuffer
GLuint FrameBufferHandle;
//The glhandle to the RenderBuffer
GLuint RenderBufferHandle;
float ClearColor[4];
int Width;
int Height;
int BPP;
public:
//Default Constructor
ZOpenGLTextureRenderTarget(ZOpenGLRenderer *_renderer, int _width, int _height, int _bpp, int _rgbaSize, float *_clearColor = NULL);
//Subclass Implementation
bool Activate();
//Subclass Implementation
void Deactivate();
void SetClearColor(float r, float g, float b, float a);
void SetClearColor(float* _in);
//Subclass Implementation (Currently Non-Functional)
void SetDimensions(int _width, int _height)
{
URFP(_width);
URFP(_height);
}
//Subclass Implementation (Currently Non-Functional)
void SetBitsPerPixel(int _bbp)
{
URFP(_bbp);
}
//Subclass Implementation (Currently Non-Functional)
void SetRGBASize(int _rgbaSize)
{
URFP(_rgbaSize);
}
//Gets the render target as a texture
ZTexture* GetTexture();
//Gets the texture as a render target
ZRenderTarget* GetRenderTarget();
};
#endif

View File

@@ -0,0 +1,46 @@
/*
ZOpenGLVertexParams.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 12/13/2012
Purpose:
OpenGL specific version of ZVertexParams that implements VAOs.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLVERTEXPARAMS_HPP
#define _ZOPENGLVERTEXPARAMS_HPP
#include <ZRenderer/ZVertexParams.hpp>
#include <ZRenderer/ZOpenGLShaderProgram.hpp>
#include <SST/SST_GLAPI.h>
class ZOpenGLRenderer;
class ZOpenGLVertexParams : public ZVertexParams
{
public:
ZOpenGLVertexParams(ZOpenGLRenderer* renderer) :
Renderer(renderer), vaoHandle(0), arrayBufferBound(0), elementBufferBound(0)
{
}
~ZOpenGLVertexParams();
void UpdateDirty(ZOpenGLShaderProgram* prgm);
ZOpenGLRenderer* Renderer;
GLuint vaoHandle; //Vertex Array Object (VAO) handle
GLuint arrayBufferBound; //VBO (GL_ARRAY_BUFFER) that was bound
GLuint elementBufferBound; //VBO (GL_ELEMENT_BUFFER) that was bound
};
#endif

View File

@@ -0,0 +1,60 @@
/*
ZOpenGLWindowRenderTarget.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 04/01/2011
Purpose:
Initializes and manages an OpenGL window.
License:
TODO
*/
#pragma once
#ifndef _ZOPENGLWINDOWRENDERTARGET_HPP
#define _ZOPENGLWINDOWRENDERTARGET_HPP
#include <ZRenderer/ZWindowRenderTargetBase.hpp>
//Forward Declarations
class ZOpenGLRenderer;
/*
Screen Render Target for the OpenGL library.
*/
class ZOpenGLWindowRenderTarget : public ZWindowRenderTargetBase
{
private:
DISABLE_COPY_AND_ASSIGN(ZOpenGLWindowRenderTarget);
protected:
//Renderer Instance
ZOpenGLRenderer *Renderer;
public:
//OpenGL Context
SST_OpenGLContext GLContext;
/*
Parameterized Constructor.
@param _renderer - the renderer instance
@param _glContext - the OpenGL context to bind to this window
@param _window - the window instance (created with libsst-wm)
@param _screen - the screen index chosen
*/
ZOpenGLWindowRenderTarget(ZOpenGLRenderer* _renderer, SST_OpenGLContext _glContext, SST_Window _window, size_t _screenIndex);
/*
Destructor.
*/
~ZOpenGLWindowRenderTarget();
//Subclass Override
virtual bool SwapBuffers();
};
#endif

View File

@@ -0,0 +1,71 @@
/*
ZRenderBuffer.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 04/03/2011
Purpose:
Buffer that can be used for depth and stencil buffers in frame buffer render targets
for off-screen rendering.
License:
TODO
*/
#pragma once
#ifndef _ZRENDERBUFFER_HPP
#define _ZRENDERBUFFER_HPP
#include <ZRenderer/ZRendererBuild.hpp>
//Enumeration of render buffer type
enum ZRenderBufferType
{
ZRBT_DEPTH16, //16-bit Depth Storage
ZRBT_DEPTH24, //24-bit Depth Storage
ZRBT_DEPTH32, //32-bit Depth Storage
ZRBT_STENCIL8, //8-bit Stencil Storage
ZRBT_DEPTH24_STENCIL8, //24-bit Depth and 8-bit Stencil
ZRBT_SIZE
};
class ZRenderBuffer
{
public:
//Virtual Destructor
virtual ~ZRenderBuffer() { }
/*
public ZRenderBuffer::GetHeight
Gets the height value for the render buffer (in pixels).
@return (size_t) - height value
@context (all)
*/
virtual size_t GetHeight() = 0;
/*
virtual public ZRenderBuffer::GetType
Gets the type of render buffer this is set up to be (depth or stencil).
@return (ZRenderBufferType) - the type of render buffer
@context (all)
*/
virtual ZRenderBufferType GetType() = 0;
/*
public ZRenderBuffer::GetWidth
Gets the width value for the render buffer (in pixels).
@return (size_t) - width value
@context (all)
*/
virtual size_t GetWidth() = 0;
};
#endif

View File

@@ -0,0 +1,114 @@
/*
ZRenderTarget.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 03/20/2011
Purpose:
Defines an interface for a rendering surface.
License:
TODO
*/
#pragma once
#ifndef _ZRENDERTARGET_HPP
#define _ZRENDERTARGET_HPP
#include <ZRenderer/ZRendererBuild.hpp>
#include <ZRenderer/ZRendererResource.hpp>
//Enumeration of possible render target types
enum ZRenderTargetType
{
ZRTT_WINDOW, //Used for window render targets
ZRTT_FRAMEBUFFER, //Used for frame buffer render targets
ZRTT_SIZE
};
//Used to flag which buffers should be cleared, and to what value
struct ZRenderTargetClearFlags
{
bool AutoClear; //Indicates that the renderer should 'clear' the toggled buffers before rendering to this target
bool ClearColorBuffer; //Indicates we should clear the color buffer
bool ClearDepthBuffer; //Indicates we should clear the depth buffer
bool ClearStencilBuffer; //Indicates we should clear the stencil buffer
float ClearColor[4]; //RGBA clear color to use
//Default Constructor
ZRenderTargetClearFlags()
: AutoClear(true), ClearColorBuffer(true), ClearDepthBuffer(true), ClearStencilBuffer(false)
{
ClearColor[0] = 0.0f;
ClearColor[1] = 0.0f;
ClearColor[2] = 0.0f;
ClearColor[3] = 1.0f;
}
};
/*
RenderTarget Interface.
*/
class ZRenderTarget : public ZRendererResource
{
public:
//Virtual Destructor
virtual ~ZRenderTarget() { }
/*
public ZRenderTarget::GetClearFlags
Gets the current set of clear flags for this render target.
@return (const ZRenderTargetClearFlags&) - clearing flags for this render target
@context (all)
*/
virtual const ZRenderTargetClearFlags& GetClearFlags() = 0;
/*
public ZRenderTarget::GetHeight
Gets the height value for the render target (in pixels).
@return (size_t)
@context (all)
*/
virtual size_t GetHeight() = 0;
/*
public ZRenderTarget::GetType
Gets the type of render target.
@return (ZRenderTargetType) - the type of render target
@context (all)
*/
virtual ZRenderTargetType GetType() = 0;
/*
public ZRenderTarget::GetWidth
Gets the width value for the render target (in pixels).
@return (size_t)
@context (all)
*/
virtual size_t GetWidth() = 0;
/*
public ZRenderTarget::SetClearFlags
Sets the clear flags for this render target.
@param _flags - flags structure which has our clear settings
@return (bool) - true if able to set flags, false if resource contended
@context (all)
*/
virtual bool SetClearFlags(const ZRenderTargetClearFlags& _flags) = 0;
};
#endif

View File

@@ -0,0 +1,559 @@
/*
ZRenderer.hpp
Authors: Patrick Baggett <ptbaggett@762studios.com>,
Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 3/20/2011
Purpose:
Defines an interface for rendering to screen in graphics-library agnostic fashion.
License:
TODO
*/
#pragma once
#ifndef _ZRENDERER_HPP
#define _ZRENDERER_HPP
#include <ZRenderer/ZRendererBuild.hpp>
#include <SST/SST_WM.h>
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZDataBuffer.hpp>
#include <ZRenderer/ZRenderTarget.hpp>
#include <ZRenderer/ZFramebufferRenderTarget.hpp>
#include <ZRenderer/ZWindowRenderTarget.hpp>
#include <ZRenderer/ZTexture.hpp>
#include <ZRenderer/ZSampler.hpp>
#include <ZRenderer/ZShader.hpp>
#include <ZRenderer/ZShaderProgram.hpp>
#include <ZRenderer/ZShaderParams.hpp>
#include <ZRenderer/ZVertexParams.hpp>
#include <ZRenderer/ZIndexParams.hpp>
//Forward Declarations
class ZRenderer;
//Typedef for a frame context (opaque handle)
typedef void* ZFrameContext;
//Rendering phases the ZRenderer can exist in
enum ZRenderPhase
{
ZRP_UNINITIALIZED, //Renderer has yet to be initialized
ZRP_IDLE, //Renderer is idle (no frame contexts currently created)
ZRP_FRAME_ACCEPTING, //Renderer is accepting SubmitDrawData calls (frame contexts have been created)
ZRP_FRAME_RENDERING, //Renderer is rendering Geometry (a frame context is rendering)
ZRP_SIZE
};
//Render State Structure, used to set up a render state for SubmitDrawData calls
struct ZRenderState
{
public:
//The default constructor for render state initializes to a sane configuration
ZRenderState()
: EnableStencilTest(false),
EnableBlend(true),
SourceBlendFunc(SBFV_SRC_ALPHA),
DestBlendFunc(DBFV_ONE_MINUS_SRC_ALPHA),
blendR(0), blendG(0), blendB(0), blendA(0),
EnableCullTest(false),
EnableDepthTest(true),
DepthFunc(DFV_LESS_THAN),
EnableDepthWrite(true) { }
/////////////////////////////////
/* Draw Sort Relevant Settings */
/////////////////////////////////
// BLENDING
uint32_t EnableBlend:1; //Enables Blending
uint32_t SourceBlendFunc:4; //Specifies Source Blending Function
uint32_t DestBlendFunc:3; //Specifies Destination Blending Function
enum SourceBlendFuncValue //Values for the Source Blend Function
{
SBFV_ZERO,
SBFV_ONE,
SBFV_SRC_COLOR,
SBFV_ONE_MINUS_SRC_COLOR,
SBFV_DST_COLOR,
SBFV_ONE_MINUS_DST_COLOR,
SBFV_SRC_ALPHA,
SBFV_ONE_MINUS_SRC_ALPHA,
SBFV_DST_ALPHA,
SBFV_ONE_MINUS_DST_ALPHA,
SBFV_CONSTANT_COLOR,
SBFV_ONE_MINUS_CONSTANT_COLOR,
SBFV_CONSTANT_ALPHA,
SBFV_ONE_MINUS_CONSTANT_ALPHA,
SBFV_SRC_ALPHA_SATURATE,
SBFV_SIZE
};
enum DestBlendFuncValue //Values for the Destination Blend Function
{
DBFV_ZERO,
DBFV_ONE,
DBFV_SRC_COLOR,
DBFV_ONE_MINUS_SRC_COLOR,
DBFV_DST_COLOR,
DBFV_ONE_MINUS_DST_COLOR,
DBFV_SRC_ALPHA,
DBFV_ONE_MINUS_SRC_ALPHA,
DBFV_DST_ALPHA,
DBFV_ONE_MINUS_DST_ALPHA,
DBFV_CONSTANT_COLOR,
DBFV_ONE_MINUS_CONSTANT_COLOR,
DBFV_CONSTANT_ALPHA,
DBFV_ONE_MINUS_CONSTANT_ALPHA,
DBFV_SIZE
};
float blendR; //Red value used when blending needs a constant color
float blendG; //Green value used when blending needs a constant color
float blendB; //Blue value used when blending needs a constant color
float blendA; //Alpha value used when blending needs a constant color
// DEPTH
uint32_t EnableDepthTest:1; //Bit Enables Depth Testing
uint32_t EnableDepthWrite:1; //Sets Depth Buffer to Read Only (Depth Values are not written)
uint32_t DepthFunc:3; //Specifies Depth Function
enum DepthFuncValue //Values for the Depth Function
{
DFV_NEVER,
DFV_LESS_THAN,
DFV_EQUAL,
DFV_LESS_THAN_EQUAL,
DFV_GREATER_THAN,
DFV_NOT_EQUAL,
DFV_GREATER_THAN_EQUAL,
DFV_ALWAYS,
DFV_SIZE
};
// CULLING
uint32_t EnableCullTest:1; //Enable or disable face culling.
uint32_t CullMode:2; //Sets up front/back/both culling
enum CullModeValue
{
CMV_FRONT,
CMV_BACK,
CMV_FRONT_AND_BACK,
CMV_SIZE
};
uint32_t CullWinding:1; //Sets winding for culling
enum CullWindingValue
{
CWV_CW,
CWV_CCW,
CWV_SIZE
};
// STENCIL
uint32_t EnableStencilTest:1; //Bit Enables Stencil Testing
uint32_t StencilTestFuncFront:4; //Specifies the stencil comparisons
uint32_t StencilTestMaskFront:8; //Mask for front facing stencil post-op
uint32_t StencilTestReferenceFront:8; //Reference value for front facing stencil post-op
uint32_t StencilTestFuncBack:4; //Specifies the stencil comparisons
uint32_t StencilTestMaskBack:8; //Mask for back facing stencil post-op
uint32_t StencilTestReferenceBack:8; //Reference value for back facing stencil post-op
enum StencilComparisonsValue //Values for the stencil comparisons
{
SCV_NEVER,
SCV_ALWAYS,
SCV_LESS,
SCV_LEQUAL,
SCV_EQUAL,
SCV_GEQUAL,
SCV_GREATER,
SCV_NOTEQUAL,
SCV_SIZE
};
uint32_t StencilOpStencilFailFront:3; //Specifies the stencil operation when stencil test fails for front-facing polys
uint32_t StencilOpStencilPassDepthFailFront:3; //Specifies the stencil operation when stencil test succeeds and depth test fails fails for front-facing polys
uint32_t StencilOpStencilPassDepthPassFront:3; //Specifies the stencil operation when stencil and depth tests pass fails for front-facing polys
uint32_t StencilOpStencilFailBack:3; //Specifies the stencil operation when stencil test fails for back-facing polys
uint32_t StencilOpStencilPassDepthFailBack:3; //Specifies the stencil operation when stencil test succeeds and depth test fails for back-facing polys
uint32_t StencilOpStencilPassDepthPassBack:3; //Specifies the stencil operation when stencil and depth tests pass for back-facing polys
enum StencilOperationValue //Values for the stencil operations
{
SOV_KEEP,
SOV_ZERO,
SOV_REPLACE,
SOV_INCR,
SOV_INCR_WRAP,
SOV_DECR,
SOV_DECR_WRAP,
SOV_INVERT,
SOV_SIZE
};
};
class ZRenderer : public ZThread
{
protected:
//Default Constructor
ZRenderer() : ZThread("ZRenderer Thread") { }
public:
//Virtual Destructor
virtual ~ZRenderer() { }
//////////////////////////
/* Lifecycle Operations */
//////////////////////////
/*
virtual public ZRenderer::Init
Initializes the Renderer for use as a long running subsystem. After this call, the
render thread will be running.
@return (bool)
@context (all)
*/
virtual bool Init() = 0;
/*
virtual public ZRenderer::Shutdown
Shuts down the system and stops the render thread.
@return (void)
@context (all)
*/
virtual void Shutdown() = 0;
///////////////////////////
/* Renderer Data Getters */
///////////////////////////
/*
virtual public ZRenderer::GetCapabilities
Returns a map describing the capabilities and configuration of this renderer. All
renderer implementations must map the following keys:
gl { directx, opengl }
gl.version { 9.0c, 10.0, 10.1, 11.0, 11.1, 2.1, 3.1, 3.2, 3.3 ... }
: version number should always have major.minor format and should be the highest version required
gl.shaderlang { hlsl_40, hlsl_30, hlsl, glsl_14, glsl_13, glsl_12, glsl_11, glsl, ... }
: shading languages accepted should be listed in a comma separated list in order of preference
data_buffer.block_alignment { integer }
: alignment requirement for buffer blocks
frame_buffer_render_target.max_color_attachments { integer }
: maximum number of color buffer attachments
Other keys may be supported depending upon the implementation.
@return (const ZHashMap<ZString, ZString>&) - map of capabilities
@context (all)
*/
virtual const ZHashMap<ZString, ZString>& GetCapabilities() = 0;
/*
virtual public ZRenderer::GetRenderPhase
Gets the current rendering phase.
@return (ZRenderPhase) - current rendering phase
@context (all)
*/
virtual ZRenderPhase GetRenderPhase() = 0;
//////////////////////////
/* Logistics Operations */
//////////////////////////
/*
virtual public ZRenderer::CreateDataBuffer
Creates a data buffer which contains data stored in graphics memory. The data
buffer is created but not initialized with values (use FillBuffer or MapBuffer).
Keep in mind when allocating a buffer that defines block data that determining the
required size to fit all blocks includes taking into account alignment requirements.
The alignment requirement for block data for this renderer can be determined through
the capabilities map with key 'buffer.block_alignment'.
@param _type - the type of buffer to allocate
@param _usage - the usage pattern the buffer will follow
@param _size - the size (in bytes) to allocate
@return (ZDataBuffer) - new data buffer object, NULL if not successful
@context (all)
*/
virtual ZPtr<ZDataBuffer> CreateDataBuffer(ZDataBufferType _type,
ZDataBufferUsage _usage,
size_t _size
) = 0;
/*
virtual public ZRenderer::CreateDrawParams
Creates a draw parameters binding class, which is provided to the draw calls and
is used to bind data to shader variables.
@param _type - the type of draw parameters binding
@return (ZPtr<ZDrawParams>) - new draw parameters object, NULL if not successful
@context (all)
*/
virtual ZPtr<ZDrawParams> CreateDrawParams(ZDrawParamsType _type) = 0;
/*
virtual public ZRenderer::CreateFrameBufferRenderTarget
Function to create a framebuffer-backed render target.
@param _width - number of pixels wide to make the frame buffer
@param _height - number of pixels tall to make the frame buffer
@return (ZPtr<ZFramebufferRenderTarget>) - new frame buffer render target, NULL if not successful
@context (all)
*/
virtual ZPtr<ZFramebufferRenderTarget> CreateFrameBufferRenderTarget(size_t _width, size_t _height) = 0;
/*
virtual public ZRenderer::CreateRenderBuffer
Function to create a render buffer for use in a frame buffer render target.
@param _type - the type of render buffer this will be
@param _width - number of pixels wide to make the render buffer
@param _height - number of pixels tall to make the render buffer
@return (ZPtr<ZRenderBuffer>) - new render buffer, NULL if not successful
@context (all)
*/
virtual ZPtr<ZRenderBuffer> CreateRenderBuffer(ZRenderBufferType _type, size_t _width, size_t _height) = 0;
/*
virtual public ZRenderer::CreateSampler
Creates a sampler object to use as a view onto a texture.
@return (ZPtr<ZSampler>) - new sampler object, NULL if unsuccessful
@context (all)
*/
virtual ZPtr<ZSampler> CreateSampler() = 0;
/*
virtual public ZRenderer::CreateShader
Function to create a shader object for the renderer.
@param _type - type of shader to create:
ZST_SOFT : Soft shaders
ZST_VERTEX : Vertex shaders
ZST_HULL : Hull shaders
ZST_DOMAIN : Domain shaders
ZST_GEOMETRY: Geometry shaders
ZST_FRAGMENT: Fragment (pixel) shaders
@return (ZPtr<ZShader>) - the created shader, NULL if not successful
@context (all)
*/
virtual ZPtr<ZShader> CreateShader(ZShaderType _type) = 0;
/*
virtual public ZRenderer::CreateShaderProgram
Function to create a shader program.
@return (ZPtr<ZShaderProgram>) - new shader program, NULL if not successful
@context (all)
*/
virtual ZPtr<ZShaderProgram> CreateShaderProgram() = 0;
/*
virtual public ZRenderer::CreateTexture
Creates a texture object.
In the case of cube map textures, the bitmap format describes a single 'side'
of the cube map texture.
If the bitmap provided has NULL for data, then the texture storage is initialized
but no data is copied.
@param _type - the type of texture
@param _format - the texture internal storage format
@param _usage - the usage type of the texture
@param _bitmap - bitmap structure containing image format and size, as well as data (can be NULL)
@param _generateMipmaps - indicating whether or not we should generate mipmaps
@return (ZPtr<ZTexture>) - new texture object, NULL if not successful
@context (all)
*/
virtual ZPtr<ZTexture> CreateTexture(ZTextureType _type,
ZTextureFormat _format,
ZTextureUsage _usage,
const ZBitmap& _bitmap,
bool _generateMipmaps) = 0;
/*
virtual public ZRenderer::CreateWindowRenderTarget
Creates a window render target.
@param _window - the window handle (created using libsst-wm)
@param _screenIndex - the screen index bound to the window
@return (ZPtr<ZRenderTarget>) - new window render target, NULL if not successful
@context (all)
*/
virtual ZPtr<ZRenderTarget> CreateWindowRenderTarget(SST_Window _window,
size_t _screenIndex
) = 0;
////////////////////////
/* Frame Data Getters */
////////////////////////
/*
virtual public ZRenderer::GetFrameRenderTarget
Gets the render target set for the given frame context.
@param _frameContext - frame context
@return (ZRenderTarget*) - the render target for the given context
@context (all)
*/
virtual ZRenderTarget* GetFrameRenderTarget(ZFrameContext _frameContext) = 0;
//////////////////////////
/* Rendering Operations */
//////////////////////////
/*
The renderer can maintain a few different states, each of which is described by an enumeration. The various
rendering operations affect this state, and thread synchronization calls such as WaitFrameStart and WaitFrameEnd
will wait until events are triggered after state changes, as follows.
BeginFrame()
| SubmitDrawData()
| | RenderFrame()
| +-------+-------+ |
| | | | |
---------------+---+-------+-------+---+-----------------------+---------------
===============|///////////////////////|///////////////////////|===============
ZRP_IDLE ... =|/ ZRP_FRAME_ACCEPTING /|/ ZRP_FRAME_RENDERING /|= ZRP_IDLE ...
===============|///////////////////////|///////////////////////|===============
| |
+-> WaitFrameStart() +-> WaitFrameEnd()
^ |
| Frame to Render? |
+<----------------------+
Because of the multi threaded nature of ZRenderer, multiple threads can call SubmitDrawData to populate
the render lists full of buffered data to draw. A single call should be placed to BeginFrame for each
frame context that is desired, and a single call to RenderFrame should occur for each frame context that has
been created.
It is guaranteed that order will be maintained between calls to RenderFrame, meaning if RenderFrame is called
for frame context 0, and then afterwards RenderFrame is called for frame context 1, frame context 0 is guaranteed
to render in its entirety before frame context 0 is rendered.
*/
/*
virtual public ZRenderer::BeginFrame
Tells the renderer that threads will begin providing draw data for a frame of rendering. The value returned
is later used as a frame context for render calls.
BeginFrame can be called multiple times, each time returning a new frame context that can be provided
for draw calls.
BeginFrame should be called once for as many frame contexts there will be before beginning render calls
for any of them. Calling BeginFrame after other frames have begun rendering results in undefined
behavior. Frame contexts should never be re-used across multiple render cycles - always ask for a new one.
@param _canvas - the canvas to render to
@return (ZFrameContext) - the frame context that has been created
@context (all)
*/
virtual ZFrameContext BeginFrame(ZPtr<ZRenderTarget> _canvas) = 0;
/*
virtual public ZRenderer::EndFrame
TODO
@param _frameContext - the frame context we are done submitting draw data to
@return (void)
@context (all)
*/
virtual void EndFrame(ZFrameContext _frameContext) = 0;
/*
virtual public ZRenderer::SubmitDrawData
Draws geometry defined in a DataBuffer (Queues them up for rendering).
@param _frameContext - the frame context to provide data for
@param _shaderProgram - the shader program to draw with
@param _shaderParams - the shader parameters binding
@param _vertexParams - the vertex parameters binding
@param _indexParams - the index parameters binding
@param _renderState - the render state to render the geometry with
@param _drawGroup - the draw group to render this call with; objects with lower draw group
are rendered before objects with higher draw group
@return (void)
@context (all)
*/
virtual void SubmitDrawData(ZFrameContext _frameContext,
ZPtr<ZShaderProgram> _shaderProgram,
ZPtr<ZShaderParams> _shaderParams,
ZPtr<ZVertexParams> _vertexParams,
ZPtr<ZIndexParams> _indexParams,
const ZRenderState& _renderState,
int _drawGroup = 0
) = 0;
/*
virtual public ZRenderer::RenderFrame
Renders the frame context.
@param _frameContext - the frame context to render
@return (void)
@context (all)
*/
virtual void RenderFrame(ZFrameContext _frameContext) = 0;
/*
virtual public ZRenderer::WaitFrameStart
Calling thread waits until RenderFrame is called for the given frame context.
@param _frameContext - the frame context to wait for
@return (void)
@context (all)
*/
virtual void WaitFrameStart(ZFrameContext _frameContext) = 0;
/*
virtual public ZRenderer::WaitFrameEnd
Calling thread waits until after the render thread has finished rendering a frame.
@param _frameContext - the frame context to wait for
@return (void)
@context (all)
*/
virtual void WaitFrameEnd(ZFrameContext _frameContext) = 0;
};
#endif

View File

@@ -0,0 +1,259 @@
/*
ZRendererBase.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 3/23/2011
Purpose:
Base implementation of the ZRenderer class, which handles many of the details that
are common to multi threaded renderers.
License:
TODO
*/
#pragma once
#ifndef _ZRENDERERBASE_HPP
#define _ZRENDERERBASE_HPP
#include <ZRenderer/ZRenderer.hpp>
#include <ZRenderer/ZDataBufferBase.hpp>
//Forward Declarations
struct ZFrameData;
//Maximum number of concurrent frame contexts
#ifndef ZRB_MAX_FRAME_CONTEXT_COUNT
#define ZRB_MAX_FRAME_CONTEXT_COUNT (4)
#endif
//Default slab allocation of Draw Objects, will auto correct at runtime if exceeded
#ifndef ZRB_DEFAULT_DRAWDATA_COUNT
#define ZRB_DEFAULT_DRAWDATA_COUNT (128)
#endif
//Default buffer size for a draw list
#ifndef ZRB_DEFAULT_DRAWDATA_BUFFER_SIZE
#define ZRB_DEFAULT_DRAWDATA_BUFFER_SIZE (128)
#endif
/*
Used to contain only the minimum data necessary to draw geometry
and hold no ownership (in smart pointer terms) over the parameters.
*/
struct ZDrawData
{
ZShaderProgram* ShaderProgram; //The shader program we will be drawing with
ZShaderParams* ShaderParams; //The shader parameters we will be using
ZVertexParams* VertexParams; //The vertex parameters we will be using
ZIndexParams* IndexParams; //The index parameters we will be using
ZRenderState RenderState; //The renderer state we will be using
int DrawGroup; //The draw group for drawing data
ZFrameData* Parent; //The parent ZFrameData struct that holds ownership
//Default Constructor
ZDrawData()
: ShaderProgram(NULL),
ShaderParams(NULL), VertexParams(NULL), IndexParams(NULL),
RenderState(), DrawGroup(-1),
Parent(NULL)
{ }
};
/*
Used to contain references to the data necessary to draw geometry per frame. Holds
strong references long enough to ensure parameters do not get deleted.
*/
struct ZFrameData
{
ZArray< ZPtr<ZShaderProgram> > ShaderPrograms; //The shader programs we will be using
ZArray< ZPtr<ZShaderParams> > ShaderParams; //The shader parameters we will be using
ZArray< ZPtr<ZVertexParams> > VertexParams; //The vertex parameters we will be using
ZArray< ZPtr<ZIndexParams> > IndexParams; //The index parameters we will be using
ZPtr<ZRenderTarget> RenderTarget; //The render target for this frame
ZArray<ZDrawData*,
ZArrayAllocator<ZDrawData*, ZRB_DEFAULT_DRAWDATA_BUFFER_SIZE> > DrawData; //Our set of draw data
//Concurrency Control Variables
ZMutex FrameLock;
ZEvent FrameEndSignal;
ZEvent FrameStartSignal;
};
/*
ZRendererBase class, which can be extended by GL-specific renderers.
*/
class ZRendererBase : public ZRenderer
{
private:
//The renderer lock
ZMutex RendererLock;
//Current Render Phase
volatile ZRenderPhase Phase;
//Slab allocator for ZFrameData
ZSlabAllocator<ZDrawData, ZRB_DEFAULT_DRAWDATA_COUNT> DrawDataAllocator;
//Slab allocator for ZFrameData
ZSlabAllocator<ZFrameData, ZRB_MAX_FRAME_CONTEXT_COUNT> FrameDataAllocator;
//The frame data available queue (available for use)
ZRingBuffer<ZFrameData*,
ZRingBuffer_OverflowUnsafe,
ZArrayAllocator<ZFrameData*, ZRB_MAX_FRAME_CONTEXT_COUNT> > FrameAvailableQueue;
//The frame data render queue (pending renders)
ZRingBuffer<ZFrameData*,
ZRingBuffer_OverflowUnsafe,
ZArrayAllocator<ZFrameData*, ZRB_MAX_FRAME_CONTEXT_COUNT> > FrameRenderQueue;
//The frame data we are rendering
ZFrameData* CurrentFrame;
protected:
//Capabilities mapping
ZHashMap<ZString, ZString> Capabilities;
//Protected Constructor
ZRendererBase();
/*
virtual protected ZRendererBase::init
This will be called by ZRendererBase::Init and should handle subclass
initialization.
@return (bool) - true if successful, false otherwise
*/
virtual bool init() = 0;
/*
virtual protected ZRendererBase::shutdown
This will be called by ZRendererBase::Shutdown and should handle subclass
shutdown.
@return (void)
*/
virtual void shutdown() = 0;
/*
virtual protected ZRendererBase::Draw
Method which should, given a list of render data, draw it to the provided render target.
@param _renderList - the sorted list of draw data objects to draw
@param _renderTarget - the render target to draw to
@return (void)
*/
virtual void Draw(ZArray<ZDrawData*,
ZArrayAllocator<ZDrawData*, ZRB_DEFAULT_DRAWDATA_BUFFER_SIZE> >& _renderList,
ZRenderTarget* _renderTarget) = 0;
public:
/*
Destructor.
*/
virtual ~ZRendererBase();
//////////////////////////
/* Lifecycle Operations */
//////////////////////////
//Subclass Implementation
virtual bool Init();
//Subclass Implementation
virtual void Shutdown();
///////////////////////////
/* Renderer Data Getters */
///////////////////////////
//Subclass Override
virtual const ZHashMap<ZString, ZString>& GetCapabilities();
//Subclass Override
virtual ZRenderPhase GetRenderPhase();
//////////////////////////
/* Logistics Operations */
//////////////////////////
//Subclass Implementation
virtual ZPtr<ZDrawParams> CreateDrawParams(ZDrawParamsType _type);
//Not Implemented
virtual ZPtr<ZDataBuffer> CreateDataBuffer(ZDataBufferType _type,
ZDataBufferUsage _usage,
size_t _size
) = 0;
//Not Implemented
virtual ZPtr<ZFramebufferRenderTarget> CreateFrameBufferRenderTarget(size_t _width, size_t _height) = 0;
//Not Implemented
virtual ZPtr<ZRenderBuffer> CreateRenderBuffer(ZRenderBufferType _type, size_t _width, size_t _height) = 0;
//Not Implemented
virtual ZPtr<ZSampler> CreateSampler() = 0;
//Not Implemented
virtual ZPtr<ZShader> CreateShader(ZShaderType _type) = 0;
//Not Implemented
virtual ZPtr<ZShaderProgram> CreateShaderProgram() = 0;
//Not Implemented
virtual ZPtr<ZTexture> CreateTexture(ZTextureType _type, ZTextureFormat _format, ZTextureUsage _usage, const ZBitmap& _bitmap, bool _generateMipmaps) = 0;
//Not Implemented
virtual ZPtr<ZRenderTarget> CreateWindowRenderTarget(SST_Window _window, size_t _screenIndex) = 0;
////////////////////////
/* Frame Data Getters */
////////////////////////
//Subclass Implementation
virtual ZRenderTarget* GetFrameRenderTarget(ZFrameContext _frameContext);
//////////////////////////
/* Rendering Operations */
//////////////////////////
//Subclass Implementation
virtual ZFrameContext BeginFrame(ZPtr<ZRenderTarget> _canvas);
virtual void EndFrame(ZFrameContext _frameContext);
//Subclass Implementation
virtual void SubmitDrawData(ZFrameContext _frameContext,
ZPtr<ZShaderProgram> _shaderProgram,
ZPtr<ZShaderParams> _shaderParams,
ZPtr<ZVertexParams> _vertexParams,
ZPtr<ZIndexParams> _indexParams,
const ZRenderState& _renderState,
int _drawGroup = 0
);
//Subclass Implementation
virtual void RenderFrame(ZFrameContext _frameContext);
//Subclass Implementation
virtual void WaitFrameStart(ZFrameContext _frameContext);
//Subclass Implementation
virtual void WaitFrameEnd(ZFrameContext _frameContext);
//Implementation of the render thread
virtual ZThreadReturn run(uint64_t _dt);
};
#endif

View File

@@ -0,0 +1,49 @@
/*
ZRendererBuild.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 5/21/2012
Purpose:
Used to generate definitions for the preprocessor using only compiler-set variables
and include headers necessary to ensure previous project build files are included
in the correct order.
License:
TODO
*/
#pragma once
#ifndef _ZRENDERERBUILD_HPP
#define _ZRENDERERBUILD_HPP
#include "ZBuild.hpp"
#include <ZUtil/ZUtilBuild.hpp>
//Version number constants for ZRenderer
#define ZRENDERER_VERSION_MAJOR 0x01
#define ZRENDERER_VERSION_MINOR 0x00
#define ZRENDERER_VERSION_PATCH 0x0000
#define ZRENDERER_VERSION (ZRENDERER_VERSION_MAJOR << 24) | (ZRENDERER_VERSION_MINOR << 16) | (ZRENDERER_VERSION_PATCH)
#define ZRENDERER_VERSION_STRING "1.0.0"
#if ZASSERT_RENDERER_ENABLE
//ZASSERT_RENDERER macro, which will trigger a breakpoint if the condition is not met
//ZASSERT_RENDERER is meant to be used within the ZRenderer project for internal assertion debugging
//ZASSERT should be used when the error condition can be caused by user actions
#define ZASSERT_RENDERER(_condition, _message) SST_OS_DebugAssert(_condition, _message)
#else
//ZASSERT_RENDERER is disabled
#define ZASSERT_RENDERER(_condition, _message) ((void)sizeof(_condition), sizeof(_message))
#endif //ZASSERT_RENDERER_ENABLE
#endif

View File

@@ -0,0 +1,153 @@
/*
ZRendererResource.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/8/2012
Purpose:
A renderer resource is anything that is created by the renderer and is used as part of
the rendering process. Generally, renderer resources are objects that act as an interface
to graphics device state, such as buffers, textures, etc.
It should be noted that resources are not safe to be used across multiple threads, even though
the renderer is multi thread capable. A resource should only be used within the context of a
single thread, and draw calls using that resource should also remain within the same thread
(this is done to avoid costly concurrent operations).
Different resources are free to be used across different threads.
Usage:
A renderer resource can be 'available', 'locked', or 'contended'. When a resource is available,
all calls to methods that modify the underlying data (or make the underlying data available for
modification) succeed and this will be indicated by the return value. If the resource is locked
or contended, the return value of the method will indicate failure to modify the resource.
If a resource is 'locked', then the resource is currently in the midst of modification. This
means that some modification methods will be unavailable. As an example, 'MapBuffer' cannot
be called while the buffer is already mapped, and 'FillBuffer' will fail if a buffer has
been mapped. A locked resource can be unlocked and returned to 'available' state before
rendering.
If a resource is contended, this means that the renderer is relying on the data that is currently
present in graphics memory, as a draw call has been placed using the data at the time of contention.
This means that any calls that would allow the user to modify the underlying data will fail. A
contended buffer becomes available when the renderer has finished reading the data needed from
the resource, which will occur at frame end.
Note that this means that the following set of actions (using an example of ZDataBuffer):
buffer = dataBuffer->MapBuffer(true);
... //Update Buffer
dataBuffer->UnmapBuffer();
renderer->SubmitDrawData(...); //Draw using this buffer
buffer = dataBuffer->MapBuffer(true);
... //Update Buffer
dataBuffer->UnmapBuffer();
renderer->SubmitDrawData(...); //Draw using the updated buffer
renderer->RenderFrame(...); //Render this frame
Will not work. The second call to 'MapBuffer' will fail because the buffer became contended
as soon as the buffer was used as an argument to 'SubmitDrawData'. The renderer's 'WaitFameEnd'
method will enable you to wait until the resource is no longer contended.
License:
TODO
*/
#pragma once
#ifndef _ZRENDERERRESOURCE_HPP
#define _ZRENDERERRESOURCE_HPP
#include <ZRenderer/ZRendererBuild.hpp>
class ZRendererResource
{
private:
DISABLE_COPY_AND_ASSIGN(ZRendererResource);
protected:
//Counter of 'owners' claiming contention
int ContentionCount;
//Flag indicating that this resource has been 'locked'
bool bIsLocked;
public:
//Default Constructor
ZRendererResource();
//Virtual Destructor
virtual ~ZRendererResource() { }
/*
public ZRendererResource::Available
Returns whether or not this resource is currently available (able to be modified).
If a resource is locked or contended, then it is not available for modification.
@return (bool) - true if available, false otherwise
@context (all)
*/
bool IsAvailable();
/*
public ZRendererResource::Lock
Locks this resource, making it unavailable for modification.
@return (void)
@context (all)
*/
void Lock();
/*
public ZRendererResource::MarkContended
Marks this resource as contended. Resources should, from this point out,
understand that modification of the underlying resource should not happen
until after the frame is drawn that would release this resource from
contention. From this point out, the caller 'owns' the resource.
Resources can be marked as contended by multiple sources, and the resource
will not be available until all owners who have marked contended have
released their claim.
Generally, this should only be called by the renderer.
@return (void)
@context (renderer)
*/
void MarkContended();
/*
public ZRendererResource::ReleaseContended
Removes a previous claim of contention. If all previous owners have
released their contention, then the resource is available.
@return (void)
@context (all)
*/
void ReleaseContention();
/*
public ZRendererResource::Unlock
Unlocks a resource, making it available for modification.
@return (void)
@context (all)
*/
void Unlock();
};
#endif

View File

@@ -0,0 +1,192 @@
/*
ZSampler.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
Samplers act as a view onto a texture object, encapsulating all the filtering, mipmapping,
and addressing settings for shaders to access a texture.
TODO - A writeup here on the various settings and how they interact, or at least a link to
some place that does
License:
TODO
*/
#pragma once
#ifndef _ZSAMPLER_HPP
#define _ZSAMPLER_HPP
#include <ZRenderer/ZRendererBuild.hpp>
#include <ZRenderer/ZRendererResource.hpp>
//This should be ~log2 of ZT_MAX_TEXTURE_DIMENSION
#ifndef ZS_DEFAULT_MAX_LOD
#define ZS_DEFAULT_MAX_LOD (13.0f)
#endif
//Enumeration of sampler wrapping modes
enum ZSamplerWrapMode
{
ZSWM_CLAMP_EDGE, //Sampling beyond the edge results in the last pixel value
ZSWM_CLAMP_BORDER, //Sampling beyond the edge results in the specified border value
ZSWM_MIRROR_REPEAT, //Sampling beyond the edge wraps back in on itself
ZSWM_REPEAT, //Sampling beyond the edge wraps around to the other side
ZSWM_SIZE
};
//Enumeration of magnification sampler filtering modes
enum ZSamplerMagFilter
{
ZSMAGF_NEAREST, //Nearest mode filter
ZSMAGF_LINEAR, //Linear mode filter
ZSMAGF_SIZE
};
//Enumeration of minification sampler filtering modes
enum ZSamplerMinFilter
{
ZSMINF_NEAREST, //Nearest-neighbor pixel, no mip levels
ZSMINF_NEAREST_MIP_NEAREST, //Nearest-neighbor sampling on nearest mip level
ZSMINF_NEAREST_MIP_LINEAR, //Nearest-neighbor sampling on lerped mip level
ZSMINF_LINEAR, //Linear interpolation, no mip levels
ZSMINF_LINEAR_MIP_NEAREST, //Lerped sampling on nearest mip level
ZSMINF_LINEAR_MIP_LINEAR, //Lerped sampling on lerped mip level
ZSMINF_SIZE
};
//Enumeration of sampler comparison modes
enum ZSamplerCompareMode
{
ZSCM_COMPARE_REF_TO_TEXTURE, //Compares reference to texture
ZSCM_NONE, //No comparison
ZSCM_SIZE
};
//Enumeration of sampler comparison functions
enum ZSamplerCompareFunc
{
ZSCF_LESS_EQUAL, //Less than or equal
ZSCF_GREATER_EQUAL, //Greater than or equal
ZSCF_LESS, //Less than
ZSCF_GREATER, //Greater than
ZSCF_EQUAL, //Equal
ZSCF_NOT_EQUAL, //Not Equal
ZSCF_ALWAYS, //Always
ZSCF_NEVER, //Never
ZSCF_SIZE
};
//Struct that encapsulates the sampler state
struct ZSamplerState
{
ZSamplerWrapMode SWrapMode; //Wrapping mode for S
ZSamplerWrapMode TWrapMode; //Wrapping mode for T (unused for 1D)
ZSamplerWrapMode RWrapMode; //Wrapping mode for R (unused for 1D, 2D)
ZSamplerMinFilter MinFilter; //Minification Filter
ZSamplerMagFilter MagFilter; //Magnification Filter
float MaxAnisotropy; //Maximum Anisotropy (< 2.0 has no effect)
float MinLOD; //Minimum LOD
float MaxLOD; //Maximum LOD
float LODBias; //LOD Bias
float BorderColor[4]; //RGBA Border Color
ZSamplerCompareMode CompareMode; //Sampler Comparison Mode
ZSamplerCompareFunc CompareFunc; //Sampler Comparison Function
//Default Configuration
ZSamplerState()
: SWrapMode(ZSWM_REPEAT), TWrapMode(ZSWM_REPEAT), RWrapMode(ZSWM_REPEAT),
MinFilter(ZSMINF_LINEAR), MagFilter(ZSMAGF_LINEAR),
MaxAnisotropy(1.0), MinLOD(0), MaxLOD(ZS_DEFAULT_MAX_LOD), LODBias(0),
CompareMode(ZSCM_NONE), CompareFunc(ZSCF_ALWAYS)
{ }
};
/*
Sampler interface class.
*/
class ZSampler : public ZRendererResource
{
public:
//Virtual Destructor
virtual ~ZSampler() { }
/*
ZSampler::Get*
The following methods are getters for the various ZSampler settings
that can be set on a given sampler. For a greater explanation of each
setting and what it does, see above.
*/
//Getters for the S, T, and R Wrap Mode set on this sampler
virtual ZSamplerWrapMode GetSWrapMode() = 0;
virtual ZSamplerWrapMode GetTWrapMode() = 0;
virtual ZSamplerWrapMode GetRWrapMode() = 0;
//Getters for the minification filter and magnification filter
virtual ZSamplerMagFilter GetMagFilter() = 0;
virtual ZSamplerMinFilter GetMinFilter() = 0;
//Getters for the maximum anisotropy, minimum LOD, maximum LOD, and LOD bias
virtual float GetMaxAnisotropy() = 0;
virtual float GetMinLOD() = 0;
virtual float GetMaxLOD() = 0;
virtual float GetLODBias() = 0;
//Getter for the border color setting (four-element array, RGBA)
virtual const float* GetBorderColor() = 0;
//Getter for the comparison mode and comparison function
virtual ZSamplerCompareMode GetCompareMode() = 0;
virtual ZSamplerCompareFunc GetCompareFunc() = 0;
//Getter for the entire sampler state
virtual const ZSamplerState& GetSamplerState() = 0;
/*
ZSampler::Set*
The following methods are setters for the various ZSampler settings than
can be set on a given sampler. For a greater explanation of each setting and what it
does, see above.
If any of the setters returns false, it is because the resource is contended.
*/
//Setters for the S, T, and R wrapping modes
virtual bool SetSWrapMode(ZSamplerWrapMode _mode) = 0;
virtual bool SetTWrapMode(ZSamplerWrapMode _mode) = 0;
virtual bool SetRWrapMode(ZSamplerWrapMode _mode) = 0;
//Setters for the minification and magnification filter
virtual bool SetMagFilter(ZSamplerMagFilter _filter) = 0;
virtual bool SetMinFilter(ZSamplerMinFilter _filter) = 0;
//Setters for maximum anisotropy, minimum LOD, maximum LOD, and LOD bias
virtual bool SetMaxAnisotropy(float _max) = 0;
virtual bool SetMinLOD(float _min) = 0;
virtual bool SetMaxLOD(float _max) = 0;
virtual bool SetLODBias(float _bias) = 0;
//Setter for border color
virtual bool SetBorderColor(float _r, float _g, float _b, float _a) = 0;
//Setter for comparison mode and comparison function
virtual bool SetCompareMode(ZSamplerCompareMode _mode) = 0;
virtual bool SetCompareFunc(ZSamplerCompareFunc _func) = 0;
//Setter for entire sampler state
virtual bool SetSamplerState(const ZSamplerState& _state) = 0;
};
#endif

View File

@@ -0,0 +1,98 @@
/*
ZSamplerBase.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
TODO
License:
TODO
*/
#pragma once
#ifndef _ZSAMPLERBASE_HPP
#define _ZSAMPLERBASE_HPP
#include <ZRenderer/ZSampler.hpp>
//Base implementation of ZSampler Interface
class ZSamplerBase : public ZSampler
{
private:
DISABLE_COPY_AND_ASSIGN(ZSamplerBase);
protected:
//Current sampler state
ZSamplerState State;
//Flag indicating values have changed
bool bIsDirty;
//Default Constructor, which initializes with some sane default settings
ZSamplerBase();
public:
//Virtual Destructor
virtual ~ZSamplerBase() { }
/*
public ZSamplerBase::GetSamplerStateResetDirty
Gets the sampler state for this device. This will return
NULL if the sampler has not been modified since the last call to
this function, and in the case it has been modified, a call to this
resets the 'dirty' flag for the buffer.
@return (ZSamplerState*)
@context (all)
*/
ZSamplerState* GetSamplerStateResetDirty();
//Subclass Getter Implementations
virtual ZSamplerWrapMode GetSWrapMode();
virtual ZSamplerWrapMode GetTWrapMode();
virtual ZSamplerWrapMode GetRWrapMode();
virtual ZSamplerMinFilter GetMinFilter();
virtual ZSamplerMagFilter GetMagFilter();
virtual float GetMaxAnisotropy();
virtual float GetMinLOD();
virtual float GetMaxLOD();
virtual float GetLODBias();
virtual const float* GetBorderColor();
virtual ZSamplerCompareMode GetCompareMode();
virtual ZSamplerCompareFunc GetCompareFunc();
virtual const ZSamplerState& GetSamplerState();
//Subclass Setter Implementations
virtual bool SetSWrapMode( ZSamplerWrapMode _mode );
virtual bool SetTWrapMode( ZSamplerWrapMode _mode );
virtual bool SetRWrapMode( ZSamplerWrapMode _mode );
virtual bool SetMinFilter( ZSamplerMinFilter _filter );
virtual bool SetMagFilter( ZSamplerMagFilter _filter );
virtual bool SetMaxAnisotropy( float _max );
virtual bool SetMinLOD( float _min );
virtual bool SetMaxLOD( float _max );
virtual bool SetLODBias( float _bias );
virtual bool SetBorderColor( float _r, float _g, float _b, float _a );
virtual bool SetCompareMode(ZSamplerCompareMode _mode);
virtual bool SetCompareFunc(ZSamplerCompareFunc _func);
virtual bool SetSamplerState(const ZSamplerState& _state);
};
#endif

View File

@@ -0,0 +1,122 @@
/*
ZShader.hpp
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 4/20/2011
Purpose:
TODO
License:
TODO
*/
#pragma once
#ifndef _ZSHADER_HPP
#define _ZSHADER_HPP
#include <ZRenderer/ZRendererBuild.hpp>
#include <ZRenderer/ZRendererResource.hpp>
#include <ZSTL/ZString.hpp>
//Shader Type
enum ZShaderType
{
ZST_SOFT, //Software Shader (unsupported)
ZST_VERTEX, //Vertex Shader
ZST_FRAGMENT, //Fragment/Pixel Shader
ZST_GEOMETRY, //Geometry Shader (unsupported)
ZST_HULL, //Hull Shader (unsupported)
ZST_DOMAIN, //Domain Shader (unsupported)
ZST_SIZE
};
//For you non OpenGL types
#define ZST_PIXEL (ZST_FRAGMENT)
class ZShader : public ZRendererResource
{
public:
/*
virtual public ZShader::ClearLog
Function to clear the log of a shader.
@return (void)
@context (all)
*/
virtual void ClearCompileLog() = 0;
/*
virtual public ZShdaer::Compile
Function to compile a shader.
@return (bool) - true if successfully compiled, false otherwise.
@context (all)
*/
virtual bool Compile() = 0;
/*
virtual public ZShdaer::IsUsable
Function to compile a shader.
@return (bool) - true if successfully compiled, false otherwise.
@context (all)
*/
virtual bool IsUsable() = 0;
/*
virtual public ZShader::GetLog
Function to get the log of a shader.
@return (ZString) - the log of the shader.
@context (all)
*/
virtual const ZString& GetCompileLog() = 0;
/*
virtual public ZShader::GetSource
Function to get the source of a shader.
@return (ZString) - the source of the shader.
@context (all)
*/
virtual const ZString& GetSource() = 0;
/*
virtual public ZShader::GetType
Function to get the type of a shader.
ZST_SOFT : Soft shaders
ZST_VERTEX : Vertex shaders
ZST_HULL : Hull shaders
ZST_DOMAIN : Domain shaders
ZST_GEOMETRY: Geometry shaders
ZST_FRAGMENT: Fragment (pixel) shaders
@return (ZShaderType) - type of shader.
@context (all)
*/
virtual ZShaderType GetType() = 0;
/*
virtual public ZShader::SetSource
Function to set the source of a shader.
@param _source - shader source, as a string
@return (void)
@context (all)
*/
virtual void SetSource(const ZString& _source) = 0;
};
#endif

View File

@@ -0,0 +1,74 @@
/*
ZShaderBase.hpp
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 4/20/2011
Purpose:
Base implementation of the ZShader interface.
License:
TODO
*/
#pragma once
#ifndef _ZSHADERBASE_HPP
#define _ZSHADERBASE_HPP
#include <ZRenderer/ZShader.hpp>
/*
Shader base class implementation.
*/
class ZShaderBase : public ZShader
{
protected:
//The type of shader
ZShaderType Type;
//The shader source
ZString Source;
//The shader compilation log
ZString Log;
//Boolean set to true indicates this is a usable shader
bool bIsUsable;
public:
/*
Constructor.
@param _type - the type of shader this is
*/
ZShaderBase(ZShaderType _type);
//Virtual Destructor
virtual ~ZShaderBase();
//Subclass Implementation
virtual void ClearCompileLog();
//Subclass Implementation
virtual const ZString& GetCompileLog();
//Subclass Implementation
virtual const ZString& GetSource();
//Subclass Implementation
virtual ZShaderType GetType();
//Subclass Implementation
virtual bool IsUsable();
//Subclass Implementation
virtual void SetSource( const ZString& _source );
//Not Implemented
virtual bool Compile() = 0;
};
#endif

View File

@@ -0,0 +1,147 @@
/*
ZShaderParams.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
Shader parameters class, to which uniform buffers and samplers are bound
and passed to draw calls. The attached buffers and samplers will be used
to provide data to the shader.
License:
TODO
*/
#pragma once
#ifndef _ZSHADERPARAMS_HPP
#define _ZSHADERPARAMS_HPP
#include <ZRenderer/ZDrawParams.hpp>
#include <ZSTL/ZSTL.hpp>
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZDataBuffer.hpp>
#include <ZRenderer/ZTexture.hpp>
#include <ZRenderer/ZSampler.hpp>
#ifndef ZSP_MAX_UNIFORM_BLOCKS
#define ZSP_MAX_UNIFORM_BLOCKS (128)
#endif
#ifndef ZSP_MAX_SAMPLERS
#define ZSP_MAX_SAMPLERS (32)
#endif
//Shader Parameters Structure, used to hold shader parameters
class ZShaderParams : public ZDrawParams
{
private:
DISABLE_COPY_AND_ASSIGN(ZShaderParams);
protected:
//A uniform block binding
struct UniformBlockBinding
{
ZName Name; //Name of the uniform block binding
ZPtr<ZDataBuffer> Buffer; //Parent buffer
ZPair<ZDataBuffer*, const ZDataBufferBlock*> Binding; //Pair Binding
};
//A sampler binding
struct SamplerBinding
{
ZName Name; //Name of the sampler binding
ZPtr<ZSampler> Sampler; //Sampler
ZPtr<ZTexture> Texture; //Texture
ZPair<ZSampler*, ZTexture*> Binding; //Pair binding
};
//These are the buffer bindings and samplers that are provided to the shader program
UniformBlockBinding UniformBlockBindings[ZSP_MAX_UNIFORM_BLOCKS];
SamplerBinding SamplerBindings[ZSP_MAX_SAMPLERS];
//Our current uniform block count and sampler count
size_t UniformBlockBindingCount;
size_t SamplerBindingCount;
public:
/*
Default Constructor.
*/
ZShaderParams();
virtual ~ZShaderParams() { }
/*
public ZShaderParams::ClearUniformBufferBlocks
Clears the current set of uniform buffer blocks.
@return (void)
@context (all)
*/
void ClearUniformBufferBlocks();
/*
public ZShaderParams::ClearSamplers
Clears the current set of sampler bindings.
@return (void)
@context (all)
*/
void ClearSamplers();
/*
public ZShaderParams::SetUniformBufferBlock
Sets the value of a uniform buffer block for a shader. Set to NULL using overload
to remove binding.
@param _name - the name of the uniform block in the shader
@param _buffer - the buffer containing the values
@param _block - the block definition for the buffer block
@return (void)
@context (all)
*/
void SetUniformBufferBlock(const ZName& _name, ZPtr<ZDataBuffer> _buffer, const ZDataBufferBlock* _block);
/*
public ZShaderParams::SetSampler
Sets the value of a sampler for a shader.
@param _name - the name of the sampler in the shader
@param _sampler - the sampler object to use
@param _texture - the texture the sampler object is a view onto
@return (void)
@context (all)
*/
void SetSampler(const ZName& _name, ZPtr<ZSampler> _sampler, ZPtr<ZTexture> _texture);
/*
The following methods are used by the renderer to get the values needed when
binding shader parameter values to pass to the shader program, to mark
all bound resources as contended, and release contention.
*/
const ZPair<ZDataBuffer*, const ZDataBufferBlock*>* GetUniformBlockByName(const ZName& _name);
const ZPair<ZSampler*, ZTexture*>* GetSamplerByName(const ZName& _name);
//Subclass Override
virtual void MarkResourcesContended();
//Subclass Override
virtual void ReleaseResourceContention();
};
#endif

View File

@@ -0,0 +1,315 @@
/*
ZShaderProgram.hpp
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 04/03/2011
Purpose:
TODO
License:
TODO
*/
#pragma once
#ifndef _ZSHADERPROGRAM_HPP
#define _ZSHADERPROGRAM_HPP
#include <ZRenderer/ZRendererBuild.hpp>
#include <ZRenderer/ZRendererResource.hpp>
#include <ZRenderer/ZShader.hpp>
#include <ZRenderer/ZSampler.hpp>
#include <ZSTL/ZString.hpp>
#include <ZUtil/ZUtil.hpp>
//Enumeration for shader stream attribute types
enum ZShaderStreamAttributeType
{
// VECTOR TYPE
ZSSAT_VECTOR_MIN,
// Single-precision float
ZSSAT_FLOAT,
ZSSAT_FLOAT_VEC2,
ZSSAT_FLOAT_VEC3,
ZSSAT_FLOAT_VEC4,
ZSSAT_VECTOR_MAX,
// MATRIX TYPE
ZSSAT_MATRIX_MIN,
// Single-precision float matrix
ZSSAT_MAT_22,
ZSSAT_MAT_23,
ZSSAT_MAT_24,
ZSSAT_MAT_32,
ZSSAT_MAT_33,
ZSSAT_MAT_34,
ZSSAT_MAT_42,
ZSSAT_MAT_43,
ZSSAT_MAT_44,
ZSSAT_MATRIX_MAX,
ZSSAT_SIZE,
ZSSAT_UNKNOWN
};
//Enumeration for types of shader uniform block member types
enum ZShaderUniformBlockMemberType
{
//VECTOR TYPE
ZSUBMT_VECTOR_MIN,
//Signed integer
ZSUBMT_INT,
ZSUBMT_INT_VEC2,
ZSUBMT_INT_VEC3,
ZSUBMT_INT_VEC4,
//Unsigned integer
ZSUBMT_UINT,
ZSUBMT_UINT_VEC2,
ZSUBMT_UINT_VEC3,
ZSUBMT_UINT_VEC4,
//Single-precision float
ZSUBMT_FLOAT,
ZSUBMT_FLOAT_VEC2,
ZSUBMT_FLOAT_VEC3,
ZSUBMT_FLOAT_VEC4,
//Half-precision float
ZSUBMT_HALF,
ZSUBMT_HALF_VEC2,
ZSUBMT_HALF_VEC3,
ZSUBMT_HALF_VEC4,
//Boolean
ZSUBMT_BOOL,
ZSUBMT_BOOL_VEC2,
ZSUBMT_BOOL_VEC3,
ZSUBMT_BOOL_VEC4,
ZSUBMT_VECTOR_MAX,
//MATRIX
ZSUBMT_MATRIX_MIN,
//Single-precision float matrix
ZSUBMT_MAT_22,
ZSUBMT_MAT_23,
ZSUBMT_MAT_24,
ZSUBMT_MAT_32,
ZSUBMT_MAT_33,
ZSUBMT_MAT_34,
ZSUBMT_MAT_42,
ZSUBMT_MAT_43,
ZSUBMT_MAT_44,
ZSUBMT_MATRIX_MAX,
ZSUBMT_SIZE
};
//Enumeration of sampler types
enum ZShaderSamplerType
{
ZSST_SAMPLER_1D, //1D texture map
ZSST_SAMPLER_2D, //2D texture map
ZSST_SAMPLER_3D, //3D texture map
ZSST_SAMPLER_CUBE, //Cubic texture map (unsupported)
ZSST_SAMPLER_1D_SHADOW, //1D shadow map (unsupported)
ZSST_SAMPLER_2D_SHADOW, //2D shadow map (unsupported)
ZSST_SIZE
};
//Struct defining a shader stream attribute
struct ZShaderStreamAttribute
{
ZName Name; //The name of the attribute
size_t Size; //The size of the attribute in terms of elements (arrays have Size > 1)
size_t Index; //Index of this attribute in the attributes array
ZShaderStreamAttributeType Type; //The type of the attribute
};
//Struct defining a uniform block member
struct ZShaderUniformBlockMember
{
ZName Name; //Name of the member
size_t Offset; //Offset (within the block) to the member
size_t Size; //Size of the member in terms of elements (arrays have Size > 1)
size_t Index; //Index of this member in the member array
size_t ArrayStride; //Stride between elements in an array (0 if not array)
size_t MatrixStride; //Stride between columns (or rows) of a matrix type (0 if not matrix type)
enum { ROW_MAJOR, COLUMN_MAJOR } MatrixOrder; //Order of a matrix type (row or column)
ZShaderUniformBlockMemberType Type; //Type of the member
};
//Struct defining a uniform block layout
struct ZShaderUniformBlock
{
ZName Name; //Name of the block
size_t Size; //Size of the block (in bytes)
size_t Index; //Index of this block in the blocks array
ZArray<ZShaderUniformBlockMember> Members; //Members contained in the block
/*
public ZShaderUniformBlock::GetMemberByName
This lookup method is used to get a pointer to a member by name, or NULL if not found.
Bear in mind that the name is qualified by the block name.
@param _name - the qualified name of the parameter
@return (const ZShaderUniformBlockMember*) - pointer to member if found, NULL if not found
*/
inline const ZShaderUniformBlockMember* GetMemberByName(const ZName& _name) const
{
for (size_t i = 0; i < Members.Size(); i++) {
if (Members.Data()[i].Name == _name) {
return &Members.Data()[i];
}
}
return NULL;
}
};
//Struct defining a shader sampler
struct ZShaderSampler
{
ZName Name; //Name of the sampler
size_t Index; //Index of this sampler in the samplers array
ZShaderSamplerType Type; //Type of the sampler
};
/*
Interface for a shader program.
*/
class ZShaderProgram : public ZRendererResource
{
public:
//Virtual Destructor
virtual ~ZShaderProgram() { }
/*
virtual public ZShaderProgram::AttachShader
Function to attach a shader. This will compile the shader.
@param _shader - The shader to attach to this shader program.
@return (bool) - true if able to compile and attach the shader
@context (all)
*/
virtual bool AttachShader(ZPtr<ZShader> _shader) = 0;
/*
virtual public ZShaderProgram::ClearLog
Function to clear the log of a shader program.
@return (void)
@context (all)
*/
virtual void ClearLog() = 0;
/*
virtual public ZShaderProgram::DetachShaders
Function to get the remove all attached shaders.
@return (void)
@context (all)
*/
virtual void DetachShaders() = 0;
/*
virtual public ZShaderProgram::GetLinkLog
Function to get the link log of a shader program.
@return (ZString) The log of the shader.
@context (all)
*/
virtual const ZString& GetLinkLog() = 0;
/*
virtual public ZShaderProgram::GetShaders
Function to get the an array of the currently attached shaders.
@return (ZArray< ZPtr<ZShader> >)
@context (all)
*/
virtual const ZArray< ZPtr<ZShader> >& GetShaders() = 0;
/*
virtual public ZShaderProgram::GetStreamAttributes
Function to get the stream shader attributes declarations for a linked shader program.
This returns an empty array until after linking.
@return (const ZArray<ZShaderStreamAttribute>&) List of shader attributes.
@context (all)
*/
virtual const ZArray<ZShaderStreamAttribute>& GetStreamDeclarations() = 0;
/*
virtual public ZShaderProgram::GetUniformBlockDeclarations
Function to get the shader uniform block declarations for a linked shader program.
This returns an empty array until after linking.
@return (const ZArray<ZShaderUniformBlock>&)
@context (all)
*/
virtual const ZArray<ZShaderUniformBlock>& GetUniformBlockDeclarations() = 0;
/*
virtual public ZShaderProgram::GetShaderSamplerDeclarations
Function to get teh shader sampler declarations for a linked shader program.
This returns an empty array until after linking.
@return (const ZArray<ZShaderSampler>&)
@context (all)
*/
virtual const ZArray<ZShaderSampler>& GetShaderSamplerDeclarations() = 0;
/*
virtual public ZShaderProgram::Link
Function to link the attached shaders into a usable shader program object.
@return (bool) True if successfully linked, false otherwise.
@context (all)
*/
virtual bool Link() = 0;
/*
virtual public ZShaderProgram::IsUsable
Function to see if shader program is usable.
@return (bool) True if shader program is usable, false otherwise.
@context (all)
*/
virtual bool IsUsable() = 0;
};
#endif

View File

@@ -0,0 +1,85 @@
/*
ZShaderProgramBase.hpp
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 04/03/2011
Purpose:
ZShaderProgramBase handles the simple logistics for shader programs (e.g., log access, check usability). It
is intended to be extended by subclasses to handle implementation-specific issues.
License:
TODO
*/
#pragma once
#ifndef _ZSHADERPROGRAMBASE_HPP
#define _ZSHADERPROGRAMBASE_HPP
#include <ZRenderer/ZShaderProgram.hpp>
#include <ZUtil/ZUtil.hpp>
class ZShaderProgramBase : public ZShaderProgram
{
protected:
//Default Constructor
ZShaderProgramBase();
//Our attached shaders (currently only support vertex and fragment)
ZPtr<ZShader> VertexShader;
ZPtr<ZShader> FragmentShader;
ZArray< ZPtr<ZShader> > Shaders;
//Our cached set of uniform blocks, samplers, and vertex streams
ZArray<ZShaderUniformBlock> UniformBlocks;
ZArray<ZShaderSampler> Samplers;
ZArray<ZShaderStreamAttribute> Streams;
//Link log for shader program
ZString Log;
//Flag for shader in usable state
bool bIsUsable;
public:
//Virtual destructor
virtual ~ZShaderProgramBase();
//Subclass Implementation
virtual bool AttachShader(ZPtr<ZShader> _shader);
//Subclass Implementation
virtual void ClearLog();
//Subclass Implementation
virtual void DetachShaders();
//Subclass Implementation
virtual const ZString& GetLinkLog();
//Subclass Implementation
virtual const ZArray<ZShaderStreamAttribute>& GetStreamDeclarations();
//Subclass Implementation
virtual const ZArray<ZShaderUniformBlock>& GetUniformBlockDeclarations();
//Subclass Implementation
virtual const ZArray<ZShaderSampler>& GetShaderSamplerDeclarations();
//Subclass Implementation
virtual const ZArray< ZPtr<ZShader> >& GetShaders();
//Subclass Implementation
virtual bool IsUsable();
//Not Implemented
virtual bool Link() = 0;
};
#endif

View File

@@ -0,0 +1,162 @@
/*
ZTexture.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 04/06/2011
Purpose:
Texture interface for the ZEngine. Texture instances are loaded and created by the
renderer, which acts as a factory for the correct type of texture.
License:
TODO
*/
#pragma once
#ifndef _ZTEXTURE_HPP
#define _ZTEXTURE_HPP
#include <ZRenderer/ZRendererBuild.hpp>
#include <ZRenderer/ZRendererResource.hpp>
#include <ZUtil/ZUtil.hpp>
#include <ZUtil/ZBitmap.hpp>
//Our maximum size for a texture
#ifndef ZT_MAX_TEXTURE_DIMENSION
#define ZT_MAX_TEXTURE_DIMENSION (8096)
#endif
/*
Enumeration of texture types. Not all are currently supported.
*/
enum ZTextureType
{
ZTT_TEXTURE1D, //1D texture map
ZTT_TEXTURE2D, //2D texture map
ZTT_TEXTURE3D, //3D texture map (unsupported)
ZTT_TEXTURE_CUBE, //Cubic texture map (unsupported)
ZTT_SIZE
};
/*
Enumeration of internal storage format for texture types.
*/
enum ZTextureFormat
{
ZTF_R8, //8-bit Unsigned Red (Normalized)
ZTF_R8_SNORM, //8-bit Signed Red (Normalized)
ZTF_R8I, //8-bit Signed Red
ZTF_R8UI, //8-bit Unsigned Red
ZTF_R16, //16-bit Unsigned Red (Normalized)
ZTF_R16_SNORM, //16-bit Signed Red (Normalized)
ZTF_R16I, //16-bit Signed Red
ZTF_R16UI, //16-bit Unsigned Red
ZTF_R16F, //16-bit Floating Point Red
ZTF_R32I, //32-bit Signed Red
ZTF_R32UI, //32-bit Unsigned Red
ZTF_R32F, //32-bit Floating Point Red
ZTF_RG8, //8-bit Unsigned Red, Green (Normalized)
ZTF_RG8_SNORM, //8-bit Signed Red, Green (Normalized)
ZTF_RG8I, //8-bit Signed Red, Green
ZTF_RG8UI, //8-bit Unsigned Red, Green
ZTF_RG16, //16-bit Unsigned Red, Green (Normalized)
ZTF_RG16_SNORM, //16-bit Signed Red, Green (Normalized)
ZTF_RG16I, //16-bit Signed Red, Green
ZTF_RG16UI, //16-bit Unsigned Red, Green
ZTF_RG16F, //16-bit Floating Point Red, Green
ZTF_RG32, //32-bit Unsigned Red, Green (Normalized)
ZTF_RG32_SNORM, //32-bit Signed Red, Green (Normalized)
ZTF_RG32I, //32-bit Signed Red, Green
ZTF_RG32UI, //32-bit Unsigned Red, Green
ZTF_RG32F, //32-bit Floating Point Red, Green
ZTF_RGB8, //8-bit Unsigned Red, Green, Blue (Normalized)
ZTF_RGB8_SNORM, //8-bit Signed Red, Green, Blue (Normalized)
ZTF_RGB8I, //8-bit Signed Red, Green, Blue
ZTF_RGB8UI, //8-bit Unsigned Red, Green, Blue
ZTF_RGB16, //16-bit Unsigned Red, Green, Blue (Normalized)
ZTF_RGB16_SNORM, //16-bit Signed Red, Green, Blue (Normalized)
ZTF_RGB16I, //16-bit Signed Red, Green, Blue
ZTF_RGB16UI, //16-bit Unsigned Red, Green, Blue
ZTF_RGB16F, //16-bit Floating Point Red, Green, Blue
ZTF_RGB32, //32-bit Unsigned Red, Green, Blue (Normalized)
ZTF_RGB32_SNORM, //32-bit Signed Red, Green, Blue (Normalized)
ZTF_RGB32I, //32-bit Signed Red, Green, Blue
ZTF_RGB32UI, //32-bit Unsigned Red, Green, Blue
ZTF_RGB32F, //32-bit Floating Point Red, Green, Blue
ZTF_RGBA8, //8-bit Unsigned Red, Green, Blue, Alpha (Normalized)
ZTF_RGBA8_SNORM, //8-bit Signed Red, Green, Blue, Alpha (Normalized)
ZTF_RGBA8I, //8-bit Signed Red, Green, Blue, Alpha
ZTF_RGBA8UI, //8-bit Unsigned Red, Green, Blue, Alpha
ZTF_RGBA16, //16-bit Unsigned Red, Green, Blue, Alpha (Normalized)
ZTF_RGBA16_SNORM, //16-bit Signed Red, Green, Blue, Alpha (Normalized)
ZTF_RGBA16I, //16-bit Signed Red, Green, Blue, Alpha
ZTF_RGBA16UI, //16-bit Unsigned Red, Green, Blue, Alpha
ZTF_RGBA16F, //16-bit Floating Point Red, Green, Blue, Alpha
ZTF_RGBA32, //32-bit Unsigned Red, Green, Blue, Alpha (Normalized)
ZTF_RGBA32_SNORM, //32-bit Signed Red, Green, Blue, Alpha (Normalized)
ZTF_RGBA32I, //32-bit Signed Red, Green, Blue, Alpha
ZTF_RGBA32UI, //32-bit Unsigned Red, Green, Blue, Alpha
ZTF_RGBA32F, //32-bit Floating Point Red, Green, Blue, Alpha
ZTF_DEPTH16, //16-bit Depth Texture
ZTF_DEPTH24, //24-bit Depth Texture
ZTF_DEPTH32, //32-bit Depth Texture
ZTF_DEPTH24_STENCIL8, //32-bit Depth, 8-bit Stencil
ZTF_SIZE
};
/*
Enumeration of texture usage types.
*/
enum ZTextureUsage
{
ZTU_STATIC, //Static Texture (never or rarely updated)
ZTU_DYNAMIC, //Dynamic Texture (updated frequently)
ZTU_STREAMING, //Streaming Texture (updated every frame)
ZTU_SIZE
};
class ZTexture : public ZRendererResource
{
public:
//Virtual Destructor
virtual ~ZTexture() { }
/*
virtual public ZTexture::GetType
Gets the type of this texture.
@return (ZTextureType) - the type of texture
*/
virtual ZTextureType GetType() = 0;
/*
virtual public ZTexture::GetUsage
Gets the usage type of this texture.
@return (ZTextureUsage)
@context (all)
*/
virtual ZTextureUsage GetUsage() = 0;
/*
public ZTexture::IsMipmapped
Tells you whether or not this texture has been mipmapped.
@return (bool) - true if mipmapped, false otherwise
@context (all)
*/
virtual bool IsMipmapped() = 0;
};
#endif

View File

@@ -0,0 +1,106 @@
/*
ZVertexParams.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 7/1/2012
Purpose:
TODO
License:
TODO
*/
#pragma once
#ifndef _ZVERTEXPARAMS_HPP
#define _ZVERTEXPARAMS_HPP
#include <ZRenderer/ZDrawParams.hpp>
#include <ZSTL/ZSTL.hpp>
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZDataBuffer.hpp>
#ifndef ZVP_MAX_STREAMS
#define ZVP_MAX_STREAMS (128)
#endif
class ZVertexParams : public ZDrawParams
{
private:
//A binding for a vertex stream
struct VertexStreamBinding
{
ZName Name; //Name of the stream attribute
ZPair<ZDataBuffer*, const ZDataBufferStream*> Binding; //Pair Binding
};
//This is the bound vertex buffer and streams
ZPtr<ZDataBuffer> VertexBuffer;
VertexStreamBinding VertexStreams[ZVP_MAX_STREAMS];
//Our current set number of streams
size_t CurrentStreamCount;
protected:
//Does this vertex parameter object need to be updated before rendered with?
bool Dirty;
public:
/*
Default Constructor.
*/
ZVertexParams();
/*
public ZVertexParams::ClearStreams
Clears the list of currently set streams.
@return (void)
@context (all)
*/
void ClearVertexStreams();
/*
public ZVertexParams::SetStream
Sets a vertex buffer stream. The vertex buffer provided to each call
of 'SetVertexStream' must be the same.
@param _name - the name of the stream binding
@param _vertexBuffer - the vertex buffer to bind streams from
@param _stream - the stream definition
@return (void)
@context (all)
*/
void SetVertexStream(const ZName& _name, ZPtr<ZDataBuffer> _vertexBuffer, const ZDataBufferStream* _stream);
/*
The following methods are used by the renderer to get the values needed when
binding shader parameter values to pass to the shader program, to mark
all bound resources as contended, and release contention.
*/
const ZPair<ZDataBuffer*, const ZDataBufferStream*>* GetStreamByName(const ZName& _name);
ZDataBuffer* GetVertexBuffer();
bool IsDirty() const { return Dirty; }
size_t GetStreamCount() const { return CurrentStreamCount; }
//Subclass Override
virtual void MarkResourcesContended();
//Subclass Override
virtual void ReleaseResourceContention();
};
#endif

View File

@@ -0,0 +1,106 @@
/*
ZWindowRenderTarget.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 04/01/2011
Purpose:
Interface class for a window render target. This interface requires that windows
be created and manipulated using libsst-wm.
License:
TODO
*/
#pragma once
#ifndef _ZWINDOWRENDERTARGET_HPP
#define _ZWINDOWRENDERTARGET_HPP
#include <ZRenderer/ZRendererBuild.hpp>
#include <SST/SST_WM.h>
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZRenderTarget.hpp>
class ZWindowRenderTarget : public ZRenderTarget
{
public:
//Virtual destructor
virtual ~ZWindowRenderTarget() { }
/*
virtual public ZWindowRenderTarget::GetAutoSwapBuffers
Gets the flag indicating whether or not this target will auto-swap buffers by the
renderer when used as a render target.
@return (bool)
@context (all)
*/
virtual bool GetAutoSwapBuffers() = 0;
/*
virtual public ZWindowRenderTarget::GetScreenIndex
Gets the screen index held by this window render target. Used to interface with libsst-wm
functionality.
@return (size_t) - the screen index
@context (all)
*/
virtual size_t GetScreenIndex() = 0;
/*
virtual public ZWindowRenderTarget::GetWindowHandle
Gets the window handle held by this window render target. Used to interface with
libsst-wm functionality.
@return (SST_Window) - the window handle
*/
virtual SST_Window GetWindowHandle() = 0;
/*
virtual public ZWindowRenderTarget::SetAutoSwapBuffers
Indicates that the renderer should automatically swap buffers after a render is
complete with this render target.
@param _value - true if we can, false if not
@return (bool) - true if able to set flag, false if resource contended
@context (all)
*/
virtual bool SetAutoSwapBuffers(bool _value) = 0;
/*
virtual public ZWindowRenderTarget::SwapBuffers
Swaps the buffers on the screen, bringing the back buffer to the front buffer. This should be called
every frame, and signals the end of the frame. This is only safe to call from within the render thread.
@return (bool) - true if able to swapbuffers, false if resource contended
@context (renderer)
*/
virtual bool SwapBuffers() = 0;
//Not Implemented
virtual const ZRenderTargetClearFlags& GetClearFlags() = 0;
//Not Implemented
virtual size_t GetHeight() = 0;
//Not Implemented
virtual ZRenderTargetType GetType() = 0;
//Not Implemented
virtual size_t GetWidth() = 0;
//Not Implemented
virtual bool SetClearFlags(const ZRenderTargetClearFlags& _flags) = 0;
};
#endif

View File

@@ -0,0 +1,88 @@
/*
ZWindowRenderTargetBase.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 04/03/2011
Purpose:
Base class for a window render target.
License:
TODO
*/
#pragma once
#ifndef _ZWINDOWRENDERTARGETBASE_HPP
#define _ZWINDOWRENDERTARGETBASE_HPP
#include <ZRenderer/ZWindowRenderTarget.hpp>
class ZWindowRenderTargetBase : public ZWindowRenderTarget
{
protected:
//The Window Handle
SST_Window WindowHandle;
//The Screen Index
size_t ScreenIndex;
//Our current clear flags
ZRenderTargetClearFlags ClearFlags;
//Whether or not we should auto-swap buffers
bool bAutoSwapBuffers;
/*
Parameterized Constructor.
@param _window - the libsst-wm window handle to this render target
@param _screenIndex - the libsst-wm index of this screen
*/
ZWindowRenderTargetBase(SST_Window _window, size_t _screenIndex);
public:
//Virtual Destructor
virtual ~ZWindowRenderTargetBase() { }
/*************************/
/* ZRenderTarget Methods */
/*************************/
//Subclass Implementation
virtual const ZRenderTargetClearFlags& GetClearFlags();
//Subclass Implementation
virtual size_t GetHeight();
//Subclass Implementation
virtual ZRenderTargetType GetType();
//Subclass Implementation
virtual size_t GetWidth();
//Subclass Implementation
virtual bool SetClearFlags(const ZRenderTargetClearFlags& _flags);
/***********************************/
/* ZWindowRenderTargetBase Methods */
/***********************************/
//Subclass Implementation
virtual bool GetAutoSwapBuffers();
//Subclass Implementation
virtual size_t GetScreenIndex();
//Subclass Implementation
virtual SST_Window GetWindowHandle();
//Subclass Implementation
virtual bool SetAutoSwapBuffers(bool _value);
//Not Implemented
virtual bool SwapBuffers() = 0;
};
#endif

View File

@@ -0,0 +1,164 @@
/*
ZFontRenderer.h
Author: Patrick Baggett <ptbaggett@762studios.com>
Purpose: TODO
Changelog
2011/09/18 - creation (ptbaggett)
*/
#pragma once
#ifndef _ZFONTRENDERER_HPP
#define _ZFONTRENDERER_HPP
#include <SST/SST_Mat44.h>
#include <ZRenderer/ZRenderer.hpp>
//Font Face
typedef void* ZFontFace;
//ZFontBounds struct, used as such
// top --- right
// | |
// left --- bottom
struct ZFontBounds
{
//ZFontBounds of a rectangle (lower-left orientation)
int left, bottom, right, top;
};
class ZFontRenderer
{
protected:
//Protected Constructor
ZFontRenderer() { }
public:
//Virtual Destructor
virtual ~ZFontRenderer() { }
/*
virtual public ZFontRenderer::createFontFace
Creates a font face from a memory image of a font file.
@param _pixelSize - The pixel size of a character. To use point size (ala MS Word), use (point size / 72.0) * DPI.
@param _fontData - The font file's data
@param _dataSize - The size in bytes of the file data.
@return (ZFontFace)
@context (all)
*/
virtual ZFontFace CreateFontFace(int _pixelSize, const void* _fontData, unsigned int _dataSize) = 0;
/*
virtual public ZFontRenderer::deleteFontFace
Deletes a font face. If this face is the currently active face, then the active face is set to NULL.
@param face - The font face to delete.
@return (void)
@context (all)
*/
virtual void DeleteFontFace(ZFontFace face) = 0;
/*
virtual public ZFontRenderer::beginText
Sets up render state to begin drawing text. The only legal functions to call between beginText(),
and endText() are renderText(), computeBounds(), and setColor().
@param _ctx - The ZFrameContext for this frame
@param _xform - The transformation
@return (void)
@context (all)
*/
virtual void BeginText(ZFrameContext _ctx, const SST_Mat44f& _xform) = 0;
/*
virtual public ZFontRenderer::endText
Restores render state when done drawing text, flushes any buffered text.
@return (void)
@context (all)
*/
virtual void EndText() = 0;
/*
virtual public ZFontRenderer::renderText
Renders text at the given XY location
@param x - The left edge of the text
@param y - The bottom edge of the text
@param text - Some letters render below this line (e.g. the letter g's "tail").
@return (void)
@context (all)
*/
virtual void RenderText(int x, int y, const char* text) = 0;
/*
virtual public ZFontRenderer::computeBounds
Computes the bounding box for text, as if it was placed at the origin.
@param text - The text to compute a bounding box for.
@param bounds - Pointer to where the computed boundaries are stored.
@return (void)
@context (all)
*/
virtual void ComputeBounds(const char* text, ZFontBounds* bounds) = 0;
/*
virtual public ZFontRenderer::setColor
Sets the color of the text. Requires that there is a current font face, set with setFontFace().
@param r - The red component in the range of [0,1]
@param g - The green component in the range of [0,1]
@param b - The blue component in the range of [0,1]
@param a - The alpha (transparency) component in the range of [0,1]
@return (void)
@context (all)
*/
virtual void SetColor(float r, float g, float b, float a) = 0;
/*
virtual public ZFontRenderer::setColor
Sets a color with a packed 32-bit integer, converting to 4x32-bit floats first. Due to
endian-ness differences, don't typecast an char[4] to int* and then dereference it!
@param rgba - The RGBA color stored as (hex) 0xRRGGBBAA
@return (void)
@context (all)
*/
virtual void SetColor(unsigned int rgba) = 0;
/*
public ZFontRenderer::setFontFace
Sets the current font face.
@param face - The face to make current
@return (void)
@context (all)
*/
virtual void SetFontFace(ZFontFace face) = 0;
/*
public ZFontRenderer::getFontFace
Gets the current font face.
@return (ZFontFace) - Handle to the current font face. It is not reference counted.
@context (all)
*/
virtual ZFontFace GetFontFace() = 0;
};
#endif

View File

@@ -0,0 +1,67 @@
/*
ZFontRendererBase.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/09/18 - creation (jcrussell)
*/
#pragma once
#ifndef _ZFONTRENDERERBASE_HPP
#define _ZFONTRENDERERBASE_HPP
#include <ZRendererUtil/ZFontRenderer.hpp>
class ZFontRendererBase : public ZFontRenderer
{
protected:
//Our current font face
ZFontFace currentFace;
public:
/*
Default Constructor.
*/
ZFontRendererBase();
/*
Destructor.
*/
virtual ~ZFontRendererBase();
//Subclass Implementation
virtual ZFontFace GetFontFace();
//Subclass Implementation
virtual void SetColor(unsigned int rgba);
//Subclass Implementation
virtual void SetFontFace(ZFontFace face);
//Not Implemented
virtual ZFontFace CreateFontFace( int PixelSize, const void* fontData, unsigned int dataSize ) = 0;
//Not Implemented
virtual void DeleteFontFace( ZFontFace face ) = 0;
//Not Implemented
virtual void BeginText( ZFrameContext _ctx, const SST_Mat44f& _xform ) = 0;
//Not Implemented
virtual void EndText() = 0;
//Not Implemented
virtual void RenderText( int x, int y, const char* text ) = 0;
//Not Implemented
virtual void ComputeBounds( const char* text, ZFontBounds* bounds ) = 0;
//Not Implemented
virtual void SetColor( float r, float g, float b, float a ) = 0;
};
#endif

View File

@@ -0,0 +1,126 @@
/*
ZOutlineEvaluator.h
Author: Patrick Baggett <ptbaggett@762studios.com>
Purpose: TODO
Changelog
2011/09/18 - creation (ptbaggett)
*/
#pragma once
#ifndef _ZOUTLINEEVALUATOR_H
#define _ZOUTLINEEVALUATOR_H
#include <ZUtil/ZUtil.hpp>
#include <SST/SST_Vec2.h>
#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
class ZOutlineEvaluator
{
private:
FT_Outline* outline;
int detail;
int curContour;
int* bounds;
std::vector<SST_Vec2f> pts;
//Process a curve
int processCurve(int contour, int curveStart);
//Evaluate a line segment
void evalLinear(FT_Vector* p0, FT_Vector* p1);
//Evaluate a quadric path (called conic)
void evalQuadratic(FT_Vector* p0, FT_Vector* p1, FT_Vector* p2);
//Evaluate a cubic path
void evalCubic(FT_Vector* p0, FT_Vector* p1, FT_Vector* p2, FT_Vector* p3);
//Adds a point
void addPoint(const FT_Vector* pt);
public:
/*
Constructor.
@param _outline -
@param _detail -
*/
ZOutlineEvaluator(FT_Outline* _outline, int _detail);
/*
Destructor.
*/
~ZOutlineEvaluator();
/*
public ZOutlineEvaluator::evaluate
TODO
@return (void)
@context (all)
*/
void evaluate();
/*
public ZOutlineEvaluator::getContourCount
TODO
@return (int)
@context (all)
*/
int getContourCount() const;
/*
public ZOutlineEvaluator::getContourStart
TODO
@param contour -
@return (int)
@context (all)
*/
int getContourStart(int contour) const;
/*
public ZOutlineEvaluator::getContourEnd
TODO
@param contour -
@return (int)
@context (all)
*/
int getContourEnd(int contour) const;
/*
public ZOutlineEvaluator::getPoint
TODO
@param pt -
@return (const SST_Vec2f*)
@context (all)
*/
const SST_Vec2f* getPoint(int pt) const;
/*
public ZOutlineEvaluator::printContourPoints
TODO
@param contour -
@return (void)
@context (all)
*/
void printContourPoints(int contour);
};
#endif

View File

@@ -0,0 +1,140 @@
/*
ZParticleEffect.h
Author: James Russell <jcrussell@762studios.com>
Purpose: A particle effect class which maintains a set of particle emitters.
Changelog
2011/08/28 - creation (jcrussell)
*/
#pragma once
#ifndef _ZPARTICLEEFFECT_H
#define _ZPARTICLEEFFECT_H
#include <ZRenderer/ZRenderer.hpp>
#include <ZRendererUtil/ZParticleEmitter.h>
class ZParticleEffect
{
private:
//The name of this particle effect
ZString Name;
//Boolean indicating this particle effect has completed
bool bIsFinished;
//The emitters attached to this particle effect
ZArray< ZSmartPointer<ZParticleEmitter> > Emitters;
public:
/*
Default Constructor.
*/
ZParticleEffect();
/*
Parameterized Constructor.
@param _name - the name of this particle effect
*/
ZParticleEffect(const ZString& _name);
/*
Destructor.
*/
~ZParticleEffect();
/*
public ZParticleEffect::AddEmitter
Adds an emitter to this particle effect. The emitter will be updated and rendered when the
effect is.
@param _emitter - the emitter to add
@return (void)
@context (all)
*/
void AddEmitter(ZPtr<ZParticleEmitter> _emitter);
/*
public ZParticleEffect::GetName
Gets the name of this particle effect.
@return (ZString) - the name of this effect
@context (all)
*/
ZString GetName();
/*
public ZParticleEffect::IsFinished
Returns true if this particle effect is finished.
@return (bool) - true if completed, false otherwise
@context (all)
*/
bool IsFinished();
/*
public ZParticleEffect::RemoveEmitter
Removes an emitter from this particle effect.
@param _emitter - the particle effect
@return (bool) - true if the emitter was contained, false otherwise
@context (all)
*/
bool RemoveEmitter(ZPtr<ZParticleEmitter> _emitter);
/*
public ZParticleEffect::Render
Renders this particle effect using the provided renderer.
@param _renderer - the renderer to use
@param _frameContext - the frame context to render with
@param _drawGroup - the draw group to render in
@return (void)
@context (all)
*/
void Render(ZRenderer* _renderer, ZFrameContext _frameContext, int _drawGroup = 0);
/*
public ZParticleEffect::SetFinished
Sets completion status of this effect to the provided value.
@param _status - completion status (true if finished, false otherwise)
@return (void)
@context (all)
*/
void SetFinished(bool _status);
/*
public ZParticleEffect::SetName
Sets the name of this particle effect.
@param _name - the name of this particle effect
@return (void)
@context (all)
*/
void SetName(const ZString& _name);
/*
public ZParticleEffect::Update
Updates this particle effect with the provided delta time since last call to update.
@param _dt - the time (in milliseconds) since the last call to Update
@return (void)
@context (all)
*/
void Update(size_t _dt);
};
#endif

View File

@@ -0,0 +1,200 @@
/*
ZParticleEmitter.h
Author: James Russell <jcrussell@762studios.com>
Purpose: Particle emitter class, which maintains a set of strategies used to store, create, update, and render
particles.
Changelog
2011/08/28 - creation (jcrussell)
*/
#pragma once
#ifndef _ZPARTICLEEMITTER_H
#define _ZPARTICLEEMITTER_H
#include <ZRenderer/ZRenderer.hpp>
#include <ZRendererUtil/ZParticleStorageAllocator.h>
#include <ZRendererUtil/ZParticleSpawnStrategy.h>
#include <ZRendererUtil/ZParticleUpdateStrategy.h>
#include <ZRendererUtil/ZParticleRenderStrategy.h>
//Forward Declaration
class ZParticleEffect;
class ZParticleEmitter
{
protected:
//Number of particles at a time this emitter supports
size_t MaxParticles;
//Boolean indicating this emitter is complete (no longer emits particles)
bool bIsFinished;
//The transform for the particle emitter
ZMatrix44f Transform;
//Particle Generator
ZPtr<ZParticleStorageAllocator> StorageAllocator;
//Particle Spawn Strategy
ZPtr<ZParticleSpawnStrategy> SpawnStrategy;
//Particle Update Strategy
ZPtr<ZParticleUpdateStrategy> UpdateStrategy;
//Particle Render Strategy
ZPtr<ZParticleRenderStrategy> RenderStrategy;
public:
/*
Default Constructor.
*/
ZParticleEmitter();
/*
Destructor.
*/
~ZParticleEmitter();
/*
public ZParticleEmitter::GetMaxParticles
Returns the current amount of max particles this particle emitter supports.
@return (size_t)
@context (all)
*/
size_t GetMaxParticles();
/*
public ZParticleEmitter::GetTransform
Gets the local transform for this particle emitter.
@return (ZMatrix44f) - local transform for this emitter
@context (all)
*/
ZMatrix44f GetTransform();
/*
public ZParticleEmitter::IsFinished
Returns true if this particle emitter will no longer emit particles.
@return (bool) - true if finished, false otherwise
@context (all)
*/
bool IsFinished();
/*
public ZParticleEmitter::Render
Renders the contained particles using the provided render strategy.
@param _particleEffect - the parent particle effect
@param _renderer - the renderer to use
@param _context - frame context to render with
@param _drawGroup - the draw group to render with
@return (void)
@context (all)
*/
void Render(ZParticleEffect* _particleEffect, ZRenderer* _renderer, ZFrameContext _context, int _drawGroup);
/*
public ZParticleEmitter::SetMaxParticles
Sets the maximum number of particles this emitter supports.
@param _maxParticles - the maximum particle count
@return (void)
@context (all)
*/
void SetMaxParticles(size_t _maxParticles);
/*
public ZParticleEmitter::SetFinished
Sets completion status of this emitter to the provided value.
@param _status - completion status (true if finished, false otherwise)
@return (void)
@context (all)
*/
void SetFinished(bool _status);
/*
public ZParticleEmitter::SetParticleStorageAllocator
Sets the particle storage allocator for this particle emitter. This will call
ZParticleStorageAllocator::AllocateParticleStorage.
@param _allocator - the allocator to use
@param _maxParticles - the number of particles to allocate storage for
@return (ZPtr<ZParticleStorageAllocator>) - the storage allocator that was previously attached
@context (all)
*/
ZPtr<ZParticleStorageAllocator> SetParticleStorageAllocator(ZPtr<ZParticleStorageAllocator> _allocator, size_t _maxParticles);
/*
public ZParticleEmitter::SetParticleSpawnStrategy
Sets the particle span strategy for this particle emitter.
@param _spawnStrategy - the spawn strategy to use
@return (ZPtr<ZParticleSpawnStrategy>) - the spawn strategy that was previously attached
@context (all)
*/
ZPtr<ZParticleSpawnStrategy> SetParticleSpawnStrategy(ZPtr<ZParticleSpawnStrategy> _spawnStrategy);
/*
public ZParticleEmitter::SetParticleUpdateStrategy
Sets the particle update strategy for this particle emitter.
@param _updateStrategy - the particle update strategy to use
@return (ZPtr<ZParticleUpdateStrategy>) - the update strategy that was previously attached
@context (all)
*/
ZPtr<ZParticleUpdateStrategy> SetParticleUpdateStrategy(ZPtr<ZParticleUpdateStrategy> _updateStrategy);
/*
public ZParticleEmitter::SetParticleRenderStrategy
Sets the render strategy for this particle emitter. This will call AllocateBuffers on the render strategy.
@param _renderStrategy - the render strategy to use
@param _renderer - the renderer to allocate buffers from
@return (ZPtr<ZParticleRenderStrategy>) - the render strategy that was previously attached
@context (all)
*/
ZPtr<ZParticleRenderStrategy> SetParticleRenderStrategy(ZPtr<ZParticleRenderStrategy> _renderStrategy, ZRenderer *_renderer);
/*
public ZParticleEmitter::SetTransform
Sets the transform for this particle emitter.
@param _transform - the transform to use
@return (void)
@context (all)
*/
void SetTransform(ZMatrix44f _transform);
/*
public ZParticleEmitter::Update
Runs through the various installed strategies, which can will both create new particles (as dictated by strategy)
and update existing ones.
@param _particleEffect - the parent particle effect
@param _dt - the time (in milliseconds) since last update
@return (void)
@context (all)
*/
void Update(ZParticleEffect* _particleEffect, size_t _dt);
};
#endif

View File

@@ -0,0 +1,80 @@
/*
ZParticleRenderStrategy.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/08/28 - creation (jcrussell)
*/
#pragma once
#ifndef _ZPARTICLERENDERSTRATEGY_H
#define _ZPARTICLERENDERSTRATEGY_H
#include <ZUtil/ZUtil.hpp>
#include <ZRenderer/ZRenderer.hpp>
#include <ZRendererUtil/ZParticleStorageAllocator.h>
//Forward Declarations
class ZParticleEffect;
class ZParticleEmitter;
class ZParticleStorageAllocator;
class ZParticleRenderStrategy
{
public:
//Virtual Destructor
~ZParticleRenderStrategy() { }
/*
public ZParticleRenderStrategy::AllocateBuffers
Called when the particle render strategy needs to allocate buffers from the renderer
for particle data.
@param _maxParticles - the number of particles to allocate buffer space for
@param _renderer - the renderer to allocate buffers from
@return (void)
@context (all)
*/
virtual void AllocateBuffers(size_t _maxParticles, ZRenderer *_renderer) = 0;
/*
virtual public ZParticleRenderStrategy::CheckParticleFormat
Checks to see if this render strategy can render the provided particle format.
@param _format - string description of the particle format
@return (bool) - true if this render strategy can handle it, false otherwise
@context (all)
*/
virtual bool CheckParticleFormat(const ZString& _format) = 0;
/*
virtual public ZParticleUpdateStrategy::RenderParticles
Renders the particle data present in particle storage.
@param _particleEffect - the emitter's parent particle effect
@param _particleEmitter - the parent emitter
@param _storageAllocator - the particle data storage
@param _renderer - the renderer to render to
@param _frameContext - the frame context to render with
@return (void)
@context (all)
*/
virtual void RenderParticles(ZParticleEffect* _particleEffect,
ZParticleEmitter* _particleEmitter,
ZParticleStorageAllocator* _storageAllocator,
ZRenderer* _renderer,
ZFrameContext _frameContext,
const ZMatrix44f& _transform,
int _drawGroup
) = 0;
};
#endif

View File

@@ -0,0 +1,61 @@
/*
ZParticleSpawnStrategy.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/08/28 - creation (jcrussell)
*/
#pragma once
#ifndef _ZPARTICLESPAWNSTRATEGY_H
#define _ZPARTICLESPAWNSTRATEGY_H
#include <ZUtil/ZUtil.hpp>
//Forward Declarations
class ZParticleEffect;
class ZParticleEmitter;
class ZParticleStorageAllocator;
class ZParticleSpawnStrategy
{
public:
//Virtual Destructor
~ZParticleSpawnStrategy() { }
/*
virtual public ZParticleSpawnStrategy::CheckParticleFormat
Checks to see if this spawn strategy can spawn the provided particle format.
@param _format - string description of the particle format
@return (bool) - true if this spawn strategy can handle it, false otherwise
@context (all)
*/
virtual bool CheckParticleFormat(const ZString& _format) = 0;
/*
virtual public ZParticleSpawnStrategy::UpdateSpawn
An update call to the spawn strategy that determines if more particles should be created. If so, the new particle data
can be placed directly into particle storage.
@param _particleEffect - the emitter's parent particle effect
@param _particleEmitter - the parent emitter
@param _storageAllocator - particle storage used by this particle effect
@param _dt - the time (in milliseconds) since last update
@return (void)
@context (all)
*/
virtual void UpdateSpawn(ZParticleEffect* _particleEffect,
ZParticleEmitter* _particleEmitter,
ZParticleStorageAllocator* _storageAllocator,
size_t _dt
) = 0;
};
#endif

View File

@@ -0,0 +1,82 @@
/*
ZParticleGenerator.h
Author: James Russell <jcrussell@762studios.com>
Purpose: The particle generator is responsible for generating / allocating the particle data
and storing it for the duration the particle emitter is alive.
Also responsible for cleanup.
Changelog
2011/08/28 - creation (jcrussell)
*/
#pragma once
#ifndef _ZPARTICLESTORAGEALLOCATOR_H
#define _ZPARTICLESTORAGEALLOCATOR_H
#include <ZUtil/ZUtil.hpp>
//Forward Declaration
class ZParticleEffect;
class ZParticleEmitter;
class ZParticleStorageAllocator
{
public:
//Virtual Destructor
virtual ~ZParticleStorageAllocator() { }
/*
virtual public ZParticleGenerator::AllocateParticleStorage
Allocates particle storage for this particle emitter.
@param _emitter - the emitter we are creating storage for
@param _maxParticles - the number of particles we allocate storage for
@return (void)
@context (all)
*/
virtual void AllocateParticleStorage(ZParticleEmitter* _emitter, size_t _maxParticles) = 0;
/*
virtual public ZParticleGenerator::DeallocateParticleStorage
Deallocates storage previously allocated with AllocateParticleStorage.
@return (void)
@context (all)
*/
virtual void DeallocateParticleStorage() = 0;
/*
virtual public ZParticleStorageAllocator::GetParticleFormat
Returns a string 'type' indicating the type of particle storage used by this allocator. Checked
against the other strategies to ensure compatibility.
@return (ZString)
@context (all)
*/
virtual ZString GetParticleFormat() = 0;
/*
virtual public ZParticleStorageAllocator::Update
Updates the storage allocator, indicating another frame has passed.
@param _effect - the particle effect
@param _emitter - the particle emitter
@param _dt - amount of time passed (in ms)
@return (void)
@context (all)
*/
virtual void Update(ZParticleEffect *_effect,
ZParticleEmitter *_emitter,
size_t _dt
) = 0;
};
#endif

View File

@@ -0,0 +1,60 @@
/*
ZParticleUpdateStrategy.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/08/28 - creation (jcrussell)
*/
#pragma once
#ifndef _ZPARTICLEUPDATESTRATEGY_H
#define _ZPARTICLEUPDATESTRATEGY_H
#include <ZUtil/ZUtil.hpp>
//Forward Declarations
class ZParticleEffect;
class ZParticleEmitter;
class ZParticleStorageAllocator;
class ZParticleUpdateStrategy
{
public:
//Virtual Destructor
~ZParticleUpdateStrategy() { }
/*
virtual public ZParticleUpdateStrategy::CheckParticleFormat
Checks to see if this update strategy can update the provided particle format.
@param _format - string description of the particle format
@return (bool) - true if this udpate strategy can handle it, false otherwise
@context (all)
*/
virtual bool CheckParticleFormat(const ZString& _format) = 0;
/*
virtual public ZParticleUpdateStrategy::UpdateParticles
Updates the particle data present in particle storage.
@param _particleEffect - the emitter's parent particle effect
@param _particleEmitter - the parent emitter
@param _storageAllocator - the particle data storage
@param _dt - the time (in millisecond) since last update
@return (void)
@context (all)
*/
virtual void UpdateParticles(ZParticleEffect* _particleEffect,
ZParticleEmitter* _particleEmitter,
ZParticleStorageAllocator* _storageAllocator,
size_t _dt
) = 0;
};
#endif

View File

@@ -0,0 +1,145 @@
#include <SST/SST_Math.h>
//Perspective Camera Class, Used to compute camera transforms
class ZPerspectiveCamera
{
protected:
bool transformDirty; //Dirty flag for computing camera transform
SST_Mat44f CameraTransform;
SST_Vec3f EyePoint;
SST_Vec3f ForwardVec;
SST_Vec3f UpVec;
SST_Vec3f RightVec;
float NearClip;
float FarClip;
float XFov;
float AspectRatio;
void ComputeCameraTransform()
{
SST_Mat44f perspectiveMatrix;
SST_Mat44f viewMatrix;
SST_Vec3f target = {ForwardVec.x + EyePoint.x,
ForwardVec.y + EyePoint.y,
ForwardVec.z + EyePoint.z};
SST_Math_Mat44fCreatePerspective(&perspectiveMatrix, this->XFov, this->AspectRatio, this->NearClip, this->FarClip);
SST_Math_Mat44fCreateLookAt(&viewMatrix, &this->EyePoint, &target, &this->UpVec);
SST_Math_Mat44fMultiplyMatrix(&perspectiveMatrix, &viewMatrix, &this->CameraTransform);
this->transformDirty = false;
}
//Flags the transform as 'dirty'
void FlagTransforms()
{
this->transformDirty = true;
}
public:
ZPerspectiveCamera()
{
SST_Vec3f eye = { 0, 0, 0 };
SST_Vec3f forward = { 0, 1, 0 };
SST_Vec3f up = { 0, 0, 1 };
SST_Vec3f right = { 1, 0, 1 };
SetEyePoint(&eye);
SetForwardVec(&forward);
SetUpVec(&up);
SetRightVec(&right);
NearClip = 1.0f;
FarClip = 10000.0f;
XFov = 90.0f;
AspectRatio = 1.0f;
this->transformDirty = true;
}
//Getters for camera data
const SST_Vec3f* GetEyePoint() { return &EyePoint; }
const SST_Vec3f* GetForwardVec() { return &ForwardVec; }
const SST_Vec3f* GetUpVec() { return &UpVec; }
const SST_Vec3f* GetRightVec() { return &RightVec; }
float GetNearClip() { return NearClip; }
float GetFarClip() { return FarClip; }
float GetXFov() { return XFov; }
float GetAspectRatio() { return AspectRatio; }
//Setters for camera data. Will flag the transform as 'dirty'
void SetEyePoint(const SST_Vec3f* _eye) { EyePoint = *_eye; FlagTransforms(); }
void SetForwardVec(const SST_Vec3f* _forward) { ForwardVec = *_forward; FlagTransforms(); }
void SetUpVec(const SST_Vec3f* _up) { UpVec = *_up; FlagTransforms(); }
void SetRightVec(const SST_Vec3f* _right) { RightVec = *_right; FlagTransforms(); }
void SetNearClip(float _nearClip) { NearClip = _nearClip; FlagTransforms(); }
void SetFarClip(float _farClip) { FarClip = _farClip; FlagTransforms(); }
void SetXFov(float _xFov) { XFov = _xFov; FlagTransforms(); }
void SetAspectRatio(float _ratio) { AspectRatio = _ratio; FlagTransforms(); }
//Movement methods, which move the camera in the direction if it's basis vectors by a factor
void MoveForward(float t)
{
SST_Vec3f tmp;
SST_Math_Vec3fScale(&ForwardVec, t, &tmp);
SST_Math_Vec3fAddLocal(&EyePoint, &tmp);
FlagTransforms();
}
void MoveUp(float t)
{
SST_Vec3f tmp;
SST_Math_Vec3fScale(&UpVec, t, &tmp);
SST_Math_Vec3fAddLocal(&EyePoint, &tmp);
FlagTransforms();
}
void MoveRight(float t)
{
SST_Vec3f tmp;
SST_Math_Vec3fScale(&RightVec, t, &tmp);
SST_Math_Vec3fAddLocal(&EyePoint, &tmp);
FlagTransforms();
}
//Rotation Methods, which rotate the camera about it's basis vectors
void RotateUp(float t)
{
SST_Math_Vec3fRotateAboutLocal(&this->ForwardVec, &this->RightVec, t);
SST_Math_Vec3fRotateAboutLocal(&this->UpVec, &this->RightVec, t);
FlagTransforms();
}
void RotateRight(float t)
{
SST_Math_Vec3fRotateAboutLocal(&this->ForwardVec, &this->UpVec, t);
SST_Math_Vec3fRotateAboutLocal(&this->RightVec, &this->UpVec, t);
FlagTransforms();
}
void RotateClockwise(float t)
{
SST_Math_Vec3fRotateAboutLocal(&this->UpVec, &this->ForwardVec, t);
SST_Math_Vec3fRotateAboutLocal(&this->RightVec, &this->ForwardVec, t);
FlagTransforms();
}
//Camera transform getters, which will trigger a recompute of the transform matrix if need be
const SST_Mat44f* GetCameraTransform()
{
if (this->transformDirty)
{
this->ComputeCameraTransform();
}
return &this->CameraTransform;
}
};

View File

@@ -0,0 +1,84 @@
/*
ZSolidFontFace.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Purpose: TODO
Changelog
2011/09/18 - creation (ptbaggett)
*/
#pragma once
#ifndef _ZSOLIDFONTFACE_HPP
#define _ZSOLIDFONTFACE_HPP
#include <SST/SST_Vec2.h>
#include <ZRendererUtil/ZFontRenderer.hpp> //Need ZFontBounds structure
//#include <vector>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
//Needed for friend class definition
class ZSolidFontRenderer;
// Structure representing glyph information for use in solid font rendering
struct ZSolidGlyphInfo
{
FT_UInt glyphId; // Glyph ID, as read from the font
ZArray<SST_Vec2f> verts; // Vertex data, every 3 vertices makes a triangle
int advancex; // Amount along X axis to advance pen by, in pixels
int advancey; // Amount along Y axis to advance pen by, in pixels
ZFontBounds bbox; // Bounding box of this glyph, in pixels
};
//Class representing a font face created by a SolidFontRenderer
class ZSolidFontFace
{
friend class ZSolidFontRenderer;
private:
FT_Face face;
char* fontData;
int hasKerning;
ZHashMap<unsigned int, ZSolidGlyphInfo> glyphCache;
public:
/*
Default Constructor.
*/
ZSolidFontFace();
/*
Destructor.
*/
~ZSolidFontFace();
/*
public ZSolidFontFace::cacheGlyph
Caches a glyph, given a UTF-32 character code. The glyph must not already be loaded.
@param charCode - The UTF-32 character code for this glyph
@return (const ZSolidGlyphInfo&) - Reference to the glyph information.
@context (all)
*/
const ZSolidGlyphInfo& CacheGlyph(unsigned int charCode);
/*
public ZSolidFontFace::getGlyph
Gets a glyph from the cache, or loads it if necessary.
@param charCode -
@return (const ZSolidGlyphInfo*)
@context (all)
*/
const ZSolidGlyphInfo* GetGlyph(unsigned int charCode);
};
#endif

View File

@@ -0,0 +1,101 @@
/*
ZSolidFontRenderer.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Purpose: TODO
Changelog
2011/09/18 - creation (ptbaggett)
*/
#pragma once
#ifndef _ZSOLIDFONTRENDERER_H
#define _ZSOLIDFONTRENDERER_H
#include <SST/SST_Mat44.h>
#include <ZRenderer/ZRenderer.hpp>
#include <ZRenderer/ZDataBuffer.hpp>
#include <ZRendererUtil/ZFontRendererBase.hpp>
#include <ZRendererUtil/ZSolidFontFace.hpp>
#include <ft2build.h>
#include FT_FREETYPE_H
#define TRICACHE_SIZE (8*1024) //Cache up to 8K polygons before drawing
class ZSolidFontRenderer : public ZFontRendererBase
{
protected:
ZRenderer* renderer;
ZPtr<ZDataBuffer> tricache;
const ZDataBufferStream* posstream;
const ZDataBufferStream* colorstream;
const ZDataBufferBlock* matrixBlock;
const ZDataBufferBlock* indexBlock;
ZPtr<ZShaderProgram> shaderprogram;
ZPtr<ZShaderParams> shaderparams;
ZPtr<ZIndexParams> indexparams;
ZPtr<ZVertexParams> vertexparams;
ZPtr<ZDataBuffer> uniforms;
ZPtr<ZDataBuffer> indexes;
ZFrameContext ctx;
SST_Mat44f xform;
//Internal used struct for vertex / color pairing
struct SolidVertex
{
float x, y;
float rgba[4];
};
SolidVertex* vtx_dma;
FT_Library library;
float color[4];
size_t nrTrisWritten;
bool inRendering;
void flushTriCache();
public:
/*
Constructor.
@param _renderer - the current renderer instance.
*/
ZSolidFontRenderer(ZRenderer* _renderer);
/*
Destructor.
*/
virtual ~ZSolidFontRenderer();
//Subclass Implementation
virtual ZFontFace CreateFontFace(int pixelSize, const void* fontData, unsigned int dataSize);
//Subclass Implementation
virtual void DeleteFontFace(ZFontFace face);
//Subclass Implementation
virtual void BeginText(ZFrameContext _ctx, const SST_Mat44f& _xform);
//Subclass Implementation
virtual void EndText();
//Subclass Implementation
virtual void RenderText(int x, int y, const char* text);
//Subclass Implementation
virtual void ComputeBounds(const char* text, ZFontBounds* bounds);
//Subclass Implementation
virtual void SetColor(float r, float g, float b, float a);
};
#endif

View File

@@ -0,0 +1,105 @@
/*
ZStandardParticleRenderStrategy.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/09/11 - creation (jcrussell)
*/
#pragma once
#ifndef _ZSTANDARDPARTICLERENDERSTRATEGY_H
#define _ZSTANDARDPARTICLERENDERSTRATEGY_H
#include <ZRendererUtil/ZParticleRenderStrategy.h>
#include <ZRendererUtil/ZStandardParticleStorageAllocator.h>
class ZStandardParticleRenderStrategy : public ZParticleRenderStrategy
{
protected:
//Vertex buffer
ZPtr<ZDataBuffer> VertexBuffer;
//Index buffer
ZPtr<ZDataBuffer> IndexBuffer;
//Material we use
ZPtr<ZMaterialSurface> ParticleMaterial;
//Texture we'll be using
ZPtr<ZTexture2D> ParticleTexture;
//Our render state
ZRenderState RenderState;
//Our UV coordinates (per vertex)
float UVs[8];
public:
/*
Constructor.
@param _maxParticles - maximum number of particles we will use
@param _renderer - the renderer instance
*/
ZStandardParticleRenderStrategy();
/*
Destructor.
*/
~ZStandardParticleRenderStrategy();
/*
public ZStandardParticleRenderStrategy::SetParticleTexture
TODO
@param _texture -
@return (void)
@context (all)
*/
void SetParticleTexture(ZPtr<ZTexture2D> _texture);
/*
public ZStandardParticleRenderStrategy::SetParticleTextureUVs
TODO
@param _uvs - uv coordinate array (size 8)
@return (void)
@context (all)
*/
void SetParticleTextureUVs(float *_uvs);
/*
public ZStandardParticleRenderStrategy::SetRenderState
TODO
@param _state -
@return (void)
@context (all)
*/
void SetRenderState(ZRenderState _state);
//Subclass Override
void AllocateBuffers(size_t _maxParticles, ZRenderer *_renderer);
//Subclass Override
virtual bool CheckParticleFormat( const ZString& _format );
//Subclass Override
virtual void RenderParticles(ZParticleEffect* _particleEffect,
ZParticleEmitter* _particleEmitter,
ZParticleStorageAllocator* _storageAllocator,
ZRenderer* _renderer,
ZFrameContext _frameContext,
const ZMatrix44f& _transform,
int _drawGroup );
};
#endif

View File

@@ -0,0 +1,218 @@
/*
ZStandardParticleSpawnStrategy.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/09/11 - creation (jcrussell)
*/
#pragma once
#ifndef _ZSTANDARDPARTICLESPAWNSTRATEGY_H
#define _ZSTANDARDPARTICLESPAWNSTRATEGY_H
#define ZSP_DEFAULT_SPAWN_MASS (1)
#define ZSP_DEFAULT_SPAWN_ENERGY (1000)
#define ZSP_DEFAULT_SPAWN_VELOCITY_X (0.0f)
#define ZSP_DEFAULT_SPAWN_VELOCITY_Y (0.0f)
#define ZSP_DEFAULT_SPAWN_VELOCITY_Z (0.0f)
#define ZSP_DEFAULT_SPAWN_FACING_X (0.0f)
#define ZSP_DEFAULT_SPAWN_FACING_Y (0.0f)
#define ZSP_DEFAULT_SPAWN_FACING_Z (1.0f)
#define ZSP_DEFAULT_SPAWN_SCALE_X (1.0f)
#define ZSP_DEFAULT_SPAWN_SCALE_Y (1.0f)
#define ZSP_DEFAULT_SPAWN_COLOR_R (1.0f)
#define ZSP_DEFAULT_SPAWN_COLOR_G (1.0f)
#define ZSP_DEFAULT_SPAWN_COLOR_B (1.0f)
#define ZSP_DEFAULT_SPAWN_COLOR_A (1.0f)
#define ZSP_DEFAULT_TEXTURE_U (0.0f)
#define ZSP_DEFAULT_TEXTURE_V (0.0f)
#define ZSP_DEFAULT_TEXTURE_OFFSET (1.0f)
#define ZSP_DEFAULT_SPAWN_INTERVAL (100)
#define ZSP_DEFAULT_SPAWN_ANGLE (0.0f)
#define ZSP_DEFAULT_SPAWN_COUNT_MIN (0)
#define ZSP_DEFAULT_SPAWN_COUNT_MAX (1)
#include <ZRendererUtil/ZStandardParticleStorageAllocator.h>
#include <ZRendererUtil/ZParticleSpawnStrategy.h>
class ZStandardParticleSpawnStrategy : public ZParticleSpawnStrategy
{
private:
//The time until our next spawn
int NextSpawn;
//Our current spawn group
size_t CurrentSpawnGroup;
protected:
//Template for the particle we will be spawning with
ZStandardParticle TemplateParticle;
//The span between particle spawns
size_t SpawnInterval;
//The half-angle we deviate within when spawning a particle [0.0 - pi]
float SpawnAngle;
//The particle count spawn range (lower, upper)
ZPair<size_t, size_t> SpawnCountRange;
public:
/*
Default Constructor.
*/
ZStandardParticleSpawnStrategy();
/*
Destructor.
*/
virtual ~ZStandardParticleSpawnStrategy();
//Subclass Override
virtual bool CheckParticleFormat( const ZString& _format );
//Subclass Override
virtual void UpdateSpawn(ZParticleEffect* _particleEffect,
ZParticleEmitter* _particleEmitter,
ZParticleStorageAllocator* _storageAllocator,
size_t _dt );
/*
public ZStandardParticleSpawnStrategy::GetSpawnAngle
TODO
@return (float)
@context (all)
*/
float GetSpawnAngle();
/*
public ZStandardParticleSpawnStrategy::GetSpawnColor
TODO
@return (const ZVector4f&)
@context (all)
*/
const ZVector4f& GetSpawnColor();
/*
public ZStandardParticleSpawnStrategy::GetSpawnEnergy
TODO
@return (size_t)
@context (all)
*/
size_t GetSpawnEnergy();
/*
public ZStandardParticleSpawnStrategy::GetSpawnInterval
TODO
@return (size_t)
@context (all)
*/
size_t GetSpawnInterval();
/*
public ZStandardParticleSpawnStrategy::GetSpawnScale
TODO
@return (const ZVector2f&)
@context (all)
*/
const ZVector2f& GetSpawnScale();
/*
public ZStandardParticleSpawnStrategy::GetSpawnVelocity
TODO
@return (const ZVector3f&)
@context (all)
*/
const ZVector3f& GetSpawnVelocity();
/*
public ZStandardParticleSpawnStrategy::SetSpawnAngle
TODO
@param _angle -
@return (void)
@context (all)
*/
void SetSpawnAngle(float _angle);
/*
public ZStandardParticleSpawnStrategy::SetSpawnColor
TODO
@param _color -
@return (void)
@context (all)
*/
void SetSpawnColor(const ZVector4f& _color);
/*
public ZStandardParticleSpawnStrategy::SetSpawnEnergy
TODO
@param _energy -
@return (void)
@context (all)
*/
void SetSpawnEnergy(size_t _energy);
/*
public ZStandardParticleSpawnStrategy::SetSpawnInterval
TODO
@param _interval -
@return (void)
@context (all)
*/
void SetSpawnInterval(size_t _interval);
/*
public ZStandardParticleSpawnStrategy::SetSpawnScale
TODO
@param _scale -
@return (void)
@context (all)
*/
void SetSpawnScale(const ZVector2f& _scale);
/*
public ZStandardParticleSpawnStrategy::SetDirection
TODO
@param _direction -
@return (void)
@context (all)
*/
void SetSpawnVelocity(const ZVector3f& _velocity);
};
#endif

View File

@@ -0,0 +1,167 @@
/*
ZStandardParticleStorageAllocator.h
Author: James Russell <jcrussell@762studios.com>
Purpose: Standard particle type allocator. Stores particle data as an array of structs containing particle data.
Changelog
2011/09/11 - creation (jcrussell)
*/
#pragma once
#ifndef _ZSTANDARDPARTICLESTORAGEALLOCATOR_H
#define _ZSTANDARDPARTICLESTORAGEALLOCATOR_H
#include <ZRendererUtil/ZParticleStorageAllocator.h>
//Struct containing our per-particle data
struct ZStandardParticle
{
//Particle mass (sign indicates charge)
int Mass;
//Particle Energy (when zero or less, dead)
int Energy;
//Particle Position (offset from emitter transform)
ZVector3f Position;
//Particle Facing (only matters if not billboarding)
ZVector3f Facing;
//Particle Velocity
ZVector3f Velocity;
//Particle Scaling
ZVector2f Scale;
//Particle Color (per vertex, includes alpha)
// 3 --- 2
// | |
// 0 --- 1
ZVector4f Color[4];
//Texture data (U, V, texture width and height)
ZVector3f TextureData;
//Particle Id
size_t Id;
//Default Constructor
ZStandardParticle()
: Mass(1), Energy(0),
Position(0, 0, 0), Facing(0, 0, 0),
Velocity(0, 0, 0), Scale(0, 0),
TextureData(0, 0, 0), Id(0)
{
for (int i = 0; i < 4; ++i)
{
Color[i].Data[0] = 0;
Color[i].Data[1] = 0;
Color[i].Data[2] = 0;
Color[i].Data[3] = 0;
}
}
};
class ZStandardParticleStorageAllocator : public ZParticleStorageAllocator
{
protected:
//The next inactive particle
int NextInactive;
//The current particle group
size_t CurrentGroup;
//The current particle within the current group
size_t CurrentParticle;
//Array containing particle storage
ZArray<ZStandardParticle> ParticleData;
//Array containing indices for particles that have been activated (must be cleared manually)
ZArray<int> NewParticles;
public:
/*
Constructor.
*/
ZStandardParticleStorageAllocator();
/*
Destructor.
*/
virtual ~ZStandardParticleStorageAllocator();
/*
public ZStandardParticleStorageAllocator::ActivateParticle
Activates a particle contained in storage and returns the index of the activated particle. This
sets the particle id.
@param _group - the group number this particle is being activated with
@return (int) - index to the activated particle
@context (all)
*/
int ActivateParticle(size_t _group);
/*
public ZStandardParticleStorageAllocator::DeactivateParticle
Deactivates a particle given the index to the particle in storage.
@param _index - index to the particle in storage
@return (void)
@context (all)
*/
void DeactivateParticle(size_t _index);
/*
public ZStandardParticleStorageAllocator::GetActiveParticleCount
Gets the number of currently active particles. So long as only the methods
ActivateParticle and DeactivateParticle have been used, they are guaranteed
to be sequential in the ParticleData array and starting at index 0.
@return (int) - number of active particles
@context (all)
*/
int GetActiveParticleCount();
/*
public ZStandardParticleStorageAllocator::GetParticleData
Gets a reference to the array containing particle data.
@return (ZArray<ZStandardParticle>&) - the particle data array
@context (all)
*/
ZArray<ZStandardParticle>& GetParticleData();
/*
public ZStandardParticleStorageAllocator::GetNewParticles
Gets an array containing indices that correspond to newly activated particles. Should be
cleared by the spawn strategy when updated.
@return (ZArray<int>&) - list of indices to particles that have been activated
@context (all)
*/
ZArray<int>& GetNewParticles();
//Subclass Override
virtual void AllocateParticleStorage( ZParticleEmitter* _emitter, size_t _maxParticles );
//Subclass Override
virtual void DeallocateParticleStorage();
//Subclass Override
virtual ZString GetParticleFormat();
//Subclass Override
virtual void Update(ZParticleEffect *_effect, ZParticleEmitter *_emitter, size_t _dt);
};
#endif

View File

@@ -0,0 +1,97 @@
/*
ZStandardParticleUpdateStrategy.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/09/11 - creation (jcrussell)
*/
#pragma once
#ifndef _ZSTANDARDPARTICLEUPDATESTRATEGY_H
#define _ZSTANDARDPARTICLEUPDATESTRATEGY_H
#include <ZRendererUtil/ZParticleUpdateStrategy.h>
#define ZSP_DEFAULT_ENERGY_BLEED (1)
#define ZSP_DEFAULT_ACCELERATION_X (0.0f)
#define ZSP_DEFAULT_ACCELERATION_Y (0.0f)
#define ZSP_DEFAULT_ACCELERATION_Z (0.5f)
class ZStandardParticleUpdateStrategy : public ZParticleUpdateStrategy
{
protected:
//Acceleration Vector
ZVector3f ParticleAcceleration;
//Energy drop per ms
size_t EnergyBleed;
public:
/*
Default Constructor.
*/
ZStandardParticleUpdateStrategy();
/*
Destructor.
*/
~ZStandardParticleUpdateStrategy();
/*
public ZStandardParticleUpdateStrategy::GetEnergyBleed
TODO
@return (const size_t)
@context (all)
*/
const size_t GetEnergyBleed();
/*
public ZStandardParticleUpdateStrategy::GetParticleAcceleration
TODO
@return (const ZVector3f)
@context (all)
*/
const ZVector3f GetParticleAcceleration();
/*
public ZStandardParticleUpdateStrategy::SetEnergyBleed
TODO
@param _bleedRate -
@return (void)
@context (all)
*/
void SetEnergyBleed(size_t _bleedRate);
/*
public ZStandardParticleUpdateStrategy::SetParticleAcceleration
TODO
@param _accel -
@return (void)
@context (all)
*/
void SetParticleAcceleration(const ZVector3f& _accel);
//Subclass Implementation
virtual bool CheckParticleFormat( const ZString& _format );
//Subclass Implementation
virtual void UpdateParticles(ZParticleEffect* _particleEffect,
ZParticleEmitter* _particleEmitter,
ZParticleStorageAllocator* _storageAllocator,
size_t _dt );
};
#endif

View File

@@ -0,0 +1,134 @@
/*
ZStaticMesh.h
Author: Chris Ertel <crertel@762studios.com>
Purpose: Classes for holding static mesh data.
Changelog
2011/09/18 - creation (crertel)
*/
#pragma once
#ifndef _ZSTATICMESH_H
#define _ZSTATICMESH_H
#include <ZUtil/ZSmartPointer.hpp>
#include <ZSTL/ZArray.hpp>
#include <ZSTL/ZString.hpp>
typedef uint32_t ZSMFaceIndex;
typedef enum ZSMChannelType
{
ZSMCT_UNKNOWN = 0,
ZSMCT_BOOL = 0x11,
ZSMCT_BOOL_VEC2 = 0x12,
ZSMCT_BOOL_VEC3 = 0x13,
ZSMCT_BOOL_VEC4 = 0x14,
ZSMCT_INT = 0x21,
ZSMCT_INT_VEC2 = 0x22,
ZSMCT_INT_VEC3 = 0x23,
ZSMCT_INT_VEC4 = 0x24,
ZSMCT_UINT = 0x31,
ZSMCT_UINT_VEC2 = 0x32,
ZSMCT_UINT_VEC3 = 0x33,
ZSMCT_UINT_VEC4 = 0x34,
ZSMCT_FLOAT = 0x41,
ZSMCT_FLOAT_VEC2 = 0x42,
ZSMCT_FLOAT_VEC3 = 0x43,
ZSMCT_FLOAT_VEC4 = 0x44
};
class ZSMChannelDefinition
{
protected:
ZString Name;
ZSMChannelType Datatype;
uint32_t StartOffset;
uint32_t Stride;
public:
ZSMChannelDefinition( ZString _name, ZSMChannelType _datatype, uint32_t _offset, uint32_t _stride)
: Name(_name), Datatype(_datatype), StartOffset(_offset), Stride(_stride)
{
}
};
class ZStaticMeshMaterial
{
protected:
ZString Name;
ZArray< ZSMFaceIndex > FaceIndices;
ZArray< ZPtr<ZSMChannelDefinition> > ChannelDefinitions;
public:
ZStaticMeshMaterial(ZString _name, ZArray< ZSMFaceIndex> _faceIndices, ZArray< ZPtr<ZSMChannelDefinition> > _channelDefinitions)
: Name(_name), FaceIndices(_faceIndices), ChannelDefinitions(_channelDefinitions)
{
}
/*
public ZStaticMeshMaterial::GetName
Function to get the name of the material.
@return (ZString) - Name of the material.
*/
inline ZString GetName() { return this->Name; }
/*
public ZStaticMeshMaterial::GetFaceIndices
Function to get the face indices for a material.
@return (ZArray<ZSMFaceIndex>) - Array of the face indices.
*/
inline ZArray<ZSMFaceIndex> GetFaceIndices() { return this->FaceIndices; }
/*
public ZStaticMeshMaterial::GetChannelDefinitions
Function to get the vertex channel definiitions for this material.
@return (ZArray<ZSMChannelDefinition>) - Array of vertex channel definitions.
*/
inline ZArray< ZPtr<ZSMChannelDefinition> > GetChannelDefinitions() { return this->ChannelDefinitions; }
};
class ZStaticMesh
{
protected:
ZArray< ZPtr<ZStaticMeshMaterial> > MaterialGroups;
ZPtr< ZArray< char > > VertexData;
public:
ZStaticMesh(ZArray< ZPtr<ZStaticMeshMaterial> > _groups, ZPtr< ZArray< char > > _vertexData)
: MaterialGroups(_groups), VertexData(_vertexData)
{
}
/*
public ZStaticMesh::GetMaterialGroups
Function to get the material groups.
@return (ZArray<ZStaticMeshMaterialGroup>) - Material groups that make up the mesh.
*/
inline ZArray< ZPtr<ZStaticMeshMaterial> > GetMaterialGroups() { return this->MaterialGroups; }
/*
public ZStaticMesh::GetVertexData
Function to get the vertex data.
@return (ZPtr< ZArray< char > >) - Vertex data for the mesh.
*/
inline ZPtr< ZArray< char > > GetVertexData() { return this->VertexData; }
};
#endif

View File

@@ -0,0 +1,27 @@
/*
ZStaticMeshLoader.h
Author: Chris Ertel <crertel@762studios.com>
Purpose: File for loading ZStaticMeshes
Changelog
2013/02/24 - Removed dependency on renderer.
2011/09/25 - creation (crertel)
*/
#pragma once
#ifndef _ZSTATICMESHLOADER_H
#define _ZSTATICMESHLOADER_H
#include <ZUtil/ZSmartPointer.hpp>
#define ZSM_CURRENT_VERSION (4)
class ZStaticMesh;
class ZStaticMeshLoader
{
public:
static ZPtr<ZStaticMesh> loadFromMemory(const void* _memory, size_t _sizeInMemory);
};
#endif

View File

@@ -0,0 +1,100 @@
/*
ZTessellator.h
Author: Patrick Baggett <ptbaggett@762studios.com>
Purpose: Header for tessellator interface. (currently requires GLU)
Changelog
2011/09/18 - creation (ptbaggett)
*/
#pragma once
#ifndef _ZTESSELLATOR_HPP
#define _ZTESSELLATOR_HPP
#include <ZRendererUtil/ZOutlineEvaluator.hpp>
//Types of tessellations we can handle
enum ZTesselatorPolyType
{
ZTPT_POLY_TRIANGLES,
ZTPT_POLY_TRIFAN,
ZTPT_POLY_TRISTRIP
};
class ZTessellator
{
protected:
//Protected Constructor
ZTessellator() { }
public:
//Virtual Destructor
virtual ~ZTessellator() { }
/*
virtual public ZTessellator::BeginPoly
TODO
@param type -
@return (void)
@context (all)
*/
virtual void BeginPoly(ZTesselatorPolyType type) = 0;
/*
virtual public ZTessellator::BeginTessellate
TODO
@return (void)
@context (all)
*/
virtual void BeginTessellate() = 0;
/*
virtual public ZTessellator::EndPoly
TODO
@return (void)
@context (all)
*/
virtual void EndPoly() = 0;
/*
virtual public ZTessellator::EndTessellate
TODO
@return (void)
@context (all)
*/
virtual void EndTessellate() = 0;
/*
virtual public ZTessellator::Tessellate
TODO
@return (void)
@context (all)
*/
virtual void Tesselate() = 0;
/*
virtual public ZTessellator::Vertex
TODO
@param p -
@return (void)
@context (all)
*/
virtual void Vertex(SST_Vec2f* p) = 0;
};
#endif

View File

@@ -0,0 +1,64 @@
/*
ZTessellatorBase.h
Author: James Russell <jcrussell@762studios.com>
Purpose: TODO
Changelog
2011/09/18 - creation (jcrussell)
*/
#pragma once
#ifndef _ZTESSELLATORBASE_HPP
#define _ZTESSELLATORBASE_HPP
#include <ZRendererUtil/ZTessellator.hpp>
//#if WINDOWS
#include <windows.h>
//#endif
#include <GL/glu.h> //TODO: remove dependency on GLU for tessellation
class ZTessellatorBase : public ZTessellator
{
protected:
//Outline Evaluator to use
ZOutlineEvaluator* Evaluator;
//Tessellator (TODO: remove dependency on GLU)
GLUtesselator *Tessellator;
public:
/*
Default Constructor.
*/
ZTessellatorBase(ZOutlineEvaluator* _eval);
/*
Destructor.
*/
virtual ~ZTessellatorBase();
//Subclass Implementation
virtual void Tesselate();
//Not Implemented
virtual void BeginTessellate() = 0;
//Not Implemented
virtual void EndTessellate() = 0;
//Not Implemented
virtual void BeginPoly( ZTesselatorPolyType type ) = 0;
//Not Implemented
virtual void EndPoly() = 0;
//Not Implemented
virtual void Vertex( SST_Vec2f* p ) = 0;
};
#endif

View File

@@ -0,0 +1,37 @@
/*
ZTransformHierarchy.h
Author: Chris Ertel <crertel@762studios.com>
Purpose: Helper classes to setup a simple transform hierarchy.
Changelog
2011/09/20 - creation (crertel)
*/
#pragma once
#ifndef _ZTRANSFORMHIERARCHY_H
#define _ZTRANSFORMHIERARCHY_H
#include <ZUtil/ZSmartPointer.hpp>
#include <ZSTL/ZArray.hpp>
#include <ZUtil/ZMath.h>
class ZTransformHierarchy
{
protected:
ZMatrix44f Transform;
ZString Name;
ZArray Children;
public:
ZTransformHierarchy();
~ZTransformHierarchy();
void Render(ZPtr<ZRenderer> _renderer, ZFrameContext _context, int _drawgroup, ZMatrix44f _transform, ZRenderState _renderState);
};
#endif

View File

@@ -0,0 +1,55 @@
/*
ZTriTessellator.h
Author: Patrick Baggett <ptbaggett@762studios.com>
Chris Ertel <crertel@762studios.com>
Purpose: Implementation of tessellator interface that tessellates into lists of triangles (unindexed)
Changelog
2011/09/18 - creation (ptbaggett)
2012/08/05 - Updated to use new SST functions.
*/
#pragma once
#ifndef _ZTRITESSELLATOR_HPP
#define _ZTRITESSELLATOR_HPP
#include <SST/SST_Vec2.h>
#include <ZRendererUtil/ZTessellatorBase.hpp>
class ZTriTessellator : public ZTessellatorBase
{
protected:
//Our set of vertices
ZArray<SST_Vec2f>& Vertices;
//Temporary use array
ZArray<SST_Vec2f> Temp;
//Tessellation poly type
ZTesselatorPolyType PolyType;
public:
//Dumps a list of vertices into 'verts' when complete
ZTriTessellator(ZOutlineEvaluator* _eval, ZArray<SST_Vec2f>& _verts);
//Subclass Implementation
virtual void BeginTessellate();
//Subclass Implementation
virtual void EndTessellate();
//Subclass Implementation
virtual void BeginPoly(ZTesselatorPolyType _type);
//Subclass Implementation
virtual void EndPoly();
//Subclass Implementation
virtual void Vertex(SST_Vec2f* _p);
};
#endif

View File

@@ -0,0 +1,379 @@
/*
ZEntity.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 2/5/2013
Purpose:
Entity class for the ZSimulation framework.
All objects affecting the simulation will exist as an entity. Entities can either
be created with state or without state. Entities with and without state can
be messaged by other entities within the simulation. Entities with state
have their state function called once per tick, and this state function
can modify the entity state, making the entity an autonomous state machine.
// ENTITY MESSAGING //
Entities are created in order to be processed in a threaded fashion. When
entities have their current state function called, they should be expected to be
able to process this in a thread-safe manner, able to call their own non-const methods
but only able to affect other entities via messaging.
After the state functions are called, remaining messages are delivered to the entity
'mailbox'. Any action that could mutate an entity that is not done from within the
call to the state function must be handled via a message.
These delivered messages are then processed in a multi threaded manner, but each entity
has it's messages processed serially, meaning that modifications can take place as per
normal.
Entity messages are processed by deferring to the handler installed for a particular
message type on an entity. If no message handler is installed for that message type
on an entity, the message handler installed for that type on the simulation message
stream will be called. If no message handler is installed there, the message is
dropped.
// ENTITY PROPERTIES //
Entities hold their state via allocation into the simulation 'property buffer', which
allows for contiguous space allocation for properties to be stored. The property
buffer is a raw memory allocator and does not care what the underlying data actually
is.
Entity properties can be allocated as 'local' or 'synchronized'. Data stored locally
is not updated to other simulation instances. Data stored in a 'synchronized' state is
mirrored to other simulation instances.
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef ZENTITY_HPP
#define ZENTITY_HPP
#include <ZUtil/ZRandomGenerator.hpp>
#include <ZUtil/ZName.hpp>
#include "ZSimulationDefs.hpp"
#include "ZPropertyBuffer.hpp"
#include "ZStringBuffer.hpp"
// forward decl
class ZSimulation;
struct ZMessage;
/*
Entity class.
*/
class ZEntity
{
public:
/*
This is the entity state typedef, which corresponds to 'AI State'. The current think state
is called once per simulation tick.
@param entity - the entity who is thinking
@param sim - the running simulation
@param dt - the time (expressed in seconds) since last call of this function
*/
typedef void (*StateFunc)(ZEntity& entity, const ZSimulation& sim, double dt);
/*
This is the entity message handler typedef, which corresponds to 'Behavior'. If there is no message
handler installed for a given message type, the default handler installed in the message queue
is used.
@param entity - the entity receiving the message
@param sim - the running simulation
@param sender - the sending entity
@param payload - the payload of the message
*/
typedef void (*MessageFunc)(ZEntity& entity, const ZSimulation& sim, eID sender, void* payload);
/*
This is the entity initialization function typedef, which can be passed to the simulation to initialize
the entity upon creation.
@param entity - the entity to initialize
@param sim - the running simulation
*/
typedef void (*InitFunc)(ZEntity& entity, const ZSimulation& sim);
/*
Entity property class. An ease of access class for reading and writing
property data.
This class does not handle type coercion on read. Types will change when
values are set.
*/
struct Property {
// we'll be using this a lot
typedef ZStringBuffer::StringKey StringKey;
enum {
BOOL, // boolean type
INT, // integer type
FLOAT, // floating point type
DOUBLE, // double precision floating point type
STRING, // string type (stored in string buffer or dynamic, limited size)
VECTOR, // vector type (4 floating point values)
MATRIX, // matrix type (16 floating point values)
NONE // untyped data
} Type; // the type of property
ZString LocalString; // local storage for strings
uint8_t Local[64]; // local storage for simple types
void* Data; // data for more complex types
size_t Size; // size of data (in bytes)
// default constructor, which initializes an empty string
Property();
// generic and array constructor, which takes data and size
Property(void* data, size_t size);
// value constructors
Property(const Property& other);
Property(const bool val);
Property(const int val);
Property(const float val);
Property(const double val);
Property(const char* val); // checks to see if this string has a string key, if not makes a dynamic string
Property(const StringKey val); // quicker method of directly creating a static string type
Property(const SST_Vec4f& val);
Property(const SST_Vec3f& val); // convenience for SST_Vec4f(x, y, z, 0.0)
Property(const SST_Vec2f& val); // convenience for SST_Vec4f(x, y, 0.0, 0.0)
Property(const SST_Mat44f& val);
// assignment operators
Property& operator = (const Property& other);
Property& operator = (const bool& val);
Property& operator = (const int& val);
Property& operator = (const float& val);
Property& operator = (const double& al);
Property& operator = (const char* val);
Property& operator = (const StringKey val); // quicker method of using a static string type
Property& operator = (const SST_Vec4f& val);
Property& operator = (const SST_Vec3f& val); // convenience for SST_Vec4f(x, y, z, 0.0)
Property& operator = (const SST_Vec2f& val); // convenience for SST_Vec4f(x, y, 0.0, 0.0)
Property& operator = (const SST_Mat44f& val);
// cast operators
operator bool () const;
operator int () const;
operator float () const;
operator double () const;
operator char* () const;
operator bool* () const;
operator int* () const;
operator float* () const;
operator double* () const;
operator SST_Vec4f () const;
operator SST_Vec3f () const; // gets [x, y, z] only
operator SST_Vec2f () const; // gets [x, y] only
operator SST_Mat44f () const;
};
// c'tor
ZEntity(eID entityId, ZSimulation& sim);
// parameterized c'tor (creates an actor)
ZEntity(eID entityId, ZSimulation& sim, StateFunc startState);
// d'tor
~ZEntity();
//////////////////////////////////////////////////////////////////////////
// Member Data Getter Functions
eID GetId() const;
ZRandomGenerator& GetPRNG();
//////////////////////////////////////////////////////////////////////////
// Property Manipulation Functions
/*
Property access functions. Used to create, remove, read, and write properties
and their values.
The 'HasProperty' function will return true if the named property exists on
this entity.
The 'CreateSyncProperty' functions is used to declare a synchronized property
on this entity. Synchronized properties are automatically mirrored across
the network system whenever a change is made. If the 'owner' boolean is
set to true, modifications to the entity on this simulation are synchronized
to other simulations. If the owner boolean is set to false, modifications
are not synchronized, and the property will be updated periodically from
other simulations. Only one simulation should be the owner of an entity,
or they will update over each other.
The 'GetProperty' function will fill out a Property instance that references
the read value of the named property. If the named property does not exist
on this entity, the function will return false.
The 'SetProperty' function will set the write value of the property to be
the value provided. If the named property does not exist, it will be created
as a non-synchronized property. Note that the read value is not updated until
the next simulation tick.
The 'EraseProperty' function will queue the property for removal at the end
of this tick, which allows 'get' operations to function as normal until the
next tick.
The template 'Get' function is a shortcut to directly get the value of
a specific property. Note that if the property does not exist, this will
return a default constructed property value.
*/
bool HasProperty(const ZName& name) const;
void CreateSyncProperty(const ZName& name, const Property& prop, bool owner);
bool GetProperty(const ZName& name, Property& val) const;
void SetProperty(const ZName& name, const Property& val);
void EraseProperty(const ZName& name);
template <typename T>
T Get(const ZName& name) const
{ Property prop; GetProperty(name, prop); return (T)prop; }
template <typename T>
void Set(const ZName& name, const T val)
{ Property prop(val); SetProperty(name, prop); }
/*************************************************************************/
/* State Management Functions */
/*
State functions. Used to get information about the current state and
manipulate the state stack, as well as call the current state function.
Push and Pop operate as you would expect for a state stack. The maximum
number of states is defined by ZENT_STACK_SIZE.
SetState sets the current state to the given state, replacing it.
ResetState clears the state stack and sets the current state to be the
provided one.
*/
StateFunc GetCurrentState() const;
double GetTimeInCurrentState() const;
void PushState(StateFunc state);
void PopState();
void SetState(StateFunc state);
void ResetState(StateFunc state);
/*
State property stack manipulation functions. Used to read and write information
to the state property stack, which can be used to pass transient information from
one state function to another.
*/
size_t GetStatePropertyCount() const;
Property PopStateProperty();
void PushStateProperty(const Property& prop);
void ClearStatePropertyStack();
/*************************************************************************/
/* Messaging Management Functions */
/*
Messages, once posted to the message queue, can be 'delivered' to entities for
sorting purposes to be later processed in a convenient fashion.
When processing delivered messages, order of delivery is maintained. Any
messages that do not have a corresponding handler type installed will be
handled by the handler installed in the message stream. If no corresponding
handler is installed there, the message is dropped, and the simulation is
notified.
*/
void DeliverMessage(ZMessage* msg);
void ProcessMessages();
void PushMessageHandler(mID type, MessageFunc handler);
void PopMessageHandler(mID type);
void ClearMessageHandlers();
protected:
/*
Typedef for the property map used by ZEntity. It has a bucket size of 32, local
storage for the buckets of 32, 10 local nodes for each hash-chain, 10 local storage
for each property array, and will not resize based on load factor. Uses a 64-bit
hash value.
*/
typedef ZHashMap<ZName, ZPropertyBuffer::Property, int64_t, ZHasher<ZName, int64_t>, 0> PropMap;
/*
Stack used to indicate which properties have been modified since last swap of properties.
*/
typedef ZArray<ZPair<ZName, ZPropertyBuffer::Property>> PropModifiedStack;
/*
Stack used to indicate which properties have been deleted since last swap of properties.
*/
typedef ZArray<ZName> PropDeletedStack;
/*
Stack used for state properties, which can be used to send data from one state to another.
*/
typedef ZArray<Property> StatePropStack;
/*
Buffer used as an entity mailbox - targeted messages are delivered here.
*/
typedef ZRingBuffer<ZMessage*> Mailbox;
/*
Typedef for the handler map used by ZEntity, which maps message type to a
stack of handlers. Only keeps two local nodes in the allocator, and will not
resize based on load factor.
*/
typedef ZHashMap<mID, ZArray<MessageFunc>, int64_t, ZHasher<ZName, int64_t>, 0,
ZListPooledAllocator<ZHashNode<mID, ZArray<MessageFunc>, int64_t>, 2 >> HandlerMap;
/* Member Data */
ZSimulation& Sim; // the simulation running this thing
const eID Id; // the id of the entity
ZRandomGenerator PRNG; // entity PRNG, kept so there are no thread conflicts with PRNG access
/* Property Management */
PropMap PropertyMap; // entity properties map
PropModifiedStack PropertyModifiedStack; // properties that need to be mirrored into the read properties map
PropDeletedStack PropertyDeletedStack; // properties have been deleted
/* State Management */
int StateIndex; // index to our current state (-1 indicates no state)
StateFunc StateStack[ZSIM_ENT_STATE_STACK_SIZE]; // stack of states (StateStack[StateIndex] is our current)
StatePropStack StatePropertyStack; // stack of properties so that states can pass data to each other
double StateTime; // amount of time we have spent in our current state
/* Message Management */
Mailbox MessageMailbox; // entity 'Mailbox', which is where messages get delivered to
HandlerMap MessageHandlers; // entity handlers, used to process received messages
private:
friend class ZSimulation;
friend class ActorTickTask;
DISABLE_COPY_AND_ASSIGN(ZEntity);
// allocates a new property
// TODO
// called by the simulation to tick the current state
void StateTick(double dt);
// called by the simulation to dealloc properties
void HandlePropertyDelete();
};
#endif

View File

@@ -0,0 +1,153 @@
/*
ZMessageStream.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 2/4/2013
Purpose:
Messaging stream class, which acts as an event loop for the entire simulation. Processes both
untargeted (or 'simulation' targeted) messages and messages that are intended for a specific entity.
Handles organization and sorting so that the messages can be processed in a thread safe fashion at
a later time.
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZMESSAGESTREAM_HPP
#define _ZMESSAGESTREAM_HPP
#include <ZUtil/ZConcurrency.hpp>
#include <ZUtil/ZSlabAllocator.hpp>
#include "ZSimulationDefs.hpp"
//Forward Declarations
class ZSimulation;
/*
Message structure. Messages are in the form of a POD struct of a set size
payload. Message layout definitions (see ZSimulationDefs.hpp for examples)
can be used to interpret the data.
*/
struct ZMessage {
mID Type; // type of the message
eID Sender; // the entity who sent the message (ZSIM_EID_SYSTEM means system or simulation)
eID Target; // the target of the message (ZSIM_EID_SYSTEM calls the default handler)
char Payload[ZSIM_MESSAGE_SIZE]; // the message payload, which can be interpreted via layout definitions
};
/*
Message handler function profile.
*/
typedef void (*ZMessageHandler)(eID _sender, eID _target, void* _payload, ZSimulation& _sim);
/*
Message streaming class, used to send messages from one entity to another or to the simulation.
*/
class ZMessageStream
{
public:
// c'tor
ZMessageStream();
// d'tor
~ZMessageStream();
// message 'Send' method, which will copy data from a struct into the message (MT must be a POD type)
template <typename MT>
void Send(mID _type, eID _sender, eID _target, MT _payload)
{
ZMessage* msg;
#if SST_COMPILER == SST_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
ZASSERT(sizeof(MT) <= ZSIM_MESSAGE_SIZE, "Message sent with payload too large!");
#if SST_COMPILER == SST_COMPILER_MSVC
#pragma warning(pop)
#endif
// Synchronized Section
{
ZLock lock(AllocatorMutex);
msg = MessageAllocator.Allocate();
}
ZASSERT(msg != NULL, "Unable to allocate message!");
msg->Type = _type;
msg->Sender = _sender;
msg->Target = _target;
MemCopy(uint8_t, msg->Payload, &_payload, sizeof(MT));
// Synchronized Section
{
ZLock lock(BufferMutex);
MessageBuffers[CurrentBufferIndex].PushBack(msg);
}
}
/*
Pumps the message queue, processing the messages that have been sent since last time this method was
called. Returns true if additional messages were generated during the processing of the current set
of messages.
Messages that are targeted at a specific entity will be delivered to that entity. If that entity cannot
be found, the message is dropped. Messages that target the reserved eID of '0' will be handled by the
message stream handlers.
Only one thread should ever be calling this method. Multiple threads calling this method will result
in that thread waiting until the previous has finished.
Returns true if messages are still available for processing, false if the current queue is empty.
*/
bool ProcessMessages(ZSimulation& _sim);
/*
External message handlers. Used to return an entity targeted message or process a targeted
message that had no installed handler.
*/
void HandleMessage(ZMessage* _msg, ZSimulation& _sim);
void ReturnMessage(ZMessage* _msg);
/*
Push and Pop Methods for Handlers.
*/
void PushHandler(mID _type, ZMessageHandler _handler);
ZMessageHandler PopHandler(mID _type);
protected:
ZMutex AllocatorMutex; // lock for allocators
ZMutex BufferMutex; // lock for buffers
ZMutex HandlerMutex; // lock for handlers
ZMutex ProcessingMutex; // lock for processing
int CurrentBufferIndex; // index to our current message buffer
ZRingBuffer<ZMessage*> MessageBuffers[2]; // the current set of messages (one receives messages while the other is processed)
ZHashMap<mID,
ZArray<ZMessageHandler>> MessageHandlers; // set of handler functions
ZSlabAllocator<ZMessage,
ZSIM_MESSAGE_ALLOC> MessageAllocator; // slab allocator for messages
private:
DISABLE_COPY_AND_ASSIGN(ZMessageStream);
};
#endif

View File

@@ -0,0 +1,165 @@
/*
ZNetworkEvent.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 9/13/2015
Purpose:
Network Event abstract class. Intended to be subclassed into various subclasses that will be
serialized / deserialized and processed on both client and server.
Note that events that originate on the server will generally not have their HandleServer method
called, as the server already processed the occurrence that originated the event. Events
that originate on the client will generally be pushed to the server, have HandleServer
called on them, which will generally also cause an event to be pushed to each client, who
will then have HandleClient called when the event gets deserialized.
From the above usage pattern, we can see that clients generally push events to the server but
do not process the local occurrence (the HandleClient) until after the server has confirmed
the event happens by pushing the event back to all clients, the original sender included.
This usage pattern is not required for client authoritative events, which are processed locally
and then handed to the server to notify other attached clients.
License:
TODO
*/
#pragma once
#ifndef _ZNETWORKEVENT_HPP
#define _ZNETWORKEVENT_HPP
#include "ZSimulationDefs.hpp"
// forward decl
class ZSimulation;
/*
ZNetworkEvent class.
*/
class ZNetworkEvent {
DISABLE_COPY_AND_ASSIGN(ZNetworkEvent);
public:
nID Type; // the type of event this is
cID NetTarget; // the connection this is targeting
cID NetIgnore; // if NetTarget is set to all, this target will be ignored
bool InQueue; // flag set during a handle method to indicate this has been queued up for sending
// handler for events on client side
virtual void HandleClient(ZSimulation& server_sim) = 0;
// handler for events on server side
virtual void HandleServer(ZSimulation& client_sim) = 0;
// called by the network system to deserialize this event from binary form (after header is read)
virtual bool Deserialize(ZBinaryBufferReader& reader) = 0;
// called by the network system to serialize this event into binary form
virtual void Serialize(ZBinaryBufferWriter& writer) = 0;
// called to get the serialized size of this event (including uint8_t message type flag)
virtual size_t GetSerializedSize() = 0;
// called by subclass to serialize the header (Type, PlayerSource, and PlayerTarget)
void SerializeHeader(ZBinaryBufferWriter& writer) {
writer.WriteU32(Type);
}
// called by subclass to get serialized header size
size_t GetHeaderSize() {
return sizeof(nID);
}
protected:
// c'tor
ZNetworkEvent(nID type) : Type(type) { }
};
/*
Network Event base implementation, which attempts to automatically handle serialization and
deserialization via template POD structs.
Note the template on the game event (DS), which indicates a POD struct. This is the data
that is serialized and sent as part of the event. Wrap the struct definition in pragma
pack statements to ensure correct behavior across systems and reduce bandwidth.
*/
template <typename DS>
class ZNetworkEventBase : public ZNetworkEvent
{
DISABLE_COPY_AND_ASSIGN(ZNetworkEventBase);
public:
// the data struct for this event
DS EventData;
// called by the network system to deserialize this event from binary form (after header is read)
virtual bool Deserialize(ZBinaryBufferReader& reader) {
if (reader.CanRead(sizeof(DS))) {
reader.ReadU8Array((uint8_t*)&EventData, sizeof(DS));
return true;
} else return false;
}
// called by the network system to serialize this event into binary form
virtual void Serialize(ZBinaryBufferWriter& writer) {
SerializeHeader(writer);
writer.WriteU8Array((uint8_t*)&EventData, sizeof(DS));
}
// called to get the serialized size of this event
virtual size_t GetSerializedSize() {
return GetHeaderSize() + sizeof(DS);
}
protected:
// c'tor
ZNetworkEventBase(nID type) : ZNetworkEvent(type) { }
};
#pragma pack (push, 1)
/*
Data struct used for message events, which will simply create the
given message on the other side and pass it to the simulation.
*/
template <typename M>
struct ZMessageEventData {
mID Type;
eID Sender;
eID Target;
M MessageData;
cID Connection;
};
#pragma pack (pop)
/*
Message network event. This is used to duplicate a message on other
connected simulations. The template parameter type is the message
data definition struct. Be sure to use pragma pack to reduce network
overhead.
*/
template <typename MT>
class ZMessageEvent : public ZNetworkEventBase<ZMessageEventData<MT>> {
public:
// c'tor
ZMessageEvent(mID msg_type) : ZNetworkEventBase(0) { }
ZMessageEvent(mID msg_type, eID sender, eID target, MT payload, cID connection)
: ZNetworkEventBase(0), EventData({msg_type, sender, target, connection, payload}) { }
// subclass implementations
virtual void HandleClient(ZSimulation& server_sim) {
server_sim.SendLocalMessage(Data.Type, Data.Sender, Data.Target, Data.MessageData);
}
virtual void HandleServer(ZSimulation& client_sim) {
client_sim.SendLocalMessage(Data.Type, Data.Sender, Data.Target, Data.MessageData);
}
};
#endif

View File

@@ -0,0 +1,82 @@
/*
NetworkRequest.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>, James Russell <jcrussell@762studios.com>
Created: 12/03/2013
Purpose:
Cancel-able network thread request, similar to ZThreadRequest, but
with more cancellation points.
Used to communicate between any other thread and the NetworkService
thread. The "payload" field contains the message's data, and the event
is used to cancel and signal when the request has been handled. For some
requests, no response is required; these are called "responseless" and
have no SST_Event object associated. Obviously, they cannot be waited on
nor canceled -- they are simply "fire and forget".
License:
Copyright 2013, 762 Studios.
*/
#ifndef __ZNETWORKREQUEST_HPP
#define __ZNETWORKREQUEST_HPP
#include <SST/SST_Concurrency.h>
class ZNetworkRequest
{
public:
// result enumeration
enum RequestResult {
RESULT_CANCELED, // nope
RESULT_FINISHED, // yep
RESULT_INPROGRESS // go away
};
// type enumeration
enum RequestType {
REQUEST_CONNECT, // connect to another simulation
REQUEST_DISCONNECT, // disconnect from a server
REQUEST_RESET, // immediately disconnect (no notice)
REQUEST_STOP_NETWORK, // stop the network thread
};
// public member variables
uint8_t Payload[64]; // generic data payload, used to input data and read results back
RequestType Type; // request type
RequestResult Result; // in progress, success, or failure
// c'tor
ZNetworkRequest(RequestType type, bool needEvent = true)
: Type(type), Result(RESULT_INPROGRESS) {
FinishedEvent = needEvent ? SST_Concurrency_CreateEvent() : NULL;
SST_Atomic_StoreRelease(&Canceled, 0);
}
// d'tor
~ZNetworkRequest() {
if (FinishedEvent) {
SST_Concurrency_DestroyEvent(FinishedEvent);
}
}
// getters
bool IsResponseless() { return (FinishedEvent == NULL); }
bool WaitFinished() { return (SST_Concurrency_WaitEvent(FinishedEvent, SST_WAIT_INFINITE) != 0); }
bool CheckFinished() { return (SST_Concurrency_WaitEvent(FinishedEvent, 0) != 0); }
void Cancel() { Canceled = 1; }
bool IsCancelPending() { return (Canceled != 0); }
// used to signal the request should be finished or canceled
void MarkFinished() { Result = RESULT_FINISHED; SST_Concurrency_SignalEvent(FinishedEvent); }
void MarkCanceled() { Result = RESULT_CANCELED; SST_Concurrency_SignalEvent(FinishedEvent); }
private:
SST_Event FinishedEvent; // when signaled, the request has been completed
volatile int Canceled; // when non-zero, the network thread will not attempt to process it
};
#endif

View File

@@ -0,0 +1,181 @@
/*
ZNetworkService.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>, James Russell <jcrussell@762studios.com>
Created: 12/03/2013
Purpose:
Network functionality for ZSimulation. Operates a thread that handles sending and
receiving of network data. Can be initialized as a server instance of a client
instance, with the real difference being that client instances connect to a single
server and servers listen for connections from multiple clients and other server
instances.
License:
Copyright 2013, 762 Studios.
*/
#pragma once
#ifndef __ZNETWORKSERVICE_HPP
#define __ZNETWORKSERVICE_HPP
#include <enet/enet.h>
#include <ZUtil/ZUtil.hpp>
#include "ZRemotePeer.hpp"
#include "ZNetworkRequest.hpp"
#include "ZNetworkUpdateStream.hpp"
// forward decl
class ZSimulation;
// class decl
class ZNetworkService
{
public:
// c'tor
ZNetworkService(ZSimulation& sim);
/*
Initializes the network system as client or server. The name is for display
purposes for both client and server.
If initialized as a server, the maximum number of simultaneous connections must
be specified.
*/
bool InitAsClient(const char* name);
bool InitAsServer(uint32_t maxConnections, uint16_t listenPort, const char* name);
/*
As a client, initializes a connection to the provided remote host. As a server,
links to another server instance to share workload. Delete this when done.
*/
ZNetworkRequest* InitiateConnection(const char* remoteHost, uint16_t port);
/*
As a client, disconnects from the server (cID for server is always zero). As
a server, disconnects the given connection. This is a soft disconnect that
notifies the other side and waits for a response. Delete this when done.
*/
ZNetworkRequest* Disconnect(cID id);
/*
Generates the disconnection event immediately, but gives no notice to the other
side. Delete this when done.
*/
ZNetworkRequest* ResetConnection(cID id);
/*
Given a connection id, gets the associated remote peer object.
*/
ZRemotePeer* GetPeer(cID id);
/*
Given the network name, gets the associated id. Returns cID(-1) if not connected
to this simulation instance.
*/
cID GetId(const char* netname);
/*
Gets a list of node and host pairings on the network. If the pairing exists in both
directions, then the connection is between two servers.
*/
void GetTopography(ZArray<ZPair<ZString, ZString>>& mappings);
// thread control methods
void SignalAndWaitShutdown();
void ThreadMain();
private:
// spawns the network thread
void SpawnThread();
// main thread = these four functions, in a loop
void PollNetEvents();
void ProcessRequests();
void PushBufferUpdates(uint64_t dt);
void PushNetworkEvents(uint64_t dt);
// handlers for requests (return value indicates 'done')
bool HandleRequest(ZNetworkRequest* req);
bool HandleConnectRequest(ZNetworkRequest* req);
bool HandleDisconnectRequest(ZNetworkRequest* req);
bool HandleResetRequest(ZNetworkRequest* req);
bool HandleStopNetworkRequest(ZNetworkRequest* req);
// handlers for ENet Events
void HandleEvent(ENetEvent* ev);
// server side
void ServerHandleConnectEvent(ENetEvent* ev); // initial connection event from ENet
void ServerHandleDisconnectEvent(ENetEvent* ev); // disconnect event from ENet
void ServerHandleReceiveEvent(ENetEvent* ev); // data received (any channel)
void ServerReceiveJoinMessage(ZRemotePeer* client, const void* data, uint32_t len); // process client (or server) join message
void ServerReceiveSystemChannel(ZRemotePeer* client, const void* data, uint32_t len); // data received
void ServerReceiveUpdateChannel(ZRemotePeer* client, const void* data, uint32_t len); // data received on update channel
void ServerReceiveEventChannel(ZRemotePeer* client, const void* data, uint32_t len); // data received on event channel
// client side
void ClientHandleConnectEvent(ENetEvent* ev); // initial connect event from ENet
void ClientHandleDisconnectEvent(ENetEvent* ev); // disconnect event from ENet
void ClientHandleReceiveEvent(ENetEvent* ev); // data received (any channel)
void ClientRecieveJoinResponse(const void* data, uint32_t len); // process server response from join message
void ClientReceiveSystemChannel(const void* data, uint32_t len); // data received on system channel
void ClientReceiveUpdateChannel(const void* data, uint32_t len); // data received from server on update channel
void ClientReceiveEventChannel(const void* data, uint32_t len); // data received from server on event channel
// adds and removes a network node mapping
void AddNode(const ZString& node, const ZString& host);
void RemoveNode(const ZString& node);
enum Netstate {
UNINITIALIZED, // not yet initialized as client or server
DISCONNECTED, // initialized as client and disconnected
LISTEN, // initialized as server and listening for connections
CONNECTING, // initiating low-level connection
JOINING, // connected, but not yet ready to play
CONNECTED // connected and ready to SIMULATE
};
ZSimulation& Sim; // simulation reference
ZString Name; // network name
Netstate State; // state of this service
SST_Thread Thread; // thread running this service
bool bIsServer; // true if initialized as server
bool bIsConnected; // true if connected
volatile int iShouldShutdown; // shutdown flag
ENetHost* Host; // enet host service (server and client)
ENetPeer* RemoteServer; // as a client, this is the server (otherwise NULL)
uint32_t NrConnectionsMax; // max number of connections
ZRemotePeer* Connections; // all connections (as client, only a single remote peer, the server)
ZMutex NodesMutex; // mutex for locking access to nodes listing
ZArray<ZPair<ZString, ZString>> Nodes; // node name and host name pairing for all simulations on the network
void* PacketBuffer; // packet data buffer, used as local copy
size_t PacketBufferSize; // size of the buffer
ZMutex QueueMutex; // mutex for locking access to request queue
ZArray<ZNetworkRequest*> SharedRequestQueue; // network request queue
ZNetworkRequest* CurrentRequest; // network request currently being processed
uint32_t WaitTime; // value used to modify polling frequency
ZArray<ZNetworkRequest*> PendingRequests; // queue used to process a single tick worth of requests
NetworkUpdateQueue DelayedUpdates; // updates that are being delayed for artificial lag simulation
NetworkEventQueue DelayedEvents; // events that are being delayed for artificial lag simulation
};
#endif

View File

@@ -0,0 +1,114 @@
/*
ZNetworkUpdateStream.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 9/13/2015
Purpose:
Exists for the express purpose of holding onto network events and property updates
that the simulation wants to send out, and providing them to the network system when
the network system requires them.
In addition, holds onto network events and updates received until the simulation asks
for them.
License:
TODO
*/
#pragma once
#ifndef _ZNETWORKUPDATESTREAM_HPP
#define _ZNETWORKUPDATESTREAM_HPP
#include <ZSTL/ZArray.hpp>
#include <ZUtil/ZUtil.hpp>
#include "ZNetworkEvent.hpp"
#include "ZPropertyBufferUpdate.hpp"
// forward decl
class ZSimulation;
// typedefs
typedef ZArray<ZNetworkEvent*, ZArrayAllocator<ZNetworkEvent*, 128>> NetworkEventQueue;
typedef ZArray<ZPropertyBufferUpdate*, ZArrayAllocator<ZPropertyBufferUpdate*, 1024>> NetworkUpdateQueue;
// class decl
class ZNetworkUpdateStream {
public:
// event constructor and destructor function
typedef ZNetworkEvent* (*EventConstructor)();
typedef void (*EventDestructor)(ZNetworkEvent*);
// c'tor
ZNetworkUpdateStream();
// d'tor
~ZNetworkUpdateStream();
/*
Maps an event type to an event constructor and destructor. Events will not be properly recreated
unless the type is mapped to a constructor function.
*/
void MapEventAlloc(nID type, EventConstructor ctor, EventDestructor dtor);
/*
Allocator for events and updates. The version without id will be called by the network
system - the deserialize method will fill out the id.
*/
ZNetworkEvent* AllocEvent(nID type);
ZPropertyBufferUpdate* AllocUpdate(eID id);
ZPropertyBufferUpdate* AllocUpdate();
/*
Deallocation for events and updates.
*/
void DeallocEvent(ZNetworkEvent* e);
void DeallocUpdate(ZPropertyBufferUpdate* u);
/*
Enqueues an event or update to sync across the network.
*/
void EnqueueOutgoingEvent(ZNetworkEvent* e);
void EnqueueOutgoingUpdate(ZPropertyBufferUpdate* u);
void EnqueueOutgoingUpdates(NetworkUpdateQueue& q);
/*
Enqueues an event or update to be processed here.
*/
void EnqueueIncomingEvent(ZNetworkEvent* e);
void EnqueueIncomingEvents(NetworkEventQueue& q);
void EnqueueIncomingUpdate(ZPropertyBufferUpdate* u);
void EnqueueIncomingUpdates(NetworkUpdateQueue& q);
/*
Read outgoing events or updates to sync across the network.
*/
void ReadOutgoingEvents(NetworkEventQueue& out);
void ReadOutgoingUpdates(NetworkUpdateQueue& out);
/*
Processes events or updates that have been enqueued.
*/
void ProcessIncomingEvents(ZSimulation& sim);
void ProcessIncomingUpdates(ZSimulation& sim);
private:
DISABLE_COPY_AND_ASSIGN(ZNetworkUpdateStream);
ZMutex EventMutex[2]; // mutex for event queues (incoming / outgoing)
ZMutex UpdateMutex[2]; // mutex for update queues (incoming / outgoing)
NetworkEventQueue Events[2]; // buffered events (incoming / outgoing)
NetworkUpdateQueue Updates[2]; // buffered updates (incoming / outgoing)
ZHashMap<nID,
ZPair<EventConstructor, EventDestructor>> Constructors; // ctor and dtor for network events
};
#endif

View File

@@ -0,0 +1,454 @@
#include <ZSimulation/ZPropertyBuffer.hpp>
#include <ZSimulation/ZNetworkUpdateStream.hpp>
#include <SST/SST_SysMem.h>
#define BUFFER_SYNC 0
#define BUFFER_LOCAL 1
#define BUFFER_WRITE 0
#define BUFFER_READ 1
#define MIN_ALLOC 4
struct PropertyPage {
eID Id; // id of the entity that these properties are allocated for
void* Data[2]; // the data for this page (read and write)
size_t Size; // amount of data on this page
size_t Offset; // the current offset on this page
PropertyPage* Next; // the next page, or NULL
ZArray<ZPair<size_t, size_t>> Avail; // available data slots on this page
ZArray<ZPair<ZPropertyBuffer::PropertyKey, size_t>> Updates; // properties that have been updated since last update
// c'tor
PropertyPage(size_t alloc_size) : Next(NULL) {
Data[0] = SST_OS_AllocPages(alloc_size*2); // allocate 2x to account for read and write
Data[1] = (char*)Data[0] + alloc_size; // split in half, with first half being write and second for read
Size = alloc_size;
Offset = 0;
}
// d'tor
~PropertyPage() {
delete Next;
if (Size > 0) {
SST_OS_FreePages(Data[0], Size*2);
}
}
};
/*************************************************************************/
// Key is currently a 64 bit integer, which is partitioned as follows
//
// [ SYNC MOE (2) | OFFSET (14) | SUB PAGE (16) | PAGE (32) ]
static ZPropertyBuffer::PropertyKey GenerateKey(ZPropertyBuffer::SyncMode mode, uint32_t page, uint16_t sub_page, uint16_t offset) {
uint64_t key;
key = mode;
key = key << 14;
key = key + offset;
key = key << 16;
key = key + sub_page;
key = key << 32;
key = key + page;
// dumb assert
static_assert(sizeof(eID) == 4, "Cannot generate property key with sizeof(eID) not 32 bits, update property buffer");
return key;
}
static void ParseKey(ZPropertyBuffer::PropertyKey key, ZPropertyBuffer::SyncMode* mode, uint32_t* page, uint16_t* sub_page, uint16_t* offset) {
*page = (uint32_t)(key & 0xFFFFFFFF);
*sub_page = (uint16_t)((key >> 32) & 0xFFFF);
*offset = (uint16_t)((key >> 48) & 0x3FFF);
*mode = (ZPropertyBuffer::SyncMode)((key >> 62) & 0xFFFF);
}
void* ZPropertyBuffer::GetData( PropertyKey key, int rw, PropertyPage** page_out /*= NULL*/, SyncMode* mode_out /*= NULL*/ )
{
SyncMode mode;
uint32_t page_idx;
uint16_t sub_page_idx, offset;
ParseKey(key, &mode, &page_idx, &sub_page_idx, &offset); // parse data key
ZArray<PropertyPage*>& pages = mode != SYNC_NONE ? Pages[BUFFER_SYNC] :
Pages[BUFFER_LOCAL]; // determine if we are using sync or local data
if (pages.Size() >= page_idx) { // determine if we have this many pages
PropertyPage* page = pages[page_idx];
for (size_t i = 0; i < sub_page_idx; i++) { // see of we can find the sub page
page = page->Next;
if (page == NULL) { // check for bad sub page index
return NULL;
}
}
if (offset % MIN_ALLOC == 0 && offset <= page->Size - MIN_ALLOC) { // see if our offset is valid
if (page_out != NULL) *page_out = page; // get pointer to page
if (mode_out != NULL) *mode_out = mode; // get sync value
return (char*)page->Data[rw] + offset; // get read / write pointer
} else return NULL;
} else return NULL;
}
/*************************************************************************/
ZPropertyBuffer::Property ZPropertyBuffer::AllocData( PropertyPage* page, eID id, uint32_t page_idx, size_t size, SyncMode mode)
{
Property prop;
ZArray<PropertyPage*>& pages = mode ? Pages[BUFFER_SYNC] : Pages[BUFFER_LOCAL]; // determine if we are using sync or local data
size_t alloc_size = size > MIN_ALLOC ? (size + MIN_ALLOC - 1) & ~(MIN_ALLOC - 1) // ensure we allocate at least MIN_ALLOC, and align to MIN_ALLOC
: size;
uint16_t sub_page_idx;
for (sub_page_idx = 0; page != NULL; sub_page_idx++) { // loop pages seeing if we can drop the data in here
if (page->Offset + size <= page->Size) { // see if we have room
uint16_t offset = (uint16_t)page->Offset; // we do, so get current offset
page->Offset = page->Offset + alloc_size; // increment stored offset by alloc size, not property size
prop.Key = GenerateKey(mode, page_idx, sub_page_idx, offset); // key for this value
prop.Write = (char*)page->Data[BUFFER_WRITE] + offset; // write pointer for this value
prop.Read = (char*)page->Data[BUFFER_READ] + offset; // read pointer for this value
prop.Size = size; // size of this value
return prop;
} else {
for (size_t i = 0; i < page->Avail.Size(); i++) { // for each available slot from previous deallocs
if (page->Avail[i].Second >= size) { // see if we have room
uint16_t offset = (uint16_t)page->Avail[i].First; // we do, so store the offset
page->Avail.Erase(i); // no longer available
prop.Key = GenerateKey(mode, page_idx, sub_page_idx, offset); // key for this value
prop.Write = (char*)page->Data[BUFFER_WRITE] + offset; // write pointer for this value
prop.Read = (char*)page->Data[BUFFER_READ] + offset; // read pointer for this value
prop.Size = size; // size of this value
return prop;
}
}
if (page->Next != NULL) {
page = page->Next; // NEXT
} else {
sub_page_idx++; // sub page index will be next index
break;
}
}
}
// found nothing, time to allocate new
if (Pages[BUFFER_LOCAL].Size() <= page_idx) { // push NULL entry for local buffer if not present at page_idx
Pages[BUFFER_LOCAL].PushBack(NULL);
}
if (Pages[BUFFER_SYNC].Size() <= page_idx) { // push NULL entry for sync buffer if not present at page_idx
Pages[BUFFER_SYNC].PushBack(NULL);
}
const uint32_t page_size = SST_OS_GetPageSize(); // system page size
const uint32_t min_buffer_alloc = page_size / 2; // minimum amount we will allocate
uint32_t page_alloc_size = min_buffer_alloc; // starting page alloc
if (size > page_alloc_size) {
page_alloc_size =
((size+min_buffer_alloc-1) & ~(min_buffer_alloc-1)); // round up to nearest multiple of min_buffer_alloc
}
PropertyPage* npage = new PropertyPage(page_alloc_size); // new page
npage->Id = id; // set id for page
npage->Offset = alloc_size; // allocate enough space for the first property
if (page != NULL) { // link page into page list
page->Next = npage;
} else { // allocating new pages
pages[page_idx] = npage;
}
prop.Key = GenerateKey(mode, page_idx, sub_page_idx, 0); // generate a key for the correct page with sub-page and offset 0
prop.Write = (char*)npage->Data[BUFFER_WRITE]; // set the write pointer
prop.Read = (char*)npage->Data[BUFFER_READ]; // set the read pointer
prop.Size = size; // set the size of the data
return prop;
}
/*************************************************************************/
ZPropertyBuffer::ZPropertyBuffer()
{
}
/*************************************************************************/
ZPropertyBuffer::~ZPropertyBuffer()
{
for (size_t i = 0; i < Pages[BUFFER_LOCAL].Size(); i++) {
delete Pages[BUFFER_LOCAL][i];
}
for (size_t i = 0; i < Pages[BUFFER_SYNC].Size(); i++) {
delete Pages[BUFFER_SYNC][i];
}
}
/*************************************************************************/
ZPropertyBuffer::Property ZPropertyBuffer::AllocProperty(eID id, size_t size, SyncMode mode)
{
// sanity check - synchronized properties should be less than ZSIM_BUFFER_SYNC_MAX
ZASSERT_RUNTIME(!mode || size < ZSIM_SYNCBUFFER_MAX, "Synchronized property allocation too large!");
auto itr = IdPageMap.Find(id);
ZArray<PropertyPage*>& pages = mode != SYNC_NONE ? Pages[BUFFER_SYNC] :
Pages[BUFFER_LOCAL];
if (itr != IdPageMap.End()) {
uint32_t page_idx = itr.GetValue();
PropertyPage* page = pages[page_idx];
return AllocData(page, id, page_idx, size, mode);
}
if (Avail.Size() > 0) {
size_t page_idx = Avail.PopBack();
IdPageMap.Put(id, page_idx);
return AllocData(NULL, id, page_idx, size, mode);
} else {
IdPageMap.Put(id, pages.Size());
return AllocData(NULL, id, pages.Size(), size, mode);
}
}
/*************************************************************************/
void ZPropertyBuffer::DeallocEntity( eID id )
{
auto itr = IdPageMap.Find(id);
if (itr != IdPageMap.End()) {
uint32_t page_idx = itr.GetValue();
delete Pages[BUFFER_LOCAL][page_idx];
delete Pages[BUFFER_SYNC][page_idx];
Pages[BUFFER_LOCAL][page_idx] = NULL;
Pages[BUFFER_SYNC][page_idx] = NULL;
Avail.PushBack(page_idx);
IdPageMap.Erase(id);
}
}
/*************************************************************************/
void ZPropertyBuffer::DeallocProperty( PropertyKey key, size_t size )
{
SyncMode mode;
uint32_t page_idx;
uint16_t sub_page_idx, offset;
ParseKey(key, &mode, &page_idx, &sub_page_idx, &offset);
ZArray<PropertyPage*>& pages = mode != SYNC_NONE ? Pages[BUFFER_SYNC] :
Pages[BUFFER_LOCAL];
PropertyPage* page = pages[page_idx];
for (size_t i = 0; i < sub_page_idx; i++) {
page = page->Next;
}
page->Avail.PushBack(ZPair<size_t, size_t>(offset, size));
}
/*************************************************************************/
void ZPropertyBuffer::FlagModified( PropertyKey key, size_t size )
{
PropertyPage* page;
SyncMode mode;
void* data = GetData(key, BUFFER_WRITE, &page, &mode);
ZASSERT(data != NULL && page != NULL, "Attempt to flag modified on invalid property key");
page->Updates.PushBack(ZPair<PropertyKey, size_t>(key, size));
}
/*************************************************************************/
void ZPropertyBuffer::UpdateModified(bool sync, ZNetworkUpdateStream& stream)
{
// wherever we have an update, copy the write buffer
for (size_t b = 0; b < 2; b++) {
for (size_t i = 0; i < Pages[b].Size(); i++) {
PropertyPage* page = Pages[b][i];
ZPropertyBufferUpdate* buffer_update = NULL;
// synchronized buffers require a property buffer update call
if (sync && b == BUFFER_SYNC && page != NULL && page->Updates.Size() > 0) {
buffer_update = stream.AllocUpdate(page->Id);
}
// for all pages and sub-pages
while (page != NULL) {
for (size_t j = 0; page != NULL && j < page->Updates.Size(); j++) {
PropertyKey key = page->Updates[j].First;
size_t size = page->Updates[j].Second;
SyncMode mode;
uint32_t page_idx;
uint16_t sub_page_idx, offset;
ParseKey(key, &mode, &page_idx, &sub_page_idx, &offset);
void* data = (char*)page->Data[BUFFER_WRITE] + offset;
MemCopyChar((char*)page->Data[BUFFER_READ] + offset, data, size);
// if needed, make it happen
if (buffer_update != NULL && mode == SYNC_SEND) {
ZPropertyBufferUpdate::Update update;
update.SubPage = sub_page_idx;
update.Offset = offset;
update.Size = size;
update.Data = (char*)page->Data[BUFFER_READ] + offset;
buffer_update->Updates.PushBack(update);
}
}
page->Updates.Clear();
page = page->Next;
}
// push the entity update
if (buffer_update != NULL) {
stream.EnqueueOutgoingUpdate(buffer_update);
}
}
}
}
/*************************************************************************/
void ZPropertyBuffer::UpdateModified( eID id, bool sync, ZNetworkUpdateStream& stream )
{
auto itr = IdPageMap.Find(id);
if (itr != IdPageMap.End()) {
uint32_t page_idx = itr.GetValue();
// wherever we have an update, copy the write buffer
for (size_t b = BUFFER_LOCAL; b != BUFFER_SYNC; b = BUFFER_SYNC) {
PropertyPage* page = Pages[b][page_idx];
ZPropertyBufferUpdate* buffer_update = NULL;
// synchronized buffers require a property buffer update call
if (sync && b == BUFFER_SYNC && page != NULL) {
buffer_update = stream.AllocUpdate(id);
}
// for all pages and sub-pages
while (page != NULL) {
for (size_t j = 0; page != NULL && j < page->Updates.Size(); j++) {
PropertyKey key = page->Updates[j].First;
size_t size = page->Updates[j].Second;
SyncMode mode;
uint32_t page_idx;
uint16_t sub_page_idx, offset;
ParseKey(key, &mode, &page_idx, &sub_page_idx, &offset);
void* data = (char*)page->Data[BUFFER_WRITE] + offset;
MemCopyChar((char*)page->Data[BUFFER_READ] + offset, data, size);
if (buffer_update != NULL && mode == SYNC_SEND) {
ZPropertyBufferUpdate::Update update;
update.SubPage = sub_page_idx;
update.Offset = offset;
update.Size = size;
update.Data = (char*)page->Data[BUFFER_READ] + offset;
buffer_update->Updates.PushBack(update);
}
}
page->Updates.Clear();
page = page->Next;
}
// push the entity update
if (buffer_update != NULL) {
stream.EnqueueOutgoingUpdate(buffer_update);
}
}
} else {
SystemLogError("Unable to update entity property buffer - invalid id");
}
}
/*************************************************************************/
static void* GetSyncData(PropertyPage* page, uint16_t offset)
{
if (offset % MIN_ALLOC == 0 && offset <= page->Size - MIN_ALLOC) { // see if our offset is valid
return (char*)page->Data[BUFFER_READ] + offset; // return read
} else return NULL;
}
void ZPropertyBuffer::ApplyBufferUpdates( const ZArray<ZPropertyBufferUpdate*>& updates )
{
for (size_t i = 0; i < updates.Size(); i++) {
ZPropertyBufferUpdate& buffer_update = *updates[i];
eID id = buffer_update.Id;
ZArray<PropertyPage*>& pages = Pages[BUFFER_SYNC]; // always sync data
auto itr = IdPageMap.Find(id); // find page mapped for id
if (itr != IdPageMap.End()) { // make sure we have a valid one
uint32_t page_idx = itr.GetValue();
PropertyPage* base_page = pages[page_idx];
for (size_t j = 0; j < buffer_update.Updates.Size(); j++) {
ZPropertyBufferUpdate::Update& update = buffer_update.Updates[j];
uint16_t sub_page_idx = update.SubPage;
uint16_t offset = update.Offset;
size_t size = update.Size;
PropertyPage* sub_page = base_page;
for (uint16_t k = 0; k < sub_page_idx; k++) {
if (sub_page->Next != NULL) {
sub_page = sub_page->Next;
}
}
if (sub_page != NULL) {
void* rd_ptr = GetSyncData(sub_page, offset);
if (rd_ptr != NULL) {
MemCopyChar(rd_ptr, update.Data, size);
} else {
SystemLogError("Recieved invalid buffer update offset");
}
} else {
SystemLogError("Recieved invalid buffer update sub page");
}
}
}
}
}

View File

@@ -0,0 +1,134 @@
/*
ZPropertyBuffer.hpp
Author: author_name <author_email@762studios.com>
Created: 8/30/2015
Purpose:
The property buffer system is an allocator which holds entity property data in
contiguous blocks of memory that can then be synchronized across the network when
properties change, though properties can be kept in non-synchronized buffers for
local use.
The buffer keeps both a read and write copy of the properties which can be updated
on call.
This allocator does not lock, so any locking that would be required must be handled
by the caller.
In order to have proper synchronization, each entity that has properties allocated
should have it's synchronized variables created in the same order on all machines.
This will ensure that the data layouts are identical and proper synchronization can
occur.
License:
TODO
*/
#pragma once
#ifndef _ZPROPERTYBUFFER_HPP
#define _ZPROPERTYBUFFER_HPP
#include "ZSimulationDefs.hpp"
#include "ZPropertyBufferUpdate.hpp"
// forward decl
struct PropertyPage;
class ZNetworkUpdateStream;
// class decl
class ZPropertyBuffer
{
public:
// key used to look up allocated data in the property buffer
typedef uint64_t PropertyKey;
// used to flag synchronization type (none, send, or receive)
enum SyncMode {
SYNC_NONE = 0,
SYNC_SEND = 1,
SYNC_RECV = 2,
SYNC_ENUM_SIZE
};
// data struct for property data
struct Property {
void* Read; // pointer to the read property
void* Write; // pointer to the write property
size_t Size; // size of the property
PropertyKey Key; // the property key
};
// c'tor
ZPropertyBuffer();
// d'tor
~ZPropertyBuffer();
/*
Allocates a chunk of memory in the property buffer given the entity id, the entity size,
and whether or not the property should be synchronized. The read buffer for the property
is returned.
Allocations from these methods return static sized properties - they will not ever be able
to increase in size - alloc a new property and remove the old one in order to increase
size. The size limit on a synchronized property is 1024 bytes.
In order to have proper synchronization, each entity that has properties allocated
should have its synchronized variables created in the same order on all machines.
This will ensure that the data layouts are identical and proper synchronization can
occur.
*/
Property AllocProperty(eID id, size_t size, SyncMode mode = SYNC_NONE );
/*
Deallocation methods, which deallocate previously allocated property data. The version
which takes an entity id deallocates all data associated with that entity id. The
version which takes a property key merely deallocates that particular property.
Deallocating individual properties is not terribly fast, so avoid it where possible.
*/
void DeallocEntity(eID id);
void DeallocProperty(PropertyKey key, size_t size);
/*
Flags a previously allocated property as modified. The size (in bytes) of the property
is required.
*/
void FlagModified(PropertyKey key, size_t size);
/*
Updates the read properties from the write properties where modifications have happened.
The version which takes an entity id will update a single entities properties.
If told to synchronize, the buffer will queue up the network updates needed to sync
the buffer state.
*/
void UpdateModified(bool sync, ZNetworkUpdateStream& stream);
void UpdateModified(eID id, bool sync, ZNetworkUpdateStream& stream);
/*
Applies buffer updates that have been read from the network. These are applied directly
to the read value of the property.
*/
void ApplyBufferUpdates(const ZArray<ZPropertyBufferUpdate*>& updates);
private:
/* synchronized and non-synchronized data storage */
ZArray<PropertyPage*> Pages[2]; // the individual buffer pages (synchronized and local)
ZHashMap<eID, uint32_t> IdPageMap; // maps the entity id to its page number
ZArray<uint32_t> Avail; // available indices from dealloc'd entities
// given the property key will get the data, page, and synchronization flag
void* GetData(PropertyKey key, int rw, PropertyPage** page_out = NULL, SyncMode* mode_out = NULL);
// will alloc data for the property (searches page, otherwise makes new pages)
Property AllocData(PropertyPage* page, eID id, uint32_t page_idx, size_t size, SyncMode mode);
};
#endif

View File

@@ -0,0 +1,62 @@
/*
ZBufferUpdate.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 9/13/2015
Purpose:
Buffer updates are created by the property buffer when synchronization
happens. They are then passed along to the network service to be serialized
and sent across the wire.
License:
TODO
*/
#pragma once
#ifndef _ZPROPERTYBUFFERUPDATE_HPP
#define _ZPROPERTYBUFFERUPDATE_HPP
#include <ZUtil/ZUtil.hpp>
#include "ZSimulationDefs.hpp"
class ZPropertyBufferUpdate {
public:
// update marker for a single bit of data in the buffer
struct Update {
uint16_t SubPage; // sub property page
uint16_t Offset; // offset into buffer (NOT into Data)
size_t Size; // size of the data
void* Data; // pointer to the data
uint8_t Local[ZSIM_SYNCBUFFER_MAX]; // local storage for Data (if copy is required)
};
eID Id; // entity we are updating in this packet
ZArray<Update> Updates; // the updates in the data array
int Delay; // simulated lag
// c'tor
ZPropertyBufferUpdate();
// parameterized c'tor
ZPropertyBufferUpdate(eID id);
// d'tor
~ZPropertyBufferUpdate();
// called by the network system to serialize this update into binary form
void Serialize(ZBinaryBufferWriter& writer);
// called by the network system to deserialize this update from binary form
bool Deserialize(ZBinaryBufferReader& reader);
// called to get the serialized size of this update
size_t GetSerializedSize();
};
#endif

View File

@@ -0,0 +1,33 @@
/*
ZPropertyBufferUpdateQueue.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 9/17/2015
Purpose:
License:
Copyright 2015, 762 Studios.
*/
#pragma once
#ifndef _ZPROPERTYBUFFERUPDATEQUEUE_HPP
#define _ZPROPERTYBUFFERUPDATEQUEUE_HPP
#include "ZPropertyBufferUpdate.hpp"
class ZPropertyBufferUpdateQueue {
public:
// c'tor
ZPropertyBufferUpdateQueue();
// d'tor
~ZPropertyBufferUpdateQueue();
private:
};
#endif

View File

@@ -0,0 +1,74 @@
/*
RemoteClient.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>, James Russell <jcrussell@762studios.com>
Created: 12/2/2013
Purpose:
Network peer as seen by a running simulation. May refer to either a
client or another server instance.
License:
Copyright 2013, 762 Studios.
*/
#ifndef __ZREMOTEPEER_HPP
#define __ZREMOTEPEER_HPP
#include <enet/enet.h>
class ZRemotePeer
{
public:
// the client state
enum PeerState {
AVAILABLE,
JOINING,
CONNECTED,
CONNECTED_LOCAL,
DISCONNECTED
};
// c'tor
ZRemotePeer() : bIsClient(true),
State(AVAILABLE),
Peer(NULL) { }
// getters
cID GetId() const { return Id; }
PeerState GetState() const { return State; }
bool IsClient() const { return bIsClient; }
const char* GetName() const { return Name; }
const char* GetHost() const { return Host; }
ENetPeer* GetPeer() { return Peer; }
// setters
void SetId(cID id) { Id = id; }
void SetState(PeerState cs) { State = cs; }
void SetClient(bool isClient) { bIsClient = isClient; }
void SetName(const char* name) { strcpy(Name, name); }
void SetHostIP(const char* host) { strcpy(Host, host); }
void SetPeer(ENetPeer* newPeer) { Peer = newPeer; }
// resets this peer object (must be called to reuse object and connection id)
void Reset() {
SetPeer(NULL);
SetState(AVAILABLE);
SetName("");
SetHostIP("");
SetClient(true);
}
private:
cID Id; // id of this connection assigned by network service
ENetPeer* Peer; // peer object
PeerState State; // overall state
bool bIsClient; // true if this connects to a client
char Host[ZSIM_NETWORK_MAX_HOST_LENGTH]; // host name in readable format
char Name[ZSIM_NETWORK_MAX_NAME_LENGTH]; // network 'name' (unique among network peers)
};
#endif

View File

@@ -0,0 +1,327 @@
/*
ZSimulation.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 2/4/2013
Purpose:
Simulation base class for the ZSimulation project. Simulation is intended to be a server
that handles the simulation of a large number of interacting entities. Entities will
interact with each other via a messaging queue which will have handlers defined per
message type.
Per this simulation, Actors are simply Entities with a 'think' function defined.
The nominal difference between server and client instances is that client instances
can only ever connect to a single server instance, whereas server instances listen
for client connections and can connect to other server instances to share the
workload.
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef ZSIMULATION_HPP
#define ZSIMULATION_HPP
#include <SST/SST_Concurrency.h>
#include <ZSTL/ZArray.hpp>
#include <ZSTL/ZArrayAlgo.hpp>
#include <ZUtil/ZUtil.hpp>
#include "ZSimulationDefs.hpp"
#include "ZMessageStream.hpp"
#include "ZEntity.hpp"
#include "ZPropertyBuffer.hpp"
#include "ZNetworkService.hpp"
/*
Simulation class, which handles the following sphere of responsibilities:
* Fixed Timestep and Entity Update
* Entity Message Passing
* Entity Lifetime and Memory Management
* Entity Property Allocation
* Entity Property Network Synchronization
* Entity Type Declaration
* Entity State Declaration
*/
class ZSimulation : public ZThread
{
public:
// c'tor
ZSimulation();
// d'tor
virtual ~ZSimulation();
// initialization methods
bool InitAsServer(bool start = true);
bool InitAsClient(bool start = true);
// shutdown method (this will deallocate entities)
void Shutdown();
// getters
uint32_t GetCurrentEntityCount() const { return CurrentEntityCount; }
const ZEntity* GetEntity(eID entityId) const { return Entities[entityId]; }
ZEntity* GetEntity(eID entityId) { return Entities[entityId]; }
ZArray<ZEntity*>& GetBaseEntities() { return BaseEntities; }
ZArray<ZEntity*>& GetActorEntities() { return ActorEntities; }
uint64_t GetCurrentFrame() const { return CurrentFrame; }
double GetCurrentFrameStartTime() const { return CurrentFrameStartTime; }
int16_t GetSimulationHz() const { return SimulationHz; }
double GetSimulationTimestep() const { return 1.0 / (double)SimulationHz; }
size_t GetSimulationThreadCount() const { return ThreadCount; }
ZPropertyBuffer& GetPropertyBuffer() { return PropertyBuffer; }
ZRandomGenerator& GetPRNG() { return PRNG; }
uint16_t GetListenPort() { return ListenPort; }
uint8_t GetSyncRate() { return SyncRate; }
ZNetworkService& GetNetworkService() { return NetworkService; }
ZNetworkUpdateStream& GetNetworkUpdateStream() { return NetworkUpdateStream; }
uint8_t GetNetworkSendRate() { return NetSendRate; }
ZString& GetNetworkName() { return NetName; }
bool IsServer() { return bIsServer; }
// function getters (can return NULL)
ZEntity::InitFunc GetEntityInitFunc(const ZName& type);
ZEntity::InitFunc GetEntityInitFunc(ZHashValue type);
ZEntity::StateFunc GetEntityStateFunc(const ZName& name);
ZEntity::StateFunc GetEntityStateFunc(ZHashValue name);
// setters
void SetHz(int16_t simHz) { SimulationHz = simHz; }
void SetThreadCount(int16_t threadCount) { ThreadCount = threadCount; }
void SetListenPort(uint16_t port) { ListenPort = port; }
void SetSyncRate(uint8_t rate) { SyncRate = rate; }
void SetNetworkName(const ZString& name) { NetName = name; }
/*
Connection method. Connects to another simulation instance. Returns the network request
object which can be used to check status of the connection attempt. Delete the request
when done.
*/
ZNetworkRequest* Connect(const char* remoteHost);
/*
Declares an entity and initialization function. All entity initialization functions
must be declared in order to ensure proper allocation of properties on all simulations,
client and server.
It is recommended that all mapping be done during simulation initialization - no locking
or concurrent access mechanisms are used when looking up mapped data.
The initialization function can be NULL, which will create an empty entity.
Ensure when declaring entity types that the name provided has its string representation.
@assert - on name collision (name hash resolves to same or entry already exists)
*/
void DeclareEntityType(const ZName& type, ZEntity::InitFunc init);
/*
Declares an entity state function. Entity states are looked up by name to ensure recognition
on all simulations, client and server.
It is recommended that all state mapping be done during simulation initialization - no locking
or concurrent access mechanisms are used when looking up mapped data.
State functions cannot be NULL.
@assert - on name collision (name hash resolves to same or entry already exists)
*/
void DeclareEntityState(const ZName& name, ZEntity::StateFunc state);
/*
Given the name, gives a string name for an entity type or state. These exist because names
can be constructed without a string representation (such as when used for network communication).
*/
ZString LookupEntityTypeName(const ZName& type);
ZString LookupEntityStateName(const ZName& name);
/*
Spawn methods which add an entity to the simulation, returning the eID (0 if failure).
Variant which takes an eID request that an entity with a specific eID be added (returns
false if unable to create).
@assert - if the entity type is undefined
*/
eID SpawnEntity(const ZName& type);
bool SpawnEntity(const ZName& type, eID id);
/*
Kill method, which removes entities from the simulation. This call cleans up the entity and any
memory it has allocated.
*/
void KillEntity(eID id);
/*
Sends a message through the simulation message queue, which will copy data from
a struct into the message for you (MT must be a POD type). Local messages are not
reflected across the network.
*/
template <typename MT> void SendLocalMessage(mID type, MT payload) const
{ const_cast<ZSimulation*>(this)->MessageQueue.Send(type, ZSIM_EID_SYSTEM, ZSIM_EID_SYSTEM, payload); }
template <typename MT> void SendLocalMessage(mID type, eID sender, eID target, MT payload) const
{ const_cast<ZSimulation*>(this)->MessageQueue.Send(type, sender, target, payload); }
/*
Sends a message across the network, which will be processed by the message queue of
another connected simulation. MT must be POD type and in order to ensure proper
processing it should not contain pointers as these will be invalid on the other side.
*/
template <typename MT> void SendNetworkMessage(mID type, MT payload, cID connection) const
{ const_cast<ZSimulation*>(this)->NetworkUpdateStream.EnqueueOutgoingEvent(new (std::nothrow) ZMessageEvent(type, ZSIM_EID_SYSTEM, ZSIM_EID_SYSTEM, payload, connection)); }
template <typename MT> void SendNetworkMessage(mID type, eID sender, eID target, MT payload, cID connection) const
{ const_cast<ZSimulation*>(this)->NetworkUpdateStream.EnqueueOutgoingEvent(new (std::nothrow) ZMessageEvent(type, sender, target, payload, connection)); }
/*
Pushes a task onto the task stream. This task will be executed by the simulation after
simulation tasks have completed.
*/
void PushTask(ZPtr<ZTask> task);
void PushTasks(ZArray<ZPtr<ZTask>>& tasks);
/*
Pushes a future onto the task stream, which can be used to evaluate task progress.
*/
template <typename RT, typename AT> void PushFuture(ZPtr<ZFuture<RT, AT>> future) {
TaskStream.PushFuture(future);
}
/*
Pushes or Pops a message handler onto the simulation. These message handlers are used for
messages that are directed at the simulation or for messages that do not have a valid
target entity.
*/
void PopHandler(mID type);
void PushHandler(mID type, ZMessageHandler handler);
/*
These methods notify the simulation that a targeted message was handled correctly or was
unhandled. The simulation will return these messages to the message pool. These functions
are primarily used by entities as they handle their own message queues.
*/
void HandledMessage(ZMessage* msg) const;
void UnhandledMessage(ZMessage* msg) const;
/*
This method notifies the simulation that an entity has had one or more of it's properties
deleted. It's not terribly efficient to delete entity properties - use sparingly.
*/
void PropertyDeleted(eID id);
protected:
int16_t SimulationHz; // current simulation Hz (tick rate per second)
size_t ThreadCount; // number of concurrent simulation threads
double CurrentTime; // current tick count (most recent)
double TotalTime; // total number of ticks that have been processed
double Accumulator; // tick accumulator, used to help fix the timestep
double LastSync; // the time we last did a network sync
uint64_t CurrentFrame; // number of simulation frames that have passed
double CurrentFrameStartTime; // time at the start of the current frame
uint32_t CurrentEntityCount; // number of entities we have spawned
size_t CurrentEntityIndex; // next entity we will hand out for simulation entities
ZEntity* Entities[ZSIM_EID_MAX + 1]; // array mapping of entity id -> entity
ZArray<ZEntity*> BaseEntities; // base entities that have been created (no think state)
ZArray<ZEntity*> ActorEntities; // actor entities that have been created (has a think state)
ZMessageStream MessageQueue; // message queue for the simulation
ZTaskStream TaskStream; // task stream for the simulation, which concurrently processes actors
ZRandomGenerator PRNG; // PRNG for the simulation
ZNetworkService NetworkService; // network service for this simulation
ZNetworkUpdateStream NetworkUpdateStream; // the network update stream that processes sync and events
bool bIsServer; // set by which init method we call
uint16_t ListenPort; // listen port for this simulation server (0 = don't listen)
uint8_t SyncRate; // the number of times per second we should send network updates
uint8_t NetSendRate; // the rate at which the buffers are synchronized (updates per second)
ZString NetName; // the name of this server / client on the network
ZPropertyBuffer PropertyBuffer; // allocator and sync manager for entity properties
ZArray<eID> PropertyDeletedStack; // list of entities that have had a property deleted
ZMutex PropertyDeletedLock; // lock for manipulating PropertyDeletedStack
ZHashMap<ZName, ZEntity::InitFunc> EntityTypeMap; // map of entity name to initialization functions
ZHashMap<ZName, ZEntity::StateFunc> EntityStateMap; // map of entity name to initialization functions
// function to get the next entity id available
eID GetNextEntityId()
{
size_t startIndex = CurrentEntityIndex;
ZEntity* ent = Entities[CurrentEntityIndex];
while (ent != NULL)
{
CurrentEntityIndex++;
if (CurrentEntityIndex > ZSIM_EID_MAX)
CurrentEntityIndex = 0;
ZASSERT_RUNTIME(CurrentEntityIndex != startIndex, "No available entity Id's! Also, wow, that's a lot of entities.");
ent = Entities[CurrentEntityIndex];
}
return (eID)CurrentEntityIndex;
}
// Entity allocation methods (override in subclass to use specialized memory management)
virtual ZEntity* AllocEntity(eID entityId);
virtual ZEntity* AllocEntity(eID entityId, ZEntity::StateFunc startState);
virtual void DeallocEntity(ZEntity* entity);
// Thread initialization method and shutdown method (be sure to call ZSimulation::initThread and ZSimulation::shutdownThread if subclassed)
virtual void initThread();
virtual void shutdownThread();
// Overridden 'Run' Method
virtual ZThreadReturn run(uint64_t dt);
// Exposed Init and Shutdown methods for subclass simulations to implement
virtual bool SubInitServer() { return true; }
virtual bool SubInitClient() { return true; }
virtual void SubShutdown() { }
// Exposed 'Simulation Tick' method for subclass simulations to implement
virtual void Tick(double dt) { URFP(dt); }
// Some private static functions for handling the base message types
static void HandleNetworkSystemShutdown(eID sender, eID target, void* payload, ZSimulation& sim); //
static void HandleConnectionEstablished(eID sender, eID target, void* payload, ZSimulation& sim); //
static void HandleConnectionFailed(eID sender, eID target, void* payload, ZSimulation& sim); //
static void HandleConnectionLost(eID sender, eID target, void* payload, ZSimulation& sim); //
static void HandleServerNodeGained(eID sender, eID target, void* payload, ZSimulation& sim); //
static void HandleServerNodeLost(eID sender, eID target, void* payload, ZSimulation& sim); //
static void HandleSpawnEntity(eID sender, eID target, void* payload, ZSimulation& sim); // spawns an entity of a specific type
static void HandleGainState(eID sender, eID target, void* payload, ZSimulation& sim); // transitions entity to 'actor' status
static void HandleLoseState(eID sender, eID target, void* payload, ZSimulation& sim); // transitions from 'actor' to 'base entity' status
static void HandleKill(eID sender, eID target, void* payload, ZSimulation& sim); // removes an entity from the simulation
static void HandleShutdownSimulation(eID sender, eID target, void* payload, ZSimulation& sim); // handles a shutdown message (shuts down this simulation)
static void HandleSetInt(eID sender, eID target, void* payload, ZSimulation& sim); // sets the integer value of a property
static void HandleSetDbl(eID sender, eID target, void* payload, ZSimulation& sim); // sets the real number value of a property
static void HandleSetVec(eID sender, eID target, void* payload, ZSimulation& sim); // sets the vector value of a property
static void HandleSetMat(eID sender, eID target, void* payload, ZSimulation& sim); // sets the matrix value of a property
static void HandleSetStr(eID sender, eID target, void* payload, ZSimulation& sim); // sets the string value of a property
private:
DISABLE_COPY_AND_ASSIGN(ZSimulation);
};
#endif

View File

@@ -0,0 +1,299 @@
/*
ZFrameworkDefs.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 2/5/2013
Purpose:
This is our definitions and typedefs file for the ZFramework project.
License:
Copyright 2013, 762 Studios
*/
#pragma once
#ifndef _ZSIMULATIONDEFS_HPP
#define _ZSIMULATIONDEFS_HPP
#include "pstdint.h"
#include <SST/SST_Math.h> // For SST_Vec*, SST_Mat*
#include <SST/SST_NetResult.h> // For SST_NetResult
#include <ZUtil/ZUtil.hpp> // For Build Definitions
//////////////////////////////////////////////////////////////////////////
// Defines
#ifndef ZSIM_ENT_STATE_STACK_SIZE
#define ZSIM_ENT_STATE_STACK_SIZE (16) // size of the entity state stack (maximum number of pushed states)
#endif
#define ZSIM_DEFAULT_HZ (10) // Simulation default Hz
#define ZSIM_EID_MAX UINT16_MAX // Maximum eID that will ever be returned by the simulation
#define ZSIM_EID_SYSTEM (0) // eID that signifies target is 'system' or the running simulation
#define ZSIM_MSG_USER_BASE (128) // This is the base required Id for user messages (anything lower is reserved)
#define ZSIM_SYNCBUFFER_MAX (1024) // Maximum size of a buffer-synchronized property
#define ZSIM_STRINGBUFFER_DEFAULT (65535) // Default size of the string buffer
#define ZSIM_NETWORK_MAX_PEER_ID (32) // Maximum length of a peer id string
#define ZSIM_NETWORK_SLOT_LOCAL (0) // Array position for a local client
#define ZSIM_NETWORK_MAX_PACKETSIZE (1400) // Maximum network packet data size (coincidentally, size of the local buffer used to read packets)
#define ZSIM_NETWORK_REPLY_TIMEOUT (50) // Timeout on waiting for a reply from a connection
#define ZSIM_NETWORK_LISTEN_PORT (0x762C) // Listen port for the simulation (port 30252)
#define ZSIM_NETWORK_PROTOCOL_VERSION 0x1000000 // Protocol version
#define ZSIM_NETWORK_BYTEORDER SST_BIG_ENDIAN // Net system byteorder
#define ZSIM_NETWORK_DISCONNECT_TIME (1000) // Amount of time (in ms) we will send disconnection notices before giving up
#define ZSIM_NETWORK_MAX_CONNECTIONS (64) // Default number of maximum connections
#define ZSIM_NETWORK_MAX_CHANNELS (3) // Maximum number of network channels
#define ZSIM_NETWORK_CH_SYSTEM (0) // System Net Channel
#define ZSIM_NETWORK_CH_UPDATE (1) // Update Stream Net Channel
#define ZSIM_NETWORK_CH_EVENT (2) // Game Event Net Channel
#define ZSIM_NETWORK_SEND_RATE (10) // Number of buffer updates per second
#define ZSIM_NETWORK_MAX_NAME_LENGTH (128) // Maximum id length for a connection (steam max name length is 32, FYI)
#define ZSIM_NETWORK_MAX_HOST_LENGTH (1024) // Maximum length for readable host name
#define ZSIM_NETWORK_TARGET_ALL (UINT16_MAX) // Indicates the network event should target all connected
#ifndef ZSIM_MESSAGE_SIZE
#define ZSIM_MESSAGE_SIZE (1024) // The payload size (in bytes) for a message, which can be interpreted via a layout definition
#endif
#ifndef ZSIM_MESSAGE_ALLOC
#define ZSIM_MESSAGE_ALLOC (65535) //The number of messages the message stream holds locally
#endif
//////////////////////////////////////////////////////////////////////////
// Typedefs
// Equivalent to typedef T D;, but makes it a strong type
// ARE YOU NOT ENTERTAINED?!?!
#define strong_typedef(T, D) \
struct D { \
T t; \
explicit D(const T _t) : t(_t) {} \
D() {}; \
D(const D& _t) : t(_t) {} \
D& operator = (const D& other) { t = other.t; return *this; } \
D& operator = (const T& other) { t = other; return *this; } \
operator const T& () const { return t; } \
operator T& () { return t; } \
bool operator == (const D& other) { return t == other.t; } \
bool operator < (const D& other) { return t < other.t; } \
T value() { return t; } \
}
typedef uint32_t eID; // entity identifier
typedef uint16_t cID; // connection identifier
typedef uint32_t nID; // net event type identifier (0 reserved by simulation)
typedef uint32_t mID; // message type identifier (0 - 127 are reserved by the simulation)
//////////////////////////////////////////////////////////////////////////
// Enumerations
// base simulation message types
enum ZMessageType {
ZSIM_MSG_NETWORK_SHUTDOWN = 1, // network system has shutdown
ZSIM_MSG_CONNECTION_ESTABLISHED, // connection attempt successful
ZSIM_MSG_CONNECTION_FAILED, // connection attempt failed
ZSIM_MSG_CONNECTION_LOST, // connection lost
ZSIM_MSG_NODE_JOINED, // server node has joined the network
ZSIM_MSG_NODE_LOST, // server node has left the network
ZSIM_MSG_ENT_SPAWN, // spawns an entity
ZSIM_MSG_ENT_GAIN_STATE, // entity has gained state (becomes Actor)
ZSIM_MSG_ENT_LOSE_STATE, // actor has lost state (becomes Entity)
ZSIM_MSG_ENT_KILL, // kills an entity
ZSIM_MSG_SET_INT_PROPERTY, // sets an integer entity property
ZSIM_MSG_SET_REAL_PROPERTY, // sets a real number entity property
ZSIM_MSG_SET_STRING_PROPERTY, // sets a string entity property
ZSIM_MSG_SET_VEC_PROPERTY, // sets a vector entity property
ZSIM_MSG_SET_MAT_PROPERTY, // sets a matrix entity property
ZSIM_MSG_SHUTDOWN_SIMULATION = ZSIM_MSG_USER_BASE - 1, // stops the running simulation and cleans up (can restart)
};
//////////////////////////////////////////////////////////////////////////
// Message Layouts
#pragma pack (push, 1) // tightly compact data in message structs
#if SST_COMPILER == SST_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable:4201) // Disables the warning about nameless structs
#pragma warning(disable:4100) // Disables the warning about unreferenced formal parameters
#endif
/* Networking Messages */
/*
Sent to the simulation when the network system thread fails to initialize.
*/
struct ZMessage_NetworkSystemShutdown {
int Reason; // 0 - stop network request, 1 - failed to poll for net events
};
/*
Sent to the simulation when a connection has been established. Contains information
about the connection and a connection identifier.
*/
struct ZMessage_ConnectionEstablished {
cID ConnectionId; // id that has been assigned to this connection
int ConnectionType; // 0 - client, 1 - server, 2 - unknown
char NetworkName[ZSIM_NETWORK_MAX_NAME_LENGTH+1]; // network name given by the other simulation
};
/*
Sent to the simulation when a connection attempt has failed. Contains information
about the connection attempt.
*/
struct ZMessage_ConnectionFailed {
int Reason; // 0 - unable to resolve host, 1 - no slots available, 2 - malformed response
char RemoteHost[ZSIM_NETWORK_MAX_HOST_LENGTH+1]; // remote host address that connection failed
};
/*
Sent to the simulation when a connection has been lost due to error. Contains information
about the error and a connection identifier. Any handler for this message should call
'Reset' on the remote peer object - otherwise the connection id remains unused.
*/
struct ZMessage_ConnectionLost {
int Reason; // 0 - terminated here, 1 - terminated other side, 2 - connection unresponsive, 3 - malformed data
cID ConnectionId; // connection id for connection that was lost
};
/*
Sent to the simulation when another simulation instance is connected to the network.
Contains the name of the node and the name of its host node.
*/
struct ZMessage_NodeGained {
char NodeName[ZSIM_NETWORK_MAX_NAME_LENGTH+1]; // network node name of the other simulation
char HostName[ZSIM_NETWORK_MAX_NAME_LENGTH+1]; // network node name of the host the simulation is connected to
};
/*
Sent to the simulation when a simulation node connection is lost. Contains the name
as well as a reason flag.
*/
struct ZMessage_NodeLost {
int Reason; // 1 - connection terminated, 2 - connection unresponsive
char NodeName[ZSIM_NETWORK_MAX_NAME_LENGTH+1]; // network node name of the lost node
};
/* Simulation Messages */
/*
Spawns an entity into the simulation.
*/
struct ZMessage_SpawnEntity {
eID RequestedId; // id being requested for the entity
ZHashValue Type; // the entity type (name hash)
ZHashValue State; // the state to spawn with (zero for no state)
};
/*
Notifies the simulation that an entity has gained state, turning a base entity into an
actor entity that will have state ticked. The sender must be a valid entity that has
gained an initial state. This is not needed if the entity is created with state.
Message source is used to find the entity.
*/
struct ZMessage_EntityGainState {
};
/*
Notifies the simulation that an actor entity has lost all state and become a base entity.
Base entities do not have their state ticked by the simulation (as they have none).
Message source is used to find the entity.
*/
struct ZMessage_EntityLoseState {
};
/*
Kills off an entity from the simulation.
Message target is used to find the entity.
*/
struct ZMessage_KillEntity {
};
/*
Simulation Stop message layout. This will take a shutdown message and shut down the
simulation.
*/
struct ZMessage_ShutdownSimulation {
char ShutdownMessage[ZSIM_MESSAGE_SIZE]; // the shutdown message
};
/* Property Set Messages */
/*
All property set messages behave in a similar fashion to cope with the threaded processing
of values.
Provided the original value of the property, this will set it if that value remains the same at
the time this message is processed. If the value has changed from the original value, this will
call the provided callback function to recompute the value. If the provided callback function is
NULL, set messages will simply apply the value regardless of original value.
The function pointer always has the following signature:
T callback_function(const T& new_value);
Where T is the property type. Note that the behavior of set messages make them unsuitable
as network messages - rely on synchronized properties instead.
*/
/*
Templated set message. Contains the new value, the original value, and the name hash which
is used to look up the property. When this message is processed it will set the property
value regardless of the current read or write value.
If you wish to have the message take the current value into account, use a lambda message.
*/
template <typename T>
struct ZMessage_Set {
uint64_t NameHash;
T Value;
};
typedef ZMessage_Set<bool> ZMessage_SetBool;
typedef ZMessage_Set<int64_t> ZMessage_SetInt;
typedef ZMessage_Set<float> ZMessage_SetFloat;
typedef ZMessage_Set<double> ZMessage_SetDouble;
typedef ZMessage_Set<SST_Vec4f> ZMessage_SetVector;
typedef ZMessage_Set<SST_Mat44f> ZMessage_SetMatrix;
typedef ZMessage_Set<char*> ZMessage_SetString;
/*
Specialized set string message that holds the string in the message (up to ZSIM_MESSAGE_SIZE).
Useful when a pointer would leave scope befor the message can be processed.
*/
struct ZMessage_SetStringCopy {
uint64_t NameHash;
char Value[ZSIM_MESSAGE_SIZE-sizeof(uint64_t)];
};
/*
Templated lambda message. Simply carries a pointer to a lambda function which is run
on the property when this message is processed.
*/
template <typename T>
struct ZMessage_Lambda {
uint64_t NameHash;
T (*LambdaFnc)(const T&);
};
#if SST_COMPILER == SST_COMPILER_MSVC
#pragma warning(pop)
#endif
#pragma pack (pop)
#endif

View File

@@ -0,0 +1,72 @@
/*
ZStringBuffer.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 10/19/2016
Purpose:
The string buffer is a specialized lookup table for strings, designed to hold
static strings for entity properties. In doing so, properties need merely keep
a reference key for a static string that is shared between entities and different
simulations, reducing memory usage and network traffic.
Dynamic strings are stored within the property buffer and are limited in size.
It is recommended that all static strings be declared during the simulation
initialization step, as no concurrency mechanisms are in place when looking up
strings from string keys. As such, there is no way of removing a string once
added.
This class is implemented as a singleton.
License:
Copyright 2016, 762 Studios.
*/
#pragma once
#ifndef _ZSTRINGBUFFER_HPP
#define _ZSTRINGBUFFER_HPP
#include "ZSimulationDefs.hpp"
class ZStringBuffer
{
public:
// typedef used to look up a static string
typedef uint32_t StringKey;
// singleton instance getter
static ZStringBuffer* Instance()
{ if (_Instance == NULL) _Instance = new ZStringBuffer(); return _Instance; }
// adds a string to the buffer
StringKey AddString(const char* str);
// given a string, finds the key (returns StringKey(-1) if not found)
StringKey GetKey(const char* str);
// given a key, finds the string (returns NULL if not found)
const char* GetString(StringKey key);
private:
static ZStringBuffer* _Instance; // singleton instance
char* Buffer; // the buffer all strings will be stored in
size_t BufferSize; // current size of the buffer
size_t BufferOffset; // current offset into the buffer
ZArray<size_t> Offsets; // string key as index into this array, which provides offset into buffer
ZHashMap<SST_HashValue64, ZArray<StringKey>> Lookup; // fast lookup for strings (narrows the search)
// c'tor
ZStringBuffer();
// d'tor
~ZStringBuffer();
};
#endif

161
Include/ZUtil/ZAlloc.hpp Normal file
View File

@@ -0,0 +1,161 @@
/*
ZAlloc.hpp (created 9/12/10)
Author : James Russell
Purpose :
Memory allocation library and memory allocation tracker for ZEngine. If ZALLOC_EXTRA_SPAMMY is defined,
then allocations will log a message to stderr when allocation occurs indicating how much.
License:
TODO
*/
#pragma once
#ifndef _ZALLOC_H
#define _ZALLOC_H
#include <ZUtil/ZUtilBuild.hpp>
#include <new>
//The compiler really should be smart enough to include size_t in the global
//namespace by default. But, on some Linux configurations, it will drop
//it in std. Explicitly including this doesn't hurt anything.
#include <stddef.h>
#if ZALLOC_CHECK_ALLOC
//Memory Checkpoint Struct
struct ZMemState
{
int Checkpoint; //Checkpoint Number
};
//Allocation Info Struct
struct ZAllocInfo
{
static int CurrentAllocCount; //Current number of unfreed allocations
static int CurrentCheckpoint; //Static current checkpoint tracker
ZAllocInfo* Next; //Next Info Node
uintptr_t Address; //Address assigned
size_t Size; //Size of the allocation
int Line; //Line Number
int Checkpoint; //Checkpoint Integer
char File[128]; //File String
};
//Adds a tracking node for an allocation
extern void ZAllocAddTrack(uintptr_t _address, size_t _size, const char *_file, int _line, int _checkpoint);
//Removes a tracking node for an allocation
extern void ZAllocRemoveTrack(uintptr_t _address);
//Dumps unfreed memory string containing a list of memory leaks
extern void ZAllocDumpUnfreed(ZMemState *_state);
//Debug Placement Operator New
extern void* operator new(size_t _size, const char *_file, int _line, int _checkpoint) throw();
extern void* operator new[](size_t _size, const char *_file, int _line, int _checkpoint) throw();
//Debug Placement Delete
extern void operator delete(void *_ptr, const char* _file, int _line, int _checkpoint);
extern void operator delete[](void *_ptr, const char* _file, int _line, int _checkpoint);
//Our arguments to znew
#define ZNEW_ARGS (__FILE__, __LINE__, ZAllocInfo::CurrentCheckpoint)
//Macros for declaring a memory 'checkpoint' and
//dumping memory leaks to stderr
#define ZALLOC_MEM_CHECKPOINT(stateP) stateP->Checkpoint = AtomicAddReturn((volatile int*)&ZAllocInfo::CurrentCheckpoint, 1)
#define ZALLOC_MEM_DUMP_LEAKS(stateP) ZAllocDumpUnfreed(stateP)
#else //!ZALLOC_CHECK_ALLOC
#define ZNEW_ARGS (std::nothrow)
#define ZALLOC_MEM_CHECKPOINT(stateP)
#define ZALLOC_MEM_DUMP_LEAKS(stateP)
#endif //ZALLOC_CHECK_ALLOC
/* Some definitions we need for znew_static */
//This is used to indicate a static allocation (basically a type flag)
struct znew_static_t { };
//Our actual static allocation overrides
extern void* operator new(size_t _size, znew_static_t _staticAlloc);
extern void* operator new[](size_t _size, znew_static_t _staticAlloc);
/* Some Memory Management Macros */
//znew loves you!
#define znew new ZNEW_ARGS //Allocate with params
#define znew_notrack new (std::nothrow) //Allocate without tracking
#define znew_static new (znew_static_t()) //Allocate, but register for delete onexit
#define zdelete delete //Delete
#define zalloc(_type, _size) ZAlloc::Alloc<_type>(_size) //Allocates an array (block of memory) using the ZAlloc allocation library
#define zfree(_data) ZAlloc::Free(_data) //Frees an array (block of memory) using the ZAlloc allocation library
#define MemCopy(_type, _dest, _src, _count) memcpy(_dest, _src, _count * sizeof(_type))
#define MemCopyFloat(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(float))
#define MemCopyInt(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(int))
#define MemCopyChar(_dest, _src, _count) memcpy(_dest, _src, _count * sizeof(char))
#define MemMove(_type, _dest, _src, _count) memmove(_dest, _src, _count * sizeof(_type))
#define MemMoveFloat(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(float))
#define MemMoveInt(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(int))
#define MemMoveChar(_dest, _src, _count) memmove(_dest, _src, _count * sizeof(char))
#define MemSet(_type, _dest, _val, _count) memset(_dest, _val, _count * sizeof(_type))
#define MemSetFloat(_dest, _val, _count) memset(_dest, _val, _count * sizeof(float))
#define MemSetInt(_dest, _val, _count) memset(_dest, _val, _count * sizeof(int))
#define MemSetChar(_dest, _val, _count) memset(_dest, _val, _count * sizeof(char))
class ZAlloc
{
public:
/*
static public Alloc
Allocation function. Gives back an allocated array of at least _size in length.
@param _size - the size of the block of type T
@return (T*) - an array of T of at least _size in length
*/
template <class T>
static T* Alloc(size_t _size);
/*
public static Free
Free function.
@param _data - an array allocated through the use of Alloc
@return (void)
*/
template <class T>
static void Free(T *_data);
};
template <class T>
T* ZAlloc::Alloc(size_t _size)
{
return new (std::nothrow) T[_size];
}
template <class T>
void ZAlloc::Free(T *_data)
{
delete [] _data;
}
#endif

View File

@@ -0,0 +1,205 @@
/*
ZAllocWindow.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 3/7/2013
Purpose:
Buffer used to maintain a sliding window of allocations in a buffer. Primary
use case is sliding packet windows, but could also be used for other forms
of data.
Able to allocate raw memory blocks or perform in-place construction using
default constructors. Destructor calls can be omitted or performed.
License:
TODO
*/
#pragma once
#ifndef _ZALLOCWINDOW_HPP
#define _ZALLOCWINDOW_HPP
#include <new> // for placement new
#include <ZUtil/ZUtilBuild.hpp>
/*
Allocation window class. Operating on a contiguous array of backing memory,
this will allocate chunks of that memory, increasing the window until the
entire block would be used.
When deallocations are performed, no memory is actually freed from the buffer
unless the earliest allocation is deallocated, which will shrink the window.
As an example, consider the following:
buffer.Allocate(A);
buffer.Allocate(B);
buffer.Allocate(C);
buffer.Allocate(D);
A large enough buffer would return four pointers and would have the following
layout (a = allocated flag, d = deallocated flag, f = free memory):
+-----------------------------------+
| a | A | a | B | a | C | a | D | f |
+-----------------------------------+
^ ^
buffer begin buffer end
buffer.Deallocate(B);
+-----------------------------------+
| a | A | d | B | a | C | a | D | f |
+-----------------------------------+
^ ^
buffer begin buffer end
buffer.Deallocate(A);
+-----------------------------------+
| f | f | f | f | a | C | a | D | f |
+-----------------------------------+
^ ^
buffer begin buffer end
Notice that when B was deallocated, no space was actually made available
in the buffer until A was deallocated. If a further attempt had been made
to allocate data, it would have returned NULL, indicating that the allocation
window was full. The only way to free data at that point would have been to
deallocate the earliest allocation (A, in this case).
The allocation window will automatically handle wrapping around when the end
of the buffer is reached.
*/
class ZAllocWindow
{
public:
// c'tor
ZAllocWindow();
// parameterized c'tor
ZAllocWindow(size_t _buffersize);
// d'tor
~ZAllocWindow();
/*
void* ZAllocWindow::Allocate
Allocates a contiguous block of memory from the buffer. If this
would wrap around such that the previously allocated data (that has
not been deallocated) would be overwritten, then it returns NULL.
An additional 8 bytes are used per allocation from the buffer for
allocation metadata.
This will always return a word aligned pointer.
The template version will default construct an object of type T.
@param _size - number of bytes to allocate
@return (void*) - the allocated block of memory (NULL if not possible)
*/
void* Allocate(size_t _size);
template <typename T> T* Allocate()
{ T* obj = (T*)Allocate(sizeof(T)); return (obj != NULL ? new (obj) T() : NULL); }
/*
void ZAllocWindow::Deallocate
Deallocates a previously allocated block of memory from the binary buffer. Since
allocation is done in a sliding window, this only moves frees up memory if this
is the oldest currently allocated block of data. Any other data that is deallocated
will be marked as freed to be made available when the oldest allocated block is freed.
The template version will call the destructor for the object.
@param _data - the data to be deallocated
@param _obj - the object to deallocate (destructor is called)
@return (void)
*/
void Deallocate(void* _data);
template <typename T> void Deallocate(T* _obj)
{ _obj->~T(); Deallocate((void*)_obj); }
/*
size_t ZAllocWindow::GetAllocCount
Gets the current number of allocations out on this allocation window.
@return (size_t) - the number of allocations
*/
size_t GetAllocCount() const
{ return NumAllocs; }
/*
void ZAllocWindow::Reset
Completely resets the allocation window, completely invalidating all
existing allocations.
@return (void)
*/
void Reset();
/*
bool ZAllocWindow::Resize
Attempts to resize the buffer. This will fail if data is currently allocated in
the buffer.
The template version will set the buffer to enough room for N objects of type T.
@param _newsize - the new desired size of the buffer
@param _count - the number of objects of type T to resize the buffer for
@return (bool) - true if able to resize, false otherwise
*/
bool Resize(size_t _newsize);
template <typename T> bool Resize(size_t _count)
{ return Resize((sizeof(T) + 8) * _count); }
/*
void ZAllocWindow::SetBuffer
Sets the backing buffer for this binary buffer. This will fail if data is currently
allocated in the buffer. If NULL, will release ownership of any previous set buffer
and allocate a new one equal to the current size.
Does not assume ownership of the buffer - will not delete it upon destruction of this
buffer.
@param _buffer - the buffer to use as backing
@param _buffersize - the size of the buffer being set
@return (bool) - true if able to use, false otherwise
*/
bool SetBuffer(void* _buffer, size_t _buffersize);
/*
size_t ZAllocWindow::Size
Returns the current size of the buffer.
@return (size_t) - size (in bytes) of the buffer
*/
size_t Size() const
{ return BufferSize; }
private:
DISABLE_COPY_AND_ASSIGN(ZAllocWindow);
void* Buffer; // The allocated buffer
void* Begin; // The (moving) front pointer of the buffer
void* End; // The (moving) back pointer of the buffer
size_t BufferSize; // The current allocated size of the buffer
bool bOwnsBuffer; // Flag indicating we own the buffer (and should free when done)
size_t NumAllocs; // The number of allocations we've done
};
#endif

53
Include/ZUtil/ZAssert.hpp Normal file
View File

@@ -0,0 +1,53 @@
/*
ZAssert.hpp
Author : Chris Ertel
Purpose : Asserts for debugging and error checking purposes.
Changelog
8/16/2010 - creation (crertel)
12/4/2011 - Updated to use libsst-os asserts (jcrussell)
*/
#pragma once
#ifndef _ZASSERT_H
#define _ZASSERT_H
#include <SST/SST_Assert.h>
/*****************/
/* Assert Macros */
/*****************/
//ZASSERT_RUNTIME macro, which will raise an error with debug output if the condition is not true after logging the message
#define ZASSERT_RUNTIME(_condition, _message) SST_OS_RuntimeAssert(_condition, _message)
//ZASSERT_RUNTIME_FAIL macro, which will raise an error with debug output
#define ZASSERT_RUNTIME_FAIL(_message) SST_OS_RuntimeError(_message)
#if ZASSERT_ENABLE
//ZASSERT macro, which will trigger a breakpoint if the condition is not met
#define ZASSERT(_condition, _message) SST_OS_DebugAssert(_condition, _message)
//ZASSERT_FAIL macro, which triggers a breakpoint
#define ZASSERT_FAIL(_message) SST_OS_DebugError(_message)
#else /* ZASSERT is disabled */
#define ZASSERT(_condition, _message)
#define ZASSERT_FAIL(_message)
#endif //ZASSERT_ENABLE
#if ZASSERT_UTIL_ENABLE
//ZASSERT_UTIL macro, which will trigger a breakpoint if the condition is not met
//ZASSERT_UTIL is meant to be used within the ZUtil project for internal assertion debugging
//ZASSERT should be used when the error condition can be caused by user actions
#define ZASSERT_UTIL(_condition, _message) SST_OS_DebugAssert(_condition, _message)
#else /* ZASSERT_UTIL is disabled */
#define ZASSERT_UTIL(_condition, _message) ((void)0)
#endif //ZASSERT_UTIL_ENABLE
#endif

View File

@@ -0,0 +1,87 @@
/*
ZBinaryBufferReader.hpp
Author: Chris Ertel <crertel@762studios.com>, Patrick Baggett <ptbaggett@762studios.com>
Created: 3/6/2013
Purpose:
Reads a binary stream from memory.
License:
TODO
*/
#pragma once
#ifndef _ZBINARYBUFFERREADER_HPP
#define _ZBINARYBUFFERREADER_HPP
#include <stddef.h>
#include <pstdint.h>
#include <ZUtil/ZBinaryReader.hpp>
class ZBinaryBufferReader : public ZBinaryReader
{
private:
const char* Data;
size_t Size;
size_t Offset;
//This is typed to char* so pointer arithmetic can occur
const char* GetPosition() const { return &Data[Offset]; }
public:
ZBinaryBufferReader(const void* _data, size_t _size, SST_ByteOrder bo)
: ZBinaryReader(bo), Data( (const char*) _data), Size(_size), Offset(0)
{
}
//Subclass implementation
uint8_t ReadU8();
//Subclass implementation
uint16_t ReadU16();
//Subclass implementation
uint32_t ReadU32();
//Subclass implementation
uint64_t ReadU64();
//Subclass implementation
void ReadU8Array(uint8_t* ptr, size_t count);
//Subclass implementation
void ReadU16Array(uint16_t* ptr, size_t count);
//Subclass implementation
void ReadU32Array(uint32_t* ptr, size_t count);
//Subclass implementation
void ReadU64Array(uint64_t* ptr, size_t count);
//Subclass implementation
size_t GetLength() const { return Size; }
//Subclass implementation
size_t GetOffset() const { return Offset; }
//Subclass implementation
void SeekTo(size_t offset) { Offset = offset; }
//New to ZBinaryBufferReader. Returns the current address that would be read by the next ReadXxx() call.
//Since 'const void*' is the constructor type, this returns 'const void*' as well. See [private] GetPosition().
const void* GetBufferReadAddress() const { return (const void*)GetPosition(); }
//New to ZBinaryBufferReader. Returns the original buffer address
const void* GetBufferBaseAddress() const { return (const void*)Data; }
//New to ZBinaryBufferReader. Reads a pointer
void* ReadPointer();
};
#endif

View File

@@ -0,0 +1,78 @@
/*
ZBinaryBufferWriter.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 6/05/2013
Purpose:
Writes a binary stream to memory
License:
TODO
*/
#pragma once
#ifndef _ZBINARYBUFFERWRITER_HPP
#define _ZBINARYBUFFERWRITER_HPP
#include <ZUtil/ZBinaryWriter.hpp>
class ZBinaryBufferWriter : public ZBinaryWriter
{
public:
ZBinaryBufferWriter(void* data, size_t _size, SST_ByteOrder bo) :
ZBinaryWriter(bo), Data((uint8_t*)data), Size(_size), Offset(0)
{
}
//Subclass implementation
void WriteU8(uint8_t v);
//Subclass implementation
void WriteU16(uint16_t v);
//Subclass implementation
void WriteU32(uint32_t v);
//Subclass implementation
void WriteU64(uint64_t v);
//Subclass implementation
void WriteU8Array(const uint8_t* v, size_t count);
//Subclass implementation
void WriteU16Array(const uint16_t* v, size_t count);
//Subclass implementation
void WriteU32Array(const uint32_t* v, size_t count);
//Subclass implementation
void WriteU64Array(const uint64_t* v, size_t count);
//Subclass implementation
size_t GetOffset() const { return Offset; }
//Subclass implementation
void SeekTo(size_t offset) { Offset = offset; }
//Specific to ZBinaryBufferWriter, returns next write address
const void* GetBufferWriteAddress() const { return &Data[Offset]; }
//Specific to ZBinaryBufferWriter, returns base address
void* GetBufferBaseAddress() const { return Data; }
//Specific to ZBinaryBufferWriter, writes a pointer
void WritePointer(void* pointer);
private:
uint8_t* Data;
size_t Size; //TODO: no safe ops ?
size_t Offset;
};
#endif

View File

@@ -0,0 +1,72 @@
/*
ZBinaryFileReader.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 3/6/2013
Purpose:
Reads a binary stream from a SST_File handle. NOTE: On 32-bit platforms, only files up to 4GB are supported.
License:
TODO
*/
#pragma once
#ifndef _ZBINARYFILEREADER_HPP
#define _ZBINARYFILEREADER_HPP
#include <SST/SST_File.h>
#include <ZUtil/ZBinaryReader.hpp>
class ZBinaryFileReader : public ZBinaryReader
{
private:
SST_File fp;
size_t Size;
size_t Offset;
public:
ZBinaryFileReader(SST_File handle, SST_ByteOrder bo);
//Subclass implementation
uint8_t ReadU8();
//Subclass implementation
uint16_t ReadU16();
//Subclass implementation
uint32_t ReadU32();
//Subclass implementation
uint64_t ReadU64();
//Subclass implementation
void ReadU8Array(uint8_t* ptr, size_t count);
//Subclass implementation
void ReadU16Array(uint16_t* ptr, size_t count);
//Subclass implementation
void ReadU32Array(uint32_t* ptr, size_t count);
//Subclass implementation
void ReadU64Array(uint64_t* ptr, size_t count);
//Subclass implementation
size_t GetLength() const { return Size; }
//Subclass implementation
size_t GetOffset() const { return Offset; }
//Subclass implementation
void SeekTo(size_t offset);
//Unique to ZBinaryFileReader
SST_File GetFileHandle() { return fp; }
};
#endif

View File

@@ -0,0 +1,68 @@
/*
ZBinaryFileWriter.hpp
Author: Chris Ertel <crertel@762studios.com>, Patrick Baggett <ptbaggett@762studios.com>
Created: 3/11/2013
Purpose:
Writes a binary stream from a SST_File handle. NOTE: On 32-bit platforms, only files up to 4GB are supported.
License:
TODO
*/
#pragma once
#ifndef _ZBINARYFILEWRITER_HPP
#define _ZBINARYFILEWRITER_HPP
#include <SST/SST_File.h>
#include <ZUtil/ZBinaryWriter.hpp>
class ZBinaryFileWriter : public ZBinaryWriter
{
public:
ZBinaryFileWriter(SST_File handle, SST_ByteOrder bo);
//Subclass implementation
void WriteU8(uint8_t v);
//Subclass implementation
void WriteU16(uint16_t v);
//Subclass implementation
void WriteU32(uint32_t v);
//Subclass implementation
void WriteU64(uint64_t v);
//Subclass implementation
void WriteU8Array(const uint8_t* v, size_t count);
//Subclass implementation
void WriteU16Array(const uint16_t* v, size_t count);
//Subclass implementation
void WriteU32Array(const uint32_t* v, size_t count);
//Subclass implementation
void WriteU64Array(const uint64_t* v, size_t count);
//Subclass implementation
size_t GetOffset() const { return Offset; }
//Subclass implementation
void SeekTo(size_t offset);
//Unique to ZBinaryFileWriter
SST_File GetFileHandle() { return fp; }
private:
SST_File fp;
size_t Offset;
};
#endif

View File

@@ -0,0 +1,749 @@
/*
ZBinaryReader.hpp
Author: Patrick Baggett <ptbaggett@762studios.com
Created: 3/6/2013
Purpose:
Binary stream reader interface
License:
TODO
*/
#pragma once
#ifndef _ZBINARYREADER_HPP
#define _ZBINARYREADER_HPP
#include <pstdint.h>
#include <SST/SST_Endian.h>
class ZBinaryReader
{
public:
ZBinaryReader(SST_ByteOrder streamOrder) :
streamByteOrder(streamOrder)
{
}
//SINGLE ELEMENT READ
/*
virtual public ZBinaryReader::ReadU8
Reads a single unsigned 8-bit value from the stream.
No validation is performed.
@return (uint8_t) - value read from the stream
*/
virtual uint8_t ReadU8() = 0;
/*
virtual public ZBinaryReader::ReadU16
Reads a single unsigned 16-bit value from the stream.
No validation is performed.
@return (uint16_t) - value read from the stream
*/
virtual uint16_t ReadU16() = 0;
/*
virtual public ZBinaryReader::ReadU32
Reads a single unsigned 32-bit value from the stream.
No validation is performed.
@return (uint32_t) - value read from the stream
*/
virtual uint32_t ReadU32() = 0;
/*
virtual public ZBinaryReader::ReadU64
Reads a single unsigned 64-bit value from the stream.
No validation is performed.
@return (uint64_t) - value read from the stream
*/
virtual uint64_t ReadU64() = 0;
/*
public ZBinaryReader::ReadF32
Reads a single 32-bit floating point value from the stream.
No validation is performed.
@return (float) - value read from the stream
*/
float ReadF32() { return cast_i2f(ReadU32()); }
/*
public ZBinaryReader::ReadF64
Reads a single 64-bit floating point value from the stream.
No validation is performed.
@return (double) - value read from the stream
*/
double ReadF64() { return cast_i2d(ReadU64()); }
//=====================================================================
//ARRAY READ
//=====================================================================
/*
virtual public ZBinaryReader::ReadU8Array
Reads an array of 8-bit unsigned values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
virtual void ReadU8Array(uint8_t* ptr, size_t count) = 0;
/*
virtual public ZBinaryReader::ReadU16Array
Reads an array of 16-bit unsigned values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
virtual void ReadU16Array(uint16_t* ptr, size_t count) = 0;
/*
virtual public ZBinaryReader::ReadU32Array
Reads an array of 32-bit unsigned values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
virtual void ReadU32Array(uint32_t* ptr, size_t count) = 0;
/*
virtual public ZBinaryReader::ReadU64Array
Reads an array of 64-bit unsigned values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
virtual void ReadU64Array(uint64_t* ptr, size_t count) = 0;
/*
public ZBinaryReader::ReadF32Array
Reads an array of 32-bit floating point values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
void ReadF32Array(float* ptr, size_t count) { ReadU32Array((uint32_t*)ptr, count); }
/*
public ZBinaryReader::ReadF64Array
Reads an array of 64-bit floating point values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
void ReadF64Array(double* ptr, size_t count) { ReadU64Array((uint64_t*)ptr, count); }
//=====================================================================
//STREAM SEEKING / POSITIONING
//=====================================================================
/*
virtual public ZBinaryReader::GetLength
Gets the total length of the stream in bytes.
@return (size_t) - The total length of the stream
*/
virtual size_t GetLength() const = 0;
/*
virtual public ZBinaryReader::GetOffset
Gets the current (zero-based) offset into the stream from which the next read will
be performed.
@return (size_t) - The offset.
*/
virtual size_t GetOffset() const = 0;
/*
public ZBinaryReader::SeekForward
Advances the offset into the stream by the given number of bytes.
No validation is performed.
@param amount - The amount of seek forward by.
@return (void)
*/
void SeekForward(size_t amount) { SeekTo(GetOffset() + amount); }
/*
public ZBinaryReader::SeekBackward
Rewinds the offset into the stream by the given number of bytes.
No validation is performed.
@param amount - The amount of seek backward by.
@return (void)
*/
void SeekBackward(size_t amount) { SeekTo(GetOffset() - amount); }
/*
virtual public ZBinaryReader::SeekTo
Directly sets the offset into the stream from which reads will occur.
No validation is performed.
@param offset - The new offset
@return (void)
*/
virtual void SeekTo(size_t offset) = 0;
/*
public ZBinaryReader::Rewind
Sets the offset to the start of the stream
@param offset - The new offset
@return (void)
*/
void Rewind() { SeekTo(0); }
/*
public ZBinaryReader::CanRead
Checks if the given number of bytes can be read
@param bytes - The number of bytes that wish to be read
@return (void)
*/
bool CanRead(size_t bytes) const { return (GetLength() - GetOffset() >= bytes); }
//=====================================================================
//SAFE SEEK FUNCTIONS
//=====================================================================
/*
public ZBinaryReader::SafeSeekForward
Attempts to advance the offset into the stream by the given number of bytes. If
this would produce an out-of-bounds result, then false is returned and the offset
is not adjusted, otherwise, the offset is adjusted and true is returned.
@param amount - The amount to seek forward by
@return (bool) - True if the seek operation succeeded, false if the value was invalid
*/
bool SafeSeekForward(size_t amount)
{
bool ok = (GetLength() - GetOffset() > amount); //i.e. length > offset + amount
if(ok)
SeekTo(GetOffset() + amount);
return ok;
}
/*
public ZBinaryReader::SafeSeekBackward
Attempts to rewind the offset into the stream by the given number of bytes. If
this would produce an out-of-bounds result, then false is returned and the offset
is not adjusted, otherwise, the offset is adjusted and true is returned.
@param amount - The amount to seek backward by
@return (bool) - True if the seek operation succeeded, false if the value was invalid
*/
bool SafeSeekBackward(size_t amount)
{
bool ok = (GetOffset() >= amount); //i.e. offset - amount >= 0
if(ok)
SeekTo(GetOffset() - amount);
return ok;
}
/*
public ZBinaryReader::SafeSeekTo
Attempts to set the offset into the stream directly. If the new offset is
out-of-bounds, then false is returned and the offset is not adjusted,
otherwise, the offset is adjusted and true is returned.
@return (bool) - True if the seek operation succeeded, false if the value was invalid
*/
bool SafeSeekTo(size_t offset)
{
bool ok = (offset < GetLength());
if(ok) SeekTo(offset);
return ok;
}
//=====================================================================
//SAFE READ FUNCTIONS
//=====================================================================
/*
public ZBinaryReader::SafeReadU8
Attempt to reads a single unsigned 8-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadU8(uint8_t* ptr)
{
bool ok = CanRead(sizeof(uint8_t));
if(ok) *ptr = ReadU8();
return ok;
}
/*
public ZBinaryReader::SafeReadU16
Attempt to reads a single unsigned 16-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadU16(uint16_t* ptr)
{
bool ok = CanRead(sizeof(uint16_t));
if(ok) *ptr = ReadU16();
return ok;
}
/*
public ZBinaryReader::SafeReadU32
Attempt to reads a single unsigned 32-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadU32(uint32_t* ptr)
{
bool ok = CanRead(sizeof(uint32_t));
if(ok) *ptr = ReadU32();
return ok;
}
/*
public ZBinaryReader::SafeReadU64
Attempt to reads a single unsigned 64-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadU64(uint64_t* ptr)
{
bool ok = CanRead(sizeof(uint64_t));
if(ok) *ptr = ReadU64();
return ok;
}
/*
public ZBinaryReader::SafeReadF32
Attempt to reads a single 32-bit floating point value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadF32(float* ptr)
{
bool ok = CanRead(sizeof(float));
if(ok) *ptr = ReadF32();
return ok;
}
/*
public ZBinaryReader::SafeReadF64
Attempt to reads a single 64-bit floating point value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadF64(double* ptr)
{
bool ok = CanRead(sizeof(double));
if(ok) *ptr = ReadF64();
return ok;
}
/*
public ZBinaryReader::SafeReadU8Array
Attempt to reads an array of unsigned 8-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadU8Array(uint8_t* ptr, size_t count)
{
bool ok = CanRead(count);
if(ok) ReadU8Array(ptr, count);
return ok;
}
/*
public ZBinaryReader::SafeReadU16Array
Attempt to reads an array of unsigned 16-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadU16Array(uint16_t* ptr, size_t count)
{
bool ok = (SIZE_MAX / count > sizeof(uint16_t)); //i.e. SIZE_MAX > count * size
ok = ok && CanRead(count * sizeof(uint16_t));
if(ok) ReadU16Array(ptr, count);
return ok;
}
/*
public ZBinaryReader::SafeReadU32Array
Attempt to reads an array of unsigned 32-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadU32Array(uint32_t* ptr, size_t count)
{
bool ok = (SIZE_MAX / count > sizeof(uint32_t)); //i.e. SIZE_MAX > count * size
ok = ok && CanRead(count * sizeof(uint32_t));
if(ok) ReadU32Array(ptr, count);
return ok;
}
/*
public ZBinaryReader::SafeReadU64Array
Attempt to reads an array of unsigned 64-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadU64Array(uint64_t* ptr, size_t count)
{
bool ok = (SIZE_MAX / count > sizeof(uint64_t)); //i.e. SIZE_MAX > count * size
ok = ok && CanRead(count * sizeof(uint64_t));
if(ok) ReadU64Array(ptr, count);
return ok;
}
/*
public ZBinaryReader::SafeReadF32Array
Attempt to reads an array of 32-bit floating point values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadF32Array(float* ptr, size_t count) { return SafeReadU32Array((uint32_t*)ptr, count); }
/*
public ZBinaryReader::SafeReadF64Array
Attempt to reads an array of 64-bit floating point values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadF64Array(double* ptr, size_t count) { return SafeReadU64Array((uint64_t*)ptr, count); }
//=====================================================================
//TYPED ALIASES
//=====================================================================
/*
public ZBinaryReader::ReadI8
Reads a single signed 8-bit value from the stream.
No validation is performed.
@return (int8_t) - value read from the stream
*/
int8_t ReadI8() { return (int8_t)ReadU8(); }
/*
public ZBinaryReader::ReadI16
Reads a single signed 16-bit value from the stream.
No validation is performed.
@return (int16_t) - value read from the stream
*/
int16_t ReadI16() { return (int16_t)ReadU16(); }
/*
public ZBinaryReader::ReadI32
Reads a single signed 32-bit value from the stream.
No validation is performed.
@return (int32_t) - value read from the stream
*/
int32_t ReadI32() { return (int32_t)ReadU32(); }
/*
public ZBinaryReader::ReadI64
Reads a single signed 64-bit value from the stream.
No validation is performed.
@return (int64_t) - value read from the stream
*/
int64_t ReadI64() { return (int64_t)ReadU64(); }
/*
public ZBinaryReader::ReadI8Array
Reads an array of 8-bit signed values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
void ReadI8Array(int8_t* ptr, size_t count) { return ReadU8Array((uint8_t*)ptr, count); }
/*
public ZBinaryReader::ReadI16Array
Reads an array of 16-bit signed values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
void ReadI16Array(int16_t* ptr, size_t count) { return ReadU16Array((uint16_t*)ptr, count); }
/*
public ZBinaryReader::ReadI32Array
Reads an array of 32-bit signed values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
void ReadI32Array(int32_t* ptr, size_t count) { return ReadU32Array((uint32_t*)ptr, count); }
/*
public ZBinaryReader::ReadI64Array
Reads an array of 64-bit signed values from the stream.
No validation is performed.
@param ptr - The base of the array
@param count - Number of elements to read
@return (void)
*/
void ReadI64Array(int64_t* ptr, size_t count) { return ReadU64Array((uint64_t*)ptr, count); }
/*
public ZBinaryReader::SafeReadI8
Attempt to reads a single signed 8-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadI8(int8_t* ptr) { return SafeReadU8((uint8_t*)ptr); }
/*
public ZBinaryReader::SafeReadI16
Attempt to reads a single signed 16-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadI16(int16_t* ptr) { return SafeReadU16((uint16_t*)ptr); }
/*
public ZBinaryReader::SafeReadI32
Attempt to reads a single signed 32-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadI32(int32_t* ptr) { return SafeReadU32((uint32_t*)ptr); }
/*
public ZBinaryReader::SafeReadI64
Attempt to reads a single signed 64-bit value from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the value is read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the read value at
@return (bool) - If the value was successfully read
*/
bool SafeReadI64(int64_t* ptr) { return SafeReadU64((uint64_t*)ptr); }
/*
public ZBinaryReader::SafeReadI8Array
Attempt to reads an array of signed 8-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadI8Array(int8_t* ptr, size_t count) { return SafeReadU8Array((uint8_t*)ptr, count); }
/*
public ZBinaryReader::SafeReadI16Array
Attempt to reads an array of signed 16-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadI16Array(int16_t* ptr, size_t count) { return SafeReadU16Array((uint16_t*)ptr, count); }
/*
public ZBinaryReader::SafeReadI32Array
Attempt to reads an array of signed 32-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadI32Array(int32_t* ptr, size_t count) { return SafeReadU32Array((uint32_t*)ptr, count); }
/*
public ZBinaryReader::SafeReadI64Array
Attempt to reads an array of signed 64-bit values from the stream. If this would
result in reading out of bounds, false is returned and *ptr is unmodified, otherwise
the values are read and stored at *ptr and true is returned.
No validation is performed.
@param ptr - The address to store the values
@param count - The number of values to read
@return (bool) - If the array was successfully read
*/
bool SafeReadI64Array(int64_t* ptr, size_t count) { return SafeReadU64Array((uint64_t*)ptr, count); }
//=====================================================================
//GETTERS / SETTERS
//=====================================================================
/*
public ZBinaryReader::GetStreamByteOrder
Gets the byte order in which the stream (source data) is read as.
@return (SST_ByteOrder) - The byte order
*/
SST_ByteOrder GetStreamByteOrder() const { return streamByteOrder; }
/*
public ZBinaryReader::SetStreamByteOrder
Sets the byte order in which the stream (source data) is read as.
@param newOrder - The new byte order
@return (void)
*/
void SetStreamByteOrder(SST_ByteOrder newOrder) { streamByteOrder = newOrder; }
private:
SST_ByteOrder streamByteOrder; //The current byte order the stream is being read in.
};
#endif

View File

@@ -0,0 +1,279 @@
/*
ZBinaryWriter.hpp
Author: Patrick Baggett <ptbaggett@762studios.com>
Created: 3/11/2013
Purpose:
Binary stream writer interface
License:
TODO
*/
#pragma once
#ifndef _ZBINARYWRITER_HPP
#define _ZBINARYWRITER_HPP
#include <SST/SST_Endian.h>
#include <pstdint.h>
class ZBinaryWriter
{
public:
ZBinaryWriter(SST_ByteOrder streamOrder) :
streamByteOrder(streamOrder)
{
}
//=====================================================================
//SINGLE ELEMENT WRITE
//=====================================================================
virtual void WriteU8(uint8_t v) = 0;
virtual void WriteU16(uint16_t v) = 0;
virtual void WriteU32(uint32_t v) = 0;
virtual void WriteU64(uint64_t v) = 0;
void WriteF32(float v) { WriteU32(cast_f2i(v)); }
void WriteF64(double v) { WriteU64(cast_d2i(v)); }
//=====================================================================
//ARRAY WRITE
//=====================================================================
/*
virtual public ZBinaryWriter::WriteU8Array
Writes an array of 8-bit unsigned values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
virtual void WriteU8Array(const uint8_t* v, size_t count) = 0;
/*
virtual public ZBinaryWriter::WriteU16Array
Writes an array of 16-bit unsigned values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
virtual void WriteU16Array(const uint16_t* v, size_t count) = 0;
/*
virtual public ZBinaryWriter::WriteU32Array
Writes an array of 32-bit unsigned values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
virtual void WriteU32Array(const uint32_t* v, size_t count) = 0;
/*
virtual public ZBinaryWriter::WriteU64Array
Writes an array of 64-bit unsigned values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
virtual void WriteU64Array(const uint64_t* v, size_t count) = 0;
/*
public ZBinaryWriter::WriteF32Array
Writes an array of 32-bit floating point values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
void WriteF32Array(const float* v, size_t count) { WriteU32Array((uint32_t*)v, count); }
/*
public ZBinaryWriter::WriteF64Array
Writes an array of 64-bit floating point values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
void WriteF64Array(const double* v, size_t count) { WriteU64Array((uint64_t*)v, count); }
//=====================================================================
//STREAM SEEKING / POSITIONING
//=====================================================================
/*
virtual public ZBinaryReader::GetOffset
Gets the current (zero-based) offset into the stream from which the next read will
be performed.
@return (size_t) - The offset.
*/
virtual size_t GetOffset() const = 0;
/*
public ZBinaryReader::SeekForward
Advances the offset into the stream by the given number of bytes.
No validation is performed.
@param amount - The amount of seek forward by.
@return (void)
*/
void SeekForward(size_t amount) { SeekTo(GetOffset() + amount); }
/*
public ZBinaryReader::SeekBackward
Rewinds the offset into the stream by the given number of bytes.
No validation is performed.
@param amount - The amount of seek backward by.
@return (void)
*/
void SeekBackward(size_t amount) { SeekTo(GetOffset() - amount); }
/*
virtual public ZBinaryReader::SeekTo
Directly sets the offset into the stream from which reads will occur.
No validation is performed.
@param offset - The new offset
@return (void)
*/
virtual void SeekTo(size_t offset) = 0;
/*
public ZBinaryReader::Rewind
Sets the offset to the start of the stream
@param offset - The new offset
@return (void)
*/
void Rewind() { SeekTo(0); }
//=====================================================================
//TYPED ALIASES
//=====================================================================
/*
public ZBinaryWriter::WriteI8
Writes a single signed 8-bit value to the stream.
@param v - value read to write to the stream
*/
void WriteI8(int8_t v) { return WriteU8((uint8_t)v); }
/*
public ZBinaryWriter::WriteI16
Writes a single signed 16-bit value to the stream.
@param v - value read to write to the stream
*/
void WriteI16(int16_t v) { return WriteU16((uint16_t)v); }
/*
public ZBinaryWriter::WriteI32
Writes a single signed 32-bit value to the stream.
@param v - value read to write to the stream
*/
void WriteI32(int32_t v) { return WriteU32((uint32_t)v); }
/*
public ZBinaryWriter::WriteI64
Writes a single signed 64-bit value to the stream.
@param v - value read to write to the stream
*/
void WriteI64(int64_t v) { return WriteU64((uint64_t)v); }
/*
public ZBinaryWriter::WriteI8Array
Writes an array of 8-bit signed values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
void WriteI8Array(const int8_t* v, size_t count) { return WriteU8Array((const uint8_t*)v, count); }
/*
public ZBinaryWriter::WriteI16Array
Writes an array of 16-bit signed values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
void WriteI16Array(const int16_t* v, size_t count) { return WriteU16Array((const uint16_t*)v, count); }
/*
public ZBinaryWriter::WriteI32Array
Writes an array of 32-bit signed values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
void WriteI32Array(const int32_t* v, size_t count) { return WriteU32Array((const uint32_t*)v, count); }
/*
public ZBinaryWriter::WriteI64Array
Writes an array of 64-bit signed values to the stream.
@param v - The base of the array
@param count - Number of elements to write
@return (void)
*/
void WriteI64Array(const int64_t* v, size_t count) { return WriteU64Array((const uint64_t*)v, count); }
//=====================================================================
//GETTERS / SETTERS
//=====================================================================
/*
public ZBinaryReader::GetStreamByteOrder
Gets the byte order in which the stream (source data) is read as.
@return (SST_ByteOrder) - The byte order
*/
SST_ByteOrder GetStreamByteOrder() const { return streamByteOrder; }
/*
public ZBinaryReader::SetStreamByteOrder
Sets the byte order in which the stream (source data) is read as.
@param newOrder - The new byte order
@return (void)
*/
void SetStreamByteOrder(SST_ByteOrder newOrder) { streamByteOrder = newOrder; }
private:
SST_ByteOrder streamByteOrder; //The current byte order the stream is being read in.
};
#endif

253
Include/ZUtil/ZBitmap.hpp Normal file
View File

@@ -0,0 +1,253 @@
/*
ZBitmap.hpp
Author: Chris Ertel <crertel@762studios.com>,
James Russell <jcrussell@762studios.com>
Created: 12/09/2010
Purpose:
Bitmap metadata class. This is designed as a metadata package for the data, and
does not assume ownership of the data. By passing around a ZBitmap instead of a raw
pointer to byte data we always have metadata about the byte data on hand.
License:
TODO
*/
#pragma once
#ifndef _ZBITMAP_H
#define _ZBITMAP_H
#include <ZUtil/ZUtilBuild.hpp>
//This is the format of the bitmap, which describes color layout and bits per channel
enum ZBitmapFormat
{
ZBF_UNKNOWN, //Unknown Format (usually uninitialized)
ZBF_R8, //8-bit Red Channel
ZBF_R8I, //8-bit Signed Red Channel
ZBF_R16, //16-bit Red Channel
ZBF_R16I, //16-bit Signed Red Channel
ZBF_R32, //32-bit Red Channel
ZBF_R32I, //32-bit Signed Red Channel
ZBF_R32F, //32-bit Floating Point Red Channel
ZBF_RG8, //8-bit Red, Green Channel
ZBF_RG8I, //8-bit Signed Red, Green Channel
ZBF_RG16, //16-bit Red, Green Channel
ZBF_RG16I, //16-bit Signed Red, Green Channel
ZBF_RG32, //32-bit Red, Green Channel
ZBF_RG32I, //32-bit Signed Red, Green Channel
ZBF_RG32F, //32-bit Floating Point Red, Green Channel
ZBF_RGB8, //8-bit Red, Green, Blue Channel
ZBF_RGB8I, //8-bit Signed Red, Green, Blue Channel
ZBF_RGB16, //16-bit Red, Green, Blue Channel
ZBF_RGB16I, //16-bit Signed Red, Green, Blue Channel
ZBF_RGB32, //32-bit Red, Green, Blue Channel
ZBF_RGB32I, //32-bit Signed Red, Green, Blue Channel
ZBF_RGB32F, //32-bit Floating Point Red, Green, Blue Channel
ZBF_RGBA8, //8-bit Red, Green, Blue, Alpha Channel
ZBF_RGBA8I, //8-bit Signed Red, Green, Blue, Alpha Channel
ZBF_RGBA16, //16-bit Red, Green, Blue, Alpha Channel
ZBF_RGBA16I, //16-bit Signed Red, Green, Blue, Alpha Channel
ZBF_RGBA32, //32-bit Red, Green, Blue, Alpha Channel
ZBF_RGBA32I, //32-bit Signed Red, Green, Blue, Alpha Channel
ZBF_RGBA32F, //32-bit Floating Point Red, Green, Blue, Alpha Channel
ZBF_BGR8, //8-bit Blue, Green, Red Channel
ZBF_BGR8I, //8-bit Signed Blue, Green, Red Channel
ZBF_BGR16, //16-bit Blue, Green, Red Channel
ZBF_BGR16I, //16-bit Signed Blue, Green, Red Channel
ZBF_BGR32, //32-bit Blue, Green, Red Channel
ZBF_BGR32I, //32-bit Signed Blue, Green, Red Channel
ZBF_BGR32F, //32-bit Floating Point Blue, Green, Red Channel
ZBF_BGRA8, //8-bit Blue, Green, Red, Alpha Channel
ZBF_BGRA8I, //8-bit Signed Blue, Green, Red, Alpha Channel
ZBF_BGRA16, //16-bit Blue, Green, Red, Alpha Channel
ZBF_BGRA16I, //16-bit Signed Blue, Green, Red, Alpha Channel
ZBF_BGRA32, //32-bit Blue, Green, Red, Alpha Channel
ZBF_BGRA32I, //32-bit Signed Blue, Green, Red, Alpha Channel
ZBF_BGRA32F, //32-bit Floating Point Blue, Green, Red, Alpha Channel
ZBF_DEPTH32, //32-bit Unsigned Depth
ZBCM_SIZE
};
/*
Bitmap data class.
*/
class ZBitmap
{
protected:
ZBitmapFormat Format; //Format of the bitmap
uint32_t Width; //Width of the bitmap
uint32_t Height; //Height of the bitmap
uint32_t Depth; //Depth of the bitmap
void* Data; //Pointer to the bitmap data (can be NULL)
public:
/*
Default Constructor
*/
ZBitmap()
: Format(ZBF_UNKNOWN),
Width(1),
Height(1),
Depth(1),
Data(NULL)
{ }
/*
Constructor.
@param _format - the bitmap format
@param _width - the width (pixels)
@param _height - the height (pixels)
*/
ZBitmap(ZBitmapFormat _format, uint32_t _width, uint32_t _height)
: Format(_format),
Width(_width),
Height(_height),
Depth(1),
Data(NULL)
{ }
/*
Constructor.
@param _format - the bitmap format
@param _width - the width (pixels)
@param _height - the height (pixels)
@param _depth - the depth (pixels)
*/
ZBitmap(ZBitmapFormat _format, uint32_t _width, uint32_t _height, uint32_t _depth)
: Format(_format),
Width(_width),
Height(_height),
Depth(_depth),
Data(NULL)
{ }
/*
Constructor.
@param _format - the bitmap format
@param _width - the width (pixels)
@param _height - the height (pixels)
@param _depth - the depth (pixels)
@param _data - the bitmap data
*/
ZBitmap(ZBitmapFormat _format, uint32_t _width, uint32_t _height, uint32_t _depth, void* _data)
: Format(_format),
Width(_width),
Height(_height),
Depth(_depth),
Data(_data)
{ }
//Determines (based off Format) the Bits Per Pixel of this bitmap
size_t GetBPP() const
{
switch(Format)
{
case ZBF_R8: return 8;
case ZBF_R8I: return 8;
case ZBF_R16: return 16;
case ZBF_R16I: return 16;
case ZBF_R32: return 32;
case ZBF_R32I: return 32;
case ZBF_R32F: return 32;
case ZBF_RG8: return 16;
case ZBF_RG8I: return 16;
case ZBF_RG16: return 32;
case ZBF_RG16I: return 32;
case ZBF_RG32: return 64;
case ZBF_RG32I: return 64;
case ZBF_RG32F: return 64;
case ZBF_RGB8: return 24;
case ZBF_RGB8I: return 24;
case ZBF_RGB16: return 48;
case ZBF_RGB16I: return 48;
case ZBF_RGB32: return 96;
case ZBF_RGB32I: return 96;
case ZBF_RGB32F: return 96;
case ZBF_RGBA8: return 32;
case ZBF_RGBA8I: return 32;
case ZBF_RGBA16: return 64;
case ZBF_RGBA16I: return 64;
case ZBF_RGBA32: return 128;
case ZBF_RGBA32I: return 128;
case ZBF_RGBA32F: return 128;
case ZBF_BGR8: return 24;
case ZBF_BGR8I: return 24;
case ZBF_BGR16: return 48;
case ZBF_BGR16I: return 48;
case ZBF_BGR32: return 96;
case ZBF_BGR32I: return 96;
case ZBF_BGR32F: return 96;
case ZBF_BGRA8: return 32;
case ZBF_BGRA8I: return 32;
case ZBF_BGRA16: return 64;
case ZBF_BGRA16I: return 64;
case ZBF_BGRA32: return 128;
case ZBF_BGRA32I: return 128;
case ZBF_BGRA32F: return 128;
default: return 0;
}
}
//Determines (based off of Width, Height, and Depth) the dimension of this bitmap (1, 2, or 3, 0 if inconsistent values)
size_t GetDimension() const
{
if (Width > 1 && Height > 1 && Depth > 1)
return 3;
else if (Width > 1 && Height > 1 && Depth <= 1)
return 2;
else if (Width > 1 && Height <= 1 && Depth <= 1)
return 1;
return 0;
}
//Computes and returns the size of the bitmap (in bytes)
size_t GetSize() const
{
return (Width * Depth * Height * GetBPP()) / 8;
}
//Getter and Settter for 'Format'
inline ZBitmapFormat GetFormat() const { return this->Format; }
inline void SetFormat(ZBitmapFormat _format) { this->Format = _format; }
//Getter and Setter for 'Width', in pixels
inline uint32_t GetWidth() const { return this->Width; }
inline void SetWidth(uint32_t _width) { this->Width = _width; }
//Getter and Setter for 'Height', in pixels
inline uint32_t GetHeight() const { return this->Height; }
inline void SetHeight(uint32_t _height) { this->Height = _height; }
//Getter and Setter for 'Depth', in pixels
inline uint32_t GetDepth() const { return this->Depth; }
inline void SetDepth(uint32_t _depth) { this->Depth = _depth; }
//Getter and Setter for 'Data'
inline void* GetData() const { return this->Data; }
inline void SetData(void* _data) { this->Data = _data; }
};
#endif

View File

@@ -0,0 +1,137 @@
/*
ZConcurrency.hpp
Author : James Russell, Patrick Baggett
Purpose : Provides a number of primitives for building concurrent programs. Each supported
platform has a separate implementation.
Changelog
1/24/11 - Creation (jcrussell)
3/17/11 - Major change to support events, mutexes, thread local storage, and semaphores. (ptbaggett)
*/
#pragma once
#ifndef _ZCONCURRENCY_HPP
#define _ZCONCURRENCY_HPP
#include <ZUtil/ZUtilBuild.hpp>
#include <ZUtil/ZSemaphore.hpp>
#include <ZUtil/ZMutex.hpp>
#include <ZUtil/ZEvent.hpp>
#include <ZUtil/ZReadWriteLock.hpp>
//Used to indicate an indefinite wait
#define ZWAIT_INFINITE (~((uint32_t)0))
//Typedef for a thread handle
typedef void* ZThreadHandle;
/*
ZEngine thread data, used as a context for threads. The fields here should not be accessed directly.
*/
struct ZThreadContext
{
//The handle to this thread
ZThreadHandle Thread;
//The id given to this thread. Unique, but may be reused after thread is destroyed
uint32_t ThreadId;
//The return status this thread exited with (invalid unless Thread == NULL)
int ThreadExitStatus;
//Default Constructor
ZThreadContext() { Invalidate(); }
//Returns if it's valid
bool IsValid() const { return Thread != NULL; }
//Marks a thread context as invalid
void Invalidate() { Thread = NULL; ThreadId = 0; ThreadExitStatus = 0; }
};
/*
Namespace used for static access to low-level thread functionality.
*/
namespace ZConcurrency
{
/*
ZThreadContext CreateThread()
Creates a thread instance that will begin running the provided function.
The thread context should be cleaned up with DestroyThread() after the
thread exits (use WaitThread() to ensure it is exited).
@param _func - function that the thread will execute. Should be of return type
int and take a void* as an argument.
@param _arg - the argument that is passed to the function.
@return (ZThreadContext) - thread context, used as a handle to the thread
*/
ZThreadContext CreateThread(int(*_func)(void*), void *_arg);
/*
void DestroyThread()
Frees memory associated with a thread context. This should only be called
after the thread is known to be dead (e.g. using WaitThread()). As implied
by the last comment, this does not kill the OS thread if it was already
running.
@param _context - Thread context to be cleaned up
@return (void)
*/
void DestroyThread(ZThreadContext& _context);
/*
void SleepThread()
Causes the calling thread to sleep for a minimum of the specified time (in ms).
@param _ms - the specified time to sleep (in ms)
@return (void)
*/
void SleepThread(uint32_t _ms);
/*
int GetThreadId()
Gets the thread ID of the calling thread.
@return (uint32_t) - int that is the thread id of the calling thread
*/
uint32_t GetThreadId();
/*
unsigned int GetTicks()
Gets the tick count since the last call to GetTicks.
@return (uint64_t) - the count (in ms) since program start.
*/
uint64_t GetTicks();
/*
int WaitThread()
Waits for a thread to terminate. This is the only way to ensure thread resources are
returned. The termination code from the thread is stored in the thread context.
@param _context - the handle returned from CreateThread (the termination code is stored here)
@return (bool) - true if the thread terminated, false otherwise
*/
bool WaitThread(ZThreadContext& _context);
/*
void YieldThread()
Causes the calling thread to yield execution to another thread.
@return (void)
*/
void YieldThread();
}
#endif

86
Include/ZUtil/ZEvent.hpp Normal file
View File

@@ -0,0 +1,86 @@
/*
ZEvent.hpp
Author: James Russell <jcrussell@762studios.com>
Purpose: RAII wrapper for SST_Event from libsst-concurrency.
Changelog
2011/11/27 - creation (jcrussell)
*/
#pragma once
#ifndef _ZEVENT_H
#define _ZEVENT_H
#include <ZUtil/ZUtilBuild.hpp>
#include <SST/SST_Event.h>
/*
Event class. Used to manage allocation and deallocation of events.
Cannot be copied or assigned, which prevents it from being used in stl-like containers.
*/
class ZEvent
{
private:
DISABLE_COPY_AND_ASSIGN(ZEvent);
//libsst Event
SST_Event Event;
public:
/*
Constructor. Creates an event from libsst-concurrency.
*/
ZEvent();
/*
Destructor. Frees our event from libsst-concurrency.
*/
~ZEvent();
/*
public ZSignal::Notify
Signals event, waking up all waiting threads. Until this event is reset, waiting threads will return.
@return (void)
@context (all)
*/
void Notify();
/*
public ZSignal::Reset
Signals reset, which causes threads that call Wait to block until signaled.
@return (void)
@context (all)
*/
void Reset();
/*
public ZSignal::Wait
Waits on a signal. Blocks until Signal is called.
@return (bool) - true if the event was signaled, false if returned before a signal (such as event not reset)
@context (all)
*/
bool Wait();
/*
public ZSignal::Wait
Waits on a signal for an amount of time.
@param _ms - the amount of time (in ms) to wait.
@return (bool) - true if the event was signaled, false if returned before a signal (event not reset our out of time).
@context (all)
*/
bool Wait(uint32_t _ms);
};
#endif

View File

@@ -0,0 +1,184 @@
/*
ZIniReader.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 4/27/2012
Purpose:
Parses INI file format in memory.
(File Begin)
# This is a commented line
; This is too
[SectionA]
Key1=Value1
Key2 =Value2
Key3= Value3
Key4 = Value4
[SectionB]
Key1 = Value1
...
(File End)
Comments must be on their own line. Sections must be unique to a file. Keys can be repeated,
but the final value seen is the value recorded.
ZIniReader class does no I/O - it merely parses in-memory representations.
The data structures it provides a read-only, but you can get a mutable copy of its data as
a ZRegistry object. The data above would be loaded into a registry with the following layout:
Root
|
+-> SectionA
| |
| +-> Key1 (Value1)
| +-> Key2 (Value2)
| +-> Key3 (Value3)
| +-> Key4 (Value4)
|
+-> SectionB
|
+-> Key1 (Value1)
License:
TODO
*/
#ifndef _ZINIREADER_HPP
#define _ZINIREADER_HPP
#include <ZUtil/ZKVTree.hpp>
/*
IniReader class.
*/
class ZIniReader
{
public:
/*
Default constructor.
*/
ZIniReader()
: ErrorMessage() { }
/*
Destructor.
*/
~ZIniReader()
{ ClearData(); }
/*
public ZIniReader::Read
Reads an INI file stored as a ZString.
@param _iniData - string holding the data of an ini file, which will be parsed
@return (bool) - True if successful, false if failure. Use GetErrorString() to get the message
*/
bool Read(const ZString& _iniData)
{ return Read(_iniData.Data(), _iniData.Length()); }
/*
public ZIniReader::Read
Reads an INI file stored as memory block
@param data - Pointer to INI data
@param length - Length of INI data
@return (bool) - true if successful, false if failure (use GetErrorString() to get the message)
*/
bool Read(const char* data, size_t length);
/*
public ZIniReader::GetErrorString
Gets the error message generated while loading the data if loading failed. If loading
the data was successful, this returns an empty string.
@return (const ZString&) - error message string
*/
const ZString& GetErrorString()
{ return ErrorMessage; }
/*
public ZIniReader::GetSection
Looks up a section by name and returns a pointer to the ZHashMap object. If the
section does not exist, NULL is returned. The hashmap contains a list of key-value pairs
found for that section
@param sectionName - The name of the section
@return (const ZHashMap<ZString, ZString>*) - The section, or NULL if it does not exist
*/
const ZHashMap<ZString, ZString>* GetSection(const ZString& sectionName);
/*
public ZIniReader::GetSection
Looks up a section by ordinal and returns a pointer to the ZHashMap object. Sections
are given in order of appearance in the file. The hashmap contains a list of key-value pairs
found for that section.
@param index - The index of the section, between 0 and GetSectionCount() - 1
@return (const ZHashMap<ZString, ZString>*) - The section
*/
const ZHashMap<ZString, ZString>* GetSection(size_t index)
{ return Sections[index]; }
/*
public ZIniReader::GetSectionCount
Gets the number of sections parsed. If Read() returned true, this will be at least one.
@return (size_t) - The number of sections parsed.
*/
size_t GetSectionCount()
{ return Sections.Size(); }
/*
public ZIniReader::GetSectionName
Gets the name for a section by ordinal. Sections names are given in order of appearance
in the file.
@param index - The index of the section, between 0 and GetSectionCount()-1
@return (const ZString&) - The section name
*/
const ZString& GetSectionName(size_t index)
{ return SectionNames[index]; }
/*
public ZIniReader::GetKVTree
Populates a ZKVTree using the read values. If loading the data has failed,
no data is entered.
To get values in the kv-tree, use the path string 'Section.Key'.
@param _kvtree - the kv-tree to contain the parsed ini values
@return (void)
*/
void GetKVTree(ZKVTree& _kvtree);
private:
DISABLE_COPY_AND_ASSIGN(ZIniReader);
ZString ErrorMessage; // Error Message (if an error has happened)
ZHashMap<ZString, ZHashMap<ZString, ZString>*> StringSectionMap; // String -> Hashmap table
ZArray<ZHashMap<ZString, ZString>*> Sections; // Linear order in which sections were found
ZArray<ZString> SectionNames; // Name of sections parsed
void SetError(const char* message, uint32_t line); // Sets the error message
void ClearData(); // Clears previously read section data
};
#endif

View File

@@ -0,0 +1,69 @@
/*
ZIniWriter.hpp
Author: James Russell <jcrussell@762studios.com>
Created: 5/6/2012
Purpose:
The 'inverse' of ZIniReader, this will take a kvtree of values (like the one given by
ZIniReader) and write to an output string in the .ini format specified in ZIniReader.hpp.
License:
TODO
*/
#pragma once
#ifndef _ZINIWRITER_HPP
#define _ZINIWRITER_HPP
#include <ZUtil/ZKVTree.hpp>
#include <ZUtil/ZSmartPointer.hpp>
/*
IniWriter class.
*/
class ZIniWriter
{
public:
/*
Default Constructor.
*/
ZIniWriter() { }
/*
Destructor.
*/
~ZIniWriter() { }
/*
public ZIniWriter::GetErrorString
Gets the error message generated while writing the data if writing failed. If writing
the data was successful, this returns an empty string.
@return (const ZString&)
*/
const ZString& GetErrorString();
/*
public ZIniWriter::Write
Writes the data from the provided kvtree into the provided output string in the 'ini' format.
@param _input - the tree to read values from
@param _output - the string to write the data into (the data is appended)
@return (bool) - true if successful, false otherwise
*/
bool Write(const ZKVTree& _input, ZString& _output);
private:
DISABLE_COPY_AND_ASSIGN(ZIniWriter);
//Error message (if an error has happened)
ZString ErrorMessage;
};
#endif

View File

@@ -0,0 +1,69 @@
/*
ZJSONReader.hpp
Author: Chris Ertel <crertel@762studios.com>
Created: 3/26/2013
Purpose:
JSON reading support, to convert JSON strings into ZKVTrees.
License:
TODO
*/
#pragma once
#ifndef _ZJSONREADER_H
#define _ZJSONREADER_H
#include <ZUtil/ZKVTree.hpp>
#include <ZUtil/ZSmartPointer.hpp>
/*
ZJSONReader class, which converts JSON data into a ZKVTree that can be used to access / iterate
the data.
*/
class ZJSONReader
{
private:
DISABLE_COPY_AND_ASSIGN(ZJSONReader);
//Error Message (if an error has happened)
ZString ErrorMessage;
const ZString JSONData;
//Registry of data
ZPtr<ZKVTree> Registry;
public:
/*
Parameterized Constructor.
@param _jsonData - string containing JSON data to parse
*/
ZJSONReader(const ZString& _jsonData);
/*
public ZJSONReader::GetErrorString
Gets the error message generated while loading the data if loading failed. If loading
the data was successful, this returns an empty string.
@return (const ZString&) - error message string
*/
const ZString& GetErrorString();
/*
public ZJSONReader::GetKVTree
Gets the registry that was constructed from the parsed JSON data. If the loading failed,
the pointer returned is NULL.
TODO - describe the format
@return (ZPtr<ZRegistry>) - registry containing the parsed JSON data
*/
ZPtr<ZKVTree> GetKVTree();
};
#endif

View File

@@ -0,0 +1,64 @@
/*
ZJSONWriter.hpp
Author: Chris Ertel <crertel@762studios.com>
Created: 3/26/2013
Purpose:
JSON writing support, to convert ZKVTrees into JSON strings.
License:
TODO
*/
#pragma once
#ifndef _ZJSONWRITER_H
#define _ZJSONWRITER_H
#include <ZUtil/ZSmartPointer.hpp>
#include <ZUtil/ZKVTree.hpp>
class ZJSONWriter
{
private:
DISABLE_COPY_AND_ASSIGN(ZJSONWriter);
//Error message (if an error has happened)
ZString ErrorMessage;
//The registry we will be getting values from
ZPtr<ZKVTree> Registry;
const ZString NoError;
public:
/*
Parameterized Constructor.
@param _registry - the registry to generate XML data from
*/
ZJSONWriter(ZPtr<ZKVTree> _registry);
/*
public ZJSONWriter::GetErrorString
Gets the error message generated while writing the data if writing failed. If writing
the data was successful, this returns an empty string.
@return (const ZString&) - a string describing an error that occurred
*/
const ZString& GetErrorString();
/*
public ZJSONWriter::Write
Writes the data from the registry into the provided output string in XML format.
@param _output - the string to write the data into (the data is appended)
@return (bool) - true if successful, false otherwise
*/
bool Write(ZString& _output);
};
#endif

Some files were not shown because too many files have changed in this diff Show More