mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
cppkore uses string/wstring as StringBase while we use std::string/std::wstring as string/wstring. Changed all types in cppkore to String/WString instead.
720 lines
23 KiB
C++
720 lines
23 KiB
C++
#include "stdafx.h"
|
|
#include <thread>
|
|
#include "AssetRenderer.h"
|
|
#include "Path.h"
|
|
#include "Thread.h"
|
|
|
|
// Include the internal font, and shaders
|
|
#include "FontArial.h"
|
|
#include "ModelFragmentShader.h"
|
|
#include "ModelVertexShader.h"
|
|
|
|
// We need to include the OpenGL classes
|
|
#include "Mangler.h"
|
|
|
|
namespace Assets
|
|
{
|
|
AssetRenderer::AssetRenderer()
|
|
: OpenGLViewport(), _Camera(0.5f* (float)MathHelper::PI, 0.45f* (float)MathHelper::PI, 100.f), _UseWireframe(false), _ShowBones(true), _ShowMaterials(true), _DrawingMode(DrawMode::Model), _DrawInformation{}, _BonePointBuffer(0), _BonePointCount(0), _DrawTexture(0)
|
|
{
|
|
}
|
|
|
|
AssetRenderer::~AssetRenderer()
|
|
{
|
|
ClearViewModel();
|
|
ClearViewTexture();
|
|
}
|
|
|
|
void AssetRenderer::SetViewModel(const Model& Model)
|
|
{
|
|
this->_DrawingMode = DrawMode::Model;
|
|
ClearViewModel();
|
|
ClearViewTexture();
|
|
|
|
for (auto& Submesh : Model.Meshes)
|
|
{
|
|
auto Draw = DrawObject();
|
|
|
|
glGenVertexArrays(1, &Draw.VertexArrayObject);
|
|
glBindVertexArray(Draw.VertexArrayObject);
|
|
|
|
// We'll take the POSITION, NORMAL, COLOR, and first UV pair...
|
|
const uint32_t Stride = sizeof(Vector3) + sizeof(Vector3) + sizeof(VertexColor) + sizeof(Vector2);
|
|
auto VertexBuffer = std::make_unique<uint8_t[]>((uint64_t)Submesh.Vertices.Count() * Stride);
|
|
|
|
uint64_t Offset = 0;
|
|
for (auto& Vertex : Submesh.Vertices)
|
|
{
|
|
std::memcpy(&VertexBuffer.get()[Offset], &Vertex.Position(), Stride);
|
|
Offset += Stride;
|
|
}
|
|
|
|
glGenBuffers(1, &Draw.VertexBuffer);
|
|
glBindBuffer(GL_ARRAY_BUFFER, Draw.VertexBuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, (Stride * (uint64_t)Submesh.Vertices.Count()), VertexBuffer.get(), GL_STATIC_DRAW);
|
|
|
|
glGenBuffers(1, &Draw.FaceBuffer);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Draw.FaceBuffer);
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (uint64_t)Submesh.Faces.Count() * 3 * sizeof(uint32_t), &Submesh.Faces[0], GL_STATIC_DRAW);
|
|
|
|
wglSwapIntervalEXT(1);
|
|
|
|
Draw.FaceCount = Submesh.Faces.Count();
|
|
Draw.VertexCount = Submesh.Vertices.Count();
|
|
|
|
if (Submesh.MaterialIndices.Count() > 0 && this->_MaterialStreamer != nullptr && Model.Materials.Count() != 0)
|
|
{
|
|
Assets::Material& Material = Model.Materials[Submesh.MaterialIndices[0]];
|
|
|
|
if (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
|
{
|
|
auto MaterialDiffuseMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Albedo].second);
|
|
if (MaterialDiffuseMap != nullptr)
|
|
{
|
|
glGenTextures(1, &Draw.Material.AlbedoMap);
|
|
this->LoadDXTextureOGL(*MaterialDiffuseMap.get(), Draw.Material.AlbedoMap);
|
|
}
|
|
}
|
|
|
|
if (Material.Slots.ContainsKey(MaterialSlotType::Normal))
|
|
{
|
|
auto MaterialNormalMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Normal].second);
|
|
if (MaterialNormalMap != nullptr)
|
|
{
|
|
glGenTextures(1, &Draw.Material.NormalMap);
|
|
this->LoadDXTextureOGL(*MaterialNormalMap.get(), Draw.Material.NormalMap);
|
|
|
|
}
|
|
}
|
|
|
|
if (Material.Slots.ContainsKey(MaterialSlotType::Gloss))
|
|
{
|
|
auto MaterialGlossMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Gloss].second);
|
|
if (MaterialGlossMap != nullptr)
|
|
{
|
|
glGenTextures(1, &Draw.Material.RoughnessMap);
|
|
this->LoadDXTextureOGL(*MaterialGlossMap.get(), Draw.Material.RoughnessMap);
|
|
|
|
}
|
|
}
|
|
|
|
if (Material.Slots.ContainsKey(MaterialSlotType::Specular))
|
|
{
|
|
auto MaterialSpecMap = this->_MaterialStreamer("", Material.Slots[MaterialSlotType::Specular].second);
|
|
if (MaterialSpecMap != nullptr)
|
|
{
|
|
glGenTextures(1, &Draw.Material.MetallicMap);
|
|
this->LoadDXTextureOGL(*MaterialSpecMap.get(), Draw.Material.MetallicMap);
|
|
|
|
}
|
|
}
|
|
|
|
Draw.LoadedMaterial = true;
|
|
}
|
|
|
|
this->_DrawObjects.Emplace(Draw);
|
|
this->_DrawInformation.VertexCount += Submesh.Vertices.Count();
|
|
this->_DrawInformation.TriangleCount += Submesh.Faces.Count();
|
|
}
|
|
|
|
glGenBuffers(1, &this->_BonePointBuffer);
|
|
List<Math::Vector3> Positions;
|
|
|
|
for (int32_t i = (int32_t)Model.Bones.Count() - 1; i >= 0; i--)
|
|
{
|
|
auto& CurrentBone = Model.Bones[i];
|
|
|
|
Positions.EmplaceBack(Math::Matrix::TransformVector(CurrentBone.GlobalPosition(), this->_Camera.GetModelMatrix()));
|
|
|
|
if (CurrentBone.Parent() > -1)
|
|
Positions.EmplaceBack(Math::Matrix::TransformVector(Model.Bones[CurrentBone.Parent()].GlobalPosition(), this->_Camera.GetModelMatrix()));
|
|
else
|
|
Positions.EmplaceBack(0.f, 0.f, 0.f);
|
|
}
|
|
|
|
this->_BonePointCount = Positions.Count();
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, this->_BonePointBuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Math::Vector3) * Positions.Count(), &Positions[0], GL_STATIC_DRAW);
|
|
|
|
this->_DrawInformation.BoneCount = Model.Bones.Count();
|
|
this->_DrawInformation.MeshCount = Model.Meshes.Count();
|
|
|
|
// Trigger a resize, then redraw, first redraw needs invalidation...
|
|
this->OnResize();
|
|
this->Invalidate();
|
|
}
|
|
|
|
void AssetRenderer::SetAssetName(const String& Name)
|
|
{
|
|
this->_DrawInformation.AssetName = Name;
|
|
this->Redraw();
|
|
}
|
|
|
|
void AssetRenderer::ClearViewModel()
|
|
{
|
|
for (auto& Draw : _DrawObjects)
|
|
{
|
|
glDeleteVertexArrays(1, &Draw.VertexArrayObject);
|
|
glDeleteBuffers(1, &Draw.VertexBuffer);
|
|
glDeleteBuffers(1, &Draw.FaceBuffer);
|
|
|
|
if (Draw.LoadedMaterial)
|
|
{
|
|
glDeleteTextures(1, &Draw.Material.AlbedoMap);
|
|
glDeleteTextures(1, &Draw.Material.AmbientOccluionMap);
|
|
glDeleteTextures(1, &Draw.Material.MetallicMap);
|
|
glDeleteTextures(1, &Draw.Material.NormalMap);
|
|
glDeleteTextures(1, &Draw.Material.RoughnessMap);
|
|
}
|
|
}
|
|
|
|
glDeleteBuffers(1, &this->_BonePointBuffer);
|
|
this->_BonePointBuffer = 0;
|
|
this->_BonePointCount = 0;
|
|
|
|
_DrawObjects.Clear();
|
|
_DrawInformation = {};
|
|
}
|
|
|
|
void AssetRenderer::SetMaterialStreamer(MaterialStreamCallback Callback)
|
|
{
|
|
this->_MaterialStreamer = std::move(Callback);
|
|
}
|
|
|
|
void AssetRenderer::SetViewTexture(const Texture& Texture)
|
|
{
|
|
this->_DrawingMode = DrawMode::Texture;
|
|
ClearViewTexture();
|
|
ClearViewModel();
|
|
|
|
glGenTextures(1, &this->_DrawTexture);
|
|
|
|
// Load into the draw texture slot
|
|
this->LoadDXTextureOGL((Assets::Texture&)Texture, this->_DrawTexture);
|
|
|
|
this->_DrawInformation.Width = Texture.Width();
|
|
this->_DrawInformation.Height = Texture.Height();
|
|
|
|
// Determine best fit scale to fit the image
|
|
float Scale = min((float)this->_ClientWidth / (float)Texture.Width(), (float)this->_ClientHeight / (float)Texture.Height());
|
|
this->_DrawInformation.Scale = min(100, (int)(Scale * 100));
|
|
}
|
|
|
|
void AssetRenderer::ClearViewTexture()
|
|
{
|
|
glDeleteTextures(1, &this->_DrawTexture);
|
|
_DrawInformation = {};
|
|
}
|
|
|
|
void AssetRenderer::SetUseWireframe(bool Value)
|
|
{
|
|
if (Value != this->_UseWireframe)
|
|
{
|
|
this->_UseWireframe = Value;
|
|
this->Redraw();
|
|
}
|
|
}
|
|
|
|
void AssetRenderer::SetShowBones(bool Value)
|
|
{
|
|
if (Value != this->_ShowBones)
|
|
{
|
|
this->_ShowBones = Value;
|
|
this->Redraw();
|
|
}
|
|
}
|
|
|
|
void AssetRenderer::SetShowMaterials(bool Value)
|
|
{
|
|
if (Value != this->_ShowMaterials)
|
|
{
|
|
this->_ShowMaterials = Value;
|
|
this->Redraw();
|
|
}
|
|
}
|
|
|
|
void AssetRenderer::SetZUpAxis(bool ZUp)
|
|
{
|
|
if (ZUp)
|
|
this->_Camera.SetUpAxis(RenderViewCameraUpAxis::Z);
|
|
else
|
|
this->_Camera.SetUpAxis(RenderViewCameraUpAxis::Y);
|
|
|
|
if (this->GetState(Forms::ControlStates::StateCreated))
|
|
this->Redraw();
|
|
}
|
|
|
|
void AssetRenderer::ResetView()
|
|
{
|
|
this->_Camera.Reset(0.5f * (float)MathHelper::PI, 0.45f * (float)MathHelper::PI, 100.f);
|
|
this->Redraw();
|
|
}
|
|
|
|
void AssetRenderer::ZoomModelToView()
|
|
{
|
|
// Using the bounding box, we need to
|
|
// TODO: Implement this zoom code
|
|
}
|
|
|
|
void AssetRenderer::OnRender()
|
|
{
|
|
// Clear the frame
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
this->RenderBackground();
|
|
|
|
switch (this->_DrawingMode)
|
|
{
|
|
case DrawMode::Model:
|
|
this->RenderGrid();
|
|
this->RenderModel();
|
|
break;
|
|
case DrawMode::Texture:
|
|
this->RenderTexture();
|
|
break;
|
|
}
|
|
|
|
this->RenderHUD();
|
|
|
|
// Render the frame
|
|
SwapBuffers(this->_DCHandle);
|
|
}
|
|
|
|
void AssetRenderer::OnResize()
|
|
{
|
|
glViewport(0, 0, this->_ClientWidth, this->_ClientHeight);
|
|
|
|
// Update the projection matrix
|
|
this->_Camera.UpdateProjectionMatrix(45.f, (float)this->_ClientWidth, (float)this->_ClientHeight, .1f, 10000.f);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadMatrixf(this->_Camera.GetProjectionMatrix().GetMatrix());
|
|
|
|
// Switch back to the modelview matrix
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
// Ask the control to do the resize event
|
|
OpenGLViewport::OnResize();
|
|
}
|
|
|
|
void AssetRenderer::OnHandleCreated()
|
|
{
|
|
OpenGLViewport::OnHandleCreated();
|
|
|
|
// Now, the opengl context is completely valid, we can initialize our font / shaders
|
|
this->_RenderFont.LoadFont(FontArial_PTRF, sizeof(FontArial_PTRF));
|
|
|
|
#if _DEBUG
|
|
// Grab the root path of the libraries...
|
|
auto CppNetPath = IO::Path::GetDirectoryName(IO::Path::GetDirectoryName(__FILE__));
|
|
auto Vert = IO::Path::Combine(CppNetPath, "cppkore_shaders\\preview.vert");
|
|
auto Frag = IO::Path::Combine(CppNetPath, "cppkore_shaders\\preview.frag");
|
|
printf("-- NOTICE: Using debug shaders from disk --\n");
|
|
printf("Vertex: %s\nFrag: %s\n", Vert.ToCString(), Frag.ToCString());
|
|
this->_ModelShader.LoadShader(Vert, Frag);
|
|
#else
|
|
this->_ModelShader.LoadShader(ModelVertexShader_Src, ModelFragmentShader_Src);
|
|
#endif
|
|
}
|
|
|
|
void AssetRenderer::OnKeyUp(const std::unique_ptr<Forms::KeyEventArgs>& EventArgs)
|
|
{
|
|
if (EventArgs->KeyCode() == Forms::Keys::W)
|
|
{
|
|
this->SetUseWireframe(!this->_UseWireframe);
|
|
}
|
|
else if (EventArgs->KeyCode() == Forms::Keys::B)
|
|
{
|
|
this->SetShowBones(!this->_ShowBones);
|
|
}
|
|
else if (EventArgs->KeyCode() == Forms::Keys::T)
|
|
{
|
|
this->SetShowMaterials(!this->_ShowMaterials);
|
|
}
|
|
|
|
OpenGLViewport::OnKeyUp(EventArgs);
|
|
}
|
|
|
|
void AssetRenderer::OnMouseDown(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs)
|
|
{
|
|
this->_TargetMousePosition = Vector2((float)EventArgs->X, (float)EventArgs->Y);
|
|
OpenGLViewport::OnMouseDown(EventArgs);
|
|
}
|
|
|
|
void AssetRenderer::OnMouseMove(const std::unique_ptr<Forms::MouseEventArgs>& EventArgs)
|
|
{
|
|
auto IsAltKey = (GetKeyState(VK_MENU) & 0x8000);
|
|
|
|
if (EventArgs->Button == Forms::MouseButtons::Left && IsAltKey)
|
|
{
|
|
float dPhi = ((float)(this->_TargetMousePosition.Y - EventArgs->Y) / 200.f);
|
|
float dTheta = ((float)(this->_TargetMousePosition.X - EventArgs->X) / 200.f);
|
|
|
|
this->_Camera.Rotate(dTheta, dPhi);
|
|
this->Redraw();
|
|
}
|
|
else if (EventArgs->Button == Forms::MouseButtons::Middle && IsAltKey)
|
|
{
|
|
float dx = ((float)(this->_TargetMousePosition.X - EventArgs->X));
|
|
float dy = ((float)(this->_TargetMousePosition.Y - EventArgs->Y));
|
|
|
|
this->_Camera.Pan(dx * .1f, dy * .1f);
|
|
this->Redraw();
|
|
}
|
|
else if (EventArgs->Button == Forms::MouseButtons::Right && IsAltKey)
|
|
{
|
|
float dx = ((float)(this->_TargetMousePosition.X - EventArgs->X) / 2.f);
|
|
|
|
this->_Camera.Zoom(-dx);
|
|
this->Redraw();
|
|
}
|
|
|
|
this->_TargetMousePosition = Vector2((float)EventArgs->X, (float)EventArgs->Y);
|
|
|
|
OpenGLViewport::OnMouseMove(EventArgs);
|
|
}
|
|
|
|
void AssetRenderer::OnMouseWheel(const std::unique_ptr<Forms::HandledMouseEventArgs>& EventArgs)
|
|
{
|
|
if (this->_DrawingMode == DrawMode::Texture)
|
|
{
|
|
if (EventArgs->Delta > 0)
|
|
this->_DrawInformation.Scale += 3;
|
|
else
|
|
this->_DrawInformation.Scale -= 3;
|
|
this->_DrawInformation.Scale = max(min(200, this->_DrawInformation.Scale), 0);
|
|
}
|
|
else if (this->_DrawingMode == DrawMode::Model)
|
|
{
|
|
this->_Camera.Zoom((float)EventArgs->Delta * .04f);
|
|
}
|
|
|
|
this->Redraw();
|
|
|
|
OpenGLViewport::OnMouseWheel(EventArgs);
|
|
}
|
|
|
|
void AssetRenderer::RenderBackground()
|
|
{
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glColor3f(this->_BackColor.GetR() / 255.f, this->_BackColor.GetG() / 255.f, this->_BackColor.GetB() / 255.f);
|
|
|
|
glVertex2f(-1.0, -1.0);
|
|
glVertex2f(1.0, -1.0);
|
|
glVertex2f(1.0, 1.0);
|
|
glVertex2f(-1.0, 1.0);
|
|
|
|
glEnd();
|
|
}
|
|
|
|
void AssetRenderer::RenderGrid()
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadMatrixf(this->_Camera.GetProjectionMatrix().GetMatrix());
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadMatrixf(this->_Camera.GetViewMatrix().GetMatrix());
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
|
|
glBegin(GL_LINES);
|
|
glLineWidth(1.f);
|
|
|
|
auto Size = 5.0f;
|
|
auto MinSize = -Size;
|
|
auto Step = 0.5f;
|
|
|
|
for (GLfloat i = MinSize; i <= Size; i += Step)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
glColor3f(0, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
glColor3f(.70f, .70f, .70f);
|
|
}
|
|
|
|
glVertex3f(i, 0, Size); glVertex3f(i, 0, MinSize);
|
|
glVertex3f(Size, 0, i); glVertex3f(MinSize, 0, i);
|
|
}
|
|
|
|
glEnd();
|
|
}
|
|
|
|
void AssetRenderer::RenderModel()
|
|
{
|
|
this->_ModelShader.Use();
|
|
|
|
if (_UseWireframe)
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
else
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
|
// Calculate and load the matrix
|
|
auto Model = this->_Camera.GetModelMatrix();
|
|
auto View = this->_Camera.GetViewMatrix();
|
|
auto Proj = this->_Camera.GetProjectionMatrix();
|
|
|
|
const uint32_t Stride = sizeof(Vector3) + sizeof(Vector3) + sizeof(VertexColor) + sizeof(Vector2);
|
|
|
|
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("model"), 1, GL_FALSE, Model.GetMatrix());
|
|
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("view"), 1, GL_FALSE, View.GetMatrix());
|
|
glUniformMatrix4fv(this->_ModelShader.GetUniformLocation("projection"), 1, GL_FALSE, Proj.GetMatrix());
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glEnableVertexAttribArray(1);
|
|
glEnableVertexAttribArray(2);
|
|
glEnableVertexAttribArray(3);
|
|
|
|
for (auto& Draw : this->_DrawObjects)
|
|
{
|
|
|
|
if (Draw.LoadedMaterial && this->_ShowMaterials)
|
|
{
|
|
const GLint DiffuseLoaded = 1;
|
|
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseLoaded"), 1, &DiffuseLoaded);
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
const GLint DiffuseLoaded = 0;
|
|
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseLoaded"), 1, &DiffuseLoaded);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, Draw.Material.AlbedoMap);
|
|
|
|
const GLint DiffuseSlot = 0;
|
|
glUniform1iv(this->_ModelShader.GetUniformLocation("diffuseTexture"), 1, &DiffuseSlot);
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE1);
|
|
glBindTexture(GL_TEXTURE_2D, Draw.Material.NormalMap);
|
|
|
|
|
|
const GLint NormalSlot = 1;
|
|
glUniform1iv(this->_ModelShader.GetUniformLocation("normalTexture"), 1, &NormalSlot);
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE2);
|
|
glBindTexture(GL_TEXTURE_2D, Draw.Material.RoughnessMap);
|
|
|
|
|
|
const GLint GlossSlot = 2;
|
|
glUniform1iv(this->_ModelShader.GetUniformLocation("glossTexture"), 1, &GlossSlot);
|
|
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE3);
|
|
glBindTexture(GL_TEXTURE_2D, Draw.Material.MetallicMap);
|
|
|
|
|
|
const GLint SpecularSlot = 3;
|
|
glUniform1iv(this->_ModelShader.GetUniformLocation("specularTexture"), 1, &SpecularSlot);
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, Draw.VertexBuffer);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, Stride, (void*)0);
|
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, Stride, (void*)12);
|
|
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, Stride, (void*)24);
|
|
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, Stride, (void*)28);
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Draw.FaceBuffer);
|
|
glDrawElements(GL_TRIANGLES, Draw.FaceCount * 3, GL_UNSIGNED_INT, (void*)0);
|
|
}
|
|
|
|
glDisableVertexAttribArray(0);
|
|
glDisableVertexAttribArray(1);
|
|
glDisableVertexAttribArray(2);
|
|
glDisableVertexAttribArray(3);
|
|
|
|
this->_ModelShader.Detatch();
|
|
|
|
if (this->_ShowBones)
|
|
{
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glColor3f(18 / 255.f, 0, 54 / 255.f);
|
|
glBindBuffer(GL_ARRAY_BUFFER, this->_BonePointBuffer);
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
|
|
|
glDrawArrays(GL_LINES, 0, this->_BonePointCount);
|
|
}
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
}
|
|
|
|
void AssetRenderer::RenderTexture()
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadMatrixf(Matrix::CreateOrthographic(0, (float)this->_ClientWidth, (float)this->_ClientHeight, 0, -1, 1).GetMatrix());
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
glColor3f(1.0f, 1.0f, 1.0f);
|
|
glDisable(GL_BLEND);
|
|
|
|
float Scale = (float)this->_DrawInformation.Scale / 100.f;
|
|
|
|
float ImageWidth = this->_DrawInformation.Width * Scale;
|
|
float ImageHeight = this->_DrawInformation.Height * Scale;
|
|
|
|
float Width = (ImageWidth);
|
|
float Height = (ImageHeight);
|
|
float X = (this->_ClientWidth - (float)Width) / 2.0f;
|
|
float Y = (this->_ClientHeight - (float)Height) / 2.0f;
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glBindTexture(GL_TEXTURE_2D, this->_DrawTexture);
|
|
glBegin(GL_QUADS);
|
|
glTexCoord2i(0, 0); glVertex2f(X, Y);
|
|
glTexCoord2i(0, 1); glVertex2f(X, Y + Height);
|
|
glTexCoord2i(1, 1); glVertex2f(X + Width, Y + Height);
|
|
glTexCoord2i(1, 0); glVertex2f(X + Width, Y);
|
|
glEnd();
|
|
}
|
|
|
|
void AssetRenderer::RenderHUD()
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadMatrixf(Matrix::CreateOrthographic(0, (float)this->_ClientWidth, (float)this->_ClientHeight, 0, -1, 1).GetMatrix());
|
|
|
|
// Scale the font size for dpi aware controls
|
|
auto Screen = GetDC(nullptr);
|
|
auto Ratio = GetDeviceCaps(Screen, LOGPIXELSX);
|
|
ReleaseDC(nullptr, Screen);
|
|
|
|
// We based layout on stock 96 dpi, which is 100% scaling on windows
|
|
// so scale linearly based on that
|
|
const auto Scale = (1.0f - (96.f / (float)Ratio)) + 1.0f;
|
|
const auto FontScale = 0.7f * Scale;
|
|
|
|
switch (this->_DrawingMode)
|
|
{
|
|
case DrawMode::Model:
|
|
glColor4f(3 / 255.f, 169 / 255.f, 244 / 255.f, 1);
|
|
|
|
_RenderFont.RenderString("Model", 22, 22, FontScale); _RenderFont.RenderString(":", 80, 22, FontScale);
|
|
_RenderFont.RenderString("Meshes", 22, 38, FontScale); _RenderFont.RenderString(":", 80, 38, FontScale);
|
|
_RenderFont.RenderString("Verts", 22, 54, FontScale); _RenderFont.RenderString(":", 80, 54, FontScale);
|
|
_RenderFont.RenderString("Tris", 22, 70, FontScale); _RenderFont.RenderString(":", 80, 70, FontScale);
|
|
_RenderFont.RenderString("Bones", 22, 86, FontScale); _RenderFont.RenderString(":", 80, 86, FontScale);
|
|
|
|
glColor4f(35 / 255.f, 206 / 255.f, 107 / 255.f, 1);
|
|
|
|
_RenderFont.RenderString(String((this->_ShowBones) ? "Hide Bones (b), " : "Draw Bones (b), ") + String((this->_ShowMaterials) ? "Shaded View (t), " : "Material View (t), ") + String((this->_UseWireframe) ? "Hide Wireframe (w)" : "Draw Wireframe (w)"), 22, this->_Height - 44.f, FontScale);
|
|
|
|
glColor4f(0.9f, 0.9f, 0.9f, 1);
|
|
|
|
_RenderFont.RenderString((this->_DrawInformation.AssetName == "") ? String("N/A") : this->_DrawInformation.AssetName, 96, 22, FontScale);
|
|
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.MeshCount), 96, 38, FontScale);
|
|
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.VertexCount), 96, 54, FontScale);
|
|
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.TriangleCount), 96, 70, FontScale);
|
|
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.BoneCount), 96, 86, FontScale);
|
|
break;
|
|
case DrawMode::Texture:
|
|
glColor4f(3 / 255.f, 169 / 255.f, 244 / 255.f, 1);
|
|
|
|
_RenderFont.RenderString("Image", 22, 22, FontScale); _RenderFont.RenderString(":", 80, 22, FontScale);
|
|
_RenderFont.RenderString("Width", 22, 38, FontScale); _RenderFont.RenderString(":", 80, 38, FontScale);
|
|
_RenderFont.RenderString("Height", 22, 54, FontScale); _RenderFont.RenderString(":", 80, 54, FontScale);
|
|
_RenderFont.RenderString("Scale", 22, 70, FontScale); _RenderFont.RenderString(":", 80, 70, FontScale);
|
|
|
|
glColor4f(0.9f, 0.9f, 0.9f, 1);
|
|
|
|
_RenderFont.RenderString((this->_DrawInformation.AssetName == "") ? String("N/A") : this->_DrawInformation.AssetName, 96, 22, FontScale);
|
|
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.Width), 96, 38, FontScale);
|
|
_RenderFont.RenderString(String::Format("%d", this->_DrawInformation.Height), 96, 54, FontScale);
|
|
_RenderFont.RenderString(String::Format("%d%%", this->_DrawInformation.Scale), 96, 70, FontScale);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void AssetRenderer::LoadDXTextureOGL(Texture& Texture, const uint32_t TextureSlot)
|
|
{
|
|
glBindTexture(GL_TEXTURE_2D, TextureSlot);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
|
|
switch (Texture.Format())
|
|
{
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC6H_UF16:
|
|
Texture.ConvertToFormat(DXGI_FORMAT_BC1_UNORM);
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM:
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM_SRGB:
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM:
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM_SRGB:
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM:
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM_SRGB:
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC4_UNORM:
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC4_SNORM:
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RED_RGTC1, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC5_UNORM:
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC5_SNORM:
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RG_RGTC2, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM_SRGB:
|
|
case DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM:
|
|
glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM, Texture.Width(), Texture.Height(), 0, Texture.BlockSize(), Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_R8_UNORM:
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, Texture.Width(), Texture.Height(), 0, GL_RED, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_R8G8_UNORM:
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, Texture.Width(), Texture.Height(), 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
|
break;
|
|
case DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM:
|
|
case DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Texture.Width(), Texture.Height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, Texture.GetPixels());
|
|
break;
|
|
default:
|
|
#if _DEBUG
|
|
printf("Unsupported DXGI->OGL mapping\n");
|
|
__debugbreak();
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
DrawObject::DrawObject()
|
|
: VertexArrayObject(0), VertexBuffer(0), FaceBuffer(0), LoadedMaterial(false), FaceCount(0), VertexCount(0), Material{(uint32_t)-1, (uint32_t)-1, (uint32_t)-1, (uint32_t)-1, (uint32_t)-1}
|
|
{
|
|
}
|
|
} |