mirror of
https://github.com/wiiu-env/AutobootModule.git
synced 2024-11-25 03:56:58 +01:00
221 lines
9.9 KiB
C++
221 lines
9.9 KiB
C++
|
#include "SplashScreenDrawer.h"
|
||
|
#include "ShaderSerializer.h"
|
||
|
#include "TGATexture.h"
|
||
|
#include "gfx.h"
|
||
|
#include "logger.h"
|
||
|
#include "utils.h"
|
||
|
#include <fstream>
|
||
|
#include <gx2/draw.h>
|
||
|
#include <gx2/mem.h>
|
||
|
#include <gx2r/draw.h>
|
||
|
#include <whb/log.h>
|
||
|
|
||
|
/*
|
||
|
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<uint8_t> 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;
|
||
|
}
|
||
|
}
|