You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lunarium_OLD/src/run_modes/testbed/scenes/simple_render_scene.cpp

407 lines
16 KiB
C++

/******************************************************************************
* File - simple_render_scene.cpp
* Author - Joey Pollack
* Date - 2021/10/27 (y/m/d)
* Mod Date - 2021/10/27 (y/m/d)
* Description - Displays a simple scene that tests basic render features.
******************************************************************************/
#include "simple_render_scene.h"
#include <core/core.h>
#include <gui/gui.h>
#include <utils/helpers.h>
#include <utils/logger.h>
#include <renderer/texture.h>
#include <renderer/frame_buffer.h>
#include <renderer/orthographic_camera.h>
#include <input/input_manager.h>
#include <utils/stb/std_image_write.h>
#include <utils/stb/stb_image.h>
#include <thread>
#include <chrono>
#include <cstdlib>
#include <ctime>
namespace lunarium
{
SimpleRenderScene::SimpleRenderScene(uint32_t logCat)
: BaseScene(logCat), mTestMode(TestMode::Basic), mFrameTime(0.0), mNumFrames(0), mpTestImageLoad3(nullptr)
{
srand((u32)time(0));
}
SimpleRenderScene::~SimpleRenderScene()
{
delete mpTestImageLoad;
}
void SimpleRenderScene::OnLoad()
{
Logger::Info(mLogCat, "Running Simple Render Test Scene");
mTextBoxWidth = 500;
// Currently the full default window size
mImageSize.Width = 1280;
mImageSize.Height = 720;
// Create the render textures
mFrameBufferOne = FrameBuffer::Create(mImageSize.Width, mImageSize.Height); //Core::Graphics().CreateRenderTexture(mImageSize.Width, mImageSize.Height, 4);
mFrameBufferTwo = FrameBuffer::Create(1024, 1024); //Core::Graphics().CreateRenderTexture(1024, 1024, 4);
// Load test image
int w, h, n;
stbi_set_flip_vertically_on_load(1);
unsigned char* buffer = stbi_load("LinkToThePast1_sized.png", &w, &h, &n, 0);
TextureFormat format = TextureFormat::RGBA;
if (n == 3)
{
format = TextureFormat::RGB;
}
mpTestImageLoad = Texture::Create(buffer, w, h, format);
mSrcWidth = w;
mSrcHeight = h;
delete[] buffer;
stbi_set_flip_vertically_on_load(0);
buffer = stbi_load("debug_texture.jpeg", &w, &h, &n, 0);
//buffer = stbi_load("lunarium_text_test.png", &w, &h, &n, 0);
format = TextureFormat::RGBA;
if (n == 3)
{
format = TextureFormat::RGB;
}
else if (n == 1)
{
format = TextureFormat::RED;
}
mpTestImageLoad2 = Texture::Create(buffer, w, h, format);
delete[] buffer;
stbi_set_flip_vertically_on_load(0);
buffer = stbi_load("lunarium_text_test.png", &w, &h, &n, 0);
format = TextureFormat::RGBA;
if (n == 3)
{
format = TextureFormat::RGB;
}
else if (n == 1)
{
format = TextureFormat::RED;
}
mpTestImageLoad3 = Texture::Create(buffer, w, h, format);
delete[] buffer;
mQuads = new Rectangle[NUM_QUADS];
for (int i = 0; i < NUM_QUADS; i++)
{
float x = (rand() % 1000);
float y = (rand() % 600);
float w = (rand() % 200) + 10;
float h = (rand() % 200) + 10;
mQuads[i] = Rectangle(x, y, w, h);
}
mQuadColors = new Color[NUM_QUADS];
mQuadTexures = new Texture*[NUM_QUADS];
for (int i = 0; i < NUM_QUADS; i++)
{
mQuadTexures[i] = (i % 2 == 0) ? mpTestImageLoad : mpTestImageLoad2;
mQuadColors[i].R = ((float)(rand() % 10000)) / 10000.0f;
mQuadColors[i].G = ((float)(rand() % 10000)) / 10000.0f;
mQuadColors[i].B = ((float)(rand() % 10000)) / 10000.0f;
mQuadColors[i].A = 1.0f;
}
angle = 0.0f;
box_angle = 0.0f;
mTextDebugPosX = 200;
mSubTex = Rectangle::MakeFromTopLeft(0, 0, 256, 256);
}
void SimpleRenderScene::OnTick(double delta)
{
if (Core::Input().IsKeyDown(KeyCode::ESCAPE))
{
Core::GetInstance().SignalShutdown();
}
// Textbox size adjustment
if (Core::Input().IsKeyDown(KeyCode::LEFT))
{
if (mTestMode == TestMode::Basic)
mTextBoxWidth -= 10;
if (mTestMode == TestMode::String)
mTextDebugPosX -= 10;
}
if (Core::Input().IsKeyDown(KeyCode::RIGHT))
{
mTextBoxWidth += 10;
if (mTestMode == TestMode::Basic)
mTextBoxWidth += 10;
if (mTestMode == TestMode::String)
mTextDebugPosX += 10;
}
if (Core::Input().IsKeyDown(KeyCode::R))
{
mSrcWidth -= 10.0f;
mSrcHeight -= 10.0f;
}
if (Core::Input().IsKeyDown(KeyCode::F))
{
mSrcWidth += 10.0f;
mSrcHeight += 10.0f;
}
mTextBoxWidth = Math::ClampI(mTextBoxWidth, 20, 500);
// Image Size adjustment
if (Core::Input().IsKeyDown(KeyCode::DOWN))
{
mImageSize.Width -= 10;
mImageSize.Height -= 10;
}
if (Core::Input().IsKeyDown(KeyCode::UP))
{
mImageSize.Width += 10;
mImageSize.Height += 10;
}
if (Core::Input().IsKeyDown(KeyCode::PAGE_UP))
{
angle += 0.1f;
}
if (Core::Input().IsKeyDown(KeyCode::PAGE_DOWN))
{
angle -= 0.1f;
}
if (Core::Input().IsKeyPressed(KeyCode::TAB))
{
if (mTestMode == TestMode::Basic)
mTestMode = TestMode::Stress;
else if (mTestMode == TestMode::Stress)
{
mSubTex = Rectangle::MakeFromTopLeft(2858, 0, 32, 32);
mTestMode = TestMode::String;
}
else if (mTestMode == TestMode::String)
{
mTestMode = TestMode::Basic;
mSubTex = Rectangle::MakeFromTopLeft(0, 0, 256, 256);
}
}
if (Core::Input().IsKeyPressed(KeyCode::Q))
{
// Test writing out a rendered image with transparency
Renderer2D& g = Core::Graphics();
Color prev = g.GetClearColor();
g.SetClearColor(Color(0.0f, 0.0f, 0.0f, 0.0f));
mFrameBufferTwo->Bind();
OrthographicCamera cam(Vec2f{0.0f, 0.0f}, Sizef{(float)mFrameBufferTwo->GetTexture()->GetWidth(), (float)mFrameBufferTwo->GetTexture()->GetHeight()});
g.BeginDraw(&cam);
// if (Failed(result))
// {
// Logger::Warn(mLogCat, "Unable to render to texture: %s", result.Description.c_str());
// return;
// }
Logger::Info(mLogCat, "Running transparent image test");
g.DrawQuad(Rectangle(500, 400, 300, 300), Color(0.5f, 0.0f, 0.75f, 1.0f));
g.DrawQuad(Rectangle(200, 300, 100, 100), Color(0.2f, 0.5f, 0.4f, 1.0f), nullptr, 45.0f);
g.DrawString("This is a test of rendering an image with transparency",
Rectangle::MakeFromTopLeft(50, 50, 600, 200), Color(0.0f, 1.0f, 0.2f, 1.0f), 0.5f);
g.EndDraw();
mpRenderedImage = mFrameBufferTwo->GetTexture();
mFrameBufferTwo->Unbind();
//mpRenderedImage = Core::GetInstance().EndRenderToTexture();
g.SetClearColor(prev);
stbi_flip_vertically_on_write(1);
stbi_write_png("lunarium_test_image.png", mpRenderedImage->GetWidth(), mpRenderedImage->GetHeight(), 4,
mpRenderedImage->GetPixels(), mpRenderedImage->GetWidth() * 4);
//Logger::Info(mLogCat, "")
}
if (Core::Input().IsKeyPressed(KeyCode::T))
{
Texture* dt = Core::Graphics().GetTextDebugTexture();
stbi_flip_vertically_on_write(0);
stbi_write_png("lunarium_text_test.png", dt->GetWidth(), dt->GetHeight(), 1,
dt->GetPixels(), dt->GetWidth() * 1);
Logger::Info(mLogCat, "Saved Text test image");
}
mImageSize.Width = Math::ClampI(mImageSize.Width, 320, 1280);
mImageSize.Height = Math::ClampI(mImageSize.Height, 180, 720);
// Render to texture testing
// mFrameBufferOne->Bind();
// OrthographicCamera cam(Vec2f{0.0f, 0.0f}, Sizef{(float)mFrameBufferOne->GetTexture()->GetWidth(), (float)mFrameBufferOne->GetTexture()->GetHeight()});
// Renderer2D& g = Core::Graphics();
// g.BeginDraw(&cam);
// // OpRes result = Core::GetInstance().BeginRenderToTexture(mFrameBufferOne);
// // if (Failed(result))
// // {
// // Logger::Error(mLogCat, "Unable to render to texture: %s", result.Description.c_str());
// // return;
// // }
// g.DrawQuad(Rectangle(300, 300, 150, 150), Color::Red());
// g.DrawQuad(Rectangle(200, 300, 100, 100), Color(0.2f, 0.5f, 0.4f, 1.0f), nullptr, 45.0f);
// //g.DrawFilledEllipse(glm::vec2(600, 300), glm::vec2(100, 150), Color(1.0f, 0.0f, 1.0f, 1.0f), 100);
// // g.DrawString("This is a test of the text renderer!", Rectangle::MakeFromTopLeft(100, 200, mTextBoxWidth, 300),
// // Color(0.0f, 1.0f, 1.0f, 1.0f), 0.5f, g.DefaultFont());
// //mpRenderedImage = Core::GetInstance().EndRenderToTexture();
// g.EndDraw();
// mpRenderedImage = mFrameBufferOne->GetTexture();
box_angle += 0.01f;
int w, h;
Core::MainWindow().GetFramebufferSize(&w, &h);
OrthographicCamera main_cam(Vec2f { 0.0f, 0.0f }, Sizef { (float)w, (float)h });
Core::GUI().NewFrame();
mTimer.Reset();
Core::Graphics().BeginDraw(&main_cam);
switch (mTestMode)
{
case TestMode::Basic: RenderScene(Core::Graphics()); break;
case TestMode::Stress: RenderBatchStressTest(Core::Graphics()); break;
case TestMode::String: RenderStringTest(Core::Graphics()); break;
}
Core::Graphics().EndDraw(); // Graphics end draw must happen before GUI end frame
DrawStatsGUI();
Core::GUI().EndFrame();
Core::MainWindow().SwapBuffers();
mFrameTime += mTimer.GetElapsedSeconds();
mNumFrames++;
mRenderStats = Core::Graphics().GetFrameStats();
Core::Graphics().ResetFrameStats();
//std::this_thread::sleep_for (std::chrono::seconds(2));
}
void SimpleRenderScene::RenderScene(Renderer2D& g)
{
// g.DrawImage(*mpRenderedImage, Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpRenderedImage->GetWidth(), (float)mpRenderedImage->GetHeight()),
// Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 1.0f, 1.0f), angle);
//g.DrawQuad(Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mImageSize.Width, (float)mImageSize.Height), Color(1.0f, 1.0f, 0.0f, 1.0f), nullptr, angle);
g.DrawQuad(Rectangle(100, 100, 16, 16), Color::White(), mpTestImageLoad2, 0.0f, mSubTex);
g.DrawSprite(mpTestImageLoad2, glm::vec2(600, 200), Rectangle::MakeFromTopLeft(255, 255, 255, 255));
// g.DrawQuad(Rectangle(200, 200, 128.0f, 128.0f), Color(0.0f, 1.0f, 0.0f, 1.0f));//, nullptr, box_angle);
// g.DrawQuad(Rectangle(400, 300, 64.0f, 64.0f), Color(0.0f, 1.0f, 1.0f, 1.0f), nullptr, box_angle);
// g.DrawQuad(Rectangle(600, 300, 100.0f, 100.0f), Color::Blue(), nullptr, 45.0f);
// g.DrawQuad(Rectangle(500, 600, 100.0f, 100.0f), Color(0.25f, 0.75f, 0.8f), nullptr, 65.0f);
// g.DrawQuad(Rectangle(800, 500, 100.0f, 100.0f), Color(0.75f, 0.5f, 0.425f), nullptr, 90.0f);
// g.DrawQuad(Rectangle(300, 400, 64.0f, 64.0f), Color(0.25f, 0.5f, 1.0f, 1.0f), nullptr, box_angle * -1);
//g.DrawQuads(mQuads, NUM_QUADS, mQuadColors);
//g->DrawImage(*mpTestImageLoad, glm::vec2(0.0f, 0.0f), Color::White());
//Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, (float)mpTestImageLoad->GetWidth(), (float)mpTestImageLoad->GetHeight());
//Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, mSrcWidth, mSrcHeight);
// Rectangle src = Rectangle::MakeFromTopLeft(0.0f, 0.0f, 16, 16);
// Rectangle dest = Rectangle::MakeFromTopLeft(100.0f, 100.0f, 512.0f, 512.0f);
//g.DrawImage(*mpTestImageLoad, src, dest, Color(1.0f, 1.0f, 1.0f, 0.9f));
// g->DrawImage(*mpTestImageLoad, src,
// dest, Color(1.0f, 1.0f, 1.0f, 0.8f));
}
void SimpleRenderScene::RenderBatchStressTest(Renderer2D& g)
{
for (int i = 0; i < mNumQuadsToRender; i++)
{
Texture* t = mUseTextures ? mQuadTexures[i] : nullptr;
g.DrawQuad(mQuads[i], mQuadColors[i], t, box_angle + (i / 10.0f));
}
}
void SimpleRenderScene::RenderStringTest(Renderer2D& g)
{
Texture* dt = g.GetTextDebugTexture();
g.DrawQuad(Rectangle(mTextDebugPosX, 300, dt->GetWidth() , dt->GetHeight() ), Color::Blue(), dt);
g.DrawQuad(Rectangle(200, 100, 32, 32), Color(0.25f, 0.75f, 0.6f, 1.0f), mpTestImageLoad3, 0.0f, mSubTex);
g.DrawString("A", Rectangle(200, 170, 32, 32), Color(0.25f, 0.75f, 0.6f, 1.0f));
g.DrawString("This is a test string!", Rectangle::MakeFromTopLeft(100, 500, 500, 50), Color::Green());
g.DrawString("This is a very long string that should end up on more than one line when printed out test string!", Rectangle::MakeFromTopLeft(300, 50, 400, 500), Color::Red());
}
void SimpleRenderScene::DrawStatsGUI()
{
std::string mode_names[3] = { "Basic", "Stress", "String" };
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(400, 800));
ImGui::Begin("RENDER INFO");
ImGui::BeginChild("Scene Info", ImVec2(ImGui::GetWindowSize().x - 15, ImGui::GetFrameHeightWithSpacing() * 3.5f), true);
ImGui::Text("Scene Info");
ImGui::Separator();
ImGui::Text("Scene Mode: %s", mode_names[mTestMode].c_str());
ImGui::EndChild();
ImGui::BeginChild("Per Frame", ImVec2(ImGui::GetWindowSize().x - 15, ImGui::GetFrameHeightWithSpacing() * 3.5f), true);
ImGui::Text("Per Frame");
ImGui::Separator();
ImGui::Text("Number of triangles: %d", mRenderStats.NumTris);
ImGui::Text("Draw calls: %d", mRenderStats.DrawCalls);
ImGui::EndChild();
ImGui::BeginChild("General", ImVec2(ImGui::GetWindowSize().x - 15, ImGui::GetFrameHeightWithSpacing() * 4.5f), true);
ImGui::Text("General Info");
ImGui::Separator();
ImGui::Text("Average Render time: %f", Core::GetInstance().GetFrameData().AverageFrameTime);
ImGui::Text("FPS: %d", Core::GetInstance().GetFrameData().CurrentFPS);
ImGui::Text("Frame Number: %d", mNumFrames);
ImGui::EndChild();
ImGui::BeginChild("Settings", ImVec2(ImGui::GetWindowSize().x - 15, ImGui::GetFrameHeightWithSpacing() * 4.5f), true);
ImGui::Text("Settings");
ImGui::Separator();
ImGui::InputInt("Number of Quads to draw", &mNumQuadsToRender);
ImGui::Checkbox("Draw Textures", &mUseTextures);
float vals[4] = {mSubTex.left(), mSubTex.top(), mSubTex.HalfWidth * 2, mSubTex.HalfHeight * 2 };
if (ImGui::DragFloat4("Sub Texture Rect", vals))
{
mSubTex = Rectangle::MakeFromTopLeft(vals[0], vals[1], vals[2], vals[3]);
}
ImGui::EndChild();
ImGui::End();
mNumQuadsToRender = Math::ClampI(mNumQuadsToRender, 0, NUM_QUADS);
}
}