#include "wgl_context.h" #ifdef WGL_USE_BACKING_WINDOW #include "backing_window.h" #endif #include "flutter_texture_buffer.h" namespace polyvox_filament { WGLContext::WGLContext(flutter::PluginRegistrarWindows *pluginRegistrar, flutter::TextureRegistrar *textureRegistrar) : _pluginRegistrar(pluginRegistrar), _textureRegistrar(textureRegistrar) { auto hwnd = pluginRegistrar->GetView()->GetNativeWindow(); HDC whdc = GetDC(hwnd); if (whdc == NULL) { std::cout << "No device context for temporary window" << std::endl; return; } std::cout << "No GL context exists, creating" << std::endl; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. 32, // Colordepth of the framebuffer. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, // Number of bits for the depthbuffer 0, // Number of bits for the stencilbuffer 0, // Number of Aux buffers in the framebuffer. PFD_MAIN_PLANE, 0, 0, 0, 0}; int pixelFormat = ChoosePixelFormat(whdc, &pfd); SetPixelFormat(whdc, pixelFormat, &pfd); // We need a tmp context to retrieve and call wglCreateContextAttribsARB. HGLRC tempContext = wglCreateContext(whdc); if (!wglMakeCurrent(whdc, tempContext)) { std::cout << "Failed to acquire temporary context" << std::endl; return; } GLenum err = glGetError(); if (err != GL_NO_ERROR) { std::cout << "GL Error @ 455 %d" << std::endl; return; } PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr; wglCreateContextAttribs = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress( "wglCreateContextAttribsARB"); if (!wglCreateContextAttribs) { std::cout << "Failed to resolve wglCreateContextAttribsARB" << std::endl; return; } for (int minor = 5; minor >= 1; minor--) { std::vector mAttribs = {WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, minor, 0}; _context = wglCreateContextAttribs(whdc, nullptr, mAttribs.data()); if (_context) { break; } } wglMakeCurrent(NULL, NULL); wglDeleteContext(tempContext); if (!_context || !wglMakeCurrent(whdc, _context)) { std::cout << "Failed to create OpenGL context." << std::endl; return; } } void WGLContext::ResizeRenderingSurface(uint32_t width, uint32_t height, uint32_t left, uint32_t top) { _backingWindow->Resize(width, height, left, top); } void WGLContext::CreateRenderingSurface( uint32_t width, uint32_t height, std::unique_ptr> result, uint32_t left, uint32_t top) { #if WGL_USE_BACKING_WINDOW if(!_backingWindow) { _backingWindow = std::make_unique( _pluginRegistrar, static_cast(width), static_cast(height), static_cast(left), static_cast(top)); } else { ResizeRenderingSurface(width, height, left, top); } std::vector resultList; resultList.push_back(flutter::EncodableValue((int64_t) nullptr)); resultList.push_back( flutter::EncodableValue((int64_t)_backingWindow->GetHandle())); resultList.push_back(flutter::EncodableValue((int64_t) nullptr)); resultList.push_back(flutter::EncodableValue((int64_t)sharedContext)); result->Success(resultList); #else if(left != 0 || top != 0) { result->Error("ERROR", "When WGL_USE_BACKING_WINDOW is false, rendering with WGL uses a Texture render target/Flutter widget and does not need a window offset."); } else if (_active.get()) { result->Error("ERROR", "Texture already exists. You must call destroyTexture before " "attempting to create a new one."); } else { _active = std::make_unique( _pluginRegistrar, _textureRegistrar, std::move(result), width, height, _context); if (_active->flutterTextureId != -1) { std::vector resultList; resultList.push_back(flutter::EncodableValue((int64_t) nullptr)); resultList.push_back(flutter::EncodableValue((int64_t) nullptr)); resultList.push_back(flutter::EncodableValue((int64_t) nullptr)); resultList.push_back(flutter::EncodableValue((int64_t)sharedContext)); result->Success(resultList); } else { result->Error("NO_FLUTTER_TEXTURE", "Unknown error registering texture with Flutter.", nullptr); } } #endif } void *WGLContext::GetSharedContext() { return (void *)_context; } } // namespace polyvox_filament