#include "SplashScreenDrawer.h" #include "ShaderSerializer.h" #include "TGATexture.h" #include "gfx.h" #include "logger.h" #include "utils.h" #include #include #include #include #include /* constexpr const char *s_textureVertexShader = R"( #version 450 layout(location = 0) in vec2 aPos; layout(location = 1) in vec2 aTexCoord; layout(location = 0) out vec2 TexCoord; void main() { TexCoord = aTexCoord; gl_Position = vec4(aPos.x, aPos.y, 0.0f, 1.0f); } )"; */ constexpr uint8_t s_textureVertexShaderCompiled[] = { 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x8A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x89, 0x00, 0x40, 0x01, 0xC0, 0xC8, 0x0F, 0x00, 0x94, 0x3C, 0xA0, 0x00, 0xC0, 0x08, 0x0B, 0x00, 0x94, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x61, 0x50, 0x6F, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0x54, 0x65, 0x78, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; /* constexpr const char *s_texturePixelShader = R"( #version 450 #extension GL_ARB_shading_language_420pack: enable layout(location = 0) in vec2 TexCoord; layout(location = 0) out vec4 FragColor; layout(binding = 0) uniform sampler2D inTexture; void main() { FragColor = texture(inTexture, TexCoord); } )";*/ constexpr uint8_t s_texturePixelShaderCompiled[] = { 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x88, 0x06, 0x20, 0x94, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0D, 0xF0, 0x00, 0x00, 0x80, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x69, 0x6E, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static GX2Texture *LoadTGAAsTexture(std::string_view path) { std::vector buffer; if (!LoadFileIntoBuffer(path, buffer)) { return nullptr; } auto *texture = TGA_LoadTexture(buffer); if (texture == nullptr) { return nullptr; } return texture; } SplashScreenDrawer::SplashScreenDrawer(std::string_view meta_dir) { // create shader group mVertexShaderWrapper = DeserializeVertexShader(s_textureVertexShaderCompiled); mPixelShaderWrapper = DeserializePixelShader(s_texturePixelShaderCompiled); mShaderGroup = {}; mShaderGroup.vertexShader = mVertexShaderWrapper->getVertexShader(); mShaderGroup.pixelShader = mPixelShaderWrapper->getPixelShader(); GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, mShaderGroup.vertexShader->program, mShaderGroup.vertexShader->size); GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, mShaderGroup.pixelShader->program, mShaderGroup.pixelShader->size); GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK); GfxInitShaderAttribute(&mShaderGroup, "aPos", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32); GfxInitShaderAttribute(&mShaderGroup, "aTexCoord", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32); GfxInitFetchShader(&mShaderGroup); // upload vertex position mPositionBuffer.flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_READ | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; mPositionBuffer.elemSize = 2 * sizeof(float); mPositionBuffer.elemCount = 4; GX2RCreateBuffer(&mPositionBuffer); void *posUploadBuffer = GX2RLockBufferEx(&mPositionBuffer, GX2R_RESOURCE_BIND_NONE); memcpy(posUploadBuffer, mPositionData, mPositionBuffer.elemSize * mPositionBuffer.elemCount); GX2RUnlockBufferEx(&mPositionBuffer, GX2R_RESOURCE_BIND_NONE); // upload texture coords mTexCoordBuffer.flags = GX2R_RESOURCE_BIND_VERTEX_BUFFER | GX2R_RESOURCE_USAGE_CPU_READ | GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ; mTexCoordBuffer.elemSize = 2 * sizeof(float); mTexCoordBuffer.elemCount = 4; GX2RCreateBuffer(&mTexCoordBuffer); void *coordsUploadBuffer = GX2RLockBufferEx(&mTexCoordBuffer, GX2R_RESOURCE_BIND_NONE); memcpy(coordsUploadBuffer, mTexCoords, mTexCoordBuffer.elemSize * mTexCoordBuffer.elemCount); GX2RUnlockBufferEx(&mTexCoordBuffer, GX2R_RESOURCE_BIND_NONE); std::string bootTvTex = std::string(meta_dir).append("/bootTvTex.tga"); std::string bootDrcTex = std::string(meta_dir).append("/bootDrcTex.tga"); mTextureTV = LoadTGAAsTexture(bootTvTex); mTextureDRC = LoadTGAAsTexture(bootDrcTex); GX2Sampler sampler; GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); } void SplashScreenDrawer::Draw() { if (!mTextureTV || !mTextureDRC) { DEBUG_FUNCTION_LINE_ERR("Textures are missing"); return; } GfxBeginRender(); GfxBeginRenderTV(); GX2SetFetchShader(&mShaderGroup.fetchShader); GX2SetVertexShader(mShaderGroup.vertexShader); GX2SetPixelShader(mShaderGroup.pixelShader); GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK); GX2RSetAttributeBuffer(&mPositionBuffer, 0, mPositionBuffer.elemSize, 0); GX2RSetAttributeBuffer(&mTexCoordBuffer, 1, mTexCoordBuffer.elemSize, 0); GX2SetPixelTexture(mTextureTV, mShaderGroup.pixelShader->samplerVars[0].location); GX2SetPixelSampler(&mSampler, mShaderGroup.pixelShader->samplerVars[0].location); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); GfxFinishRenderTV(); GfxBeginRenderDRC(); GX2SetFetchShader(&mShaderGroup.fetchShader); GX2SetVertexShader(mShaderGroup.vertexShader); GX2SetPixelShader(mShaderGroup.pixelShader); GX2SetShaderMode(GX2_SHADER_MODE_UNIFORM_BLOCK); GX2RSetAttributeBuffer(&mPositionBuffer, 0, mPositionBuffer.elemSize, 0); GX2RSetAttributeBuffer(&mTexCoordBuffer, 1, mTexCoordBuffer.elemSize, 0); GX2SetPixelTexture(mTextureDRC, mShaderGroup.pixelShader->samplerVars[0].location); GX2SetPixelSampler(&mSampler, mShaderGroup.pixelShader->samplerVars[0].location); GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); GfxFinishRenderDRC(); GfxFinishRender(); } SplashScreenDrawer::~SplashScreenDrawer() { GX2RDestroyBufferEx(&mPositionBuffer, GX2R_RESOURCE_BIND_NONE); GX2RDestroyBufferEx(&mTexCoordBuffer, GX2R_RESOURCE_BIND_NONE); if (mTextureTV) { if (mTextureTV->surface.image != nullptr) { free(mTextureTV->surface.image); mTextureTV->surface.image = nullptr; } ::free(mTextureTV); mTextureTV = nullptr; } if (mTextureDRC) { if (mTextureDRC->surface.image != nullptr) { free(mTextureDRC->surface.image); mTextureDRC->surface.image = nullptr; } ::free(mTextureDRC); mTextureDRC = nullptr; } }