mirror of
https://github.com/encounter/cpp3ds.git
synced 2026-03-30 11:04:22 -07:00
Add variable GPU buffer size and System Font textures
This commit is contained in:
@@ -216,6 +216,13 @@ public :
|
||||
////////////////////////////////////////////////////////////
|
||||
bool loadFromImage(const Image& image, const IntRect& area = IntRect());
|
||||
|
||||
#ifndef EMULATION
|
||||
bool loadFromPreprocessedFile(const std::string& filename, size_t width, size_t height, GPU_TEXCOLOR format);
|
||||
bool loadFromPreprocessedMemory(void *data, size_t size, size_t width, size_t height, GPU_TEXCOLOR format, bool copyData = true);
|
||||
|
||||
C3D_Tex* getNativeTexture() { return m_texture; }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the size of the texture
|
||||
///
|
||||
@@ -501,6 +508,7 @@ private :
|
||||
unsigned int m_texture; ///< Internal texture identifier
|
||||
#else
|
||||
C3D_Tex* m_texture; ///< Internal texture identifier
|
||||
bool m_ownsData; ///< Check if this object owns the data and needs to free it
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -24,7 +24,11 @@ public:
|
||||
void render();
|
||||
void run();
|
||||
void exit();
|
||||
Game();
|
||||
#ifdef EMULATION
|
||||
Game(size_t gpuCommandBufSize = 0);
|
||||
#else
|
||||
Game(size_t gpuCommandBufSize = C3D_DEFAULT_CMDBUF_SIZE);
|
||||
#endif
|
||||
virtual ~Game();
|
||||
protected:
|
||||
Window windowTop, windowBottom;
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace
|
||||
C3D_MtxStack projectionMatrix, modelviewMatrix, textureMatrix;
|
||||
}
|
||||
|
||||
void CitroInit()
|
||||
void CitroInit(size_t commandBufferSize)
|
||||
{
|
||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||
C3D_Init(commandBufferSize);
|
||||
|
||||
// Configure attributes for use with the vertex shader
|
||||
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <citro3d.h>
|
||||
|
||||
void CitroInit();
|
||||
void CitroInit(size_t commandBufferSize);
|
||||
void CitroDestroy();
|
||||
void CitroBindUniforms(shaderProgram_s* program);
|
||||
void CitroUpdateMatrixStacks();
|
||||
|
||||
+117
-10
@@ -37,6 +37,8 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <c3d/texture.h>
|
||||
#include <cpp3ds/System/FileInputStream.hpp>
|
||||
#include <cpp3ds/System/FileSystem.hpp>
|
||||
#include "CitroHelpers.hpp"
|
||||
|
||||
// Note: vertical flip flag set so 0,0 is top left of texture
|
||||
@@ -124,6 +126,7 @@ m_texture (nullptr),
|
||||
m_isSmooth (false),
|
||||
m_isRepeated (false),
|
||||
m_pixelsFlipped(false),
|
||||
m_ownsData (true),
|
||||
m_cacheId (getUniqueId())
|
||||
{
|
||||
|
||||
@@ -138,6 +141,7 @@ m_texture (nullptr),
|
||||
m_isSmooth (copy.m_isSmooth),
|
||||
m_isRepeated (copy.m_isRepeated),
|
||||
m_pixelsFlipped(false),
|
||||
m_ownsData (true),
|
||||
m_cacheId (getUniqueId())
|
||||
{
|
||||
if (copy.m_texture)
|
||||
@@ -148,12 +152,11 @@ m_cacheId (getUniqueId())
|
||||
////////////////////////////////////////////////////////////
|
||||
Texture::~Texture()
|
||||
{
|
||||
// Destroy the OpenGL texture
|
||||
if (m_texture)
|
||||
{
|
||||
if (m_ownsData)
|
||||
C3D_TexDelete(m_texture);
|
||||
|
||||
if (m_texture)
|
||||
delete m_texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -295,6 +298,74 @@ bool Texture::loadFromImage(const Image& image, const IntRect& area)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::loadFromPreprocessedFile(const std::string& filename, size_t width, size_t height, GPU_TEXCOLOR format)
|
||||
{
|
||||
if (filename.empty())
|
||||
return false;
|
||||
|
||||
FileInputStream file;
|
||||
file.open(filename);
|
||||
|
||||
size_t size = file.getSize();
|
||||
void *data = malloc(size);
|
||||
file.read(data, size);
|
||||
|
||||
bool ret = loadFromPreprocessedMemory(data, size, width, height, format, true);
|
||||
free(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Texture::loadFromPreprocessedMemory(void *data, size_t size, size_t width, size_t height, GPU_TEXCOLOR format, bool copyData)
|
||||
{
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
m_ownsData = copyData;
|
||||
m_size.x = width;
|
||||
m_size.y = height;
|
||||
m_actualSize = m_size;
|
||||
m_pixelsFlipped = false;
|
||||
|
||||
ensureGlContext();
|
||||
|
||||
// Create the citro3d texture, or delete if already created
|
||||
if (!m_texture)
|
||||
m_texture = new C3D_Tex();
|
||||
else
|
||||
C3D_TexDelete(m_texture);
|
||||
|
||||
if (!m_texture)
|
||||
return false;
|
||||
|
||||
if (copyData)
|
||||
{
|
||||
C3D_TexInit(m_texture, width, height, format);
|
||||
C3D_TexUpload(m_texture, data);
|
||||
}
|
||||
else
|
||||
m_texture->data = data;
|
||||
|
||||
m_texture->size = size;
|
||||
m_texture->fmt = format;
|
||||
m_texture->height = height;
|
||||
m_texture->width = width;
|
||||
|
||||
C3D_TexSetWrap(m_texture,
|
||||
m_isRepeated ? GPU_REPEAT : GPU_CLAMP_TO_EDGE,
|
||||
m_isRepeated ? GPU_REPEAT : GPU_CLAMP_TO_EDGE);
|
||||
C3D_TexSetFilter(m_texture,
|
||||
m_isSmooth ? GPU_LINEAR : GPU_NEAREST,
|
||||
m_isSmooth ? GPU_LINEAR : GPU_NEAREST);
|
||||
|
||||
m_cacheId = getUniqueId();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Vector2u Texture::getSize() const
|
||||
{
|
||||
@@ -312,9 +383,19 @@ Image Texture::copyToImage() const
|
||||
// Create an array of pixels
|
||||
std::vector<Uint8> pixels(m_size.x * m_size.y * 4);
|
||||
|
||||
u32 *data = (u32*)malloc(m_texture->size);
|
||||
u32 *data = (u32*)linearAlloc(m_texture->size);
|
||||
|
||||
imageUntile32((u8*)data, (u8*)m_texture->data, 0, 0, m_texture->width, m_texture->height, m_texture->width, m_texture->height);
|
||||
if (m_texture->width < 64 || m_texture->height < 64)
|
||||
imageUntile32((u8*)data, (u8*)m_texture->data, 0, 0, m_texture->width, m_texture->height, m_texture->width, m_texture->height);
|
||||
else
|
||||
{
|
||||
u32 dim = GX_BUFFER_DIM(m_texture->width, m_texture->height);
|
||||
GX_DisplayTransfer((u32*)m_texture->data, dim, data, dim, TEXTURE_TRANSFER_FLAGS);
|
||||
gspWaitForPPF();
|
||||
GSPGPU_FlushDataCache(data, m_texture->size);
|
||||
for (int i = 0; i < m_texture->width * m_texture->height; ++i)
|
||||
data[i] = __builtin_bswap32(data[i]);
|
||||
}
|
||||
|
||||
if ((m_size == m_actualSize) && !m_pixelsFlipped)
|
||||
{
|
||||
@@ -354,7 +435,7 @@ Image Texture::copyToImage() const
|
||||
Image image;
|
||||
image.create(m_size.x, m_size.y, &pixels[0]);
|
||||
|
||||
free(data);
|
||||
linearFree(data);
|
||||
|
||||
return image;
|
||||
}
|
||||
@@ -376,11 +457,37 @@ void Texture::update(const Uint8* pixels, unsigned int width, unsigned int heigh
|
||||
|
||||
if (pixels && m_texture)
|
||||
{
|
||||
u8* dest = (u8*)m_texture->data;
|
||||
if (m_texture->width < 64 || m_texture->height < 64)
|
||||
{
|
||||
u8* dest = (u8*)m_texture->data;
|
||||
|
||||
imageTile32(dest, pixels, x, y, width, height, m_texture->width, m_texture->height);
|
||||
imageTile32(dest, pixels, x, y, width, height, m_texture->width, m_texture->height);
|
||||
|
||||
C3D_TexFlush(m_texture);
|
||||
C3D_TexFlush(m_texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
const u32 *pixels32 = reinterpret_cast<const u32*>(pixels);
|
||||
u32 *data = (u32*)linearAlloc(m_texture->size);
|
||||
u32 dim = GX_BUFFER_DIM(m_texture->width, m_texture->height);
|
||||
|
||||
GX_DisplayTransfer((u32*)m_texture->data, dim, data, dim, TEXTURE_TRANSFER_FLAGS);
|
||||
gspWaitForPPF();
|
||||
|
||||
for (int h = 0; h < height; ++h)
|
||||
{
|
||||
for (int w = 0; w < width; ++w)
|
||||
{
|
||||
data[(y+h)*m_texture->width+x+w] = __builtin_bswap32(pixels32[(h*width) + w]);
|
||||
}
|
||||
}
|
||||
GSPGPU_FlushDataCache(data, m_texture->size);
|
||||
|
||||
GX_DisplayTransfer(data, dim, (u32*)m_texture->data, dim, TEXTURE_TRANSFER_FLAGS | GX_TRANSFER_OUT_TILED(1));
|
||||
gspWaitForPPF();
|
||||
|
||||
linearFree(data);
|
||||
}
|
||||
|
||||
m_pixelsFlipped = false;
|
||||
m_cacheId = getUniqueId();
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
namespace cpp3ds {
|
||||
|
||||
// System font sheets to be fetched and released by Game
|
||||
cpp3ds::Texture *system_font_textures = nullptr;
|
||||
|
||||
//Apt hook cookie
|
||||
static aptHookCookie apt_hook_cookie;
|
||||
@@ -21,12 +23,12 @@ static void apt_clock_hook(APT_HookType hook, void* param)
|
||||
}
|
||||
|
||||
|
||||
Game::Game()
|
||||
Game::Game(size_t gpuCommandBufSize)
|
||||
: m_triggerExit(false)
|
||||
{
|
||||
if (!Console::isEnabled() && !Console::isEnabledBasic())
|
||||
gfxInitDefault();
|
||||
CitroInit();
|
||||
CitroInit(gpuCommandBufSize);
|
||||
osSetSpeedupEnable(true);
|
||||
Service::enable(RomFS);
|
||||
I18n::getInstance(); // Init and load localization file(s)
|
||||
@@ -39,11 +41,27 @@ Game::Game()
|
||||
if (!Shader::Default.loadBinary(defaultShader.data, defaultShader.size, Shader::Vertex)){
|
||||
err() << "Failed to load default_shader.vsh from cpp3ds core.";
|
||||
}
|
||||
|
||||
// Load system font texture sheets
|
||||
if (R_SUCCEEDED(fontEnsureMapped()))
|
||||
{
|
||||
TGLP_s* glyphInfo = fontGetGlyphInfo();
|
||||
system_font_textures = new cpp3ds::Texture[glyphInfo->nSheets];
|
||||
for (int i = 0; i < glyphInfo->nSheets; ++i)
|
||||
{
|
||||
system_font_textures[i].loadFromPreprocessedMemory(
|
||||
fontGetGlyphSheetTex(i), glyphInfo->sheetSize,
|
||||
glyphInfo->sheetWidth, glyphInfo->sheetHeight,
|
||||
(GPU_TEXCOLOR)glyphInfo->sheetFmt, false);
|
||||
system_font_textures[i].setSmooth(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
delete[] system_font_textures;
|
||||
Service::disable(All);
|
||||
CitroDestroy();
|
||||
gfxExit();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace cpp3ds {
|
||||
|
||||
Game::Game()
|
||||
Game::Game(size_t gpuCommandBufSize)
|
||||
: m_triggerExit(false)
|
||||
{
|
||||
priv::ensureExtensionsInit();
|
||||
|
||||
Reference in New Issue
Block a user