1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Implementa BitmapContent

This commit is contained in:
Danilo Borges Santos 2024-11-20 12:02:35 -03:00
parent c35518902c
commit 7695aa2eeb
7 changed files with 374 additions and 16 deletions

View 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

View File

@ -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 { };

View 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

View File

@ -1,10 +0,0 @@
#ifndef XNA_PIPELINE_LOGGER_HPP
#define XNA_PIPELINE_LOGGER_HPP
namespace xna {
class ContentBuilderLogger {
};
}
#endif

View File

@ -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;
};
}

View File

@ -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)

View 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);
}
}