Initial commit
This commit is contained in:
137
Include/ZBuild.hpp
Normal file
137
Include/ZBuild.hpp
Normal 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
29
Include/ZNet/ZNet.hpp
Normal 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
|
||||
|
||||
57
Include/ZNet/ZNetBandwidthMeter.hpp
Normal file
57
Include/ZNet/ZNetBandwidthMeter.hpp
Normal 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
|
||||
|
||||
98
Include/ZNet/ZNetClient.hpp
Normal file
98
Include/ZNet/ZNetClient.hpp
Normal 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
|
||||
44
Include/ZNet/ZNetConsts.hpp
Normal file
44
Include/ZNet/ZNetConsts.hpp
Normal 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
|
||||
|
||||
45
Include/ZNet/ZNetEvent.hpp
Normal file
45
Include/ZNet/ZNetEvent.hpp
Normal 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
184
Include/ZNet/ZNetHost.hpp
Normal 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
|
||||
|
||||
46
Include/ZNet/ZNetPacket.hpp
Normal file
46
Include/ZNet/ZNetPacket.hpp
Normal 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
|
||||
|
||||
|
||||
165
Include/ZNet/ZNetPacketChannel.hpp
Normal file
165
Include/ZNet/ZNetPacketChannel.hpp
Normal 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
143
Include/ZNet/ZNetPeer.hpp
Normal 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
240
Include/ZNet/ZNetServer.hpp
Normal 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
49
Include/ZNet/ZNetUtil.hpp
Normal 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
|
||||
|
||||
|
||||
288
Include/ZRenderer/ZDataBuffer.hpp
Normal file
288
Include/ZRenderer/ZDataBuffer.hpp
Normal 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
|
||||
130
Include/ZRenderer/ZDataBufferBase.hpp
Normal file
130
Include/ZRenderer/ZDataBufferBase.hpp
Normal 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
|
||||
91
Include/ZRenderer/ZDimensionTexture.hpp
Normal file
91
Include/ZRenderer/ZDimensionTexture.hpp
Normal 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
|
||||
110
Include/ZRenderer/ZDimensionTextureBase.hpp
Normal file
110
Include/ZRenderer/ZDimensionTextureBase.hpp
Normal 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
|
||||
|
||||
62
Include/ZRenderer/ZDrawParams.hpp
Normal file
62
Include/ZRenderer/ZDrawParams.hpp
Normal 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
|
||||
|
||||
138
Include/ZRenderer/ZFrameBufferRenderTarget.hpp
Normal file
138
Include/ZRenderer/ZFrameBufferRenderTarget.hpp
Normal 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
|
||||
150
Include/ZRenderer/ZFrameBufferRenderTargetBase.hpp
Normal file
150
Include/ZRenderer/ZFrameBufferRenderTargetBase.hpp
Normal 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
|
||||
|
||||
163
Include/ZRenderer/ZIndexParams.hpp
Normal file
163
Include/ZRenderer/ZIndexParams.hpp
Normal 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
|
||||
98
Include/ZRenderer/ZOpenGLDataBuffer.hpp
Normal file
98
Include/ZRenderer/ZOpenGLDataBuffer.hpp
Normal 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
|
||||
262
Include/ZRenderer/ZOpenGLDimensionTexture.hpp
Normal file
262
Include/ZRenderer/ZOpenGLDimensionTexture.hpp
Normal 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
|
||||
53
Include/ZRenderer/ZOpenGLFrameBufferRenderTarget.hpp
Normal file
53
Include/ZRenderer/ZOpenGLFrameBufferRenderTarget.hpp
Normal 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
|
||||
|
||||
84
Include/ZRenderer/ZOpenGLRenderBuffer.hpp
Normal file
84
Include/ZRenderer/ZOpenGLRenderBuffer.hpp
Normal 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
|
||||
197
Include/ZRenderer/ZOpenGLRenderer.hpp
Normal file
197
Include/ZRenderer/ZOpenGLRenderer.hpp
Normal 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
|
||||
162
Include/ZRenderer/ZOpenGLSampler.hpp
Normal file
162
Include/ZRenderer/ZOpenGLSampler.hpp
Normal 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
|
||||
|
||||
66
Include/ZRenderer/ZOpenGLShader.hpp
Normal file
66
Include/ZRenderer/ZOpenGLShader.hpp
Normal 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
|
||||
69
Include/ZRenderer/ZOpenGLShaderProgram.hpp
Normal file
69
Include/ZRenderer/ZOpenGLShaderProgram.hpp
Normal 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
|
||||
92
Include/ZRenderer/ZOpenGLTextureRenderTarget.h
Normal file
92
Include/ZRenderer/ZOpenGLTextureRenderTarget.h
Normal 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
|
||||
46
Include/ZRenderer/ZOpenGLVertexParams.hpp
Normal file
46
Include/ZRenderer/ZOpenGLVertexParams.hpp
Normal 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
|
||||
60
Include/ZRenderer/ZOpenGLWindowRenderTarget.hpp
Normal file
60
Include/ZRenderer/ZOpenGLWindowRenderTarget.hpp
Normal 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
|
||||
71
Include/ZRenderer/ZRenderBuffer.hpp
Normal file
71
Include/ZRenderer/ZRenderBuffer.hpp
Normal 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
|
||||
114
Include/ZRenderer/ZRenderTarget.hpp
Normal file
114
Include/ZRenderer/ZRenderTarget.hpp
Normal 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
|
||||
559
Include/ZRenderer/ZRenderer.hpp
Normal file
559
Include/ZRenderer/ZRenderer.hpp
Normal 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
|
||||
259
Include/ZRenderer/ZRendererBase.hpp
Normal file
259
Include/ZRenderer/ZRendererBase.hpp
Normal 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
|
||||
49
Include/ZRenderer/ZRendererBuild.hpp
Normal file
49
Include/ZRenderer/ZRendererBuild.hpp
Normal 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
|
||||
|
||||
153
Include/ZRenderer/ZRendererResource.hpp
Normal file
153
Include/ZRenderer/ZRendererResource.hpp
Normal 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
|
||||
|
||||
192
Include/ZRenderer/ZSampler.hpp
Normal file
192
Include/ZRenderer/ZSampler.hpp
Normal 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
|
||||
98
Include/ZRenderer/ZSamplerBase.hpp
Normal file
98
Include/ZRenderer/ZSamplerBase.hpp
Normal 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
|
||||
|
||||
122
Include/ZRenderer/ZShader.hpp
Normal file
122
Include/ZRenderer/ZShader.hpp
Normal 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
|
||||
74
Include/ZRenderer/ZShaderBase.hpp
Normal file
74
Include/ZRenderer/ZShaderBase.hpp
Normal 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
|
||||
147
Include/ZRenderer/ZShaderParams.hpp
Normal file
147
Include/ZRenderer/ZShaderParams.hpp
Normal 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
|
||||
315
Include/ZRenderer/ZShaderProgram.hpp
Normal file
315
Include/ZRenderer/ZShaderProgram.hpp
Normal 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
|
||||
85
Include/ZRenderer/ZShaderProgramBase.hpp
Normal file
85
Include/ZRenderer/ZShaderProgramBase.hpp
Normal 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
|
||||
162
Include/ZRenderer/ZTexture.hpp
Normal file
162
Include/ZRenderer/ZTexture.hpp
Normal 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
|
||||
106
Include/ZRenderer/ZVertexParams.hpp
Normal file
106
Include/ZRenderer/ZVertexParams.hpp
Normal 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
|
||||
106
Include/ZRenderer/ZWindowRenderTarget.hpp
Normal file
106
Include/ZRenderer/ZWindowRenderTarget.hpp
Normal 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
|
||||
88
Include/ZRenderer/ZWindowRenderTargetBase.hpp
Normal file
88
Include/ZRenderer/ZWindowRenderTargetBase.hpp
Normal 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
|
||||
164
Include/ZRendererUtil/ZFontRenderer.hpp
Normal file
164
Include/ZRendererUtil/ZFontRenderer.hpp
Normal 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
|
||||
67
Include/ZRendererUtil/ZFontRendererBase.hpp
Normal file
67
Include/ZRendererUtil/ZFontRendererBase.hpp
Normal 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
|
||||
|
||||
126
Include/ZRendererUtil/ZOutlineEvaluator.hpp
Normal file
126
Include/ZRendererUtil/ZOutlineEvaluator.hpp
Normal 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
|
||||
140
Include/ZRendererUtil/ZParticleEffect.h
Normal file
140
Include/ZRendererUtil/ZParticleEffect.h
Normal 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
|
||||
|
||||
200
Include/ZRendererUtil/ZParticleEmitter.h
Normal file
200
Include/ZRendererUtil/ZParticleEmitter.h
Normal 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
|
||||
|
||||
80
Include/ZRendererUtil/ZParticleRenderStrategy.h
Normal file
80
Include/ZRendererUtil/ZParticleRenderStrategy.h
Normal 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
|
||||
|
||||
61
Include/ZRendererUtil/ZParticleSpawnStrategy.h
Normal file
61
Include/ZRendererUtil/ZParticleSpawnStrategy.h
Normal 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
|
||||
|
||||
82
Include/ZRendererUtil/ZParticleStorageAllocator.h
Normal file
82
Include/ZRendererUtil/ZParticleStorageAllocator.h
Normal 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
|
||||
|
||||
60
Include/ZRendererUtil/ZParticleUpdateStrategy.h
Normal file
60
Include/ZRendererUtil/ZParticleUpdateStrategy.h
Normal 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
|
||||
|
||||
145
Include/ZRendererUtil/ZPerspectiveCamera.hpp
Normal file
145
Include/ZRendererUtil/ZPerspectiveCamera.hpp
Normal 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;
|
||||
}
|
||||
};
|
||||
84
Include/ZRendererUtil/ZSolidFontFace.hpp
Normal file
84
Include/ZRendererUtil/ZSolidFontFace.hpp
Normal 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
|
||||
101
Include/ZRendererUtil/ZSolidFontRenderer.hpp
Normal file
101
Include/ZRendererUtil/ZSolidFontRenderer.hpp
Normal 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
|
||||
105
Include/ZRendererUtil/ZStandardParticleRenderStrategy.h
Normal file
105
Include/ZRendererUtil/ZStandardParticleRenderStrategy.h
Normal 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
|
||||
|
||||
218
Include/ZRendererUtil/ZStandardParticleSpawnStrategy.h
Normal file
218
Include/ZRendererUtil/ZStandardParticleSpawnStrategy.h
Normal 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
|
||||
|
||||
167
Include/ZRendererUtil/ZStandardParticleStorageAllocator.h
Normal file
167
Include/ZRendererUtil/ZStandardParticleStorageAllocator.h
Normal 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
|
||||
|
||||
97
Include/ZRendererUtil/ZStandardParticleUpdateStrategy.h
Normal file
97
Include/ZRendererUtil/ZStandardParticleUpdateStrategy.h
Normal 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
|
||||
|
||||
134
Include/ZRendererUtil/ZStaticMesh.hpp
Normal file
134
Include/ZRendererUtil/ZStaticMesh.hpp
Normal 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
|
||||
27
Include/ZRendererUtil/ZStaticMeshLoader.hpp
Normal file
27
Include/ZRendererUtil/ZStaticMeshLoader.hpp
Normal 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
|
||||
100
Include/ZRendererUtil/ZTessellator.hpp
Normal file
100
Include/ZRendererUtil/ZTessellator.hpp
Normal 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
|
||||
|
||||
64
Include/ZRendererUtil/ZTessellatorBase.hpp
Normal file
64
Include/ZRendererUtil/ZTessellatorBase.hpp
Normal 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
|
||||
|
||||
37
Include/ZRendererUtil/ZTransformHierarchy.hpp
Normal file
37
Include/ZRendererUtil/ZTransformHierarchy.hpp
Normal 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
|
||||
55
Include/ZRendererUtil/ZTriTessellator.hpp
Normal file
55
Include/ZRendererUtil/ZTriTessellator.hpp
Normal 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
|
||||
|
||||
379
Include/ZSimulation/ZEntity.hpp
Normal file
379
Include/ZSimulation/ZEntity.hpp
Normal 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
|
||||
|
||||
153
Include/ZSimulation/ZMessageStream.hpp
Normal file
153
Include/ZSimulation/ZMessageStream.hpp
Normal 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
|
||||
|
||||
165
Include/ZSimulation/ZNetworkEvent.hpp
Normal file
165
Include/ZSimulation/ZNetworkEvent.hpp
Normal 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
|
||||
82
Include/ZSimulation/ZNetworkRequest.hpp
Normal file
82
Include/ZSimulation/ZNetworkRequest.hpp
Normal 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
|
||||
181
Include/ZSimulation/ZNetworkService.hpp
Normal file
181
Include/ZSimulation/ZNetworkService.hpp
Normal 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
|
||||
114
Include/ZSimulation/ZNetworkUpdateStream.hpp
Normal file
114
Include/ZSimulation/ZNetworkUpdateStream.hpp
Normal 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
|
||||
454
Include/ZSimulation/ZPropertyBuffer.cpp
Normal file
454
Include/ZSimulation/ZPropertyBuffer.cpp
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
134
Include/ZSimulation/ZPropertyBuffer.hpp
Normal file
134
Include/ZSimulation/ZPropertyBuffer.hpp
Normal 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
|
||||
62
Include/ZSimulation/ZPropertyBufferUpdate.hpp
Normal file
62
Include/ZSimulation/ZPropertyBufferUpdate.hpp
Normal 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
|
||||
33
Include/ZSimulation/ZPropertyBufferUpdateQueue.hpp
Normal file
33
Include/ZSimulation/ZPropertyBufferUpdateQueue.hpp
Normal 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
|
||||
74
Include/ZSimulation/ZRemotePeer.hpp
Normal file
74
Include/ZSimulation/ZRemotePeer.hpp
Normal 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
|
||||
327
Include/ZSimulation/ZSimulation.hpp
Normal file
327
Include/ZSimulation/ZSimulation.hpp
Normal 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
|
||||
299
Include/ZSimulation/ZSimulationDefs.hpp
Normal file
299
Include/ZSimulation/ZSimulationDefs.hpp
Normal 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
|
||||
72
Include/ZSimulation/ZStringBuffer.hpp
Normal file
72
Include/ZSimulation/ZStringBuffer.hpp
Normal 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
161
Include/ZUtil/ZAlloc.hpp
Normal 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
|
||||
|
||||
205
Include/ZUtil/ZAllocWindow.hpp
Normal file
205
Include/ZUtil/ZAllocWindow.hpp
Normal 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
53
Include/ZUtil/ZAssert.hpp
Normal 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
|
||||
87
Include/ZUtil/ZBinaryBufferReader.hpp
Normal file
87
Include/ZUtil/ZBinaryBufferReader.hpp
Normal 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
|
||||
|
||||
78
Include/ZUtil/ZBinaryBufferWriter.hpp
Normal file
78
Include/ZUtil/ZBinaryBufferWriter.hpp
Normal 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
|
||||
|
||||
72
Include/ZUtil/ZBinaryFileReader.hpp
Normal file
72
Include/ZUtil/ZBinaryFileReader.hpp
Normal 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
|
||||
|
||||
68
Include/ZUtil/ZBinaryFileWriter.hpp
Normal file
68
Include/ZUtil/ZBinaryFileWriter.hpp
Normal 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
|
||||
|
||||
749
Include/ZUtil/ZBinaryReader.hpp
Normal file
749
Include/ZUtil/ZBinaryReader.hpp
Normal 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
|
||||
|
||||
279
Include/ZUtil/ZBinaryWriter.hpp
Normal file
279
Include/ZUtil/ZBinaryWriter.hpp
Normal 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
253
Include/ZUtil/ZBitmap.hpp
Normal 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
|
||||
137
Include/ZUtil/ZConcurrency.hpp
Normal file
137
Include/ZUtil/ZConcurrency.hpp
Normal 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
86
Include/ZUtil/ZEvent.hpp
Normal 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
|
||||
|
||||
184
Include/ZUtil/ZIniReader.hpp
Normal file
184
Include/ZUtil/ZIniReader.hpp
Normal 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
|
||||
|
||||
69
Include/ZUtil/ZIniWriter.hpp
Normal file
69
Include/ZUtil/ZIniWriter.hpp
Normal 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
|
||||
69
Include/ZUtil/ZJSONReader.hpp
Normal file
69
Include/ZUtil/ZJSONReader.hpp
Normal 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
|
||||
64
Include/ZUtil/ZJSONWriter.hpp
Normal file
64
Include/ZUtil/ZJSONWriter.hpp
Normal 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
Reference in New Issue
Block a user