diff --git a/CMakeLists.txt b/CMakeLists.txt index ef3e2aa..50a74e3 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED true) option(AMY_GOD_DEV "Turn this on if you think you are god" OFF) # THis option should be disabled if you use STB_IMAGE in you main project -set(AMY_BUILD_STB_IMAGE CACHE BOOL 0) +set(AMY_BUILD_STB_IMAGE 0) set(AMY_BUILD_STB_TRUETYPE 1) set(AMY_WITH_MPG123 "Include MP3 Support" CACHE BOOL 1) diff --git a/example/source/main.cpp b/example/source/main.cpp index a0a5a28..1a9123e 100755 --- a/example/source/main.cpp +++ b/example/source/main.cpp @@ -11,18 +11,18 @@ class Example : public Amy::App { Top = C3D::CreateScreen(GFX_TOP); Mgr = new Amy::AssetMgr(); Iron::Init(); + Mgr->AutoLoad("icon", "romfs:/icon.png"); auto fnt = Iron::Font::New(); fnt->LoadBMF("romfs:/ComicNeue.png"); - Mgr->AutoLoad("icon", "romfs:/icon.png"); Mgr->Add("font", fnt); // Mgr->AutoLoad("font", "romfs:/ComicNeue.ttf"); - dl = new Iron::Drawlist(); + dl = Iron::Drawlist::New(); dl->SetFont(Mgr->Get("font")); } ~Example() { + dl.reset(); delete Top; - delete dl; delete Mgr; Iron::Exit(); C3D::Deinit(); @@ -59,7 +59,7 @@ class Example : public Amy::App { Iron::NewFrame(); Iron::DrawOn(Top); - Iron::Draw(*dl); + Iron::Draw(dl->Data()); dl->Clear(); C3D::EndFrame(); Amy::GTrace::End("Main"); @@ -67,7 +67,7 @@ class Example : public Amy::App { C3D::Screen* Top; Amy::AssetMgr* Mgr; - Iron::Drawlist* dl; + Iron::Drawlist::Ref dl = nullptr; }; int main() { diff --git a/include/amethyst/iron.hpp b/include/amethyst/iron.hpp index 8715a65..16ef130 100644 --- a/include/amethyst/iron.hpp +++ b/include/amethyst/iron.hpp @@ -70,7 +70,7 @@ class Iron { struct Codepoint { ui Cp = 0; fvec4 Uv; - Texture::Ref Tex; + Texture::Ref Tex = nullptr; fvec2 Size; float Offset = 0; // Unused?? bool Valid = true; @@ -213,7 +213,7 @@ class Iron { private: static void pSetupShader(); - static void pFragConfig(); + static void pFragConfig(GPU_TEXCOLOR clr); static void pInitSolidTex(); static bool pCheckSize(size_t idx, size_t vtx); diff --git a/source/c3d.cpp b/source/c3d.cpp index 39782d2..2d44a39 100755 --- a/source/c3d.cpp +++ b/source/c3d.cpp @@ -69,15 +69,14 @@ void C3D::Shader::Load(const std::vector& data) { } void C3D::Shader::Compile(const std::string& code) { - auto ret = Pica::AssembleCode(code.c_str()); - Load(ret); + Load(Pica::AssembleCode(code.c_str())); } void C3D::Shader::Use() { - // C3D_BindProgram(&pProgram); // code works perfectly without C3D_BindProgram - // but nor withour shaderProgramUse ... + // but nor without shaderProgramUse ... shaderProgramUse(&pProgram); + C3D_BindProgram(&pProgram); C3D_SetAttrInfo(&pInfo); } diff --git a/source/image.cpp b/source/image.cpp index 17270cc..b398a2f 100755 --- a/source/image.cpp +++ b/source/image.cpp @@ -92,6 +92,17 @@ int Image::GetBppOfFmt(const Image::Format& fmt) { void Image::Convert(Image& img, const Format& dst) { if (img.pFmt == dst) { return; + } else if (img.pFmt == RGBA && dst == A8) { + std::vector cpy = img.pBuffer; + img.pBuffer.resize(img.pW * img.pH); + for (int y = 0; y < img.pH; y++) { + for (int x = 0; x < img.pW; x++) { + int src = (y * img.pW + x) * 4; + int dst = (y * img.pW + x); + img.pBuffer[dst] = cpy[src + 3]; + } + } + img.pFmt = A8; } else if (img.pFmt == RGB && dst == BGR) { Utils::Image::ReverseBuf(img.pBuffer, img.pW, img.pH, 3); img.pFmt = BGR; diff --git a/source/iron/font.cpp b/source/iron/font.cpp index 8bb8d59..fbe3d54 100644 --- a/source/iron/font.cpp +++ b/source/iron/font.cpp @@ -12,12 +12,14 @@ namespace Amy { // Dont read this code please ... tnaks void Iron::Font::LoadBMF(ksr path) { Image img(path); - if (img.Width() != img.Height() || img.Bpp() != 4) { + img.Convert(Image::A8); + if (img.Width() != img.Height() || img.Bpp() != 1 || img.Width() <= 0 || + img.Height() <= 0) { throw std::runtime_error( "[Amy] Font: BMF is not in rgba or not 1x1 dimensioned!"); } auto base = Amy::Texture::New(); - base->Load(img.GetBuffer(), img.Width(), img.Height(), img.Bpp()); + base->Load(img.GetBuffer(), img.Width(), img.Height(), img.Bpp(), img.Fmt()); base->Unloadable(false); PxHeight = img.Height() / 16; for (int i = 0; i < img.Height(); i += PxHeight) { @@ -26,25 +28,26 @@ void Iron::Font::LoadBMF(ksr path) { Amy::Texture::Ref tex = Amy::Texture::New(); for (int y = i; y < i + PxHeight; y++) { for (int x = j; x < j + PxHeight; x++) { - if (img.GetBuffer()[((y * img.Width() + x) * 4) + 3] != 0) { + if (img.GetBuffer()[y * img.Width() + x] != 0) { maxw = std::max(maxw, x - j); } } } - maxw++; - tex->Load(base->Ptr(), base->Size(), base->Uv()); Codepoint cp; + cp.Valid = maxw != 0; cp.Cp = (i / PxHeight) * 16 + (j / PxHeight); cp.Offset = 0.f; - cp.Size = fvec2(maxw, PxHeight); - cp.Tex = tex; - cp.Uv = fvec4(float(j) / float(img.Width()), - 1.f - float(i) / float(img.Height()), - float(j + maxw) / float(img.Width()), - 1.f - float(i + PxHeight) / float(img.Height())); - cp.Valid = maxw != 0; + if (cp.Valid) { + tex->Load(base->Ptr(), base->Size(), base->Uv()); + cp.Size = fvec2(maxw + 1, PxHeight); + cp.Tex = tex; + cp.Uv = fvec4(float(j) / float(img.Width()), + 1.f - float(i) / float(img.Height()), + float(j + maxw + 1) / float(img.Width()), + 1.f - float(i + PxHeight) / float(img.Height())); + Textures.push_back(tex); + } pCodeMap[(i / PxHeight) * 16 + (j / PxHeight)] = cp; - Textures.push_back(tex); } } } @@ -81,7 +84,7 @@ void Iron::Font::LoadTTF(const vec& data, int size) { // Cache to not render same codepoint tex twice std::map buf_cache; - std::vector font_tex(texszs * texszs * 4, 0); + std::vector font_tex(texszs * texszs, 0); auto tex = Texture::New(); fvec2 off; @@ -147,12 +150,8 @@ void Iron::Font::LoadTTF(const vec& data, int size) { for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { int map_pos = ((static_cast(off.y) + y) * texszs + - (static_cast(off.x) + x)) * - 4; - font_tex[map_pos + 0] = 255; - font_tex[map_pos + 1] = 255; - font_tex[map_pos + 2] = 255; - font_tex[map_pos + 3] = bitmap[x + y * w]; + (static_cast(off.x) + x)); + font_tex[map_pos] = bitmap[x + y * w]; } } @@ -171,7 +170,7 @@ void Iron::Font::LoadTTF(const vec& data, int size) { void Iron::Font::pMakeAtlas(bool final, vec& font_tex, int texszs, Texture::Ref tex) { - tex->Load(font_tex, texszs, texszs); + tex->Load(font_tex, texszs, texszs, 1, Amy::Image::A8); Textures.push_back(tex); } diff --git a/source/iron/iron.cpp b/source/iron/iron.cpp index f9faf62..a761694 100644 --- a/source/iron/iron.cpp +++ b/source/iron/iron.cpp @@ -80,14 +80,14 @@ void Iron::DrawOn(C3D::Screen* screen) { void Iron::Draw(const std::vector& data) { // disable depthtest cause we have no z buffer C3D::DepthTest(false); - pFragConfig(); size_t i = 0; while (i < data.size()) { Texture::Ref tex = data[i]->Tex; - if (!tex) { + if (!tex || !tex->Ptr()) { i++; continue; } + pFragConfig(tex->Ptr()->fmt); auto scissorOn = data[i]->ScissorOn; auto scissor = data[i]->ScissorRect; auto start = m_idx; @@ -133,17 +133,30 @@ void Iron::pSetupShader() { uLocProj = m_shader->loc("projection"); } -void Iron::pFragConfig() { +void Iron::pFragConfig(GPU_TEXCOLOR clr) { C3D::Frag::Edit(); - C3D::Frag::Src(C3D_Both, GPU_TEXTURE0); - C3D::Frag::Func(C3D_Both, GPU_MODULATE); + switch (clr) { + case GPU_A4: + case GPU_A8: + case GPU_L4: + case GPU_L8: + C3D::Frag::Src(C3D_Alpha, GPU_TEXTURE0); + C3D::Frag::Func(C3D_RGB, GPU_REPLACE); + C3D::Frag::Func(C3D_Alpha, GPU_MODULATE); + break; + + default: + C3D::Frag::Src(C3D_Both, GPU_TEXTURE0); + C3D::Frag::Func(C3D_Both, GPU_MODULATE); + break; + } } void Iron::pInitSolidTex() { // i know there is a lot of memory wasted :( - std::vector pixels(16 * 16 * 4, 0xff); + std::vector pixels(16 * 16, 0xff); m_solid = Texture::New(); - m_solid->Load(pixels, 16, 16); + m_solid->Load(pixels, 16, 16, 1, Amy::Image::A8); if (!m_solid->Ptr()) { throw Error("white tex failed to load!"); }