186 lines
4.1 KiB
C++
186 lines
4.1 KiB
C++
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
|
|
|
#include "Win32GPUSwapChainOGL.h"
|
|
|
|
#if GRAPHICS_API_OPENGL && PLATFORM_WINDOWS
|
|
|
|
#include "Engine/Threading/Threading.h"
|
|
#include "Engine/Platform/Window.h"
|
|
#include "Engine/Platform/Windows/WindowsWindow.h"
|
|
#include "Win32ContextOGL.h"
|
|
#include "../RenderToolsOGL.h"
|
|
|
|
Win32GPUSwapChainOGL* Win32GPUSwapChainOGL::Create(GPUDeviceOGL* device, const String& name, Window* parent)
|
|
{
|
|
auto winWindow = (WindowsWindow*)parent;
|
|
auto hwnd = winWindow->GetHWND();
|
|
auto hdc = GetDC(hwnd);
|
|
|
|
Win32ContextOGL::PlatformInitPixelFormatForDevice(hdc);
|
|
|
|
return New<Win32GPUSwapChainOGL>(device, name, parent, hwnd, hdc);
|
|
}
|
|
|
|
Win32GPUSwapChainOGL::Win32GPUSwapChainOGL(GPUDeviceOGL* device, const String& name, Window* parent, HWND hwnd, HDC hdc)
|
|
: GPUSwapChainOGL(device, name, parent)
|
|
, _hwnd(hwnd)
|
|
, _hdc(hdc)
|
|
, _context(0)
|
|
, _isDisposing(false)
|
|
{
|
|
}
|
|
|
|
Win32GPUSwapChainOGL::~Win32GPUSwapChainOGL()
|
|
{
|
|
ReleaseDC(_hwnd, _hdc);
|
|
}
|
|
|
|
void Win32GPUSwapChainOGL::ReleaseGPU()
|
|
{
|
|
if (_isDisposing || _memoryUsage == 0)
|
|
return;
|
|
_isDisposing = true;
|
|
|
|
// TODO: disable fullscreenmode
|
|
|
|
// Release data
|
|
_backBufferHandle.Release();
|
|
if (_context)
|
|
{
|
|
// Check if the main context is going to be closed
|
|
if (_context == Win32ContextOGL::OpenGLContext)
|
|
{
|
|
// Release all GPU resources
|
|
_device->Dispose();
|
|
|
|
// Release all the child windows
|
|
while (Win32ContextOGL::ChildWindows.HasItems())
|
|
{
|
|
Win32ContextOGL::ChildWindows[0]->ReleaseGPU();
|
|
}
|
|
|
|
Win32ContextOGL::OpenGLContext = 0;
|
|
Win32ContextOGL::OpenGLContextWin = 0;
|
|
}
|
|
else
|
|
{
|
|
Win32ContextOGL::ChildWindows.Remove(this);
|
|
}
|
|
Win32ContextOGL::ContextMakeCurrent(NULL, NULL);
|
|
wglDeleteContext(_context);
|
|
_context = nullptr;
|
|
}
|
|
_memoryUsage = 0;
|
|
_width = _height = 0;
|
|
|
|
// Restore the main context if still valid
|
|
if (Win32ContextOGL::OpenGLContext)
|
|
{
|
|
Win32ContextOGL::ContextMakeCurrent(Win32ContextOGL::OpenGLContextWin, Win32ContextOGL::OpenGLContext);
|
|
}
|
|
|
|
_isDisposing = false;
|
|
}
|
|
|
|
bool Win32GPUSwapChainOGL::IsFullscreen()
|
|
{
|
|
// TODO: support fullscreen on OpenGL
|
|
return false;
|
|
}
|
|
|
|
void Win32GPUSwapChainOGL::SetFullscreen(bool isFullscreen)
|
|
{
|
|
// TODO: support fullscreen on OpenGL
|
|
LOG(Warning, "TODO: support fullscreen on OpenGL/Windows");
|
|
}
|
|
|
|
bool Win32GPUSwapChainOGL::Resize(int32 width, int32 height)
|
|
{
|
|
// Check if size won't change
|
|
if (width == _width && height == _height)
|
|
{
|
|
// Back
|
|
return false;
|
|
}
|
|
|
|
// Wait for GPU to flush commands
|
|
WaitForGPU();
|
|
|
|
// Lock device
|
|
GPUDeviceLock lock(_device);
|
|
|
|
// Check if has no context
|
|
if (_context == 0)
|
|
{
|
|
// Create the context
|
|
Win32ContextOGL::PlatformCreateOpenGLContextCore(&_context, _hdc, Win32ContextOGL::OpenGLContext);
|
|
if (_context == 0)
|
|
{
|
|
LOG(Error, "Failed to create OpenGL device context");
|
|
return true;
|
|
}
|
|
|
|
// Check if the main context is missing
|
|
if (Win32ContextOGL::OpenGLContext == 0)
|
|
{
|
|
// Be a master context
|
|
Win32ContextOGL::OpenGLContext = _context;
|
|
Win32ContextOGL::OpenGLContextWin = _hdc;
|
|
|
|
// Init device
|
|
_device->InitWithMainContext();
|
|
}
|
|
else
|
|
{
|
|
// Be a child context
|
|
Win32ContextOGL::ChildWindows.Add(this);
|
|
}
|
|
|
|
// Use the main context
|
|
Win32ContextOGL::ContextMakeCurrent(Win32ContextOGL::OpenGLContextWin, Win32ContextOGL::OpenGLContext);
|
|
}
|
|
else
|
|
{
|
|
// TODO: need to resize the backuffer? win32 window gets resized by the platform backend
|
|
}
|
|
|
|
// Init back buffer handle
|
|
_backBufferHandle.InitAsBackbuffer(this, GPU_BACK_BUFFER_PIXEL_FORMAT);
|
|
|
|
// Cache data
|
|
_width = width;
|
|
_height = height;
|
|
|
|
// Calculate memory usage
|
|
_memoryUsage = CalculateTextureMemoryUsage(PixelFormat::R8G8B8A8_UNorm, _width, _height, 1) * 2;
|
|
|
|
return false;
|
|
}
|
|
|
|
void Win32GPUSwapChainOGL::Present(bool vsync)
|
|
{
|
|
// TODO: vsync on OpenGL
|
|
//wglSwapIntervalEXT(vsync ? 1 : 0);
|
|
//VALIDATE_OPENGL_RESULT();
|
|
|
|
// Present frame
|
|
SwapBuffers(_hdc);
|
|
|
|
// Base
|
|
GPUSwapChain::Present(vsync);
|
|
}
|
|
|
|
bool Win32GPUSwapChainOGL::DownloadData(TextureData* result)
|
|
{
|
|
MISSING_CODE("Win32GPUSwapChainOGL::DownloadData");
|
|
return true;
|
|
}
|
|
|
|
Task* Win32GPUSwapChainOGL::DownloadDataAsync(TextureData* result)
|
|
{
|
|
MISSING_CODE("Win32GPUSwapChainOGL::DownloadDataAsync");
|
|
return nullptr;
|
|
}
|
|
|
|
#endif
|