#include "stdafx.h" #include #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((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 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& 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& EventArgs) { this->_TargetMousePosition = Vector2((float)EventArgs->X, (float)EventArgs->Y); OpenGLViewport::OnMouseDown(EventArgs); } void AssetRenderer::OnMouseMove(const std::unique_ptr& 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& 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} { } }