mirror of
https://github.com/NoelFB/blah.git
synced 2024-11-25 16:18:57 +08:00
refactored graphics & streams into single files - easier to maintain & read
This commit is contained in:
parent
9c7d8a4418
commit
99595f265f
|
@ -11,30 +11,16 @@ add_library(blah
|
||||||
src/common.cpp
|
src/common.cpp
|
||||||
src/time.cpp
|
src/time.cpp
|
||||||
src/input.cpp
|
src/input.cpp
|
||||||
|
src/stream.cpp
|
||||||
src/graphics/batch.cpp
|
src/graphics.cpp
|
||||||
src/graphics/blend.cpp
|
|
||||||
src/graphics/material.cpp
|
|
||||||
src/graphics/mesh.cpp
|
|
||||||
src/graphics/renderpass.cpp
|
|
||||||
src/graphics/shader.cpp
|
|
||||||
src/graphics/spritefont.cpp
|
|
||||||
src/graphics/subtexture.cpp
|
|
||||||
src/graphics/target.cpp
|
|
||||||
src/graphics/texture.cpp
|
|
||||||
|
|
||||||
src/containers/str.cpp
|
src/containers/str.cpp
|
||||||
|
src/drawing/batch.cpp
|
||||||
|
src/drawing/spritefont.cpp
|
||||||
|
src/drawing/subtexture.cpp
|
||||||
src/images/aseprite.cpp
|
src/images/aseprite.cpp
|
||||||
src/images/font.cpp
|
src/images/font.cpp
|
||||||
src/images/image.cpp
|
src/images/image.cpp
|
||||||
src/images/packer.cpp
|
src/images/packer.cpp
|
||||||
|
|
||||||
src/streams/bufferstream.cpp
|
|
||||||
src/streams/filestream.cpp
|
|
||||||
src/streams/memorystream.cpp
|
|
||||||
src/streams/stream.cpp
|
|
||||||
|
|
||||||
src/internal/renderer_opengl.cpp
|
src/internal/renderer_opengl.cpp
|
||||||
src/internal/renderer_d3d11.cpp
|
src/internal/renderer_d3d11.cpp
|
||||||
src/internal/platform_sdl2.cpp
|
src/internal/platform_sdl2.cpp
|
||||||
|
|
|
@ -5,22 +5,16 @@
|
||||||
#include "blah/filesystem.h"
|
#include "blah/filesystem.h"
|
||||||
#include "blah/time.h"
|
#include "blah/time.h"
|
||||||
#include "blah/input.h"
|
#include "blah/input.h"
|
||||||
|
#include "blah/stream.h"
|
||||||
|
#include "blah/graphics.h"
|
||||||
|
|
||||||
#include "blah/containers/vector.h"
|
#include "blah/containers/vector.h"
|
||||||
#include "blah/containers/stackvector.h"
|
#include "blah/containers/stackvector.h"
|
||||||
#include "blah/containers/str.h"
|
#include "blah/containers/str.h"
|
||||||
|
|
||||||
#include "blah/graphics/batch.h"
|
#include "blah/drawing/batch.h"
|
||||||
#include "blah/graphics/spritefont.h"
|
#include "blah/drawing/spritefont.h"
|
||||||
#include "blah/graphics/subtexture.h"
|
#include "blah/drawing/subtexture.h"
|
||||||
#include "blah/graphics/blend.h"
|
|
||||||
#include "blah/graphics/material.h"
|
|
||||||
#include "blah/graphics/mesh.h"
|
|
||||||
#include "blah/graphics/renderpass.h"
|
|
||||||
#include "blah/graphics/sampler.h"
|
|
||||||
#include "blah/graphics/shader.h"
|
|
||||||
#include "blah/graphics/target.h"
|
|
||||||
#include "blah/graphics/texture.h"
|
|
||||||
|
|
||||||
#include "blah/images/aseprite.h"
|
#include "blah/images/aseprite.h"
|
||||||
#include "blah/images/font.h"
|
#include "blah/images/font.h"
|
||||||
|
@ -31,8 +25,3 @@
|
||||||
#include "blah/math/spatial.h"
|
#include "blah/math/spatial.h"
|
||||||
#include "blah/math/color.h"
|
#include "blah/math/color.h"
|
||||||
#include "blah/math/ease.h"
|
#include "blah/math/ease.h"
|
||||||
|
|
||||||
#include "blah/streams/bufferstream.h"
|
|
||||||
#include "blah/streams/filestream.h"
|
|
||||||
#include "blah/streams/memorystream.h"
|
|
||||||
#include "blah/streams/stream.h"
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/common.h>
|
#include <blah/common.h>
|
||||||
|
#include <blah/graphics.h>
|
||||||
#include <blah/math/spatial.h>
|
#include <blah/math/spatial.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
|
@ -10,31 +11,6 @@ namespace Blah
|
||||||
// Application Logging Functions
|
// Application Logging Functions
|
||||||
using AppLogFn = Func<void, const char*, Log::Category>;
|
using AppLogFn = Func<void, const char*, Log::Category>;
|
||||||
|
|
||||||
// Type of Renderer the Application is using
|
|
||||||
enum class RendererType
|
|
||||||
{
|
|
||||||
None = -1,
|
|
||||||
OpenGL,
|
|
||||||
D3D11,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Renderer Information
|
|
||||||
struct RendererInfo
|
|
||||||
{
|
|
||||||
// The type of Renderer being used
|
|
||||||
RendererType type = RendererType::None;
|
|
||||||
|
|
||||||
// Whether Mesh Instancing is available
|
|
||||||
bool instancing = false;
|
|
||||||
|
|
||||||
// Whether the Texture origin is the bottom left.
|
|
||||||
// This is true for OpenGL.
|
|
||||||
bool origin_bottom_left = false;
|
|
||||||
|
|
||||||
// Maximum Texture Size available
|
|
||||||
int max_texture_size = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Application Configuration
|
// Application Configuration
|
||||||
struct Config
|
struct Config
|
||||||
{
|
{
|
||||||
|
@ -84,10 +60,6 @@ namespace Blah
|
||||||
AppLogFn on_log = nullptr;
|
AppLogFn on_log = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward declare Target for the BackBuffer
|
|
||||||
class Target;
|
|
||||||
using TargetRef = Ref<Target>;
|
|
||||||
|
|
||||||
// Application
|
// Application
|
||||||
namespace App
|
namespace App
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
|
#include <blah/drawing/spritefont.h>
|
||||||
|
#include <blah/drawing/subtexture.h>
|
||||||
#include <blah/math/spatial.h>
|
#include <blah/math/spatial.h>
|
||||||
#include <blah/math/color.h>
|
#include <blah/math/color.h>
|
||||||
#include <blah/graphics/subtexture.h>
|
#include <blah/graphics.h>
|
||||||
#include <blah/graphics/spritefont.h>
|
|
||||||
#include <blah/containers/vector.h>
|
|
||||||
#include <blah/graphics/blend.h>
|
|
||||||
#include <blah/graphics/sampler.h>
|
|
||||||
#include <blah/graphics/renderpass.h>
|
|
||||||
#include <blah/app.h>
|
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -235,6 +232,6 @@ namespace Blah
|
||||||
Vector<DrawBatch> m_batches;
|
Vector<DrawBatch> m_batches;
|
||||||
int m_batch_insert = 0;
|
int m_batch_insert = 0;
|
||||||
|
|
||||||
void render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4f& matrix);
|
void render_single_batch(DrawCall& pass, const DrawBatch& b, const Mat4x4f& matrix);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -2,10 +2,8 @@
|
||||||
#include <blah/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/graphics/subtexture.h>
|
#include <blah/drawing/subtexture.h>
|
||||||
#include <blah/images/font.h>
|
#include <blah/images/font.h>
|
||||||
#include <blah/math/spatial.h>
|
|
||||||
#include <blah/filesystem.h>
|
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/graphics/texture.h>
|
#include <blah/graphics.h>
|
||||||
#include <blah/math/spatial.h>
|
#include <blah/math/spatial.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
|
@ -42,6 +42,9 @@ namespace Blah
|
||||||
// Default Destructor
|
// Default Destructor
|
||||||
virtual ~File() = default;
|
virtual ~File() = default;
|
||||||
|
|
||||||
|
// Gets the Mode the File was opened with
|
||||||
|
FileMode mode() const;
|
||||||
|
|
||||||
// Gets the File Length
|
// Gets the File Length
|
||||||
virtual size_t length() = 0;
|
virtual size_t length() = 0;
|
||||||
|
|
||||||
|
@ -52,10 +55,13 @@ namespace Blah
|
||||||
virtual size_t seek(size_t position) = 0;
|
virtual size_t seek(size_t position) = 0;
|
||||||
|
|
||||||
// Reads from the File into the buffer, and returns how many bytes were successfully read
|
// Reads from the File into the buffer, and returns how many bytes were successfully read
|
||||||
virtual size_t read(unsigned char* buffer, size_t length) = 0;
|
virtual size_t read(void* buffer, size_t length) = 0;
|
||||||
|
|
||||||
// Writes from the buffer into the File, nd returns how many bytes were successfully written
|
// Writes from the buffer into the File, nd returns how many bytes were successfully written
|
||||||
virtual size_t write(const unsigned char* buffer, size_t length) = 0;
|
virtual size_t write(const void* buffer, size_t length) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileMode m_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Directory
|
namespace Directory
|
||||||
|
|
663
include/blah/graphics.h
Normal file
663
include/blah/graphics.h
Normal file
|
@ -0,0 +1,663 @@
|
||||||
|
#pragma once
|
||||||
|
#include <blah/common.h>
|
||||||
|
#include <blah/containers/vector.h>
|
||||||
|
#include <blah/containers/stackvector.h>
|
||||||
|
#include <blah/containers/str.h>
|
||||||
|
#include <blah/math/spatial.h>
|
||||||
|
#include <blah/images/image.h>
|
||||||
|
#include <blah/stream.h>
|
||||||
|
|
||||||
|
namespace Blah
|
||||||
|
{
|
||||||
|
class Shader; using ShaderRef = Ref<Shader>;
|
||||||
|
class Texture; using TextureRef = Ref<Texture>;
|
||||||
|
class Target; using TargetRef = Ref<Target>;
|
||||||
|
class Mesh; using MeshRef = Ref<Mesh>;
|
||||||
|
class Material; using MaterialRef = Ref<Material>;
|
||||||
|
|
||||||
|
// Type of Renderer the Application is using
|
||||||
|
enum class RendererType
|
||||||
|
{
|
||||||
|
None = -1,
|
||||||
|
OpenGL,
|
||||||
|
D3D11,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Renderer Information
|
||||||
|
struct RendererInfo
|
||||||
|
{
|
||||||
|
// The type of Renderer being used
|
||||||
|
RendererType type = RendererType::None;
|
||||||
|
|
||||||
|
// Whether Mesh Instancing is available
|
||||||
|
bool instancing = false;
|
||||||
|
|
||||||
|
// Whether the Texture origin is the bottom left.
|
||||||
|
// This is true for OpenGL.
|
||||||
|
bool origin_bottom_left = false;
|
||||||
|
|
||||||
|
// Maximum Texture Size available
|
||||||
|
int max_texture_size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Depth comparison function to use during a draw call
|
||||||
|
enum class Compare
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Always,
|
||||||
|
Never,
|
||||||
|
Less,
|
||||||
|
Equal,
|
||||||
|
LessOrEqual,
|
||||||
|
Greater,
|
||||||
|
NotEqual,
|
||||||
|
GreatorOrEqual
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cull mode during a draw call
|
||||||
|
enum class Cull
|
||||||
|
{
|
||||||
|
// No Culling enabled
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
// Cull front faces
|
||||||
|
Front = 1,
|
||||||
|
|
||||||
|
// Cull back faces
|
||||||
|
Back = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BlendOp
|
||||||
|
{
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
ReverseSubtract,
|
||||||
|
Min,
|
||||||
|
Max
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BlendFactor
|
||||||
|
{
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
SrcColor,
|
||||||
|
OneMinusSrcColor,
|
||||||
|
DstColor,
|
||||||
|
OneMinusDstColor,
|
||||||
|
SrcAlpha,
|
||||||
|
OneMinusSrcAlpha,
|
||||||
|
DstAlpha,
|
||||||
|
OneMinusDstAlpha,
|
||||||
|
ConstantColor,
|
||||||
|
OneMinusConstantColor,
|
||||||
|
ConstantAlpha,
|
||||||
|
OneMinusConstantAlpha,
|
||||||
|
SrcAlphaSaturate,
|
||||||
|
Src1Color,
|
||||||
|
OneMinusSrc1Color,
|
||||||
|
Src1Alpha,
|
||||||
|
OneMinusSrc1Alpha
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BlendMask
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Red = 1,
|
||||||
|
Green = 2,
|
||||||
|
Blue = 4,
|
||||||
|
Alpha = 8,
|
||||||
|
RGB = Red | Green | Blue,
|
||||||
|
RGBA = Red | Green | Blue | Alpha,
|
||||||
|
};
|
||||||
|
|
||||||
|
// BlendMode using for rendering
|
||||||
|
struct BlendMode
|
||||||
|
{
|
||||||
|
// Normal, pre-multiplied, Blend Mode
|
||||||
|
static const BlendMode Normal;
|
||||||
|
|
||||||
|
// Subtractive Blend Mode
|
||||||
|
static const BlendMode Subtract;
|
||||||
|
|
||||||
|
BlendOp color_op;
|
||||||
|
BlendFactor color_src;
|
||||||
|
BlendFactor color_dst;
|
||||||
|
BlendOp alpha_op;
|
||||||
|
BlendFactor alpha_src;
|
||||||
|
BlendFactor alpha_dst;
|
||||||
|
BlendMask mask;
|
||||||
|
u32 rgba;
|
||||||
|
|
||||||
|
BlendMode() = default;
|
||||||
|
|
||||||
|
BlendMode(BlendOp op, BlendFactor src, BlendFactor dst) :
|
||||||
|
color_op(op), color_src(src), color_dst(dst),
|
||||||
|
alpha_op(op), alpha_src(src), alpha_dst(dst),
|
||||||
|
mask(BlendMask::RGBA), rgba(0xffffffff) {}
|
||||||
|
|
||||||
|
BlendMode(
|
||||||
|
BlendOp color_op, BlendFactor color_src, BlendFactor color_dst,
|
||||||
|
BlendOp alpha_op, BlendFactor alpha_src, BlendFactor alpha_dst,
|
||||||
|
BlendMask blend_mask, u32 blend_rgba) :
|
||||||
|
color_op(color_op), color_src(color_src), color_dst(color_dst),
|
||||||
|
alpha_op(alpha_op), alpha_src(alpha_src), alpha_dst(alpha_dst),
|
||||||
|
mask(blend_mask), rgba(blend_rgba) {}
|
||||||
|
|
||||||
|
constexpr bool operator==(const BlendMode& rhs) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
color_op == rhs.color_op && color_src == rhs.color_src && color_dst == rhs.color_dst &&
|
||||||
|
alpha_op == rhs.alpha_op && alpha_src == rhs.alpha_src && alpha_dst == rhs.alpha_dst &&
|
||||||
|
mask == rhs.mask && rgba == rhs.rgba;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator!=(const BlendMode& rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Texture filter
|
||||||
|
enum class TextureFilter
|
||||||
|
{
|
||||||
|
None, // Will fallback to whatever default the driver sets
|
||||||
|
Linear, // Linear interpolation
|
||||||
|
Nearest // Nearest Neighbour interpolation
|
||||||
|
};
|
||||||
|
|
||||||
|
// Texture Wrap Mode
|
||||||
|
enum class TextureWrap
|
||||||
|
{
|
||||||
|
None, // Will fallback to whatever default the driver sets
|
||||||
|
Clamp, // Clamps the texture to the edges
|
||||||
|
Repeat // Repeats the texture
|
||||||
|
};
|
||||||
|
|
||||||
|
// Texture Sampler State, applied during rendering
|
||||||
|
struct TextureSampler
|
||||||
|
{
|
||||||
|
// Filter Mode
|
||||||
|
TextureFilter filter;
|
||||||
|
|
||||||
|
// Wrap X Mode
|
||||||
|
TextureWrap wrap_x;
|
||||||
|
|
||||||
|
// Wrap Y Mode
|
||||||
|
TextureWrap wrap_y;
|
||||||
|
|
||||||
|
TextureSampler() :
|
||||||
|
filter(TextureFilter::Linear), wrap_x(TextureWrap::Repeat), wrap_y(TextureWrap::Repeat) {}
|
||||||
|
|
||||||
|
TextureSampler(TextureFilter filter) :
|
||||||
|
filter(filter), wrap_x(TextureWrap::Repeat), wrap_y(TextureWrap::Repeat) {}
|
||||||
|
|
||||||
|
TextureSampler(TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y) :
|
||||||
|
filter(filter), wrap_x(wrap_x), wrap_y(wrap_y) {}
|
||||||
|
|
||||||
|
bool operator==(const TextureSampler& rhs) const
|
||||||
|
{
|
||||||
|
return filter == rhs.filter && wrap_x == rhs.wrap_x && wrap_y == rhs.wrap_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const TextureSampler& rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TextureFormat
|
||||||
|
{
|
||||||
|
None, // Invalid Format
|
||||||
|
R, // Single 8-bit channe;
|
||||||
|
RG, // 2 8-bit channels
|
||||||
|
RGBA, // 4 8-bit channels
|
||||||
|
DepthStencil, // Depth 24, Stencil 8
|
||||||
|
Count // Total Formats
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ClearMask
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Color = 1,
|
||||||
|
Depth = 2,
|
||||||
|
Stencil = 4,
|
||||||
|
All = (int)Color | (int)Depth | (int)Stencil
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported Uniform Types
|
||||||
|
enum class UniformType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Float,
|
||||||
|
Float2,
|
||||||
|
Float3,
|
||||||
|
Float4,
|
||||||
|
Mat3x2,
|
||||||
|
Mat4x4,
|
||||||
|
Texture2D,
|
||||||
|
Sampler2D
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported Shader Types
|
||||||
|
enum class ShaderType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Vertex = 1 << 0,
|
||||||
|
Fragment = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uniform Info, provided by the Shader
|
||||||
|
struct UniformInfo
|
||||||
|
{
|
||||||
|
// Name of the Uniform
|
||||||
|
String name;
|
||||||
|
|
||||||
|
// The Value type of the Uniform
|
||||||
|
UniformType type;
|
||||||
|
|
||||||
|
// The Shader type the Uniform is a part of
|
||||||
|
ShaderType shader;
|
||||||
|
|
||||||
|
// Some rendering APIs have uniform buffers. The `buffer_index`
|
||||||
|
// specifies which buffer the uniform belongs to
|
||||||
|
int buffer_index;
|
||||||
|
|
||||||
|
// Array length of the Uniform (ex. a vec2[4] would be 4)
|
||||||
|
int array_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported Vertex value types
|
||||||
|
enum class VertexType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Float,
|
||||||
|
Float2,
|
||||||
|
Float3,
|
||||||
|
Float4,
|
||||||
|
Byte4,
|
||||||
|
UByte4,
|
||||||
|
Short2,
|
||||||
|
UShort2,
|
||||||
|
Short4,
|
||||||
|
UShort4
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vertex Attribute information
|
||||||
|
struct VertexAttribute
|
||||||
|
{
|
||||||
|
// Location / Attribute Index
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
// Vertex Type
|
||||||
|
VertexType type = VertexType::None;
|
||||||
|
|
||||||
|
// Whether the Vertex should be normalized (doesn't apply to Floats)
|
||||||
|
bool normalized = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vertex Format information.
|
||||||
|
// Holds a list of attributes and total stride per-vertex.
|
||||||
|
struct VertexFormat
|
||||||
|
{
|
||||||
|
// List of Attributes
|
||||||
|
StackVector<VertexAttribute, 16> attributes;
|
||||||
|
|
||||||
|
// Total size in bytes of each Vertex element
|
||||||
|
int stride = 0;
|
||||||
|
|
||||||
|
VertexFormat() = default;
|
||||||
|
VertexFormat(const StackVector<VertexAttribute, 16>& attributes, int stride = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported Vertex Index formats
|
||||||
|
enum class IndexFormat
|
||||||
|
{
|
||||||
|
// Indices are 16 bit unsigned integers
|
||||||
|
UInt16,
|
||||||
|
|
||||||
|
// Indices are 32 bit unsigned integers
|
||||||
|
UInt32
|
||||||
|
};
|
||||||
|
|
||||||
|
// Data to be passed to the shader to construct it
|
||||||
|
struct ShaderData
|
||||||
|
{
|
||||||
|
struct HLSL_Attribute
|
||||||
|
{
|
||||||
|
// Semantic Name
|
||||||
|
const char* semantic_name = nullptr;
|
||||||
|
|
||||||
|
// (optional) Semantic Index
|
||||||
|
int semantic_index = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vertex Shader Program data
|
||||||
|
String vertex;
|
||||||
|
|
||||||
|
// Fragment Shader Program data
|
||||||
|
String fragment;
|
||||||
|
|
||||||
|
// HLSL Attributes - required for D3D11
|
||||||
|
StackVector<HLSL_Attribute, 16> hlsl_attributes;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A shader used during Rendering
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Shader() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Copy / Moves not allowed
|
||||||
|
Shader(const Shader&) = delete;
|
||||||
|
Shader(Shader&&) = delete;
|
||||||
|
Shader& operator=(const Shader&) = delete;
|
||||||
|
Shader& operator=(Shader&&) = delete;
|
||||||
|
|
||||||
|
// Default Destructor
|
||||||
|
virtual ~Shader() = default;
|
||||||
|
|
||||||
|
// Creates a Shader with the given Shader Data.
|
||||||
|
// If the Shader creation fails, it will return an invalid ShaderRef.
|
||||||
|
static ShaderRef create(const ShaderData& data);
|
||||||
|
|
||||||
|
// Gets a list of Shader Uniforms from Shader
|
||||||
|
virtual Vector<UniformInfo>& uniforms() = 0;
|
||||||
|
|
||||||
|
// Gets a list of Shader Uniforms from Shader
|
||||||
|
virtual const Vector<UniformInfo>& uniforms() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A 2D Texture held by the GPU to be used during rendering
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Texture() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Copy / Moves not allowed
|
||||||
|
Texture(const Texture&) = delete;
|
||||||
|
Texture(Texture&&) = delete;
|
||||||
|
Texture& operator=(const Texture&) = delete;
|
||||||
|
Texture& operator=(Texture&&) = delete;
|
||||||
|
|
||||||
|
// Default Destructor
|
||||||
|
virtual ~Texture() = default;
|
||||||
|
|
||||||
|
// Creates a new Texture.
|
||||||
|
// If the Texture creation fails, it will return an invalid TextureRef.
|
||||||
|
static TextureRef create(const Image& image);
|
||||||
|
|
||||||
|
// Creates a new Texture.
|
||||||
|
// If image data is provided, it should be the full size of the texture.
|
||||||
|
// If the Texture creation fails, it will return an invalid TextureRef.
|
||||||
|
static TextureRef create(int width, int height, TextureFormat format, unsigned char* data = nullptr);
|
||||||
|
|
||||||
|
// Creates a new Texture from a Stream.
|
||||||
|
// If the Texture creation fails, it will return an invalid TextureRef.
|
||||||
|
static TextureRef create(Stream& stream);
|
||||||
|
|
||||||
|
// Creates a new Texture from a File.
|
||||||
|
// If the Texture creation fails, it will return an invalid TextureRef.
|
||||||
|
static TextureRef create(const FilePath& file);
|
||||||
|
|
||||||
|
// gets the width of the texture
|
||||||
|
virtual int width() const = 0;
|
||||||
|
|
||||||
|
// gets the height of the texture
|
||||||
|
virtual int height() const = 0;
|
||||||
|
|
||||||
|
// Gets the format of the Texture
|
||||||
|
virtual TextureFormat format() const = 0;
|
||||||
|
|
||||||
|
// Sets the data of the Texture.
|
||||||
|
// Note that the data should be the same format and size as the Texture. There is no row padding.
|
||||||
|
virtual void set_data(const u8* data) = 0;
|
||||||
|
|
||||||
|
// Sets the data of the Texture to the provided Color buffer.
|
||||||
|
// If the Texture Format is not RGBA, this won't do anything.
|
||||||
|
void set_data(const Color* data);
|
||||||
|
|
||||||
|
// Gets the data of the Texture.
|
||||||
|
// Note that the data will be written to in the same format as the Texture,
|
||||||
|
// and you should allocate enough space for the full texture. There is no row padding.
|
||||||
|
virtual void get_data(u8* data) = 0;
|
||||||
|
|
||||||
|
// Gets the data of the Texture.
|
||||||
|
// If the Texture Format is not RGBA, this won't do anything.
|
||||||
|
void get_data(Color* data);
|
||||||
|
|
||||||
|
// Returns true if the Texture is part of a FrameBuffer
|
||||||
|
virtual bool is_framebuffer() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Up to 4 color textures + 1 depth/stencil
|
||||||
|
using Attachments = StackVector<TextureRef, 5>;
|
||||||
|
using AttachmentFormats = StackVector<TextureFormat, 5>;
|
||||||
|
|
||||||
|
// Target is a 2D Buffer that can be drawn to.
|
||||||
|
// It can hold up to 4 color Textures, and 1 Depth/Stencil Texture.
|
||||||
|
class Target
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Target() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Copy / Moves not allowed
|
||||||
|
Target(const Target&) = delete;
|
||||||
|
Target(Target&&) = delete;
|
||||||
|
Target& operator=(const Target&) = delete;
|
||||||
|
Target& operator=(Target&&) = delete;
|
||||||
|
|
||||||
|
// Default Destructor
|
||||||
|
virtual ~Target() = default;
|
||||||
|
|
||||||
|
// Creates a new Target with a single Color texture
|
||||||
|
// If the Target creation fails, it will return an invalid TargetRef.
|
||||||
|
static TargetRef create(int width, int height);
|
||||||
|
|
||||||
|
// Creates a new Target with the given Texture Attachments. You must provide at least one Attachment.
|
||||||
|
// If the Target creation fails, it will return an invalid TargetRef.
|
||||||
|
static TargetRef create(int width, int height, const AttachmentFormats& textures);
|
||||||
|
|
||||||
|
// Gets the list of Attachments from the Target
|
||||||
|
virtual Attachments& textures() = 0;
|
||||||
|
|
||||||
|
// Gets the list of Attachments from the Target
|
||||||
|
virtual const Attachments& textures() const = 0;
|
||||||
|
|
||||||
|
// Gets the Attachment at a given index from the Target
|
||||||
|
TextureRef& texture(int index);
|
||||||
|
|
||||||
|
// Gets the Attachment at a given index from the Target
|
||||||
|
const TextureRef& texture(int index) const;
|
||||||
|
|
||||||
|
// Gets the width of the Target
|
||||||
|
virtual int width() const;
|
||||||
|
|
||||||
|
// Gets the height of the Target
|
||||||
|
virtual int height() const;
|
||||||
|
|
||||||
|
// Clears the Target
|
||||||
|
virtual void clear(Color color = Color::black, float depth = 1.0f, u8 stencil = 0, ClearMask mask = ClearMask::All) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A Mesh is a set of Indices and Vertices which are used for drawing
|
||||||
|
class Mesh
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Mesh() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Copy / Moves not allowed
|
||||||
|
Mesh(const Mesh&) = delete;
|
||||||
|
Mesh(Mesh&&) = delete;
|
||||||
|
Mesh& operator=(const Mesh&) = delete;
|
||||||
|
Mesh& operator=(Mesh&&) = delete;
|
||||||
|
|
||||||
|
// Default Destructor
|
||||||
|
virtual ~Mesh() = default;
|
||||||
|
|
||||||
|
// Creates a new Mesh.
|
||||||
|
// If the Mesh creation fails, it will return an invalid Mesh.
|
||||||
|
static MeshRef create();
|
||||||
|
|
||||||
|
// Uploads the given index buffer to the Mesh
|
||||||
|
virtual void index_data(IndexFormat format, const void* indices, i64 count) = 0;
|
||||||
|
|
||||||
|
// Uploads the given vertex buffer to the Mesh
|
||||||
|
virtual void vertex_data(const VertexFormat& format, const void* vertices, i64 count) = 0;
|
||||||
|
|
||||||
|
// Uploads the given instance buffer to the Mesh
|
||||||
|
virtual void instance_data(const VertexFormat& format, const void* instances, i64 count) = 0;
|
||||||
|
|
||||||
|
// Gets the index count of the Mesh
|
||||||
|
virtual i64 index_count() const = 0;
|
||||||
|
|
||||||
|
// Gets the vertex count of the Mesh
|
||||||
|
virtual i64 vertex_count() const = 0;
|
||||||
|
|
||||||
|
// Gets the instance count of the Mesh
|
||||||
|
virtual i64 instance_count() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Materials hold values that can be assigned to a shader during rendering
|
||||||
|
class Material final
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Material(const ShaderRef& shader);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Copy / Moves not allowed
|
||||||
|
Material(const Material&) = delete;
|
||||||
|
Material(Material&&) = delete;
|
||||||
|
Material& operator=(const Material&) = delete;
|
||||||
|
Material& operator=(Material&&) = delete;
|
||||||
|
|
||||||
|
// Default destructor
|
||||||
|
~Material() = default;
|
||||||
|
|
||||||
|
// Creates a new Material from the given Shader.
|
||||||
|
// If the Shader is invalid, it will return an invalid MaterialRef.
|
||||||
|
static MaterialRef create(const ShaderRef& shader);
|
||||||
|
|
||||||
|
// Clones the material and returns a new one
|
||||||
|
MaterialRef clone() const;
|
||||||
|
|
||||||
|
// Returns the Shader assigned to the Material.
|
||||||
|
ShaderRef shader() const;
|
||||||
|
|
||||||
|
// Sets the texture
|
||||||
|
void set_texture(const char* name, const TextureRef& texture, int array_index = 0);
|
||||||
|
|
||||||
|
// Sets the texture
|
||||||
|
void set_texture(int slot, const TextureRef& texture, int array_index = 0);
|
||||||
|
|
||||||
|
// Gets the texture, or an empty reference if invalid
|
||||||
|
TextureRef get_texture(const char* name, int array_index = 0) const;
|
||||||
|
|
||||||
|
// Gets the texture, or an empty reference if invalid
|
||||||
|
TextureRef get_texture(int slot, int array_index = 0) const;
|
||||||
|
|
||||||
|
// Sets the sampler
|
||||||
|
void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0);
|
||||||
|
|
||||||
|
// Sets the sampler
|
||||||
|
void set_sampler(int slot, const TextureSampler& sampler, int array_index = 0);
|
||||||
|
|
||||||
|
// Gets the sampler
|
||||||
|
TextureSampler get_sampler(const char* name, int array_index = 0) const;
|
||||||
|
|
||||||
|
// Gets the sampler
|
||||||
|
TextureSampler get_sampler(int slot, int array_index = 0) const;
|
||||||
|
|
||||||
|
// Sets the value. `length` is the total number of floats to set
|
||||||
|
// For example if the uniform is a float2[4], a total of 8 float values
|
||||||
|
// can be set.
|
||||||
|
void set_value(const char* name, const float* value, i64 length);
|
||||||
|
|
||||||
|
// Shorthands to more easily assign uniform values
|
||||||
|
void set_value(const char* name, float value);
|
||||||
|
void set_value(const char* name, const Vec2f& value);
|
||||||
|
void set_value(const char* name, const Vec3f& value);
|
||||||
|
void set_value(const char* name, const Vec4f& value);
|
||||||
|
void set_value(const char* name, const Mat3x2f& value);
|
||||||
|
void set_value(const char* name, const Mat4x4f& value);
|
||||||
|
void set_value(const char* name, const Vector<float>& value);
|
||||||
|
void set_value(const char* name, const Vector<Vec2f>& value);
|
||||||
|
void set_value(const char* name, const Vector<Vec3f>& value);
|
||||||
|
void set_value(const char* name, const Vector<Vec4f>& value);
|
||||||
|
void set_value(const char* name, const Vector<Mat3x2f>& value);
|
||||||
|
void set_value(const char* name, const Vector<Mat4x4f>& value);
|
||||||
|
|
||||||
|
// Gets a pointer to the values of the given Uniform, or nullptr if it doesn't exist.
|
||||||
|
const float* get_value(const char* name, i64* length = nullptr) const;
|
||||||
|
|
||||||
|
// Checks if the shader attached to the material has a uniform value with the given name
|
||||||
|
bool has_value(const char* name) const;
|
||||||
|
|
||||||
|
// Returns the internal Texture buffer
|
||||||
|
const Vector<TextureRef>& textures() const;
|
||||||
|
|
||||||
|
// Returns the internal Sampler buffer
|
||||||
|
const Vector<TextureSampler>& samplers() const;
|
||||||
|
|
||||||
|
// Returns the interal float buffer of all the values
|
||||||
|
const float* data() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ShaderRef m_shader;
|
||||||
|
Vector<TextureRef> m_textures;
|
||||||
|
Vector<TextureSampler> m_samplers;
|
||||||
|
Vector<float> m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A single draw call
|
||||||
|
struct DrawCall
|
||||||
|
{
|
||||||
|
// Framebuffer to draw to
|
||||||
|
TargetRef target;
|
||||||
|
|
||||||
|
// Mesh to draw with
|
||||||
|
MeshRef mesh;
|
||||||
|
|
||||||
|
// Material to draw with
|
||||||
|
MaterialRef material;
|
||||||
|
|
||||||
|
// Whether the DrawCall should use a specific viewport
|
||||||
|
bool has_viewport;
|
||||||
|
|
||||||
|
// Whether the DrawCall should use a scissor rectangle
|
||||||
|
bool has_scissor;
|
||||||
|
|
||||||
|
// The viewport (only used if hasViewport is true)
|
||||||
|
Rectf viewport;
|
||||||
|
|
||||||
|
// The scissor rectangle (only used if hasScissor is true)
|
||||||
|
Rectf scissor;
|
||||||
|
|
||||||
|
// First index in the Mesh to draw from
|
||||||
|
i64 index_start;
|
||||||
|
|
||||||
|
// Total amount of indices to draw from the Mesh
|
||||||
|
i64 index_count;
|
||||||
|
|
||||||
|
// Total amount of instances to draw from the Mesh
|
||||||
|
i64 instance_count;
|
||||||
|
|
||||||
|
// Depth Compare Function
|
||||||
|
Compare depth;
|
||||||
|
|
||||||
|
// Cull Mode
|
||||||
|
Cull cull;
|
||||||
|
|
||||||
|
// Blend Mode
|
||||||
|
BlendMode blend;
|
||||||
|
|
||||||
|
// Initializes a default DrawCall
|
||||||
|
DrawCall();
|
||||||
|
|
||||||
|
// Performs the render
|
||||||
|
void perform();
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,105 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/common.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
enum class BlendOp
|
|
||||||
{
|
|
||||||
Add,
|
|
||||||
Subtract,
|
|
||||||
ReverseSubtract,
|
|
||||||
Min,
|
|
||||||
Max
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BlendFactor
|
|
||||||
{
|
|
||||||
Zero,
|
|
||||||
One,
|
|
||||||
SrcColor,
|
|
||||||
OneMinusSrcColor,
|
|
||||||
DstColor,
|
|
||||||
OneMinusDstColor,
|
|
||||||
SrcAlpha,
|
|
||||||
OneMinusSrcAlpha,
|
|
||||||
DstAlpha,
|
|
||||||
OneMinusDstAlpha,
|
|
||||||
ConstantColor,
|
|
||||||
OneMinusConstantColor,
|
|
||||||
ConstantAlpha,
|
|
||||||
OneMinusConstantAlpha,
|
|
||||||
SrcAlphaSaturate,
|
|
||||||
Src1Color,
|
|
||||||
OneMinusSrc1Color,
|
|
||||||
Src1Alpha,
|
|
||||||
OneMinusSrc1Alpha
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BlendMask
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Red = 1,
|
|
||||||
Green = 2,
|
|
||||||
Blue = 4,
|
|
||||||
Alpha = 8,
|
|
||||||
RGB = Red | Green | Blue,
|
|
||||||
RGBA = Red | Green | Blue | Alpha,
|
|
||||||
};
|
|
||||||
|
|
||||||
// BlendMode using for rendering
|
|
||||||
struct BlendMode
|
|
||||||
{
|
|
||||||
// Normal, pre-multiplied, Blend Mode
|
|
||||||
static const BlendMode Normal;
|
|
||||||
|
|
||||||
// Subtractive Blend Mode
|
|
||||||
static const BlendMode Subtract;
|
|
||||||
|
|
||||||
BlendOp color_op;
|
|
||||||
BlendFactor color_src;
|
|
||||||
BlendFactor color_dst;
|
|
||||||
BlendOp alpha_op;
|
|
||||||
BlendFactor alpha_src;
|
|
||||||
BlendFactor alpha_dst;
|
|
||||||
BlendMask mask;
|
|
||||||
u32 rgba;
|
|
||||||
|
|
||||||
BlendMode() = default;
|
|
||||||
|
|
||||||
BlendMode(BlendOp op, BlendFactor src, BlendFactor dst) :
|
|
||||||
color_op(op),
|
|
||||||
color_src(src),
|
|
||||||
color_dst(dst),
|
|
||||||
alpha_op(op),
|
|
||||||
alpha_src(src),
|
|
||||||
alpha_dst(dst),
|
|
||||||
mask(BlendMask::RGBA),
|
|
||||||
rgba(0xffffffff) {}
|
|
||||||
|
|
||||||
BlendMode(
|
|
||||||
BlendOp color_op, BlendFactor color_src, BlendFactor color_dst,
|
|
||||||
BlendOp alpha_op, BlendFactor alpha_src, BlendFactor alpha_dst,
|
|
||||||
BlendMask blend_mask, u32 blend_rgba) :
|
|
||||||
color_op(color_op),
|
|
||||||
color_src(color_src),
|
|
||||||
color_dst(color_dst),
|
|
||||||
alpha_op(alpha_op),
|
|
||||||
alpha_src(alpha_src),
|
|
||||||
alpha_dst(alpha_dst),
|
|
||||||
mask(blend_mask),
|
|
||||||
rgba(blend_rgba) {}
|
|
||||||
|
|
||||||
bool operator==(const BlendMode& rhs) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
color_op == rhs.color_op && color_src == rhs.color_src && color_dst == rhs.color_dst &&
|
|
||||||
alpha_op == rhs.alpha_op && alpha_src == rhs.alpha_src && alpha_dst == rhs.alpha_dst &&
|
|
||||||
mask == rhs.mask && rgba == rhs.rgba;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const BlendMode& rhs) const
|
|
||||||
{
|
|
||||||
return !(*this == rhs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include <blah/graphics/texture.h>
|
|
||||||
#include <blah/graphics/shader.h>
|
|
||||||
#include <blah/graphics/sampler.h>
|
|
||||||
#include <blah/containers/vector.h>
|
|
||||||
#include <blah/math/spatial.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
class Material;
|
|
||||||
using MaterialRef = Ref<Material>;
|
|
||||||
|
|
||||||
// Materials hold values that can be assigned to a shader during rendering
|
|
||||||
class Material final
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Material(const ShaderRef& shader);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Copy / Moves not allowed
|
|
||||||
Material(const Material&) = delete;
|
|
||||||
Material(Material&&) = delete;
|
|
||||||
Material& operator=(const Material&) = delete;
|
|
||||||
Material& operator=(Material&&) = delete;
|
|
||||||
|
|
||||||
// Default destructor
|
|
||||||
~Material() = default;
|
|
||||||
|
|
||||||
// Creates a new Material from the given Shader.
|
|
||||||
// If the Shader is invalid, it will return an invalid MaterialRef.
|
|
||||||
static MaterialRef create(const ShaderRef& shader);
|
|
||||||
|
|
||||||
// Clones the material and returns a new one
|
|
||||||
MaterialRef clone() const;
|
|
||||||
|
|
||||||
// Returns the Shader assigned to the Material.
|
|
||||||
ShaderRef shader() const;
|
|
||||||
|
|
||||||
// Sets the texture
|
|
||||||
void set_texture(const char* name, const TextureRef& texture, int array_index = 0);
|
|
||||||
|
|
||||||
// Sets the texture
|
|
||||||
void set_texture(int slot, const TextureRef& texture, int array_index = 0);
|
|
||||||
|
|
||||||
// Gets the texture, or an empty reference if invalid
|
|
||||||
TextureRef get_texture(const char* name, int array_index = 0) const;
|
|
||||||
|
|
||||||
// Gets the texture, or an empty reference if invalid
|
|
||||||
TextureRef get_texture(int slot, int array_index = 0) const;
|
|
||||||
|
|
||||||
// Sets the sampler
|
|
||||||
void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0);
|
|
||||||
|
|
||||||
// Sets the sampler
|
|
||||||
void set_sampler(int slot, const TextureSampler& sampler, int array_index = 0);
|
|
||||||
|
|
||||||
// Gets the sampler
|
|
||||||
TextureSampler get_sampler(const char* name, int array_index = 0) const;
|
|
||||||
|
|
||||||
// Gets the sampler
|
|
||||||
TextureSampler get_sampler(int slot, int array_index = 0) const;
|
|
||||||
|
|
||||||
// Sets the value. `length` is the total number of floats to set
|
|
||||||
// For example if the uniform is a float2[4], a total of 8 float values
|
|
||||||
// can be set.
|
|
||||||
void set_value(const char* name, const float* value, i64 length);
|
|
||||||
|
|
||||||
// Shorthands to more easily assign uniform values
|
|
||||||
void set_value(const char* name, float value);
|
|
||||||
void set_value(const char* name, const Vec2f& value);
|
|
||||||
void set_value(const char* name, const Vec3f& value);
|
|
||||||
void set_value(const char* name, const Vec4f& value);
|
|
||||||
void set_value(const char* name, const Mat3x2f& value);
|
|
||||||
void set_value(const char* name, const Mat4x4f& value);
|
|
||||||
void set_value(const char* name, const Vector<float>& value);
|
|
||||||
void set_value(const char* name, const Vector<Vec2f>& value);
|
|
||||||
void set_value(const char* name, const Vector<Vec3f>& value);
|
|
||||||
void set_value(const char* name, const Vector<Vec4f>& value);
|
|
||||||
void set_value(const char* name, const Vector<Mat3x2f>& value);
|
|
||||||
void set_value(const char* name, const Vector<Mat4x4f>& value);
|
|
||||||
|
|
||||||
// Gets a pointer to the values of the given Uniform, or nullptr if it doesn't exist.
|
|
||||||
const float* get_value(const char* name, i64* length = nullptr) const;
|
|
||||||
|
|
||||||
// Checks if the shader attached to the material has a uniform value with the given name
|
|
||||||
bool has_value(const char* name) const;
|
|
||||||
|
|
||||||
// Returns the internal Texture buffer
|
|
||||||
const Vector<TextureRef>& textures() const;
|
|
||||||
|
|
||||||
// Returns the internal Sampler buffer
|
|
||||||
const Vector<TextureSampler>& samplers() const;
|
|
||||||
|
|
||||||
// Returns the interal float buffer of all the values
|
|
||||||
const float* data() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ShaderRef m_shader;
|
|
||||||
Vector<TextureRef> m_textures;
|
|
||||||
Vector<TextureSampler> m_samplers;
|
|
||||||
Vector<float> m_data;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include <blah/containers/stackvector.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
// Supported Vertex value types
|
|
||||||
enum class VertexType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Float,
|
|
||||||
Float2,
|
|
||||||
Float3,
|
|
||||||
Float4,
|
|
||||||
Byte4,
|
|
||||||
UByte4,
|
|
||||||
Short2,
|
|
||||||
UShort2,
|
|
||||||
Short4,
|
|
||||||
UShort4
|
|
||||||
};
|
|
||||||
|
|
||||||
// Vertex Attribute information
|
|
||||||
struct VertexAttribute
|
|
||||||
{
|
|
||||||
// Location / Attribute Index
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
// Vertex Type
|
|
||||||
VertexType type = VertexType::None;
|
|
||||||
|
|
||||||
// Whether the Vertex should be normalized (doesn't apply to Floats)
|
|
||||||
bool normalized = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Vertex Format information.
|
|
||||||
// Holds a list of attributes and total stride per-vertex.
|
|
||||||
struct VertexFormat
|
|
||||||
{
|
|
||||||
// List of Attributes
|
|
||||||
StackVector<VertexAttribute, 16> attributes;
|
|
||||||
|
|
||||||
// Total size in bytes of each Vertex element
|
|
||||||
int stride = 0;
|
|
||||||
|
|
||||||
VertexFormat() = default;
|
|
||||||
VertexFormat(const StackVector<VertexAttribute, 16>& attributes, int stride = 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Supported Vertex Index formats
|
|
||||||
enum class IndexFormat
|
|
||||||
{
|
|
||||||
// Indices are 16 bit unsigned integers
|
|
||||||
UInt16,
|
|
||||||
|
|
||||||
// Indices are 32 bit unsigned integers
|
|
||||||
UInt32
|
|
||||||
};
|
|
||||||
|
|
||||||
class Mesh;
|
|
||||||
using MeshRef = Ref<Mesh>;
|
|
||||||
|
|
||||||
// A Mesh is a set of Indices and Vertices which are used for drawing
|
|
||||||
class Mesh
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
Mesh() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Copy / Moves not allowed
|
|
||||||
Mesh(const Mesh&) = delete;
|
|
||||||
Mesh(Mesh&&) = delete;
|
|
||||||
Mesh& operator=(const Mesh&) = delete;
|
|
||||||
Mesh& operator=(Mesh&&) = delete;
|
|
||||||
|
|
||||||
// Default Destructor
|
|
||||||
virtual ~Mesh() = default;
|
|
||||||
|
|
||||||
// Creates a new Mesh.
|
|
||||||
// If the Mesh creation fails, it will return an invalid Mesh.
|
|
||||||
static MeshRef create();
|
|
||||||
|
|
||||||
// Uploads the given index buffer to the Mesh
|
|
||||||
virtual void index_data(IndexFormat format, const void* indices, i64 count) = 0;
|
|
||||||
|
|
||||||
// Uploads the given vertex buffer to the Mesh
|
|
||||||
virtual void vertex_data(const VertexFormat& format, const void* vertices, i64 count) = 0;
|
|
||||||
|
|
||||||
// Uploads the given instance buffer to the Mesh
|
|
||||||
virtual void instance_data(const VertexFormat& format, const void* instances, i64 count) = 0;
|
|
||||||
|
|
||||||
// Gets the index count of the Mesh
|
|
||||||
virtual i64 index_count() const = 0;
|
|
||||||
|
|
||||||
// Gets the vertex count of the Mesh
|
|
||||||
virtual i64 vertex_count() const = 0;
|
|
||||||
|
|
||||||
// Gets the instance count of the Mesh
|
|
||||||
virtual i64 instance_count() const = 0;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include <blah/math/spatial.h>
|
|
||||||
#include <blah/containers/str.h>
|
|
||||||
#include <blah/graphics/texture.h>
|
|
||||||
#include <blah/graphics/target.h>
|
|
||||||
#include <blah/graphics/mesh.h>
|
|
||||||
#include <blah/graphics/shader.h>
|
|
||||||
#include <blah/graphics/material.h>
|
|
||||||
#include <blah/graphics/blend.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
// Depth comparison function to use during a draw call
|
|
||||||
enum class Compare
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Always,
|
|
||||||
Never,
|
|
||||||
Less,
|
|
||||||
Equal,
|
|
||||||
LessOrEqual,
|
|
||||||
Greater,
|
|
||||||
NotEqual,
|
|
||||||
GreatorOrEqual
|
|
||||||
};
|
|
||||||
|
|
||||||
// Cull mode during a draw call
|
|
||||||
enum class Cull
|
|
||||||
{
|
|
||||||
// No Culling enabled
|
|
||||||
None = 0,
|
|
||||||
|
|
||||||
// Cull front faces
|
|
||||||
Front = 1,
|
|
||||||
|
|
||||||
// Cull back faces
|
|
||||||
Back = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
// A single draw call
|
|
||||||
struct RenderPass
|
|
||||||
{
|
|
||||||
// Framebuffer to draw to
|
|
||||||
TargetRef target;
|
|
||||||
|
|
||||||
// Mesh to draw with
|
|
||||||
MeshRef mesh;
|
|
||||||
|
|
||||||
// Material to draw with
|
|
||||||
MaterialRef material;
|
|
||||||
|
|
||||||
// Whether the RenderPass should use a specific viewport
|
|
||||||
bool has_viewport;
|
|
||||||
|
|
||||||
// Whether the RenderPass should use a scissor rectangle
|
|
||||||
bool has_scissor;
|
|
||||||
|
|
||||||
// The viewport (only used if hasViewport is true)
|
|
||||||
Rectf viewport;
|
|
||||||
|
|
||||||
// The scissor rectangle (only used if hasScissor is true)
|
|
||||||
Rectf scissor;
|
|
||||||
|
|
||||||
// First index in the Mesh to draw from
|
|
||||||
i64 index_start;
|
|
||||||
|
|
||||||
// Total amount of indices to draw from the Mesh
|
|
||||||
i64 index_count;
|
|
||||||
|
|
||||||
// Total amount of instances to draw from the Mesh
|
|
||||||
i64 instance_count;
|
|
||||||
|
|
||||||
// Depth Compare Function
|
|
||||||
Compare depth;
|
|
||||||
|
|
||||||
// Cull Mode
|
|
||||||
Cull cull;
|
|
||||||
|
|
||||||
// Blend Mode
|
|
||||||
BlendMode blend;
|
|
||||||
|
|
||||||
// Initializes a default RenderPass
|
|
||||||
RenderPass();
|
|
||||||
|
|
||||||
// Performs the render
|
|
||||||
void perform();
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
// Texture filter
|
|
||||||
enum class TextureFilter
|
|
||||||
{
|
|
||||||
// None will fallback to whatever default the driver sets
|
|
||||||
None,
|
|
||||||
|
|
||||||
// Linear interpolation
|
|
||||||
Linear,
|
|
||||||
|
|
||||||
// Nearest Neighbour interpolation
|
|
||||||
Nearest
|
|
||||||
};
|
|
||||||
|
|
||||||
// Texture Wrap Mode
|
|
||||||
enum class TextureWrap
|
|
||||||
{
|
|
||||||
// None will fallback to whatever default the driver sets
|
|
||||||
None,
|
|
||||||
|
|
||||||
// Clamps the texture to the edges
|
|
||||||
Clamp,
|
|
||||||
|
|
||||||
// Repeats the texture
|
|
||||||
Repeat
|
|
||||||
};
|
|
||||||
|
|
||||||
// Texture Sampler State, applied during rendering
|
|
||||||
struct TextureSampler
|
|
||||||
{
|
|
||||||
// Filter Mode
|
|
||||||
TextureFilter filter;
|
|
||||||
|
|
||||||
// Wrap X Mode
|
|
||||||
TextureWrap wrap_x;
|
|
||||||
|
|
||||||
// Wrap Y Mode
|
|
||||||
TextureWrap wrap_y;
|
|
||||||
|
|
||||||
TextureSampler() :
|
|
||||||
filter(TextureFilter::Linear),
|
|
||||||
wrap_x(TextureWrap::Repeat),
|
|
||||||
wrap_y(TextureWrap::Repeat) {}
|
|
||||||
|
|
||||||
TextureSampler(TextureFilter filter) :
|
|
||||||
filter(filter),
|
|
||||||
wrap_x(TextureWrap::Repeat),
|
|
||||||
wrap_y(TextureWrap::Repeat) {}
|
|
||||||
|
|
||||||
TextureSampler(TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y) :
|
|
||||||
filter(filter),
|
|
||||||
wrap_x(wrap_x),
|
|
||||||
wrap_y(wrap_y) {}
|
|
||||||
|
|
||||||
bool operator==(const TextureSampler& rhs) const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
filter == rhs.filter &&
|
|
||||||
wrap_x == rhs.wrap_x &&
|
|
||||||
wrap_y == rhs.wrap_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const TextureSampler& rhs) const
|
|
||||||
{
|
|
||||||
return !(*this == rhs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,102 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include <blah/containers/stackvector.h>
|
|
||||||
#include <blah/containers/str.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
// Supported Uniform Types
|
|
||||||
enum class UniformType
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Float,
|
|
||||||
Float2,
|
|
||||||
Float3,
|
|
||||||
Float4,
|
|
||||||
Mat3x2,
|
|
||||||
Mat4x4,
|
|
||||||
Texture2D,
|
|
||||||
Sampler2D
|
|
||||||
};
|
|
||||||
|
|
||||||
// Supported Shader Types
|
|
||||||
enum class ShaderType
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Vertex = 1 << 0,
|
|
||||||
Fragment = 1 << 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// Uniform Info, provided by the Shader
|
|
||||||
struct UniformInfo
|
|
||||||
{
|
|
||||||
// Name of the Uniform
|
|
||||||
String name;
|
|
||||||
|
|
||||||
// The Value type of the Uniform
|
|
||||||
UniformType type;
|
|
||||||
|
|
||||||
// The Shader type the Uniform is a part of
|
|
||||||
ShaderType shader;
|
|
||||||
|
|
||||||
// Some rendering APIs have uniform buffers. The `buffer_index`
|
|
||||||
// specifies which buffer the uniform belongs to
|
|
||||||
int buffer_index;
|
|
||||||
|
|
||||||
// Array length of the Uniform (ex. a vec2[4] would be 4)
|
|
||||||
int array_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Data to be passed to the shader to construct it
|
|
||||||
struct ShaderData
|
|
||||||
{
|
|
||||||
struct HLSL_Attribute
|
|
||||||
{
|
|
||||||
// Semantic Name
|
|
||||||
const char* semantic_name = nullptr;
|
|
||||||
|
|
||||||
// (optional) Semantic Index
|
|
||||||
int semantic_index = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Vertex Shader Program data
|
|
||||||
String vertex;
|
|
||||||
|
|
||||||
// Fragment Shader Program data
|
|
||||||
String fragment;
|
|
||||||
|
|
||||||
// HLSL Attributes - required for D3D11
|
|
||||||
StackVector<HLSL_Attribute, 16> hlsl_attributes;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Shader;
|
|
||||||
using ShaderRef = Ref<Shader>;
|
|
||||||
|
|
||||||
// A shader used during Rendering
|
|
||||||
class Shader
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
Shader() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Copy / Moves not allowed
|
|
||||||
Shader(const Shader&) = delete;
|
|
||||||
Shader(Shader&&) = delete;
|
|
||||||
Shader& operator=(const Shader&) = delete;
|
|
||||||
Shader& operator=(Shader&&) = delete;
|
|
||||||
|
|
||||||
// Default Destructor
|
|
||||||
virtual ~Shader() = default;
|
|
||||||
|
|
||||||
// Creates a Shader with the given Shader Data.
|
|
||||||
// If the Shader creation fails, it will return an invalid ShaderRef.
|
|
||||||
static ShaderRef create(const ShaderData& data);
|
|
||||||
|
|
||||||
// Gets a list of Shader Uniforms from Shader
|
|
||||||
virtual Vector<UniformInfo>& uniforms() = 0;
|
|
||||||
|
|
||||||
// Gets a list of Shader Uniforms from Shader
|
|
||||||
virtual const Vector<UniformInfo>& uniforms() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include <blah/graphics/texture.h>
|
|
||||||
#include <blah/containers/stackvector.h>
|
|
||||||
#include <blah/math/color.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
enum class ClearMask
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Color = 1,
|
|
||||||
Depth = 2,
|
|
||||||
Stencil = 4,
|
|
||||||
All = (int)Color | (int)Depth | (int)Stencil
|
|
||||||
};
|
|
||||||
|
|
||||||
// Up to 4 color textures + 1 depth/stencil
|
|
||||||
using Attachments = StackVector<TextureRef, 5>;
|
|
||||||
using AttachmentFormats = StackVector<TextureFormat, 5>;
|
|
||||||
|
|
||||||
class Target;
|
|
||||||
using TargetRef = Ref<Target>;
|
|
||||||
|
|
||||||
// Target is a 2D Buffer that can be drawn to.
|
|
||||||
// It can hold up to 4 color Textures, and 1 Depth/Stencil Texture.
|
|
||||||
class Target
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
Target() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Copy / Moves not allowed
|
|
||||||
Target(const Target&) = delete;
|
|
||||||
Target(Target&&) = delete;
|
|
||||||
Target& operator=(const Target&) = delete;
|
|
||||||
Target& operator=(Target&&) = delete;
|
|
||||||
|
|
||||||
// Default Destructor
|
|
||||||
virtual ~Target() = default;
|
|
||||||
|
|
||||||
// Creates a new Target with a single Color texture
|
|
||||||
// If the Target creation fails, it will return an invalid TargetRef.
|
|
||||||
static TargetRef create(int width, int height);
|
|
||||||
|
|
||||||
// Creates a new Target with the given Texture Attachments. You must provide at least one Attachment.
|
|
||||||
// If the Target creation fails, it will return an invalid TargetRef.
|
|
||||||
static TargetRef create(int width, int height, const AttachmentFormats& textures);
|
|
||||||
|
|
||||||
// Gets the list of Attachments from the Target
|
|
||||||
virtual Attachments& textures() = 0;
|
|
||||||
|
|
||||||
// Gets the list of Attachments from the Target
|
|
||||||
virtual const Attachments& textures() const = 0;
|
|
||||||
|
|
||||||
// Gets the Attachment at a given index from the Target
|
|
||||||
TextureRef& texture(int index);
|
|
||||||
|
|
||||||
// Gets the Attachment at a given index from the Target
|
|
||||||
const TextureRef& texture(int index) const;
|
|
||||||
|
|
||||||
// Gets the width of the Target
|
|
||||||
virtual int width() const;
|
|
||||||
|
|
||||||
// Gets the height of the Target
|
|
||||||
virtual int height() const;
|
|
||||||
|
|
||||||
// Clears the Target
|
|
||||||
virtual void clear(Color color = Color::black, float depth = 1.0f, u8 stencil = 0, ClearMask mask = ClearMask::All) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include <blah/filesystem.h>
|
|
||||||
#include <blah/math/color.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
enum class TextureFormat
|
|
||||||
{
|
|
||||||
// Invalid Format
|
|
||||||
None,
|
|
||||||
|
|
||||||
// Single 8-bit channe;
|
|
||||||
R,
|
|
||||||
|
|
||||||
// 2 8-bit channels
|
|
||||||
RG,
|
|
||||||
|
|
||||||
// 4 8-bit channels
|
|
||||||
RGBA,
|
|
||||||
|
|
||||||
// Depth 24, Stencil 8
|
|
||||||
DepthStencil,
|
|
||||||
|
|
||||||
// Total Formats
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
class Image;
|
|
||||||
class Stream;
|
|
||||||
class Texture;
|
|
||||||
using TextureRef = Ref<Texture>;
|
|
||||||
|
|
||||||
// A 2D Texture held by the GPU to be used during rendering
|
|
||||||
class Texture
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
Texture() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Copy / Moves not allowed
|
|
||||||
Texture(const Texture&) = delete;
|
|
||||||
Texture(Texture&&) = delete;
|
|
||||||
Texture& operator=(const Texture&) = delete;
|
|
||||||
Texture& operator=(Texture&&) = delete;
|
|
||||||
|
|
||||||
// Default Destructor
|
|
||||||
virtual ~Texture() = default;
|
|
||||||
|
|
||||||
// Creates a new Texture.
|
|
||||||
// If the Texture creation fails, it will return an invalid TextureRef.
|
|
||||||
static TextureRef create(const Image& image);
|
|
||||||
|
|
||||||
// Creates a new Texture.
|
|
||||||
// If image data is provided, it should be the full size of the texture.
|
|
||||||
// If the Texture creation fails, it will return an invalid TextureRef.
|
|
||||||
static TextureRef create(int width, int height, TextureFormat format, unsigned char* data = nullptr);
|
|
||||||
|
|
||||||
// Creates a new Texture from a Stream.
|
|
||||||
// If the Texture creation fails, it will return an invalid TextureRef.
|
|
||||||
static TextureRef create(Stream& stream);
|
|
||||||
|
|
||||||
// Creates a new Texture from a File.
|
|
||||||
// If the Texture creation fails, it will return an invalid TextureRef.
|
|
||||||
static TextureRef create(const FilePath& file);
|
|
||||||
|
|
||||||
// gets the width of the texture
|
|
||||||
virtual int width() const = 0;
|
|
||||||
|
|
||||||
// gets the height of the texture
|
|
||||||
virtual int height() const = 0;
|
|
||||||
|
|
||||||
// Gets the format of the Texture
|
|
||||||
virtual TextureFormat format() const = 0;
|
|
||||||
|
|
||||||
// Sets the data of the Texture.
|
|
||||||
// Note that the data should be the same format and size as the Texture. There is no row padding.
|
|
||||||
virtual void set_data(const u8* data) = 0;
|
|
||||||
|
|
||||||
// Sets the data of the Texture to the provided Color buffer.
|
|
||||||
// If the Texture Format is not RGBA, this won't do anything.
|
|
||||||
void set_data(const Color* data);
|
|
||||||
|
|
||||||
// Gets the data of the Texture.
|
|
||||||
// Note that the data will be written to in the same format as the Texture,
|
|
||||||
// and you should allocate enough space for the full texture. There is no row padding.
|
|
||||||
virtual void get_data(u8* data) = 0;
|
|
||||||
|
|
||||||
// Gets the data of the Texture.
|
|
||||||
// If the Texture Format is not RGBA, this won't do anything.
|
|
||||||
void get_data(Color* data);
|
|
||||||
|
|
||||||
// Returns true if the Texture is part of a FrameBuffer
|
|
||||||
virtual bool is_framebuffer() const = 0;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <blah/common.h>
|
||||||
#include <blah/math/color.h>
|
#include <blah/math/color.h>
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/stream.h>
|
||||||
#include <blah/filesystem.h>
|
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/stream.h>
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <blah/math/color.h>
|
#include <blah/math/color.h>
|
||||||
#include <blah/math/spatial.h>
|
#include <blah/math/spatial.h>
|
||||||
#include <blah/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
#include <blah/stream.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <blah/common.h>
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/math/color.h>
|
#include <blah/math/color.h>
|
||||||
#include <blah/math/spatial.h>
|
#include <blah/math/spatial.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/streams/bufferstream.h>
|
#include <blah/stream.h>
|
||||||
#include <blah/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
|
|
|
@ -234,14 +234,14 @@ namespace Blah
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const Color Color::transparent = Color( 0, 0, 0, 0);
|
inline const Color Color::transparent = Color( 0, 0, 0, 0);
|
||||||
inline const Color Color::white = Color(255, 255, 255, 255);
|
inline const Color Color::white = Color(255, 255, 255);
|
||||||
inline const Color Color::black = Color(0, 0, 0, 255);
|
inline const Color Color::black = Color( 0, 0, 0);
|
||||||
inline const Color Color::red = Color(255, 0, 0, 255);
|
inline const Color Color::red = Color(255, 0, 0);
|
||||||
inline const Color Color::green = Color(0, 255, 0, 255);
|
inline const Color Color::green = Color( 0, 255, 0);
|
||||||
inline const Color Color::blue = Color(0, 0, 255, 255);
|
inline const Color Color::blue = Color( 0, 0, 255);
|
||||||
inline const Color Color::yellow = Color(255, 255, 0, 255);
|
inline const Color Color::yellow = Color(255, 255, 0);
|
||||||
inline const Color Color::purple = Color(255, 0, 255, 255);
|
inline const Color Color::purple = Color(255, 0, 255);
|
||||||
inline const Color Color::teal = Color(0, 255, 255, 255);
|
inline const Color Color::teal = Color( 0, 255, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef BLAH_HEX_VALUE
|
#undef BLAH_HEX_VALUE
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/calc.h>
|
|
||||||
#include <blah/common.h>
|
#include <blah/common.h>
|
||||||
|
#include <blah/math/calc.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/math/calc.h>
|
||||||
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
// Stream is a generic handler to read and write data to various buffers.
|
||||||
|
// The purpose is to allow serializers to not care what they're writing data to,
|
||||||
|
// be it a file or memory.
|
||||||
class Stream
|
class Stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -44,7 +49,7 @@ namespace Blah
|
||||||
// reads a string until a newline '\n' or null-terminator '\0' is found
|
// reads a string until a newline '\n' or null-terminator '\0' is found
|
||||||
String read_line();
|
String read_line();
|
||||||
|
|
||||||
// reads a number
|
// reads a number, returns the value read.
|
||||||
u8 read_u8 (Endian endian = Endian::Little);
|
u8 read_u8 (Endian endian = Endian::Little);
|
||||||
u16 read_u16(Endian endian = Endian::Little);
|
u16 read_u16(Endian endian = Endian::Little);
|
||||||
u32 read_u32(Endian endian = Endian::Little);
|
u32 read_u32(Endian endian = Endian::Little);
|
||||||
|
@ -81,4 +86,86 @@ namespace Blah
|
||||||
// writes the amount of bytes to the stream from the given buffer, and returns the amount written
|
// writes the amount of bytes to the stream from the given buffer, and returns the amount written
|
||||||
virtual size_t write_data(const void* buffer, size_t length) = 0;
|
virtual size_t write_data(const void* buffer, size_t length) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// File Stream reads & writes over a File handle
|
||||||
|
class FileStream : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileStream() = default;
|
||||||
|
FileStream(const FilePath& path, FileMode mode);
|
||||||
|
FileStream(const FileRef& file);
|
||||||
|
|
||||||
|
size_t length() const override;
|
||||||
|
size_t position() const override;
|
||||||
|
size_t seek(size_t position) override;
|
||||||
|
bool is_open() const override;
|
||||||
|
bool is_readable() const override;
|
||||||
|
bool is_writable() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t read_data(void* ptr, size_t length) override;
|
||||||
|
size_t write_data(const void* ptr, size_t length) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
FileRef m_file;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Memory Stream moves over an existing buffer.
|
||||||
|
// The Buffer must exist for the duration of the Memory Stream.
|
||||||
|
class MemoryStream : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemoryStream() = default;
|
||||||
|
MemoryStream(u8* data, size_t length);
|
||||||
|
MemoryStream(const u8* data, size_t length);
|
||||||
|
|
||||||
|
size_t length() const override;
|
||||||
|
size_t position() const override;
|
||||||
|
size_t seek(size_t seek_to) override;
|
||||||
|
bool is_open() const override;
|
||||||
|
bool is_readable() const override;
|
||||||
|
bool is_writable() const override;
|
||||||
|
|
||||||
|
u8* data();
|
||||||
|
const u8* data() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t read_data(void* ptr, size_t length) override;
|
||||||
|
size_t write_data(const void* ptr, size_t length) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
u8* m_data = nullptr;
|
||||||
|
const u8* m_const_data = nullptr;
|
||||||
|
size_t m_length = 0;
|
||||||
|
size_t m_position = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Buffer Stream reads and writes to an internal buffer.
|
||||||
|
// It will grow the capacity if it needs to while writing.
|
||||||
|
class BufferStream : public Stream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BufferStream() = default;
|
||||||
|
BufferStream(int capacity);
|
||||||
|
|
||||||
|
size_t length() const override;
|
||||||
|
size_t position() const override;
|
||||||
|
size_t seek(size_t seek_to) override;
|
||||||
|
bool is_open() const override;
|
||||||
|
bool is_readable() const override;
|
||||||
|
bool is_writable() const override;
|
||||||
|
|
||||||
|
void resize(size_t length);
|
||||||
|
void clear();
|
||||||
|
u8* data();
|
||||||
|
const u8* data() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t read_data(void* ptr, size_t length) override;
|
||||||
|
size_t write_data(const void* ptr, size_t length) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<u8> m_buffer;
|
||||||
|
size_t m_position = 0;
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/streams/stream.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
// Buffer Stream reads and writes to an internal buffer.
|
|
||||||
// It will grow the capacity if it needs to while writing.
|
|
||||||
class BufferStream : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BufferStream() = default;
|
|
||||||
BufferStream(int capacity);
|
|
||||||
|
|
||||||
size_t length() const override;
|
|
||||||
size_t position() const override;
|
|
||||||
size_t seek(size_t seek_to) override;
|
|
||||||
bool is_open() const override;
|
|
||||||
bool is_readable() const override;
|
|
||||||
bool is_writable() const override;
|
|
||||||
|
|
||||||
void resize(size_t length);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
u8* data();
|
|
||||||
const u8* data() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
size_t read_data(void* ptr, size_t length) override;
|
|
||||||
size_t write_data(const void* ptr, size_t length) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Vector<u8> m_buffer;
|
|
||||||
size_t m_position = 0;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/streams/stream.h>
|
|
||||||
#include <blah/filesystem.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
class FileStream : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FileStream() = default;
|
|
||||||
FileStream(const FilePath& path, FileMode mode);
|
|
||||||
FileStream(FileStream&& fs) noexcept;
|
|
||||||
FileStream& operator=(FileStream&& fs) noexcept;
|
|
||||||
|
|
||||||
size_t length() const override;
|
|
||||||
size_t position() const override;
|
|
||||||
size_t seek(size_t position) override;
|
|
||||||
bool is_open() const override;
|
|
||||||
bool is_readable() const override;
|
|
||||||
bool is_writable() const override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
size_t read_data(void* ptr, size_t length) override;
|
|
||||||
size_t write_data(const void* ptr, size_t length) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
FileMode m_mode = FileMode::OpenRead;
|
|
||||||
FileRef m_file;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/streams/stream.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
// Memory Stream moves over an existing buffer.
|
|
||||||
// The Buffer must exist for the duration of the Memory Stream.
|
|
||||||
class MemoryStream : public Stream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MemoryStream() = default;
|
|
||||||
MemoryStream(u8* data, size_t length);
|
|
||||||
MemoryStream(const u8* data, size_t length);
|
|
||||||
|
|
||||||
size_t length() const override;
|
|
||||||
size_t position() const override;
|
|
||||||
size_t seek(size_t seek_to) override;
|
|
||||||
bool is_open() const override;
|
|
||||||
bool is_readable() const override;
|
|
||||||
bool is_writable() const override;
|
|
||||||
|
|
||||||
u8* data();
|
|
||||||
const u8* data() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
size_t read_data(void* ptr, size_t length) override;
|
|
||||||
size_t write_data(const void* ptr, size_t length) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
u8* m_data = nullptr;
|
|
||||||
const u8* m_const_data = nullptr;
|
|
||||||
size_t m_length = 0;
|
|
||||||
size_t m_position = 0;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include <blah/app.h>
|
#include <blah/app.h>
|
||||||
#include <blah/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/time.h>
|
#include <blah/time.h>
|
||||||
#include <blah/graphics/target.h>
|
|
||||||
#include "internal/internal.h"
|
#include "internal/internal.h"
|
||||||
#include "internal/platform.h"
|
#include "internal/platform.h"
|
||||||
#include "internal/renderer.h"
|
#include "internal/renderer.h"
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
#include <blah/graphics/batch.h>
|
#include <blah/drawing/batch.h>
|
||||||
#include <blah/graphics/texture.h>
|
|
||||||
#include <blah/graphics/target.h>
|
|
||||||
#include <blah/graphics/mesh.h>
|
|
||||||
#include <blah/graphics/shader.h>
|
|
||||||
#include <blah/graphics/material.h>
|
|
||||||
#include <blah/math/calc.h>
|
#include <blah/math/calc.h>
|
||||||
#include <blah/app.h>
|
#include <blah/app.h>
|
||||||
#include "../internal/internal.h"
|
#include "../internal/internal.h"
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
@ -296,7 +290,7 @@ void Batch::render(const TargetRef& target, const Mat4x4f& matrix)
|
||||||
m_mesh->index_data(IndexFormat::UInt32, m_indices.data(), m_indices.size());
|
m_mesh->index_data(IndexFormat::UInt32, m_indices.data(), m_indices.size());
|
||||||
m_mesh->vertex_data(format, m_vertices.data(), m_vertices.size());
|
m_mesh->vertex_data(format, m_vertices.data(), m_vertices.size());
|
||||||
|
|
||||||
RenderPass pass;
|
DrawCall pass;
|
||||||
pass.target = target;
|
pass.target = target;
|
||||||
pass.mesh = m_mesh;
|
pass.mesh = m_mesh;
|
||||||
pass.has_viewport = false;
|
pass.has_viewport = false;
|
||||||
|
@ -321,7 +315,7 @@ void Batch::render(const TargetRef& target, const Mat4x4f& matrix)
|
||||||
render_single_batch(pass, m_batch, matrix);
|
render_single_batch(pass, m_batch, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4f& matrix)
|
void Batch::render_single_batch(DrawCall& pass, const DrawBatch& b, const Mat4x4f& matrix)
|
||||||
{
|
{
|
||||||
// get the material
|
// get the material
|
||||||
pass.material = b.material;
|
pass.material = b.material;
|
|
@ -1,7 +1,5 @@
|
||||||
#include <blah/graphics/spritefont.h>
|
#include <blah/drawing/spritefont.h>
|
||||||
#include <blah/images/font.h>
|
|
||||||
#include <blah/images/packer.h>
|
#include <blah/images/packer.h>
|
||||||
#include <blah/common.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <blah/graphics/subtexture.h>
|
#include <blah/drawing/subtexture.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/math/calc.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
|
@ -1,5 +1,4 @@
|
||||||
#include <blah/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
#include <blah/streams/filestream.h>
|
|
||||||
#include "internal/internal.h"
|
#include "internal/internal.h"
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
@ -7,9 +6,13 @@ using namespace Blah;
|
||||||
FileRef File::open(const FilePath& path, FileMode mode)
|
FileRef File::open(const FilePath& path, FileMode mode)
|
||||||
{
|
{
|
||||||
BLAH_ASSERT_PLATFORM();
|
BLAH_ASSERT_PLATFORM();
|
||||||
|
|
||||||
|
FileRef ref;
|
||||||
if (App::Internal::platform)
|
if (App::Internal::platform)
|
||||||
return App::Internal::platform->file_open(path.cstr(), mode);
|
ref = App::Internal::platform->file_open(path.cstr(), mode);
|
||||||
return FileRef();
|
if (ref)
|
||||||
|
ref->m_mode = mode;
|
||||||
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool File::exists(const FilePath& path)
|
bool File::exists(const FilePath& path)
|
||||||
|
@ -28,6 +31,11 @@ bool File::destroy(const FilePath& path)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileMode File::mode() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
|
||||||
bool Directory::create(const FilePath& path)
|
bool Directory::create(const FilePath& path)
|
||||||
{
|
{
|
||||||
BLAH_ASSERT_PLATFORM();
|
BLAH_ASSERT_PLATFORM();
|
||||||
|
|
|
@ -1,9 +1,211 @@
|
||||||
#include <blah/graphics/material.h>
|
#include <blah/graphics.h>
|
||||||
#include <blah/common.h>
|
#include "internal/internal.h"
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
const BlendMode BlendMode::Normal = BlendMode(
|
||||||
|
BlendOp::Add,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::OneMinusSrcAlpha,
|
||||||
|
BlendOp::Add,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::OneMinusSrcAlpha,
|
||||||
|
BlendMask::RGBA,
|
||||||
|
0xffffffff
|
||||||
|
);
|
||||||
|
|
||||||
|
const BlendMode BlendMode::Subtract = BlendMode(
|
||||||
|
BlendOp::ReverseSubtract,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendOp::Add,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendFactor::One,
|
||||||
|
BlendMask::RGBA,
|
||||||
|
0xffffffff
|
||||||
|
);
|
||||||
|
|
||||||
|
VertexFormat::VertexFormat(const StackVector<VertexAttribute, 16>& attr, int str)
|
||||||
|
{
|
||||||
|
attributes = attr;
|
||||||
|
stride = str;
|
||||||
|
|
||||||
|
if (stride <= 0)
|
||||||
|
{
|
||||||
|
stride = 0;
|
||||||
|
|
||||||
|
for (auto& it : attributes)
|
||||||
|
{
|
||||||
|
switch (it.type)
|
||||||
|
{
|
||||||
|
case VertexType::None: break;
|
||||||
|
case VertexType::Float: stride += 4; break;
|
||||||
|
case VertexType::Float2: stride += 8; break;
|
||||||
|
case VertexType::Float3: stride += 12; break;
|
||||||
|
case VertexType::Float4: stride += 16; break;
|
||||||
|
case VertexType::Byte4: stride += 4; break;
|
||||||
|
case VertexType::UByte4: stride += 4; break;
|
||||||
|
case VertexType::Short2: stride += 4; break;
|
||||||
|
case VertexType::UShort2: stride += 4; break;
|
||||||
|
case VertexType::Short4: stride += 8; break;
|
||||||
|
case VertexType::UShort4: stride += 8; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderRef Shader::create(const ShaderData& data)
|
||||||
|
{
|
||||||
|
BLAH_ASSERT_RENDERER();
|
||||||
|
BLAH_ASSERT(data.vertex.length() > 0, "Must provide a Vertex Shader");
|
||||||
|
BLAH_ASSERT(data.fragment.length() > 0, "Must provide a Fragment Shader");
|
||||||
|
BLAH_ASSERT(data.hlsl_attributes.size() > 0 || App::renderer().type != RendererType::D3D11, "D3D11 Shaders must have hlsl_attributes assigned");
|
||||||
|
|
||||||
|
ShaderRef shader;
|
||||||
|
|
||||||
|
if (App::Internal::renderer)
|
||||||
|
shader = App::Internal::renderer->create_shader(&data);
|
||||||
|
|
||||||
|
// validate the shader
|
||||||
|
if (shader)
|
||||||
|
{
|
||||||
|
auto& uniforms = shader->uniforms();
|
||||||
|
|
||||||
|
// make sure its uniforms are valid
|
||||||
|
for (auto& it : uniforms)
|
||||||
|
if (it.type == UniformType::None)
|
||||||
|
{
|
||||||
|
auto error = String::fmt("Uniform '%s' has an invalid type!\n\tOnly Float/Float2/Float3/Float4/Mat3x2/Mat4x4/Texture are allowed!", it.name.cstr());
|
||||||
|
BLAH_ASSERT(false, error.cstr());
|
||||||
|
return ShaderRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure uniform names don't overlap
|
||||||
|
for (int i = 0; i < uniforms.size(); i++)
|
||||||
|
for (int j = i + 1; j < uniforms.size(); j++)
|
||||||
|
if (uniforms[i].name == uniforms[j].name)
|
||||||
|
{
|
||||||
|
auto error = String::fmt("Shader Uniform names '%s' overlap! All Names must be unique.", uniforms[0].name.cstr());
|
||||||
|
BLAH_ASSERT(false, error.cstr());
|
||||||
|
return ShaderRef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureRef Texture::create(const Image& image)
|
||||||
|
{
|
||||||
|
return create(image.width, image.height, TextureFormat::RGBA, (unsigned char*)image.pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureRef Texture::create(int width, int height, TextureFormat format, unsigned char* data)
|
||||||
|
{
|
||||||
|
BLAH_ASSERT_RENDERER();
|
||||||
|
BLAH_ASSERT(width > 0 && height > 0, "Texture width and height must be larger than 0");
|
||||||
|
BLAH_ASSERT((int)format > (int)TextureFormat::None && (int)format < (int)TextureFormat::Count, "Invalid texture format");
|
||||||
|
|
||||||
|
if (App::Internal::renderer)
|
||||||
|
{
|
||||||
|
auto tex = App::Internal::renderer->create_texture(width, height, format);
|
||||||
|
|
||||||
|
if (tex && data != nullptr)
|
||||||
|
tex->set_data(data);
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TextureRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureRef Texture::create(Stream& stream)
|
||||||
|
{
|
||||||
|
return create(Image(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureRef Texture::create(const FilePath& file)
|
||||||
|
{
|
||||||
|
return create(Image(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::set_data(const Color* data)
|
||||||
|
{
|
||||||
|
if (format() == TextureFormat::RGBA)
|
||||||
|
set_data((u8*)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::get_data(Color* data)
|
||||||
|
{
|
||||||
|
if (format() == TextureFormat::RGBA)
|
||||||
|
get_data((u8*)data);
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetRef Target::create(int width, int height)
|
||||||
|
{
|
||||||
|
AttachmentFormats formats;
|
||||||
|
formats.push_back(TextureFormat::RGBA);
|
||||||
|
return create(width, height, formats);
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetRef Target::create(int width, int height, const AttachmentFormats& textures)
|
||||||
|
{
|
||||||
|
BLAH_ASSERT_RENDERER();
|
||||||
|
BLAH_ASSERT(width > 0 && height > 0, "Target width and height must be larger than 0");
|
||||||
|
BLAH_ASSERT(textures.size() > 0, "At least one texture must be provided");
|
||||||
|
|
||||||
|
int color_count = 0;
|
||||||
|
int depth_count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < textures.size(); i++)
|
||||||
|
{
|
||||||
|
BLAH_ASSERT((int)textures[i] > (int)TextureFormat::None && (int)textures[i] < (int)TextureFormat::Count, "Invalid texture format");
|
||||||
|
|
||||||
|
if (textures[i] == TextureFormat::DepthStencil)
|
||||||
|
depth_count++;
|
||||||
|
else
|
||||||
|
color_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
BLAH_ASSERT(depth_count <= 1, "Target can only have 1 Depth/Stencil Texture");
|
||||||
|
BLAH_ASSERT(color_count <= Attachments::capacity - 1, "Exceeded maximum Color texture count");
|
||||||
|
|
||||||
|
if (App::Internal::renderer)
|
||||||
|
return App::Internal::renderer->create_target(width, height, textures.data(), textures.size());
|
||||||
|
|
||||||
|
return TargetRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureRef& Target::texture(int index)
|
||||||
|
{
|
||||||
|
return textures()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const TextureRef& Target::texture(int index) const
|
||||||
|
{
|
||||||
|
return textures()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
int Target::width() const
|
||||||
|
{
|
||||||
|
return textures()[0]->width();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Target::height() const
|
||||||
|
{
|
||||||
|
return textures()[0]->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
MeshRef Mesh::create()
|
||||||
|
{
|
||||||
|
BLAH_ASSERT_RENDERER();
|
||||||
|
|
||||||
|
if (App::Internal::renderer)
|
||||||
|
return App::Internal::renderer->create_mesh();
|
||||||
|
|
||||||
|
return MeshRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
int blah_calc_uniform_size(const UniformInfo& uniform)
|
int blah_calc_uniform_size(const UniformInfo& uniform)
|
||||||
|
@ -437,3 +639,93 @@ const float* Material::data() const
|
||||||
{
|
{
|
||||||
return m_data.begin();
|
return m_data.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DrawCall::DrawCall()
|
||||||
|
{
|
||||||
|
blend = BlendMode::Normal;
|
||||||
|
target = App::backbuffer();
|
||||||
|
mesh = MeshRef();
|
||||||
|
material = MaterialRef();
|
||||||
|
has_viewport = false;
|
||||||
|
has_scissor = false;
|
||||||
|
viewport = Rectf();
|
||||||
|
scissor = Rectf();
|
||||||
|
index_start = 0;
|
||||||
|
index_count = 0;
|
||||||
|
instance_count = 0;
|
||||||
|
depth = Compare::None;
|
||||||
|
cull = Cull::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawCall::perform()
|
||||||
|
{
|
||||||
|
BLAH_ASSERT_RENDERER();
|
||||||
|
BLAH_ASSERT(material, "Trying to draw with an invalid Material");
|
||||||
|
BLAH_ASSERT(material->shader(), "Trying to draw with an invalid Shader");
|
||||||
|
BLAH_ASSERT(mesh, "Trying to draw with an invalid Mesh");
|
||||||
|
|
||||||
|
if (!App::Internal::renderer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// copy call
|
||||||
|
DrawCall pass = *this;
|
||||||
|
|
||||||
|
// Validate Backbuffer
|
||||||
|
if (!pass.target)
|
||||||
|
{
|
||||||
|
pass.target = App::backbuffer();
|
||||||
|
Log::warn("Trying to draw with an invalid Target; falling back to Back Buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate Index Count
|
||||||
|
i64 index_count = pass.mesh->index_count();
|
||||||
|
if (pass.index_start + pass.index_count > index_count)
|
||||||
|
{
|
||||||
|
Log::warn(
|
||||||
|
"Trying to draw more indices than exist in the index buffer (%i-%i / %i); trimming extra indices",
|
||||||
|
pass.index_start,
|
||||||
|
pass.index_start + pass.index_count,
|
||||||
|
index_count);
|
||||||
|
|
||||||
|
if (pass.index_start > pass.index_count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pass.index_count = pass.index_count - pass.index_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate Instance Count
|
||||||
|
i64 instance_count = pass.mesh->instance_count();
|
||||||
|
if (pass.instance_count > instance_count)
|
||||||
|
{
|
||||||
|
Log::warn(
|
||||||
|
"Trying to draw more instances than exist in the index buffer (%i / %i); trimming extra instances",
|
||||||
|
pass.instance_count,
|
||||||
|
instance_count);
|
||||||
|
|
||||||
|
pass.instance_count = instance_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the total drawable size
|
||||||
|
auto draw_size = Vec2f(pass.target->width(), pass.target->height());
|
||||||
|
|
||||||
|
// Validate Viewport
|
||||||
|
if (!pass.has_viewport)
|
||||||
|
{
|
||||||
|
pass.viewport.x = 0;
|
||||||
|
pass.viewport.y = 0;
|
||||||
|
pass.viewport.w = draw_size.x;
|
||||||
|
pass.viewport.h = draw_size.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass.viewport = pass.viewport.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate Scissor
|
||||||
|
if (pass.has_scissor)
|
||||||
|
pass.scissor = pass.scissor.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y));
|
||||||
|
|
||||||
|
// perform render
|
||||||
|
App::Internal::renderer->render(pass);
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
#include <blah/graphics/blend.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
const BlendMode BlendMode::Normal = BlendMode(
|
|
||||||
BlendOp::Add,
|
|
||||||
BlendFactor::One,
|
|
||||||
BlendFactor::OneMinusSrcAlpha,
|
|
||||||
BlendOp::Add,
|
|
||||||
BlendFactor::One,
|
|
||||||
BlendFactor::OneMinusSrcAlpha,
|
|
||||||
BlendMask::RGBA,
|
|
||||||
0xffffffff
|
|
||||||
);
|
|
||||||
|
|
||||||
const BlendMode BlendMode::Subtract = BlendMode(
|
|
||||||
BlendOp::ReverseSubtract,
|
|
||||||
BlendFactor::One,
|
|
||||||
BlendFactor::One,
|
|
||||||
BlendOp::Add,
|
|
||||||
BlendFactor::One,
|
|
||||||
BlendFactor::One,
|
|
||||||
BlendMask::RGBA,
|
|
||||||
0xffffffff
|
|
||||||
);
|
|
|
@ -1,44 +0,0 @@
|
||||||
#include <blah/graphics/mesh.h>
|
|
||||||
#include "../internal/internal.h"
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
MeshRef Mesh::create()
|
|
||||||
{
|
|
||||||
BLAH_ASSERT_RENDERER();
|
|
||||||
|
|
||||||
if (App::Internal::renderer)
|
|
||||||
return App::Internal::renderer->create_mesh();
|
|
||||||
|
|
||||||
return MeshRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexFormat::VertexFormat(const StackVector<VertexAttribute, 16>& attr, int stride)
|
|
||||||
{
|
|
||||||
attributes = attr;
|
|
||||||
|
|
||||||
if (stride <= 0)
|
|
||||||
{
|
|
||||||
stride = 0;
|
|
||||||
|
|
||||||
for (auto& it : attributes)
|
|
||||||
{
|
|
||||||
switch (it.type)
|
|
||||||
{
|
|
||||||
case VertexType::None: break;
|
|
||||||
case VertexType::Float: stride += 4; break;
|
|
||||||
case VertexType::Float2: stride += 8; break;
|
|
||||||
case VertexType::Float3: stride += 12; break;
|
|
||||||
case VertexType::Float4: stride += 16; break;
|
|
||||||
case VertexType::Byte4: stride += 4; break;
|
|
||||||
case VertexType::UByte4: stride += 4; break;
|
|
||||||
case VertexType::Short2: stride += 4; break;
|
|
||||||
case VertexType::UShort2: stride += 4; break;
|
|
||||||
case VertexType::Short4: stride += 8; break;
|
|
||||||
case VertexType::UShort4: stride += 8; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->stride = stride;
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
#include <blah/graphics/renderpass.h>
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include "../internal/internal.h"
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
RenderPass::RenderPass()
|
|
||||||
{
|
|
||||||
blend = BlendMode::Normal;
|
|
||||||
target = App::backbuffer();
|
|
||||||
mesh = MeshRef();
|
|
||||||
material = MaterialRef();
|
|
||||||
has_viewport = false;
|
|
||||||
has_scissor = false;
|
|
||||||
viewport = Rectf();
|
|
||||||
scissor = Rectf();
|
|
||||||
index_start = 0;
|
|
||||||
index_count = 0;
|
|
||||||
instance_count = 0;
|
|
||||||
depth = Compare::None;
|
|
||||||
cull = Cull::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderPass::perform()
|
|
||||||
{
|
|
||||||
BLAH_ASSERT_RENDERER();
|
|
||||||
BLAH_ASSERT(material, "Trying to draw with an invalid Material");
|
|
||||||
BLAH_ASSERT(material->shader(), "Trying to draw with an invalid Shader");
|
|
||||||
BLAH_ASSERT(mesh, "Trying to draw with an invalid Mesh");
|
|
||||||
|
|
||||||
if (!App::Internal::renderer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// copy call
|
|
||||||
RenderPass pass = *this;
|
|
||||||
|
|
||||||
// Validate Backbuffer
|
|
||||||
if (!pass.target)
|
|
||||||
{
|
|
||||||
pass.target = App::backbuffer();
|
|
||||||
Log::warn("Trying to draw with an invalid Target; falling back to Back Buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate Index Count
|
|
||||||
i64 index_count = pass.mesh->index_count();
|
|
||||||
if (pass.index_start + pass.index_count > index_count)
|
|
||||||
{
|
|
||||||
Log::warn(
|
|
||||||
"Trying to draw more indices than exist in the index buffer (%i-%i / %i); trimming extra indices",
|
|
||||||
pass.index_start,
|
|
||||||
pass.index_start + pass.index_count,
|
|
||||||
index_count);
|
|
||||||
|
|
||||||
if (pass.index_start > pass.index_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pass.index_count = pass.index_count - pass.index_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate Instance Count
|
|
||||||
i64 instance_count = pass.mesh->instance_count();
|
|
||||||
if (pass.instance_count > instance_count)
|
|
||||||
{
|
|
||||||
Log::warn(
|
|
||||||
"Trying to draw more instances than exist in the index buffer (%i / %i); trimming extra instances",
|
|
||||||
pass.instance_count,
|
|
||||||
instance_count);
|
|
||||||
|
|
||||||
pass.instance_count = instance_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the total drawable size
|
|
||||||
auto draw_size = Vec2f(pass.target->width(), pass.target->height());
|
|
||||||
|
|
||||||
// Validate Viewport
|
|
||||||
if (!pass.has_viewport)
|
|
||||||
{
|
|
||||||
pass.viewport.x = 0;
|
|
||||||
pass.viewport.y = 0;
|
|
||||||
pass.viewport.w = draw_size.x;
|
|
||||||
pass.viewport.h = draw_size.y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pass.viewport = pass.viewport.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate Scissor
|
|
||||||
if (pass.has_scissor)
|
|
||||||
pass.scissor = pass.scissor.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y));
|
|
||||||
|
|
||||||
// perform render
|
|
||||||
App::Internal::renderer->render(pass);
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
#include <blah/graphics/shader.h>
|
|
||||||
#include <blah/app.h>
|
|
||||||
#include "../internal/internal.h"
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
ShaderRef Shader::create(const ShaderData& data)
|
|
||||||
{
|
|
||||||
BLAH_ASSERT_RENDERER();
|
|
||||||
BLAH_ASSERT(data.vertex.length() > 0, "Must provide a Vertex Shader");
|
|
||||||
BLAH_ASSERT(data.fragment.length() > 0, "Must provide a Fragment Shader");
|
|
||||||
BLAH_ASSERT(data.hlsl_attributes.size() > 0 || App::renderer().type != RendererType::D3D11, "D3D11 Shaders must have hlsl_attributes assigned");
|
|
||||||
|
|
||||||
ShaderRef shader;
|
|
||||||
|
|
||||||
if (App::Internal::renderer)
|
|
||||||
shader = App::Internal::renderer->create_shader(&data);
|
|
||||||
|
|
||||||
// validate the shader
|
|
||||||
if (shader)
|
|
||||||
{
|
|
||||||
auto& uniforms = shader->uniforms();
|
|
||||||
|
|
||||||
// make sure its uniforms are valid
|
|
||||||
for (auto& it : uniforms)
|
|
||||||
if (it.type == UniformType::None)
|
|
||||||
{
|
|
||||||
auto error = String::fmt("Uniform '%s' has an invalid type!\n\tOnly Float/Float2/Float3/Float4/Mat3x2/Mat4x4/Texture are allowed!", it.name.cstr());
|
|
||||||
BLAH_ASSERT(false, error.cstr());
|
|
||||||
return ShaderRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure uniform names don't overlap
|
|
||||||
for (int i = 0; i < uniforms.size(); i ++)
|
|
||||||
for (int j = i + 1; j < uniforms.size(); j ++)
|
|
||||||
if (uniforms[i].name == uniforms[j].name)
|
|
||||||
{
|
|
||||||
auto error = String::fmt("Shader Uniform names '%s' overlap! All Names must be unique.", uniforms[0].name.cstr());
|
|
||||||
BLAH_ASSERT(false, error.cstr());
|
|
||||||
return ShaderRef();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return shader;
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
#include <blah/graphics/target.h>
|
|
||||||
#include "../internal/internal.h"
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
TargetRef Target::create(int width, int height)
|
|
||||||
{
|
|
||||||
AttachmentFormats formats;
|
|
||||||
formats.push_back(TextureFormat::RGBA);
|
|
||||||
return create(width, height, formats);
|
|
||||||
}
|
|
||||||
|
|
||||||
TargetRef Target::create(int width, int height, const AttachmentFormats& textures)
|
|
||||||
{
|
|
||||||
BLAH_ASSERT_RENDERER();
|
|
||||||
BLAH_ASSERT(width > 0 && height > 0, "Target width and height must be larger than 0");
|
|
||||||
BLAH_ASSERT(textures.size() > 0, "At least one texture must be provided");
|
|
||||||
|
|
||||||
int color_count = 0;
|
|
||||||
int depth_count = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < textures.size(); i++)
|
|
||||||
{
|
|
||||||
BLAH_ASSERT((int)textures[i] > (int)TextureFormat::None && (int)textures[i] < (int)TextureFormat::Count, "Invalid texture format");
|
|
||||||
|
|
||||||
if (textures[i] == TextureFormat::DepthStencil)
|
|
||||||
depth_count++;
|
|
||||||
else
|
|
||||||
color_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
BLAH_ASSERT(depth_count <= 1, "Target can only have 1 Depth/Stencil Texture");
|
|
||||||
BLAH_ASSERT(color_count <= Attachments::capacity - 1, "Exceeded maximum Color texture count");
|
|
||||||
|
|
||||||
if (App::Internal::renderer)
|
|
||||||
return App::Internal::renderer->create_target(width, height, textures.data(), textures.size());
|
|
||||||
|
|
||||||
return TargetRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureRef& Target::texture(int index)
|
|
||||||
{
|
|
||||||
return textures()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
const TextureRef& Target::texture(int index) const
|
|
||||||
{
|
|
||||||
return textures()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
int Target::width() const
|
|
||||||
{
|
|
||||||
return textures()[0]->width();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Target::height() const
|
|
||||||
{
|
|
||||||
return textures()[0]->height();
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
#include <blah/graphics/texture.h>
|
|
||||||
#include <blah/images/image.h>
|
|
||||||
#include <blah/streams/stream.h>
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include "../internal/internal.h"
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
TextureRef Texture::create(const Image& image)
|
|
||||||
{
|
|
||||||
return create(image.width, image.height, TextureFormat::RGBA, (unsigned char*)image.pixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureRef Texture::create(int width, int height, TextureFormat format, unsigned char* data)
|
|
||||||
{
|
|
||||||
BLAH_ASSERT_RENDERER();
|
|
||||||
BLAH_ASSERT(width > 0 && height > 0, "Texture width and height must be larger than 0");
|
|
||||||
BLAH_ASSERT((int)format > (int)TextureFormat::None && (int)format < (int)TextureFormat::Count, "Invalid texture format");
|
|
||||||
|
|
||||||
if (App::Internal::renderer)
|
|
||||||
{
|
|
||||||
auto tex = App::Internal::renderer->create_texture(width, height, format);
|
|
||||||
|
|
||||||
if (tex && data != nullptr)
|
|
||||||
tex->set_data(data);
|
|
||||||
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TextureRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureRef Texture::create(Stream& stream)
|
|
||||||
{
|
|
||||||
return create(Image(stream));
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureRef Texture::create(const FilePath& file)
|
|
||||||
{
|
|
||||||
return create(Image(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::set_data(const Color* data)
|
|
||||||
{
|
|
||||||
if (format() == TextureFormat::RGBA)
|
|
||||||
set_data((u8*)data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::get_data(Color* data)
|
|
||||||
{
|
|
||||||
if (format() == TextureFormat::RGBA)
|
|
||||||
get_data((u8*)data);
|
|
||||||
}
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include <blah/images/aseprite.h>
|
#include <blah/images/aseprite.h>
|
||||||
#include <blah/streams/filestream.h>
|
|
||||||
#include <blah/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
#include <blah/common.h>
|
|
||||||
#include <blah/math/calc.h>
|
#include <blah/math/calc.h>
|
||||||
|
|
||||||
#define STBI_NO_STDIO
|
#define STBI_NO_STDIO
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include <blah/images/font.h>
|
#include <blah/images/font.h>
|
||||||
#include <blah/streams/filestream.h>
|
|
||||||
#include <blah/math/calc.h>
|
#include <blah/math/calc.h>
|
||||||
#include <blah/common.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/streams/stream.h>
|
|
||||||
#include <blah/streams/filestream.h>
|
|
||||||
#include <blah/common.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include <blah/images/packer.h>
|
#include <blah/images/packer.h>
|
||||||
#include <blah/common.h>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <blah/math/calc.h>
|
#include <blah/math/calc.h>
|
||||||
#include "internal/internal.h"
|
#include "internal/internal.h"
|
||||||
#include "internal/platform.h"
|
#include "internal/platform.h"
|
||||||
#include <blah/graphics/target.h>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/filesystem.h>
|
|
||||||
#include <blah/input.h>
|
#include <blah/input.h>
|
||||||
|
#include <blah/filesystem.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
|
|
|
@ -67,8 +67,8 @@ namespace Blah
|
||||||
size_t length() override { return SDL_RWsize(handle); }
|
size_t length() override { return SDL_RWsize(handle); }
|
||||||
size_t position() override { return SDL_RWtell(handle); }
|
size_t position() override { return SDL_RWtell(handle); }
|
||||||
size_t seek(size_t position) override { return SDL_RWseek(handle, position, RW_SEEK_SET); }
|
size_t seek(size_t position) override { return SDL_RWseek(handle, position, RW_SEEK_SET); }
|
||||||
size_t read(unsigned char* buffer, size_t length) override { return SDL_RWread(handle, buffer, sizeof(char), length); }
|
size_t read(void* buffer, size_t length) override { return SDL_RWread(handle, buffer, sizeof(char), length); }
|
||||||
size_t write(const unsigned char* buffer, size_t length) override { return SDL_RWwrite(handle, buffer, sizeof(char), length); }
|
size_t write(const void* buffer, size_t length) override { return SDL_RWwrite(handle, buffer, sizeof(char), length); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SDL2_Platform : public Platform
|
struct SDL2_Platform : public Platform
|
||||||
|
|
|
@ -44,8 +44,8 @@ namespace Blah
|
||||||
size_t length() override;
|
size_t length() override;
|
||||||
size_t position() override;
|
size_t position() override;
|
||||||
size_t seek(size_t position) override;
|
size_t seek(size_t position) override;
|
||||||
size_t read(unsigned char* buffer, size_t length) override;
|
size_t read(void* buffer, size_t length) override;
|
||||||
size_t write(const unsigned char* buffer, size_t length) override;
|
size_t write(const void* buffer, size_t length) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Win32_Platform : public Platform
|
struct Win32_Platform : public Platform
|
||||||
|
@ -181,7 +181,7 @@ size_t Win32File::seek(size_t position)
|
||||||
return result.QuadPart;
|
return result.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Win32File::read(unsigned char* buffer, size_t length)
|
size_t Win32File::read(void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
static const DWORD read_step = 65536;
|
static const DWORD read_step = 65536;
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ size_t Win32File::read(unsigned char* buffer, size_t length)
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Win32File::write(const unsigned char* buffer, size_t length)
|
size_t Win32File::write(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
static const DWORD write_step = 65536;
|
static const DWORD write_step = 65536;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/app.h>
|
#include <blah/app.h>
|
||||||
#include <blah/graphics/renderpass.h>
|
#include <blah/graphics.h>
|
||||||
#include <blah/graphics/texture.h>
|
|
||||||
#include <blah/graphics/target.h>
|
|
||||||
#include <blah/graphics/shader.h>
|
|
||||||
#include <blah/graphics/mesh.h>
|
|
||||||
#include <blah/graphics/material.h>
|
|
||||||
#include <blah/math/color.h>
|
#include <blah/math/color.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
|
@ -38,7 +33,7 @@ namespace Blah
|
||||||
virtual void after_render() = 0;
|
virtual void after_render() = 0;
|
||||||
|
|
||||||
// Performs a draw call
|
// Performs a draw call
|
||||||
virtual void render(const RenderPass& pass) = 0;
|
virtual void render(const DrawCall& pass) = 0;
|
||||||
|
|
||||||
// Clears the backbuffer
|
// Clears the backbuffer
|
||||||
virtual void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) = 0;
|
virtual void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) = 0;
|
||||||
|
|
|
@ -136,7 +136,7 @@ namespace Blah
|
||||||
void update() override;
|
void update() override;
|
||||||
void before_render() override;
|
void before_render() override;
|
||||||
void after_render() override;
|
void after_render() override;
|
||||||
void render(const RenderPass& pass) override;
|
void render(const DrawCall& pass) override;
|
||||||
void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) override;
|
void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) override;
|
||||||
TextureRef create_texture(int width, int height, TextureFormat format) override;
|
TextureRef create_texture(int width, int height, TextureFormat format) override;
|
||||||
TargetRef create_target(int width, int height, const TextureFormat* attachments, int attachment_count) override;
|
TargetRef create_target(int width, int height, const TextureFormat* attachments, int attachment_count) override;
|
||||||
|
@ -145,9 +145,9 @@ namespace Blah
|
||||||
|
|
||||||
ID3D11InputLayout* get_layout(D3D11_Shader* shader, const VertexFormat& format);
|
ID3D11InputLayout* get_layout(D3D11_Shader* shader, const VertexFormat& format);
|
||||||
ID3D11BlendState* get_blend(const BlendMode& blend);
|
ID3D11BlendState* get_blend(const BlendMode& blend);
|
||||||
ID3D11RasterizerState* get_rasterizer(const RenderPass& pass);
|
ID3D11RasterizerState* get_rasterizer(const DrawCall& pass);
|
||||||
ID3D11SamplerState* get_sampler(const TextureSampler& sampler);
|
ID3D11SamplerState* get_sampler(const TextureSampler& sampler);
|
||||||
ID3D11DepthStencilState* get_depthstencil(const RenderPass& pass);
|
ID3D11DepthStencilState* get_depthstencil(const DrawCall& pass);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Utility Methods
|
// Utility Methods
|
||||||
|
@ -947,7 +947,7 @@ namespace Blah
|
||||||
return MeshRef(new D3D11_Mesh());
|
return MeshRef(new D3D11_Mesh());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer_D3D11::render(const RenderPass& pass)
|
void Renderer_D3D11::render(const DrawCall& pass)
|
||||||
{
|
{
|
||||||
auto ctx = context;
|
auto ctx = context;
|
||||||
auto mesh = (D3D11_Mesh*)pass.mesh.get();
|
auto mesh = (D3D11_Mesh*)pass.mesh.get();
|
||||||
|
@ -1531,7 +1531,7 @@ namespace Blah
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11RasterizerState* Renderer_D3D11::get_rasterizer(const RenderPass& pass)
|
ID3D11RasterizerState* Renderer_D3D11::get_rasterizer(const DrawCall& pass)
|
||||||
{
|
{
|
||||||
for (auto& it : rasterizer_cache)
|
for (auto& it : rasterizer_cache)
|
||||||
if (it.cull == pass.cull && it.has_scissor == pass.has_scissor)
|
if (it.cull == pass.cull && it.has_scissor == pass.has_scissor)
|
||||||
|
@ -1572,7 +1572,7 @@ namespace Blah
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID3D11DepthStencilState* Renderer_D3D11::get_depthstencil(const RenderPass& pass)
|
ID3D11DepthStencilState* Renderer_D3D11::get_depthstencil(const DrawCall& pass)
|
||||||
{
|
{
|
||||||
for (auto& it : depthstencil_cache)
|
for (auto& it : depthstencil_cache)
|
||||||
if (it.depth == pass.depth)
|
if (it.depth == pass.depth)
|
||||||
|
|
|
@ -418,7 +418,7 @@ namespace Blah
|
||||||
void update() override;
|
void update() override;
|
||||||
void before_render() override;
|
void before_render() override;
|
||||||
void after_render() override;
|
void after_render() override;
|
||||||
void render(const RenderPass& pass) override;
|
void render(const DrawCall& pass) override;
|
||||||
void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) override;
|
void clear_backbuffer(Color color, float depth, u8 stencil, ClearMask mask) override;
|
||||||
TextureRef create_texture(int width, int height, TextureFormat format) override;
|
TextureRef create_texture(int width, int height, TextureFormat format) override;
|
||||||
TargetRef create_target(int width, int height, const TextureFormat* attachments, int attachment_count) override;
|
TargetRef create_target(int width, int height, const TextureFormat* attachments, int attachment_count) override;
|
||||||
|
@ -1272,7 +1272,7 @@ namespace Blah
|
||||||
return MeshRef(resource);
|
return MeshRef(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer_OpenGL::render(const RenderPass& pass)
|
void Renderer_OpenGL::render(const DrawCall& pass)
|
||||||
{
|
{
|
||||||
// Bind the Target
|
// Bind the Target
|
||||||
if (pass.target == App::backbuffer())
|
if (pass.target == App::backbuffer())
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/stream.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
// Stream Base Class Implementation
|
||||||
|
|
||||||
size_t Stream::pipe(Stream& stream, size_t length)
|
size_t Stream::pipe(Stream& stream, size_t length)
|
||||||
{
|
{
|
||||||
const int BUFFER_LENGTH = 4096;
|
const int BUFFER_LENGTH = 4096;
|
||||||
|
@ -33,7 +35,6 @@ size_t Stream::read(void* buffer, size_t length)
|
||||||
return read_data(buffer, length);
|
return read_data(buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reads a string. if length < 0, assumes null-terminated
|
|
||||||
String Stream::read_string(int length)
|
String Stream::read_string(int length)
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
|
@ -204,3 +205,190 @@ size_t Stream::write_f64(double value, Endian endian)
|
||||||
return write_data(&value, sizeof(double));
|
return write_data(&value, sizeof(double));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// File Stream Implementation
|
||||||
|
|
||||||
|
FileStream::FileStream(const FilePath& path, FileMode mode)
|
||||||
|
: m_file(File::open(path, mode)) {}
|
||||||
|
|
||||||
|
FileStream::FileStream(const FileRef& file)
|
||||||
|
: m_file(file) {}
|
||||||
|
|
||||||
|
size_t FileStream::length() const
|
||||||
|
{
|
||||||
|
return (m_file ? m_file->length() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileStream::position() const
|
||||||
|
{
|
||||||
|
return (m_file ? m_file->position() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileStream::seek(size_t seek_to)
|
||||||
|
{
|
||||||
|
return (m_file ? m_file->seek(seek_to) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileStream::read_data(void* ptr, size_t length)
|
||||||
|
{
|
||||||
|
return (m_file ? m_file->read(ptr, length) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileStream::write_data(const void* ptr, size_t length)
|
||||||
|
{
|
||||||
|
return (m_file ? m_file->write(ptr, length) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileStream::is_open() const
|
||||||
|
{
|
||||||
|
return m_file ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileStream::is_readable() const
|
||||||
|
{
|
||||||
|
return m_file && m_file->mode() != FileMode::CreateWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileStream::is_writable() const
|
||||||
|
{
|
||||||
|
return m_file && m_file->mode() != FileMode::OpenRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Memory Stream Implementation
|
||||||
|
|
||||||
|
MemoryStream::MemoryStream(u8* data, size_t length)
|
||||||
|
: m_data(data), m_const_data(nullptr), m_length(length), m_position(0) {}
|
||||||
|
|
||||||
|
MemoryStream::MemoryStream(const u8* data, size_t length)
|
||||||
|
: m_data(nullptr), m_const_data(data), m_length(length), m_position(0) {}
|
||||||
|
|
||||||
|
size_t MemoryStream::length() const
|
||||||
|
{
|
||||||
|
return m_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MemoryStream::position() const
|
||||||
|
{
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MemoryStream::seek(size_t seek_to)
|
||||||
|
{
|
||||||
|
return m_position = (seek_to < 0 ? 0 : (seek_to > m_length ? m_length : seek_to));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MemoryStream::read_data(void* ptr, size_t len)
|
||||||
|
{
|
||||||
|
const u8* src = (m_data ? m_data : m_const_data);
|
||||||
|
|
||||||
|
if (src == nullptr || ptr == nullptr || len <= 0 || m_length <= 0 || m_position >= m_length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (len > m_length - m_position)
|
||||||
|
len = m_length - m_position;
|
||||||
|
|
||||||
|
memcpy(ptr, src + m_position, len);
|
||||||
|
m_position += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MemoryStream::write_data(const void* ptr, size_t len)
|
||||||
|
{
|
||||||
|
if (m_data == nullptr || ptr == nullptr || len <= 0 || m_length <= 0 || m_position >= m_length)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (len > m_length - m_position)
|
||||||
|
len = m_length - m_position;
|
||||||
|
|
||||||
|
memcpy(m_data + m_position, ptr, len);
|
||||||
|
m_position += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemoryStream::is_open() const { return (m_data || m_const_data) && m_length > 0; }
|
||||||
|
bool MemoryStream::is_readable() const { return (m_data || m_const_data) && m_length > 0; }
|
||||||
|
bool MemoryStream::is_writable() const { return m_data != nullptr && m_length > 0; }
|
||||||
|
u8* MemoryStream::data() { return m_data; }
|
||||||
|
const u8* MemoryStream::data() const { return (m_data ? m_data : m_const_data); }
|
||||||
|
|
||||||
|
|
||||||
|
// Buffer Stream Implementation
|
||||||
|
|
||||||
|
BufferStream::BufferStream(int capacity)
|
||||||
|
{
|
||||||
|
m_buffer.resize(capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BufferStream::length() const
|
||||||
|
{
|
||||||
|
return m_buffer.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BufferStream::position() const
|
||||||
|
{
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BufferStream::seek(size_t seek_to)
|
||||||
|
{
|
||||||
|
return m_position = (seek_to < 0 ? 0 : (seek_to > m_buffer.size() ? m_buffer.size() : seek_to));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BufferStream::read_data(void* ptr, size_t len)
|
||||||
|
{
|
||||||
|
if (ptr == nullptr || len <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (len > m_buffer.size() - m_position)
|
||||||
|
len = m_buffer.size() - m_position;
|
||||||
|
|
||||||
|
memcpy(ptr, m_buffer.data() + m_position, (size_t)len);
|
||||||
|
m_position += len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BufferStream::write_data(const void* ptr, size_t len)
|
||||||
|
{
|
||||||
|
if (len < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// resize
|
||||||
|
if (m_position + len > m_buffer.size())
|
||||||
|
resize(m_position + len);
|
||||||
|
|
||||||
|
// copy data
|
||||||
|
if (ptr != nullptr)
|
||||||
|
memcpy(m_buffer.data() + m_position, ptr, (size_t)len);
|
||||||
|
|
||||||
|
// increment position
|
||||||
|
m_position += len;
|
||||||
|
|
||||||
|
// return the amount we wrote
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BufferStream::is_open() const { return true; }
|
||||||
|
bool BufferStream::is_readable() const { return true; }
|
||||||
|
bool BufferStream::is_writable() const { return true; }
|
||||||
|
|
||||||
|
void BufferStream::resize(size_t length)
|
||||||
|
{
|
||||||
|
m_buffer.resize(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BufferStream::clear()
|
||||||
|
{
|
||||||
|
m_buffer.clear();
|
||||||
|
m_position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* BufferStream::data()
|
||||||
|
{
|
||||||
|
return m_buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* BufferStream::data() const
|
||||||
|
{
|
||||||
|
return m_buffer.data();
|
||||||
|
}
|
|
@ -1,82 +0,0 @@
|
||||||
#include "blah/streams/bufferstream.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
BufferStream::BufferStream(int capacity)
|
|
||||||
{
|
|
||||||
m_buffer.resize(capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t BufferStream::length() const
|
|
||||||
{
|
|
||||||
return m_buffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t BufferStream::position() const
|
|
||||||
{
|
|
||||||
return m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t BufferStream::seek(size_t seek_to)
|
|
||||||
{
|
|
||||||
return m_position = (seek_to < 0 ? 0 : (seek_to > m_buffer.size() ? m_buffer.size() : seek_to));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t BufferStream::read_data(void* ptr, size_t len)
|
|
||||||
{
|
|
||||||
if (ptr == nullptr || len <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (len > m_buffer.size() - m_position)
|
|
||||||
len = m_buffer.size() - m_position;
|
|
||||||
|
|
||||||
memcpy(ptr, m_buffer.data() + m_position, (size_t)len);
|
|
||||||
m_position += len;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t BufferStream::write_data(const void* ptr, size_t len)
|
|
||||||
{
|
|
||||||
if (len < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// resize
|
|
||||||
if (m_position + len > m_buffer.size())
|
|
||||||
resize(m_position + len);
|
|
||||||
|
|
||||||
// copy data
|
|
||||||
if (ptr != nullptr)
|
|
||||||
memcpy(m_buffer.data() + m_position, ptr, (size_t)len);
|
|
||||||
|
|
||||||
// increment position
|
|
||||||
m_position += len;
|
|
||||||
|
|
||||||
// return the amount we wrote
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BufferStream::is_open() const { return true; }
|
|
||||||
bool BufferStream::is_readable() const { return true; }
|
|
||||||
bool BufferStream::is_writable() const { return true; }
|
|
||||||
|
|
||||||
void BufferStream::resize(size_t length)
|
|
||||||
{
|
|
||||||
m_buffer.resize(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BufferStream::clear()
|
|
||||||
{
|
|
||||||
m_buffer.clear();
|
|
||||||
m_position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8* BufferStream::data()
|
|
||||||
{
|
|
||||||
return m_buffer.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* BufferStream::data() const
|
|
||||||
{
|
|
||||||
return m_buffer.data();
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
#include <blah/streams/filestream.h>
|
|
||||||
#include <blah/common.h>
|
|
||||||
#include "../internal/platform.h"
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
FileStream::FileStream(const FilePath& path, FileMode mode)
|
|
||||||
: m_mode(mode)
|
|
||||||
, m_file(File::open(path, mode))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStream::FileStream(FileStream&& src) noexcept
|
|
||||||
{
|
|
||||||
m_file = src.m_file;
|
|
||||||
m_mode = src.m_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileStream& FileStream::operator=(FileStream&& src) noexcept
|
|
||||||
{
|
|
||||||
m_file = src.m_file;
|
|
||||||
m_mode = src.m_mode;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FileStream::length() const
|
|
||||||
{
|
|
||||||
if (m_file)
|
|
||||||
return m_file->length();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FileStream::position() const
|
|
||||||
{
|
|
||||||
if (m_file)
|
|
||||||
return m_file->position();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FileStream::seek(size_t seek_to)
|
|
||||||
{
|
|
||||||
if (m_file)
|
|
||||||
return m_file->seek(seek_to);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FileStream::read_data(void* ptr, size_t length)
|
|
||||||
{
|
|
||||||
if (length <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (m_file)
|
|
||||||
return m_file->read((unsigned char*)ptr, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t FileStream::write_data(const void* ptr, size_t length)
|
|
||||||
{
|
|
||||||
if (length <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (m_file)
|
|
||||||
return m_file->write((const unsigned char*)ptr, length);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileStream::is_open() const
|
|
||||||
{
|
|
||||||
return m_file.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileStream::is_readable() const
|
|
||||||
{
|
|
||||||
return m_file.get() && (m_mode != FileMode::CreateWrite);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileStream::is_writable() const
|
|
||||||
{
|
|
||||||
return m_file.get() && (m_mode != FileMode::OpenRead);
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
#include <blah/streams/memorystream.h>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
MemoryStream::MemoryStream(u8* data, size_t length)
|
|
||||||
: m_data(data), m_const_data(nullptr), m_length(length), m_position(0) {}
|
|
||||||
|
|
||||||
MemoryStream::MemoryStream(const u8* data, size_t length)
|
|
||||||
: m_data(nullptr), m_const_data(data), m_length(length), m_position(0) {}
|
|
||||||
|
|
||||||
size_t MemoryStream::length() const
|
|
||||||
{
|
|
||||||
return m_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MemoryStream::position() const
|
|
||||||
{
|
|
||||||
return m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MemoryStream::seek(size_t seek_to)
|
|
||||||
{
|
|
||||||
return m_position = (seek_to < 0 ? 0 : (seek_to > m_length ? m_length : seek_to));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MemoryStream::read_data(void* ptr, size_t len)
|
|
||||||
{
|
|
||||||
const u8* src = (m_data ? m_data : m_const_data);
|
|
||||||
|
|
||||||
if (src == nullptr || ptr == nullptr || len <= 0 || m_length <= 0 || m_position >= m_length)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (len > m_length - m_position)
|
|
||||||
len = m_length - m_position;
|
|
||||||
|
|
||||||
memcpy(ptr, src + m_position, len);
|
|
||||||
m_position += len;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t MemoryStream::write_data(const void* ptr, size_t len)
|
|
||||||
{
|
|
||||||
if (m_data == nullptr || ptr == nullptr || len <= 0 || m_length <= 0 || m_position >= m_length)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (len > m_length - m_position)
|
|
||||||
len = m_length - m_position;
|
|
||||||
|
|
||||||
memcpy(m_data + m_position, ptr, len);
|
|
||||||
m_position += len;
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MemoryStream::is_open() const
|
|
||||||
{
|
|
||||||
return (m_data || m_const_data) && m_length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MemoryStream::is_readable() const
|
|
||||||
{
|
|
||||||
return (m_data || m_const_data) && m_length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MemoryStream::is_writable() const
|
|
||||||
{
|
|
||||||
return m_data != nullptr && m_length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8* MemoryStream::data()
|
|
||||||
{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* MemoryStream::data() const
|
|
||||||
{
|
|
||||||
return (m_data ? m_data : m_const_data);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user