mirror of
https://github.com/borgesdan/xn65
synced 2024-12-29 21:54:47 +01:00
Implementa BitmapContent
This commit is contained in:
parent
c35518902c
commit
7695aa2eeb
121
includes/pipeline/graphics.hpp
Normal file
121
includes/pipeline/graphics.hpp
Normal file
@ -0,0 +1,121 @@
|
||||
#ifndef XNA_PIPELINE_GRAPHICS_HPP
|
||||
#define XNA_PIPELINE_GRAPHICS_HPP
|
||||
|
||||
#include "pipeline.hpp"
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include "xna/exception.hpp"
|
||||
#include "xna/common/numerics.hpp"
|
||||
#include "xna/graphics/shared.hpp"
|
||||
|
||||
namespace xna {
|
||||
class BitmapContent : public ContentItem {
|
||||
public:
|
||||
BitmapContent(int32_t width, int32_t height) {
|
||||
if (width <= 0 || height <= 0)
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
}
|
||||
|
||||
//Gets or sets the width of the bitmap, in pixels.
|
||||
constexpr int32_t Width() const { return width; }
|
||||
|
||||
//Gets or sets the width of the bitmap, in pixels.
|
||||
constexpr void Width(int32_t value) {
|
||||
if(value <= 0)
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
|
||||
width = value;
|
||||
}
|
||||
|
||||
//Gets or sets the height of the bitmap, in pixels.
|
||||
constexpr int32_t Height() const { return height; }
|
||||
|
||||
//Gets or sets the height of the bitmap, in pixels.
|
||||
constexpr void Height(int32_t value) {
|
||||
if (value <= 0)
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
|
||||
height = value;
|
||||
}
|
||||
|
||||
//Copies one bitmap into another.
|
||||
static inline void Copy(BitmapContent const& sourceBitmap, BitmapContent& destinationBitmap) {
|
||||
BitmapContent::Copy(sourceBitmap, Rectangle(0, 0, sourceBitmap.Width(), sourceBitmap.Height()),
|
||||
destinationBitmap, Rectangle(0, 0, destinationBitmap.Width(), destinationBitmap.Height()));
|
||||
}
|
||||
|
||||
//Copies one bitmap into another.
|
||||
static void Copy(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion,
|
||||
BitmapContent& destinationBitmap, Rectangle const& destinationRegion);
|
||||
|
||||
static bool InteropCopy(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion,
|
||||
BitmapContent& destinationBitmap, Rectangle const& destinationRegion);
|
||||
|
||||
//Writes encoded bitmap content.
|
||||
virtual void SetPixelData(std::vector<uint8_t> const& sourceData) = 0;
|
||||
//Reads encoded bitmap content.
|
||||
virtual std::vector<uint8_t> GetPixelData() const = 0;
|
||||
//Gets the corresponding GPU texture format for the specified bitmap type.
|
||||
virtual bool TryGetFormat(SurfaceFormat& format) const = 0;
|
||||
|
||||
protected:
|
||||
BitmapContent() = default;
|
||||
|
||||
//Validates the arguments to the Copy function.
|
||||
static void ValidateCopyArguments(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion,
|
||||
BitmapContent const& destinationBitmap, Rectangle const& destinationRegion);
|
||||
|
||||
//Attempts to copy a region of the specified bitmap onto another.
|
||||
virtual bool TryCopyTo(BitmapContent& destinationBitmap, Rectangle const& sourceRegion, Rectangle const& destionationRegion) const = 0;
|
||||
|
||||
//Attempts to copy a region from a specified bitmap.
|
||||
virtual bool TryCopyFrom(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion, Rectangle const& destionationRegion) = 0;
|
||||
|
||||
private:
|
||||
int32_t width{ 0 };
|
||||
int32_t height{ 0 };
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class PixelBitmapContent : public BitmapContent {
|
||||
public:
|
||||
PixelBitmapContent(int32_t width, int32_t height) : BitmapContent(width, height){}
|
||||
|
||||
//Writes encoded bitmap content.
|
||||
void SetPixelData(std::vector<uint8_t> const& sourceData) override {}
|
||||
//Reads encoded bitmap content.
|
||||
std::vector<uint8_t> GetPixelData() const override { return {}; }
|
||||
//Gets the corresponding GPU texture format for the specified bitmap type.
|
||||
bool TryGetFormat(SurfaceFormat& format) const override { return false; }
|
||||
|
||||
protected:
|
||||
//Attempts to copy a region of the specified bitmap onto another.
|
||||
bool TryCopyTo(BitmapContent& destinationBitmap, Rectangle const& sourceRegion, Rectangle const& destionationRegion) const override { return false; }
|
||||
|
||||
//Attempts to copy a region from a specified bitmap.
|
||||
bool TryCopyFrom(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion, Rectangle const& destionationRegion) override { return false; }
|
||||
};
|
||||
|
||||
|
||||
//Provides methods for accessing a mipmap chain.
|
||||
class MipmapChain {
|
||||
|
||||
};
|
||||
|
||||
//Provides methods for maintaining a mipmap chain.
|
||||
class MipmapChainCollection {
|
||||
public:
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//Provides a base class for all texture objects.
|
||||
class TextureContent : public ContentItem {
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
#ifndef XNA_PIPELINE_IMPORTER_HPP
|
||||
#define XNA_PIPELINE_IMPORTER_HPP
|
||||
|
||||
#include "logger.hpp"
|
||||
#include "pipeline.hpp"
|
||||
#include <any>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@ -29,7 +29,7 @@ namespace xna {
|
||||
|
||||
//Implements a file format importer for use with game assets.
|
||||
template <typename T>
|
||||
struct ContentImporter_T : public IContentImporter {
|
||||
struct ContentImporter : public IContentImporter {
|
||||
//Imports an asset from the specified file.
|
||||
virtual T Import(std::string const& filename, ContentImporterContext& context) = 0;
|
||||
|
||||
@ -75,7 +75,7 @@ namespace xna {
|
||||
|
||||
};
|
||||
|
||||
struct XmlImporter : ContentImporter_T<std::any> {
|
||||
struct XmlImporter : ContentImporter<std::any> {
|
||||
std::any Import(std::string const& filename, ContentImporterContext& context) override {
|
||||
//TODO: XmlReader
|
||||
return { };
|
||||
|
13
includes/pipeline/importers.hpp
Normal file
13
includes/pipeline/importers.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef XNA_PIPELINE_IMPORTERS_HPP
|
||||
#define XNA_PIPELINE_IMPORTERS_HPP
|
||||
|
||||
#include "pipeline.hpp"
|
||||
#include "importer.hpp"
|
||||
|
||||
namespace xna {
|
||||
class TextureImporter {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,10 +0,0 @@
|
||||
#ifndef XNA_PIPELINE_LOGGER_HPP
|
||||
#define XNA_PIPELINE_LOGGER_HPP
|
||||
|
||||
namespace xna {
|
||||
class ContentBuilderLogger {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -1,9 +1,159 @@
|
||||
#ifndef XNA_PIPELINE_PIPELINE_HPP
|
||||
#define XNA_PIPELINE_PIPELINE_HPP
|
||||
|
||||
namespace xna {
|
||||
class Pipeline {
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include "xna/exception.hpp"
|
||||
#include "xna/helpers.hpp"
|
||||
|
||||
|
||||
namespace xna {
|
||||
class ContentBuilderLogger {
|
||||
|
||||
};
|
||||
|
||||
//Base class for dictionaries that map string identifiers to data values.
|
||||
template <typename T>
|
||||
class NamedValueDictionary {
|
||||
public:
|
||||
void Add(std::string const& key, T const& value) {
|
||||
return AddItem(key, value);
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
ClearItems();
|
||||
}
|
||||
|
||||
bool ContainsKey(std::string const& key) {
|
||||
return items.contains(key);
|
||||
}
|
||||
|
||||
size_t Count() const {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
bool Remove(std::string const& key) {
|
||||
return RemoveItem(key);
|
||||
}
|
||||
|
||||
bool TryGetValue(std::string const& key, T& value) {
|
||||
if (items.contains(key))
|
||||
{
|
||||
value = items[key];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
T& operator[](std::string const& key) {
|
||||
return *items[key];
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void AddItem(std::string const& key, T const& value) {
|
||||
if (key.empty()) {
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
}
|
||||
|
||||
if constexpr (XnaHelper::IsSmartPoint<T>()) {
|
||||
if (value == nullptr)
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
}
|
||||
|
||||
items.insert({ key, value });
|
||||
}
|
||||
|
||||
virtual void ClearItems() {
|
||||
items.clear();
|
||||
}
|
||||
|
||||
virtual bool RemoveItem(std::string const& key) {
|
||||
if (key.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& search = items.find(key);
|
||||
|
||||
if (search == items.end())
|
||||
return false;
|
||||
|
||||
items.erase(key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void SetItem(std::string const& key, T const& value) {
|
||||
if (key.empty()) {
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
}
|
||||
|
||||
if constexpr (XnaHelper::IsSmartPoint<T>()) {
|
||||
if (value == nullptr)
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
}
|
||||
|
||||
items[key] = value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, T> items;
|
||||
};
|
||||
|
||||
//Provides properties describing the origin of the game asset, such as the original source file and creation tool.
|
||||
//This information is used for error reporting, and by processors that need to determine from what directory the asset was originally loaded.
|
||||
struct ContentIdentity {
|
||||
constexpr ContentIdentity() = default;
|
||||
constexpr ContentIdentity(std::string sourceFilename) :
|
||||
SourceFilename(sourceFilename) {}
|
||||
constexpr ContentIdentity(std::string sourceFilename, std::string sourceTool) :
|
||||
SourceFilename(sourceFilename), SourceTool(sourceTool) {}
|
||||
constexpr ContentIdentity(std::string sourceFilename, std::string sourceTool, std::string fragmentIdentifier) :
|
||||
SourceFilename(sourceFilename), SourceTool(sourceTool), FragmentIdentifier(fragmentIdentifier) {}
|
||||
|
||||
//Gets or sets the file name of the asset source.
|
||||
//Optional = true
|
||||
std::string SourceFilename;
|
||||
//Gets or sets the creation tool of the asset.
|
||||
//Optional = true
|
||||
std::string SourceTool;
|
||||
//Gets or sets the specific location of the content item within the larger source file.
|
||||
//Optional = true
|
||||
std::string FragmentIdentifier;
|
||||
};
|
||||
|
||||
//Provides properties that define opaque data for a game asset.
|
||||
class OpaqueDataDictionary : NamedValueDictionary<std::any> {
|
||||
|
||||
};
|
||||
|
||||
//Provides properties that define various aspects of content stored using the intermediate file format of the XNA Framework.
|
||||
class ContentItem {
|
||||
public:
|
||||
ContentItem() {
|
||||
opaqueData = std::make_shared<OpaqueDataDictionary>();
|
||||
}
|
||||
|
||||
//Gets or sets the name of the content item.
|
||||
std::string Name() const { return name; }
|
||||
//Gets or sets the identity of the content item.
|
||||
std::shared_ptr<ContentIdentity> Identity() const { return identity; }
|
||||
//Gets the opaque data of the content item.
|
||||
std::shared_ptr<OpaqueDataDictionary> OpaqueData() const { return opaqueData; }
|
||||
|
||||
//Gets or sets the name of the content item.
|
||||
void Name(std::string const& value) { name = value; }
|
||||
//Gets or sets the identity of the content item.
|
||||
void Identity(std::shared_ptr<ContentIdentity> const& value) { identity = value; }
|
||||
|
||||
private:
|
||||
//Optional = true
|
||||
std::string name;
|
||||
//Optional = true
|
||||
std::shared_ptr<ContentIdentity> identity;
|
||||
//Optional = true
|
||||
std::shared_ptr<OpaqueDataDictionary> opaqueData;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
add_library (Xn65Pipeline STATIC
|
||||
"writer.cpp"
|
||||
"compiler.cpp"
|
||||
"importer.cpp")
|
||||
"importer.cpp" "graphics.cpp")
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET Xn65Pipeline PROPERTY CXX_STANDARD 20)
|
||||
|
84
sources/pipeline/graphics.cpp
Normal file
84
sources/pipeline/graphics.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include "pipeline/graphics.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace xna {
|
||||
void xna::BitmapContent::Copy(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion, BitmapContent& destinationBitmap, Rectangle const& destinationRegion)
|
||||
{
|
||||
BitmapContent::ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);
|
||||
|
||||
if (sourceBitmap.TryCopyTo(destinationBitmap, sourceRegion, destinationRegion) || destinationBitmap.TryCopyFrom(sourceBitmap, sourceRegion, destinationRegion))
|
||||
return;
|
||||
|
||||
auto bitmapContent1 = std::make_shared<PixelBitmapContent<Vector4>>(sourceBitmap.Width(), sourceBitmap.Height());
|
||||
auto rectangle1 = Rectangle(0, 0, bitmapContent1->Width(), bitmapContent1->Height());
|
||||
|
||||
auto bmp1 = reinterpret_pointer_cast<BitmapContent>(bitmapContent1);
|
||||
|
||||
if (sourceBitmap.TryCopyTo(*bmp1, sourceRegion, rectangle1) && destinationBitmap.TryCopyFrom(*bmp1, rectangle1, destinationRegion))
|
||||
return;
|
||||
|
||||
auto bitmapContent2 = std::make_shared<PixelBitmapContent<Vector4>>(sourceBitmap.Width(), sourceBitmap.Height());
|
||||
auto bitmapContent3 = std::make_shared<PixelBitmapContent<Vector4>>(destinationBitmap.Width(), destinationBitmap.Height());
|
||||
|
||||
auto rectangle2 = Rectangle(0, 0, sourceBitmap.Width(), sourceBitmap.Height());
|
||||
auto rectangle3 = Rectangle(0, 0, destinationBitmap.Width(), destinationBitmap.Height());
|
||||
|
||||
auto bmpContent2 = reinterpret_pointer_cast<BitmapContent>(bitmapContent2);
|
||||
auto bmpContent3 = reinterpret_pointer_cast<BitmapContent>(bitmapContent3);
|
||||
|
||||
if (!sourceBitmap.TryCopyTo(*bmpContent2, rectangle2, rectangle2) || !destinationBitmap.TryCopyTo(*bmpContent3, rectangle3, rectangle3)
|
||||
|| !bmpContent3->TryCopyFrom(*bmpContent2, sourceRegion, destinationRegion) || !destinationBitmap.TryCopyFrom(*bmpContent3, rectangle3, rectangle3))
|
||||
{
|
||||
Exception::Throw(Exception::INVALID_OPERATION);
|
||||
}
|
||||
}
|
||||
|
||||
bool xna::BitmapContent::InteropCopy(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion, BitmapContent& destinationBitmap, Rectangle const& destinationRegion)
|
||||
{
|
||||
BitmapContent::ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);
|
||||
|
||||
bool flag = false;
|
||||
SurfaceFormat format1;
|
||||
SurfaceFormat format2;
|
||||
|
||||
if (destinationBitmap.TryGetFormat(format1) && sourceBitmap.TryGetFormat(format2))
|
||||
{
|
||||
if (format2 != format1 && (format2 == SurfaceFormat::NormalizedByte2
|
||||
|| format2 == SurfaceFormat::NormalizedByte4
|
||||
|| format1 == SurfaceFormat::NormalizedByte2
|
||||
|| format1 == SurfaceFormat::NormalizedByte4
|
||||
|| format2 == SurfaceFormat::Rg32
|
||||
|| format2 == SurfaceFormat::Single
|
||||
|| format2 == SurfaceFormat::Vector2
|
||||
|| format2 == SurfaceFormat::HalfSingle
|
||||
|| format2 == SurfaceFormat::HalfVector2))
|
||||
return false;
|
||||
|
||||
auto pixelData1 = sourceBitmap.GetPixelData();
|
||||
auto pixelData2 = destinationBitmap.GetPixelData();
|
||||
try
|
||||
{
|
||||
//TODO: ImageProcessor?
|
||||
//ImageProcessor.Convert(sourceBitmap.Width, sourceBitmap.Height, format2, new Rectangle ? (sourceRegion), pixelData1, destinationBitmap.Width, destinationBitmap.Height, format1, new Rectangle ? (destinationRegion), pixelData2);
|
||||
destinationBitmap.SetPixelData(pixelData2);
|
||||
flag = true;
|
||||
}
|
||||
catch(std::exception& ex)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
void xna::BitmapContent::ValidateCopyArguments(BitmapContent const& sourceBitmap, Rectangle const& sourceRegion,
|
||||
BitmapContent const& destinationBitmap, Rectangle const& destinationRegion) {
|
||||
|
||||
if (sourceRegion.Left() < 0 || sourceRegion.Top() < 0 || sourceRegion.Width < 0 || sourceRegion.Height < 0 || sourceRegion.Right() > sourceBitmap.Width() || sourceRegion.Bottom() > sourceBitmap.Height())
|
||||
Exception::Throw(Exception::OUT_OF_BOUNDS);
|
||||
|
||||
if (destinationRegion.Left() < 0 || destinationRegion.Top() < 0 || destinationRegion.Width < 0 || destinationRegion.Height < 0 || destinationRegion.Right() > destinationBitmap.Width() || destinationRegion.Bottom() > destinationBitmap.Height())
|
||||
Exception::Throw(Exception::OUT_OF_BOUNDS);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user