summaryrefslogblamecommitdiffstats
path: root/src/Rml.cpp
blob: d886377d29f89ba69ef93347a88255a496bb7aa1 (plain) (tree)
1
2
3
4
5




                           
































                                                                                      







                                                                    
                                                                  



                                                                                                                          
 

                                                                                                                            
 


                                                                                                                                        
 
                                        

                                       

                                      






                                                                               
 




                                                                                         
 
                                                               
 
                                                      
 





























                                                                                  
 
    


                                           


                                                                                                                                                                               

                                                                                                                             
    

                                      
                                
                                                                                                
                                                                   
                                        
                                                    
            
                             
                                                                                             
                                     

                                                 


                                                           
                                                 


                                                                                
                                                              






                                                                                                                                               






                                                                                                                                                                  
 



                                                                     
                                           


                                                                                      

                                                                                           
 

                            
 


























                                                                                                  
                                                                                               

















                                                                                             
#include "Rml.hpp"

#include <easylogging++.h>

#include "AssetManager.hpp"
#include "Utility.hpp"

double RmlSystemInterface::GetElapsedTime() {
	return totalTime;
}

bool RmlSystemInterface::LogMessage(Rml::Log::Type type, const Rml::String& message) {
    switch (type) {
    case Rml::Log::Type::LT_ALWAYS:
        LOG(ERROR) << message;
        break;
    case Rml::Log::Type::LT_ERROR:
        LOG(ERROR) << message;
        break;
    case Rml::Log::Type::LT_ASSERT:
        LOG(ERROR) << message;
        break;
    case Rml::Log::Type::LT_WARNING:
        LOG(WARNING) << message;
        break;
    case Rml::Log::Type::LT_INFO:
        LOG(INFO) << message;
        break;
    case Rml::Log::Type::LT_DEBUG:
        LOG(DEBUG) << message;
        break;
    case Rml::Log::Type::LT_MAX:
        LOG(DEBUG) << message;
        break;
    }
    return true;
}

void RmlSystemInterface::SetClipboardText(const Rml::String& text) {
    clipboard = text;
}

void RmlSystemInterface::GetClipboardText(Rml::String& text) {
    text = clipboard;
}

RmlRenderInterface::RmlRenderInterface(RenderState& renderState) {
    std::string vertexSource, pixelSource, texPixelSource;
    {
        auto vertAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/vert/rml");
        vertexSource = std::string((char*)vertAsset->data.data(), (char*)vertAsset->data.data() + vertAsset->data.size());

        auto pixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rml");
        pixelSource = std::string((char*)pixelAsset->data.data(), (char*)pixelAsset->data.data() + pixelAsset->data.size());

        auto texPixelAsset = AssetManager::GetAssetByAssetName("/altcraft/shaders/frag/rmltex");
        texPixelSource = std::string((char*)texPixelAsset->data.data(), (char*)texPixelAsset->data.data() + texPixelAsset->data.size());
    }

    auto gal = Gal::GetImplementation();

    vertexBuffer = gal->CreateBuffer();
    indexBuffer = gal->CreateBuffer();

    {
        auto pipelineConfig = gal->CreatePipelineConfig();
        pipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32);
        pipelineConfig->AddShaderParameter("translation", Gal::Type::Vec2);
        pipelineConfig->SetTarget(gal->GetDefaultFramebuffer());
        pipelineConfig->SetVertexShader(gal->LoadVertexShader(vertexSource));
        pipelineConfig->SetPixelShader(gal->LoadPixelShader(pixelSource));

        auto vertBuffBind = pipelineConfig->BindVertexBuffer({
            {"pos", Gal::Type::Vec2},
            {"color", Gal::Type::Vec4u8},
            {"", Gal::Type::Vec2}, //it's not used in shader, so driver optimizes it away
            });

        auto indexBuffBind = pipelineConfig->BindIndexBuffer();

        pipeline = gal->BuildPipeline(pipelineConfig);

        pipelineInstance = pipeline->CreateInstance({
            {vertBuffBind, vertexBuffer},
            {indexBuffBind, indexBuffer},
            });
    }
    
    {
        auto texPipelineConfig = gal->CreatePipelineConfig();
        texPipelineConfig->AddShaderParameter("viewportSize", Gal::Type::Vec2u32);
        texPipelineConfig->AddShaderParameter("translation", Gal::Type::Vec2);
        texPipelineConfig->AddShaderParameter("fontTexture", Gal::Type::Int32);
        texPipelineConfig->SetTarget(gal->GetDefaultFramebuffer());
        texPipelineConfig->SetVertexShader(gal->LoadVertexShader(vertexSource));
        texPipelineConfig->SetPixelShader(gal->LoadPixelShader(texPixelSource));

        auto texVertBuffBind = texPipelineConfig->BindVertexBuffer({
            {"pos", Gal::Type::Vec2},
            {"color", Gal::Type::Vec4u8},
            {"tex_coord", Gal::Type::Vec2},
            });

        auto texIndexBuffBind = texPipelineConfig->BindIndexBuffer();

        texPipeline = gal->BuildPipeline(texPipelineConfig);

        texPipelineInstance = texPipeline->CreateInstance({
            {texVertBuffBind, vertexBuffer},
            {texIndexBuffBind, indexBuffer},
            });
    }

    
}

RmlRenderInterface::~RmlRenderInterface() {
}

void RmlRenderInterface::RenderGeometry(Rml::Vertex* vertices, int num_vertices, int* indices, int num_indices, Rml::TextureHandle texture, const Rml::Vector2f& translation) {
    indexBuffer->SetData({ reinterpret_cast<std::byte*>(indices), reinterpret_cast<std::byte*>(indices + num_indices) });
    vertexBuffer->SetData({ reinterpret_cast<std::byte*>(vertices), reinterpret_cast<std::byte*>(vertices + num_vertices) });
    
    auto tex = textures.find(texture);
    if (tex != textures.end()) {
        texPipeline->Activate();
        texPipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y));
        texPipeline->SetDynamicTexture("fontTexture", tex->second);
        texPipelineInstance->Activate();
        texPipelineInstance->Render(0, num_indices);
    } else {
        pipeline->Activate();
        pipeline->SetShaderParameter("translation", glm::vec2(translation.x, translation.y));
        pipelineInstance->Activate();
        pipelineInstance->Render(0, num_indices);
    }
}

void RmlRenderInterface::EnableScissorRegion(bool enable) {
    Gal::GetImplementation()->SetScissor(enable);
}

void RmlRenderInterface::SetScissorRegion(int x, int y, int width, int height) {
    Gal::GetImplementation()->SetScissor(x, y, width, height);
}

bool RmlRenderInterface::LoadTexture(Rml::TextureHandle& texture_handle, Rml::Vector2i& texture_dimensions, const Rml::String& source) {
    return false;
}

bool RmlRenderInterface::GenerateTexture(Rml::TextureHandle& texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions) {
    size_t textureId = textures.empty() ? 1 : textures.rbegin()->first + 1;
    auto gal = Gal::GetImplementation();
    auto textureConfig = gal->CreateTexture2DConfig(source_dimensions.x, source_dimensions.y, Gal::Format::R8G8B8A8);
    auto texture = gal->BuildTexture(textureConfig);
    texture->SetData({ reinterpret_cast<const std::byte*>(source),reinterpret_cast<const std::byte*>(source + (source_dimensions.x * source_dimensions.y) * 4) });
    textures.insert({ textureId,texture });
    texture_handle = textureId;

    return true;
}

void RmlRenderInterface::ReleaseTexture(Rml::TextureHandle texture) {
    textures.erase(textures.find(texture));
}

void RmlRenderInterface::Update(unsigned int windowWidth, unsigned int windowHeight) {
    pipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight));
    texPipeline->SetShaderParameter("viewportSize", glm::uvec2(windowWidth, windowHeight));

    vpWidth = windowWidth;
    vpHeight = windowHeight;
}

Rml::FileHandle RmlFileInterface::Open(const Rml::String& path) {
    Rml::FileHandle fileId = handles.rbegin() != handles.rend() ? handles.rbegin()->first + 1 : 1;
    while (handles.find(fileId) != handles.end())
        fileId++;

    AssetHandle handle;
    handle.fileName = path;
    std::string assetName = path;
    if (*assetName.begin() != '/')
        assetName = "/" + assetName;
    handle.assetPtr = AssetManager::GetAssetByAssetName(assetName);
    handle.filePos = 0;

    if (handle.assetPtr != nullptr)
        handles.insert(std::make_pair(fileId, handle));
    else
        fileId = 0;
    return fileId;
}

void RmlFileInterface::Close(Rml::FileHandle file) {
    handles.erase(file);
}

size_t RmlFileInterface::Read(void* buffer, size_t size, Rml::FileHandle file) {
    size_t readed = 0;
    readed = _min((size_t)(handles[file].assetPtr->data.size() - handles[file].filePos), size);
    std::memcpy(buffer, handles[file].assetPtr->data.data() + handles[file].filePos, readed);
    handles[file].filePos += readed;
    return readed;
}

bool RmlFileInterface::Seek(Rml::FileHandle file, long offset, int origin) {
    unsigned long long base = 0;
    if (origin == SEEK_CUR)
        base = handles[file].filePos;
    else if (origin == SEEK_END)
        base = handles[file].assetPtr->data.size();
    handles[file].filePos = base + offset;
    return true;
}

size_t RmlFileInterface::Tell(Rml::FileHandle file) {
    return handles[file].filePos;
}