/* * Initializes the OpenGL context. Returns true at * success and false at failure. */ int GL3_InitContext(void* win) { // Coders are stupid. if (win == NULL) { ri.Sys_Error(ERR_FATAL, "R_InitContext() must not be called with NULL argument!"); return false; } window = (SDL_Window *)win; // Initialize GL context. context = SDL_GL_CreateContext(window); if(context == NULL) { R_Printf(PRINT_ALL, "GL3_InitContext(): Creating OpenGL Context failed: %s\n", SDL_GetError()); window = NULL; return false; } // Check if we've got the requested MSAA. int msaa_samples = 0; if (gl_msaa_samples->value) { if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples) == 0) { ri.Cvar_SetValue("gl_msaa_samples", msaa_samples); } } // Check if we've got at least 8 stencil bits int stencil_bits = 0; if (gl3config.stencil) { if (SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits) < 0 || stencil_bits < 8) { gl3config.stencil = false; } } // Enable vsync if requested. GL3_SetVsync(); // Load GL pointrs through GLAD and check context. if( !gladLoadGLLoader(SDL_GL_GetProcAddress)) { R_Printf(PRINT_ALL, "GL3_InitContext(): ERROR: loading OpenGL function pointers failed!\n"); return false; } else if (GLVersion.major < 3 || (GLVersion.major == 3 && GLVersion.minor < 2)) { R_Printf(PRINT_ALL, "GL3_InitContext(): ERROR: glad only got GL version %d.%d!\n", GLVersion.major, GLVersion.minor); return false; } else { R_Printf(PRINT_ALL, "Successfully loaded OpenGL function pointers using glad, got version %d.%d!\n", GLVersion.major, GLVersion.minor); } gl3config.debug_output = GLAD_GL_ARB_debug_output != 0; gl3config.anisotropic = GLAD_GL_EXT_texture_filter_anisotropic != 0; gl3config.major_version = GLVersion.major; gl3config.minor_version = GLVersion.minor; // Debug context setup. if (gl3_debugcontext && gl3_debugcontext->value && gl3config.debug_output) { glDebugMessageCallbackARB(DebugCallback, NULL); // Call GL3_DebugCallback() synchronously, i.e. directly when and // where the error happens (so we can get the cause in a backtrace) glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } // Window title - set here so we can display renderer name in it. char title[40] = {0}; snprintf(title, sizeof(title), "Yamagi Quake II %s - OpenGL 3.2", YQ2VERSION); SDL_SetWindowTitle(window, title); return true; }
/** * @brief * Constructor */ ContextWindows::ContextWindows(handle nativeWindowHandle) : mOpenGLRuntimeLinking(new OpenGLRuntimeLinking()), mNativeWindowHandle(nativeWindowHandle), mDummyWindow(NULL_HANDLE), mWindowDeviceContext(NULL_HANDLE), mWindowRenderContext(NULL_HANDLE) { // Is OpenGL available? if (mOpenGLRuntimeLinking->isOpenGLAvaiable()) { // Create a OpenGL dummy window? // -> Under MS Windows, a OpenGL context is always coupled to a window... even if we're not going to render into a window at all... if (NULL_HANDLE == mNativeWindowHandle) { // Setup and register the window class for the OpenGL dummy window WNDCLASS windowDummyClass; windowDummyClass.hInstance = ::GetModuleHandle(nullptr); windowDummyClass.lpszClassName = TEXT("OpenGLDummyWindow"); windowDummyClass.lpfnWndProc = DefWindowProc; windowDummyClass.style = 0; windowDummyClass.hIcon = nullptr; windowDummyClass.hCursor = nullptr; windowDummyClass.lpszMenuName = nullptr; windowDummyClass.cbClsExtra = 0; windowDummyClass.cbWndExtra = 0; windowDummyClass.hbrBackground = nullptr; ::RegisterClass(&windowDummyClass); // Create the OpenGL dummy window mNativeWindowHandle = mDummyWindow = reinterpret_cast<handle>(::CreateWindow(TEXT("OpenGLDummyWindow"), TEXT("PFormat"), WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 8, 8, HWND_DESKTOP, nullptr, ::GetModuleHandle(nullptr), nullptr)); } // Is there a valid window handle? if (NULL_HANDLE != mNativeWindowHandle) { // Get the device context of the OpenGL window mWindowDeviceContext = ::GetDC(reinterpret_cast<HWND>(mNativeWindowHandle)); if (NULL_HANDLE != mWindowDeviceContext) { // Get the color depth of the deskop int bits = 32; { HDC deskTopDC = ::GetDC(nullptr); bits = ::GetDeviceCaps(deskTopDC, BITSPIXEL); ::ReleaseDC(nullptr, deskTopDC); } // Get the first best pixel format const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = { sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor 1, // Version number PFD_DRAW_TO_WINDOW | // Format must support window PFD_SUPPORT_OPENGL | // Format must support OpenGL PFD_DOUBLEBUFFER, // Must support double buffering PFD_TYPE_RGBA, // Request an RGBA format static_cast<UCHAR>(bits), // Select our color depth 0, 0, 0, 0, 0, 0, // Color bits ignored 0, // No alpha buffer 0, // Shift bit ignored 0, // No accumulation buffer 0, 0, 0, 0, // Accumulation bits ignored static_cast<BYTE>(24), // Z-buffer (depth buffer) 0, // No stencil buffer 0, // No auxiliary buffer PFD_MAIN_PLANE, // Main drawing layer 0, // Reserved 0, 0, 0 // Layer masks ignored }; const int pixelFormat = ::ChoosePixelFormat(mWindowDeviceContext, &pixelFormatDescriptor); if (0 != pixelFormat) { // Set the pixel format ::SetPixelFormat(mWindowDeviceContext, pixelFormat, &pixelFormatDescriptor); // Create a legacy OpenGL render context HGLRC legacyRenderContext = wglCreateContext(mWindowDeviceContext); if (NULL_HANDLE != legacyRenderContext) { // Make the legacy OpenGL render context to the current one wglMakeCurrent(mWindowDeviceContext, legacyRenderContext); // Create the render context of the OpenGL window mWindowRenderContext = createOpenGLContext(); // Destroy the legacy OpenGL render context wglMakeCurrent(nullptr, nullptr); wglDeleteContext(legacyRenderContext); // If there's an OpenGL context, do some final initialization steps if (NULL_HANDLE != mWindowRenderContext) { // Make the OpenGL context to the current one wglMakeCurrent(mWindowDeviceContext, mWindowRenderContext); } } else { // Error, failed to create a legacy OpenGL render context! } } else { // Error, failed to choose a pixel format! } } else { // Error, failed to obtain the device context of the OpenGL window! } } else { // Error, failed to create the OpenGL window! } // Is there a valid render context? if (nullptr != mWindowRenderContext) { // Initialize the OpenGL extensions getExtensions().initialize(); #ifdef RENDERER_OUTPUT_DEBUG // "GL_ARB_debug_output"-extension available? if (getExtensions().isGL_ARB_debug_output()) { // Synchronous debug output, please // -> Makes it easier to find the place causing the issue glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); // We don't need to configure the debug output by using "glDebugMessageControlARB()", // by default all messages are enabled and this is good this way // Set the debug message callback function glDebugMessageCallbackARB(&ContextWindows::debugMessageCallback, nullptr); } #endif } } }
void RasterizerGLES3::initialize() { if (OS::get_singleton()->is_stdout_verbose()) { print_line("Using GLES3 video driver"); } #ifdef GLAD_ENABLED if (!gladLoadGL()) { ERR_PRINT("Error initializing GLAD"); } // GLVersion seems to be used for both GL and GL ES, so we need different version checks for them #ifdef OPENGL_ENABLED // OpenGL 3.3 Core Profile required if (GLVersion.major < 3 && GLVersion.minor < 3) { #else // OpenGL ES 3.0 if (GLVersion.major < 3) { #endif ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n" "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n" "Godot Engine will self-destruct as soon as you acknowledge this error message.", "Fatal error: Insufficient OpenGL / GLES driver support"); } if (OS::get_singleton()->is_stdout_verbose()) { if (GLAD_GL_ARB_debug_output) { glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glDebugMessageCallbackARB(_gl_debug_print, NULL); glEnable(_EXT_DEBUG_OUTPUT); } else { print_line("OpenGL debugging not supported!"); } } #endif // GLAD_ENABLED /* // For debugging if (GLAD_GL_ARB_debug_output) { glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PORTABILITY_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PERFORMANCE_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_OTHER_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageInsertARB( GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_OTHER_ARB, 1, GL_DEBUG_SEVERITY_HIGH_ARB,5, "hello"); } */ const GLubyte *renderer = glGetString(GL_RENDERER); print_line("OpenGL ES 3.0 Renderer: " + String((const char *)renderer)); storage->initialize(); canvas->initialize(); scene->initialize(); } void RasterizerGLES3::begin_frame() { uint64_t tick = OS::get_singleton()->get_ticks_usec(); double delta = double(tick - prev_ticks) / 1000000.0; delta *= Engine::get_singleton()->get_time_scale(); time_total += delta; if (delta == 0) { //to avoid hiccups delta = 0.001; } prev_ticks = tick; double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); if (time_total > time_roll_over) time_total = 0; //roll over every day (should be customz storage->frame.time[0] = time_total; storage->frame.time[1] = Math::fmod(time_total, 3600); storage->frame.time[2] = Math::fmod(time_total, 900); storage->frame.time[3] = Math::fmod(time_total, 60); storage->frame.count++; storage->frame.delta = delta; storage->frame.prev_tick = tick; storage->update_dirty_resources(); storage->info.render_final = storage->info.render; storage->info.render.reset(); scene->iteration(); }
int Application::run(Application* self) { m_self = self; if (!framework::Utils::exists("data/gui")) { Logger::toLog("Error: could not find gui directory. Probably working directory has not been set correctly (especially if you are running from IDE).\n"); return EXIT_FAILURE; } init(); m_isRunning = true; glfwSetErrorCallback(&Application::errorCallback); if (!glfwInit()) { Logger::toLog("Error: glfwInit failed"); return EXIT_FAILURE; } glfwWindowHint(GLFW_VISIBLE, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); glfwWindowHint(GLFW_RED_BITS, 8); glfwWindowHint(GLFW_GREEN_BITS, 8); glfwWindowHint(GLFW_BLUE_BITS, 8); glfwWindowHint(GLFW_ALPHA_BITS, 0); glfwWindowHint(GLFW_DEPTH_BITS, 32); glfwWindowHint(GLFW_STENCIL_BITS, 0); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, m_info.majorVersion); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, m_info.minorVersion); #ifdef _DEBUG glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); #endif glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_SAMPLES, m_info.samples); glfwWindowHint(GLFW_STEREO, m_info.flags.stereo ? GL_TRUE : GL_FALSE); // create window m_window = glfwCreateWindow(m_info.windowWidth, m_info.windowHeight, m_info.title.c_str(), m_info.flags.fullscreen ? glfwGetPrimaryMonitor() : NULL, NULL); if (!m_window) { glfwTerminate(); return EXIT_FAILURE; } glfwSetWindowSizeCallback(m_window, &Application::_setWindowSize); glfwSetKeyCallback(m_window, &Application::_onKey); glfwSetCharCallback(m_window, &Application::_onChar); glfwSetMouseButtonCallback(m_window, &Application::_onMouse); glfwSetCursorPosCallback(m_window, &Application::_onCursor); glfwSetScrollCallback(m_window, &Application::_onScroll); glfwSetInputMode(m_window, GLFW_CURSOR, m_info.flags.cursor ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_HIDDEN); // center position GLFWmonitor* primary = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(primary); int posx = (mode->width - m_info.windowWidth) >> 1; int posy = (mode->height - m_info.windowHeight) >> 1; glfwSetWindowPos(m_window, posx, posy); // set vsync glfwMakeContextCurrent(m_window); glfwSwapInterval((int)m_info.flags.vsync); // init GL3w gl3wInit(); std::vector<int> multisamplingLevels; if (!checkOpenGLVersion() || !checkDeviceCapabilities(multisamplingLevels)) { glfwDestroyWindow(m_window); glfwTerminate(); return EXIT_FAILURE; } #ifdef _DEBUG Logger::toLogWithFormat("Video adapter: %s - %s, OpenGL: %s\n", (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER), (const char*)glGetString(GL_VERSION)); #endif if (m_info.flags.debug) { if (gl3wIsSupported(4, 3)) { glDebugMessageCallback(debugCallback, this); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } else if (IsExtensionSupported("GL_ARB_debug_output")) { glDebugMessageCallbackARB(debugCallback, this); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } } initGui(); if (!StandardGpuPrograms::init()) { glfwDestroyWindow(m_window); glfwTerminate(); return EXIT_FAILURE; } initAxes(); startup(m_rootWindow); do { glfwMakeContextCurrent(m_window); Texture::beginFrame(); if (fabs(m_lastTime) < 1e-7) { render(0); Texture::endFrame(); renderGui(0); m_lastTime = glfwGetTime(); } else { double curTime = glfwGetTime(); double delta = curTime - m_lastTime; // fps counter measureFps(delta); // rendering render(delta); Texture::endFrame(); renderGui(delta); m_lastTime = curTime; } glfwSwapBuffers(m_window); glfwPollEvents(); if (glfwWindowShouldClose(m_window)) { m_isRunning = GL_FALSE; } m_isRunning &= (glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_RELEASE); } while(m_isRunning); shutdown(); destroyAllDestroyable(); destroyGui(); glfwDestroyWindow(m_window); glfwTerminate(); return EXIT_SUCCESS; }
void InitWindow() { const int width = GetConfigInt("window.width", 640); const int height = GetConfigInt("window.height", 480); const char* title = GetConfigString("window.title", "Konstrukt"); const bool debug = GetConfigBool("opengl.debug", false); const bool vsync = GetConfigBool("opengl.vsync", true); LogInfo("Compiled with GLFW %d.%d.%d", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION); LogInfo("Using GLFW %s", glfwGetVersionString()); assert(g_Window == NULL); glfwSetErrorCallback(OnGLFWError); if(!glfwInit()) FatalError("GLFW init failed."); glfwDefaultWindowHints(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_DEPTH_BITS, GetConfigInt("opengl.depth-bits", 24)); glfwWindowHint(GLFW_STENCIL_BITS, 0); glfwWindowHint(GLFW_SAMPLES, GetConfigInt("opengl.samples", 0)); glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, debug ? GL_TRUE : GL_FALSE); g_Window = glfwCreateWindow(width, height, title, NULL, NULL); if(!g_Window) FatalError("Window creation failed."); glfwGetWindowSize(g_Window, &g_WindowWidth, &g_WindowHeight); glfwGetFramebufferSize(g_Window, &g_FramebufferWidth, &g_FramebufferHeight); glfwMakeContextCurrent(g_Window); if(!flextInit(g_Window)) FatalError("Failed to load OpenGL extensions."); LogInfo("Using OpenGL %s\n" "Vendor: %s\n" "Renderer: %s\n" "GLSL: %s", glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_SHADING_LANGUAGE_VERSION)); if(vsync) { if(glfwExtensionSupported("GLX_EXT_swap_control_tear") || glfwExtensionSupported("WGL_EXT_swap_control_tear")) glfwSwapInterval(-1); // enable vsync (allow the driver to swap even if a frame arrives a little bit late) else glfwSwapInterval(1); // enable vsync } else { glfwSwapInterval(0); // disable vsync } glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetInputMode(g_Window, GLFW_STICKY_KEYS, GL_FALSE); glfwSetInputMode(g_Window, GLFW_STICKY_MOUSE_BUTTONS, GL_FALSE); if(debug) { if(!FLEXT_ARB_debug_output) FatalError("Debug output requested, but it's not supported!"); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glDebugMessageCallbackARB(OnDebugEvent, NULL); LogInfo("Debug output supported! You may receive debug messages from your OpenGL driver."); } glfwSetWindowSizeCallback(g_Window, OnWindowResize); glfwSetFramebufferSizeCallback(g_Window, OnFramebufferResize); glfwSetMouseButtonCallback(g_Window, OnMouseButtonAction); glfwSetScrollCallback(g_Window, OnMouseScroll); glfwSetCursorPosCallback(g_Window, OnCursorMove); glfwSetKeyCallback(g_Window, OnKeyAction); }
bool GL_Init(HWND window, std::string *error_message) { *error_message = "ok"; hWnd = window; GLuint PixelFormat; // TODO: Change to use WGL_ARB_pixel_format instead static const PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_TYPE_RGBA, // Request An RGBA Format 24, // Select Our Color Depth 0, 0, 0, 0, 0, 0, // Color Bits Ignored 8, // No Alpha Buffer 0, // Shift Bit Ignored 0, // No Accumulation Buffer 0, 0, 0, 0, // Accumulation Bits Ignored 16, // At least a 16Bit Z-Buffer (Depth Buffer) 8, // 8-bit Stencil Buffer 0, // No Auxiliary Buffer PFD_MAIN_PLANE, // Main Drawing Layer 0, // Reserved 0, 0, 0 // Layer Masks Ignored }; hDC = GetDC(hWnd); if (!hDC) { *error_message = "Failed to get a device context."; return false; // Return FALSE } if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { *error_message = "Can't find a suitable PixelFormat."; return false; } if (!SetPixelFormat(hDC, PixelFormat, &pfd)) { *error_message = "Can't set the PixelFormat."; return false; } if (!(hRC = wglCreateContext(hDC))) { *error_message = "Can't create a GL rendering context."; return false; } if (!wglMakeCurrent(hDC, hRC)) { *error_message = "Can't activate the GL rendering context."; return false; } // Check for really old OpenGL drivers and refuse to run really early in some cases. // TODO: Also either tell the user to give up or point the user to the right websites. Here's some collected // information about a system that will not work: // GL_VERSION GL_VENDOR GL_RENDERER // "1.4.0 - Build 8.14.10.2364" "intel" intel Pineview Platform I18NCategory *err = GetI18NCategory("Error"); std::string glVersion = (const char *)glGetString(GL_VERSION); std::string glRenderer = (const char *)glGetString(GL_RENDERER); const std::string openGL_1 = "1."; if (glRenderer == "GDI Generic" || glVersion.substr(0, openGL_1.size()) == openGL_1) { //The error may come from 16-bit colour mode //Check Colour depth HDC dc = GetDC(NULL); u32 colour_depth = GetDeviceCaps(dc, BITSPIXEL); ReleaseDC(NULL, dc); if (colour_depth != 32) { MessageBox(0, L"Please switch your display to 32-bit colour mode", L"OpenGL Error", MB_OK); ExitProcess(1); } const char *defaultError = "Insufficient OpenGL driver support detected!\n\n" "Your GPU reports that it does not support OpenGL 2.0. Would you like to try using DirectX 9 instead?\n\n" "DirectX is currently compatible with less games, but on your GPU it may be the only choice.\n\n" "Visit the forums at http://forums.ppsspp.org for more information.\n\n"; std::wstring versionDetected = ConvertUTF8ToWString(glVersion + "\n\n"); std::wstring error = ConvertUTF8ToWString(err->T("InsufficientOpenGLDriver", defaultError)); std::wstring title = ConvertUTF8ToWString(err->T("OpenGLDriverError", "OpenGL driver error")); std::wstring combined = versionDetected + error; bool yes = IDYES == MessageBox(hWnd, combined.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); if (yes) { // Change the config to D3D and restart. g_Config.iGPUBackend = GPU_BACKEND_DIRECT3D9; g_Config.Save(); W32Util::ExitAndRestart(); } // Avoid further error messages. Let's just bail, it's safe, and we can't continue. ExitProcess(1); } if (GLEW_OK != glewInit()) { *error_message = "Failed to initialize GLEW."; return false; } CheckGLExtensions(); int contextFlags = g_Config.bGfxDebugOutput ? WGL_CONTEXT_DEBUG_BIT_ARB : 0; // Alright, now for the modernity. First try a 4.4, then 4.3, context, if that fails try 3.3. // I can't seem to find a way that lets you simply request the newest version available. const int attribs44[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 4, WGL_CONTEXT_FLAGS_ARB, contextFlags, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; const int attribs43[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 4, WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_FLAGS_ARB, contextFlags, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; const int attribs33[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, WGL_CONTEXT_FLAGS_ARB, contextFlags, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; HGLRC m_hrc; if(wglewIsSupported("WGL_ARB_create_context") == 1) { m_hrc = wglCreateContextAttribsARB(hDC, 0, attribs44); if (!m_hrc) m_hrc = wglCreateContextAttribsARB(hDC, 0, attribs43); if (!m_hrc) m_hrc = wglCreateContextAttribsARB(hDC, 0, attribs33); if (!m_hrc) { // Fall back m_hrc = hRC; } else { // Switch to the new ARB context. wglMakeCurrent(NULL, NULL); wglDeleteContext(hRC); wglMakeCurrent(hDC, m_hrc); } } else { // We can't make a GL 3.x context. Use an old style context (GL 2.1 and before) m_hrc = hRC; } if (GLEW_OK != glewInit()) { *error_message = "Failed to re-initialize GLEW."; return false; } if (!m_hrc) { *error_message = "No m_hrc"; return false; } hRC = m_hrc; GL_SwapInterval(0); // TODO: Also support GL_KHR_debug which might be more widely supported? if (g_Config.bGfxDebugOutput && glewIsSupported("GL_ARB_debug_output")) { glGetError(); glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); // print debug output to stderr if (glGetError()) { ERROR_LOG(G3D, "Failed to register a debug log callback"); } glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); if (glGetError()) { ERROR_LOG(G3D, "Failed to enable synchronous debug output"); } // For extra verbosity uncomment this (MEDIUM and HIGH are on by default): // glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, nullptr, GL_TRUE); } pauseRequested = false; resumeRequested = false; // These are auto-reset events. pauseEvent = CreateEvent(NULL, FALSE, FALSE, NULL); resumeEvent = CreateEvent(NULL, FALSE, FALSE, NULL); return true; // Success }
void initContext() { glretrace::Context *currentContext = glretrace::getCurrentContext(); /* Ensure we have adequate extension support */ assert(currentContext); supportsTimestamp = currentContext->hasExtension("GL_ARB_timer_query"); supportsElapsed = currentContext->hasExtension("GL_EXT_timer_query") || supportsTimestamp; supportsOcclusion = currentContext->hasExtension("GL_ARB_occlusion_query"); supportsDebugOutput = currentContext->hasExtension("GL_ARB_debug_output"); supportsARBShaderObjects = currentContext->hasExtension("GL_ARB_shader_objects"); /* Check for timer query support */ if (retrace::profilingGpuTimes) { if (!supportsTimestamp && !supportsElapsed) { std::cout << "Error: Cannot run profile, GL_EXT_timer_query extension is not supported." << std::endl; exit(-1); } GLint bits = 0; glGetQueryiv(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS, &bits); if (!bits) { std::cout << "Error: Cannot run profile, GL_QUERY_COUNTER_BITS == 0." << std::endl; exit(-1); } } /* Check for occlusion query support */ if (retrace::profilingPixelsDrawn && !supportsOcclusion) { std::cout << "Error: Cannot run profile, GL_ARB_occlusion_query extension is not supported." << std::endl; exit(-1); } /* Setup debug message call back */ if (retrace::debug && supportsDebugOutput) { glretrace::Context *currentContext = glretrace::getCurrentContext(); glDebugMessageCallbackARB(&debugOutputCallback, currentContext); if (DEBUG_OUTPUT_SYNCHRONOUS) { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } } /* Sync the gpu and cpu start times */ if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) { if (!retrace::profiler.hasBaseTimes()) { double cpuTimeScale = 1.0E9 / getTimeFrequency(); GLint64 currentTime = getCurrentTime() * cpuTimeScale; retrace::profiler.setBaseCpuTime(currentTime); retrace::profiler.setBaseGpuTime(currentTime); } } if (retrace::profilingMemoryUsage) { GLint64 currentVsize, currentRss; getCurrentVsize(currentVsize); retrace::profiler.setBaseVsizeUsage(currentVsize); getCurrentRss(currentRss); retrace::profiler.setBaseRssUsage(currentRss); } }
void EnableDrawing (HGLRC *hRC) { WindowResizedCallback = &WindowResized; /** * Edited by Cool Breeze on 16th October 2013 * + Updated the Pixel Format to support 24-bitdepth buffers * + Correctly create a GL 3.x compliant context */ HGLRC LegacyRC; PIXELFORMATDESCRIPTOR pfd; int iFormat; enigma::window_hDC = GetDC (hWnd); ZeroMemory (&pfd, sizeof (pfd)); pfd.nSize = sizeof (pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 24; pfd.iLayerType = PFD_MAIN_PLANE; iFormat = ChoosePixelFormat (enigma::window_hDC, &pfd); if (iFormat==0) { show_error("Failed to set the format of the OpenGL graphics device.",1); } SetPixelFormat ( enigma::window_hDC, iFormat, &pfd ); LegacyRC = wglCreateContext( enigma::window_hDC ); wglMakeCurrent( enigma::window_hDC, LegacyRC ); // -- Initialise GLEW GLenum err = glewInit(); if (GLEW_OK != err) { return; } // -- Define an array of Context Attributes int attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, #ifdef DEBUG_MODE WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, #else WGL_CONTEXT_FLAGS_ARB, 0, #endif 0 }; if ( wglewIsSupported("WGL_ARB_create_context") ) { *hRC = wglCreateContextAttribsARB( enigma::window_hDC,0, attribs ); wglMakeCurrent( NULL,NULL ); wglDeleteContext( LegacyRC ); wglMakeCurrent(enigma::window_hDC, *hRC ); } else // Unable to get a 3.3 Core Context, use the Legacy 1.x context { *hRC = LegacyRC; } #ifdef DEBUG_MODE glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); printf("OpenGL version supported by this platform (%s): \n", glGetString(GL_VERSION)); GLuint ids[] = { 131185 }; glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_OTHER_ARB, GL_DONT_CARE, 1, ids, GL_FALSE); //Disable notification about rendering HINTS like so: //OpenGL: Buffer detailed info: Buffer object 1 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations. [source=API type=OTHER severity=UNDEFINED (33387) id=131185] #endif //TODO: This never reports higher than 8, but display_aa should be 14 if 2,4,and 8 are supported and 8 only when only 8 is supported glGetIntegerv(GL_MAX_SAMPLES_EXT, &enigma_user::display_aa); }
void RasterizerGLES2::initialize() { if (OS::get_singleton()->is_stdout_verbose()) { print_line("Using GLES2 video driver"); } #ifdef GLAD_ENABLED if (!gladLoadGL()) { ERR_PRINT("Error initializing GLAD"); } // GLVersion seems to be used for both GL and GL ES, so we need different version checks for them #ifdef OPENGL_ENABLED // OpenGL 2.1 Profile required if (GLVersion.major < 2) { #else // OpenGL ES 3.0 if (GLVersion.major < 2) { #endif ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n" "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 2.1 / OpenGL ES 2.0, sorry :(\n" "Godot Engine will self-destruct as soon as you acknowledge this error message.", "Fatal error: Insufficient OpenGL / GLES driver support"); } #ifdef GLES_OVER_GL //Test GL_ARB_framebuffer_object extension if (!GLAD_GL_ARB_framebuffer_object) { //Try older GL_EXT_framebuffer_object extension if (GLAD_GL_EXT_framebuffer_object) { glIsRenderbuffer = glIsRenderbufferEXT; glBindRenderbuffer = glBindRenderbufferEXT; glDeleteRenderbuffers = glDeleteRenderbuffersEXT; glGenRenderbuffers = glGenRenderbuffersEXT; glRenderbufferStorage = glRenderbufferStorageEXT; glGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT; glIsFramebuffer = glIsFramebufferEXT; glBindFramebuffer = glBindFramebufferEXT; glDeleteFramebuffers = glDeleteFramebuffersEXT; glGenFramebuffers = glGenFramebuffersEXT; glCheckFramebufferStatus = glCheckFramebufferStatusEXT; glFramebufferTexture1D = glFramebufferTexture1DEXT; glFramebufferTexture2D = glFramebufferTexture2DEXT; glFramebufferTexture3D = glFramebufferTexture3DEXT; glFramebufferRenderbuffer = glFramebufferRenderbufferEXT; glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT; glGenerateMipmap = glGenerateMipmapEXT; } else { ERR_PRINT("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n" "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); OS::get_singleton()->alert("Your system's graphic drivers seem not to support GL_ARB(EXT)_framebuffer_object OpenGL extension, sorry :(\n" "Godot Engine will self-destruct as soon as you acknowledge this error message.", "Fatal error: Insufficient OpenGL / GLES driver support"); } } #endif if (true || OS::get_singleton()->is_stdout_verbose()) { if (GLAD_GL_ARB_debug_output) { glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glDebugMessageCallbackARB(_gl_debug_print, NULL); glEnable(_EXT_DEBUG_OUTPUT); } else { print_line("OpenGL debugging not supported!"); } } #endif // GLAD_ENABLED // For debugging #ifdef GLES_OVER_GL if (GLAD_GL_ARB_debug_output) { glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PORTABILITY_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PERFORMANCE_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_OTHER_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE); /* glDebugMessageInsertARB( GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_OTHER_ARB, 1, GL_DEBUG_SEVERITY_HIGH_ARB, 5, "hello"); */ } #endif const GLubyte *renderer = glGetString(GL_RENDERER); print_line("OpenGL ES 2.0 Renderer: " + String((const char *)renderer)); storage->initialize(); canvas->initialize(); scene->initialize(); } void RasterizerGLES2::begin_frame(double frame_step) { time_total += frame_step; if (frame_step == 0) { //to avoid hiccups frame_step = 0.001; } // double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); // if (time_total > time_roll_over) // time_total = 0; //roll over every day (should be customz storage->frame.time[0] = time_total; storage->frame.time[1] = Math::fmod(time_total, 3600); storage->frame.time[2] = Math::fmod(time_total, 900); storage->frame.time[3] = Math::fmod(time_total, 60); storage->frame.count++; storage->frame.delta = frame_step; storage->update_dirty_resources(); storage->info.render_final = storage->info.render; storage->info.render.reset(); scene->iteration(); }
/* =============== GLimp_InitExtensions =============== */ static void GLimp_InitExtensions( void ) { ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" ); if ( GLEW_ARB_debug_output ) { if ( r_glDebugProfile->integer ) { glDebugMessageCallbackARB( GLimp_DebugCallback, NULL ); glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB ); ri.Printf( PRINT_ALL, "...using GL_ARB_debug_output\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_debug_output\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_debug_output not found\n" ); } // GL_ARB_multitexture if ( glConfig.driverType != GLDRV_OPENGL3 ) { if ( GLEW_ARB_multitexture ) { glGetIntegerv( GL_MAX_TEXTURE_UNITS_ARB, &glConfig.maxActiveTextures ); if ( glConfig.maxActiveTextures > 1 ) { ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" ); } else { ri.Error( ERR_FATAL, "...not using GL_ARB_multitexture, < 2 texture units" ); } } else { ri.Error( ERR_FATAL, "...GL_ARB_multitexture not found" ); } } // GL_ARB_depth_texture if ( GLEW_ARB_depth_texture ) { ri.Printf( PRINT_ALL, "...using GL_ARB_depth_texture\n" ); } else { ri.Error( ERR_FATAL, "...GL_ARB_depth_texture not found" ); } // GL_ARB_texture_cube_map if ( GLEW_ARB_texture_cube_map ) { glGetIntegerv( GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig2.maxCubeMapTextureSize ); ri.Printf( PRINT_ALL, "...using GL_ARB_texture_cube_map\n" ); } else { ri.Error( ERR_FATAL, "...GL_ARB_texture_cube_map not found" ); } GL_CheckErrors(); // GL_ARB_vertex_program if ( GLEW_ARB_vertex_program ) { ri.Printf( PRINT_ALL, "...using GL_ARB_vertex_program\n" ); } else { ri.Error( ERR_FATAL, "...GL_ARB_vertex_program not found" ); } // GL_ARB_vertex_buffer_object if ( GLEW_ARB_vertex_buffer_object ) { ri.Printf( PRINT_ALL, "...using GL_ARB_vertex_buffer_object\n" ); } else { ri.Error( ERR_FATAL, "...GL_ARB_vertex_buffer_object not found" ); } // GL_ARB_occlusion_query glConfig2.occlusionQueryAvailable = qfalse; glConfig2.occlusionQueryBits = 0; if ( GLEW_ARB_occlusion_query ) { if ( r_ext_occlusion_query->value ) { glConfig2.occlusionQueryAvailable = qtrue; glGetQueryivARB( GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &glConfig2.occlusionQueryBits ); ri.Printf( PRINT_ALL, "...using GL_ARB_occlusion_query\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_occlusion_query\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_occlusion_query not found\n" ); } GL_CheckErrors(); // GL_ARB_shader_objects if ( GLEW_ARB_shader_objects ) { ri.Printf( PRINT_ALL, "...using GL_ARB_shader_objects\n" ); } else { ri.Error( ERR_FATAL, "...GL_ARB_shader_objects not found" ); } // GL_ARB_vertex_shader if ( GLEW_ARB_vertex_shader ) { int reservedComponents; GL_CheckErrors(); glGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig2.maxVertexUniforms ); GL_CheckErrors(); //glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &glConfig.maxVaryingFloats); GL_CheckErrors(); glGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig2.maxVertexAttribs ); GL_CheckErrors(); reservedComponents = 16 * 10; // approximation how many uniforms we have besides the bone matrices /* if(glConfig.driverType == GLDRV_MESA) { // HACK // restrict to number of vertex uniforms to 512 because of: // xreal.x86_64: nv50_program.c:4181: nv50_program_validate_data: Assertion `p->param_nr <= 512' failed glConfig2.maxVertexUniforms = Maths::clamp(glConfig2.maxVertexUniforms, 0, 512); } */ glConfig2.maxVertexSkinningBones = Maths::clamp( ( glConfig2.maxVertexUniforms - reservedComponents ) / 16, 0, MAX_BONES ); glConfig2.vboVertexSkinningAvailable = r_vboVertexSkinning->integer && ( ( glConfig2.maxVertexSkinningBones >= 12 ) ? qtrue : qfalse ); ri.Printf( PRINT_ALL, "...using GL_ARB_vertex_shader\n" ); } else { ri.Error( ERR_FATAL, "...GL_ARB_vertex_shader not found" ); } GL_CheckErrors(); // GL_ARB_fragment_shader if ( GLEW_ARB_fragment_shader ) { ri.Printf( PRINT_ALL, "...using GL_ARB_fragment_shader\n" ); } else { ri.Error( ERR_FATAL, "...GL_ARB_fragment_shader not found" ); } // GL_ARB_shading_language_100 if ( GLEW_ARB_shading_language_100 ) { int majorVersion, minorVersion; Q_strncpyz( glConfig2.shadingLanguageVersionString, ( char * ) glGetString( GL_SHADING_LANGUAGE_VERSION_ARB ), sizeof( glConfig2.shadingLanguageVersionString ) ); if ( sscanf( glConfig2.shadingLanguageVersionString, "%i.%i", &majorVersion, &minorVersion ) != 2 ) { ri.Printf( PRINT_ALL, "WARNING: unrecognized shading language version string format\n" ); } glConfig2.shadingLanguageVersion = majorVersion * 100 + minorVersion; ri.Printf( PRINT_ALL, "...found shading language version %i\n", glConfig2.shadingLanguageVersion ); ri.Printf( PRINT_ALL, "...using GL_ARB_shading_language_100\n" ); } else { ri.Printf( ERR_FATAL, "...GL_ARB_shading_language_100 not found\n" ); } GL_CheckErrors(); // GL_ARB_texture_non_power_of_two glConfig2.textureNPOTAvailable = qfalse; if ( GLEW_ARB_texture_non_power_of_two ) { if ( r_ext_texture_non_power_of_two->integer ) { glConfig2.textureNPOTAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_ARB_texture_non_power_of_two\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_texture_non_power_of_two\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_texture_non_power_of_two not found\n" ); } // GL_ARB_draw_buffers glConfig2.drawBuffersAvailable = qfalse; if ( GLEW_ARB_draw_buffers ) { glGetIntegerv( GL_MAX_DRAW_BUFFERS_ARB, &glConfig2.maxDrawBuffers ); if ( r_ext_draw_buffers->integer ) { glConfig2.drawBuffersAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_ARB_draw_buffers\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_draw_buffers\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_draw_buffers not found\n" ); } // GL_ARB_half_float_pixel glConfig2.textureHalfFloatAvailable = qfalse; if ( GLEW_ARB_half_float_pixel ) { if ( r_ext_half_float_pixel->integer ) { glConfig2.textureHalfFloatAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_ARB_half_float_pixel\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_half_float_pixel\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_half_float_pixel not found\n" ); } // GL_ARB_texture_float glConfig2.textureFloatAvailable = qfalse; if ( GLEW_ARB_texture_float ) { if ( r_ext_texture_float->integer ) { glConfig2.textureFloatAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_ARB_texture_float\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_texture_float\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_texture_float not found\n" ); } // GL_ARB_texture_rg glConfig2.textureRGAvailable = qfalse; if ( glConfig.driverType == GLDRV_OPENGL3 || GLEW_ARB_texture_rg ) { if ( r_ext_texture_rg->integer ) { glConfig2.textureRGAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_ARB_texture_rg\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_texture_rg\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_texture_rg not found\n" ); } // GL_ARB_texture_compression glConfig.textureCompression = TC_NONE; if ( GLEW_ARB_texture_compression ) { if ( r_ext_compressed_textures->integer ) { glConfig2.ARBTextureCompressionAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_ARB_texture_compression\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_texture_compression\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_texture_compression not found\n" ); } // GL_ARB_vertex_array_object glConfig2.vertexArrayObjectAvailable = qfalse; if ( GLEW_ARB_vertex_array_object ) { if ( r_ext_vertex_array_object->integer ) { glConfig2.vertexArrayObjectAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_ARB_vertex_array_object\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ARB_vertex_array_object\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ARB_vertex_array_object not found\n" ); } // GL_EXT_texture_compression_s3tc if ( GLEW_EXT_texture_compression_s3tc ) { if ( r_ext_compressed_textures->integer ) { glConfig.textureCompression = TC_S3TC; ri.Printf( PRINT_ALL, "...using GL_EXT_texture_compression_s3tc\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_compression_s3tc\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_texture_compression_s3tc not found\n" ); } // GL_EXT_texture3D glConfig2.texture3DAvailable = qfalse; if ( GLEW_EXT_texture3D ) { //if(r_ext_texture3d->value) { glConfig2.texture3DAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_EXT_texture3D\n" ); } /* else { ri.Printf(PRINT_ALL, "...ignoring GL_EXT_texture3D\n"); } */ } else { ri.Printf( PRINT_ALL, "...GL_EXT_texture3D not found\n" ); } // GL_EXT_stencil_wrap glConfig2.stencilWrapAvailable = qfalse; if ( GLEW_EXT_stencil_wrap ) { if ( r_ext_stencil_wrap->value ) { glConfig2.stencilWrapAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_EXT_stencil_wrap\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_stencil_wrap\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_stencil_wrap not found\n" ); } // GL_EXT_texture_filter_anisotropic glConfig2.textureAnisotropyAvailable = qfalse; if ( GLEW_EXT_texture_filter_anisotropic ) { glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig2.maxTextureAnisotropy ); if ( r_ext_texture_filter_anisotropic->value ) { glConfig2.textureAnisotropyAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" ); } GL_CheckErrors(); // GL_EXT_stencil_two_side if ( GLEW_EXT_stencil_two_side ) { if ( r_ext_stencil_two_side->value ) { ri.Printf( PRINT_ALL, "...using GL_EXT_stencil_two_side\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_stencil_two_side\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_stencil_two_side not found\n" ); } // GL_EXT_depth_bounds_test if ( GLEW_EXT_depth_bounds_test ) { if ( r_ext_depth_bounds_test->value ) { ri.Printf( PRINT_ALL, "...using GL_EXT_depth_bounds_test\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_depth_bounds_test\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_depth_bounds_test not found\n" ); } // GL_EXT_framebuffer_object glConfig2.framebufferObjectAvailable = qfalse; if ( GLEW_EXT_framebuffer_object ) { glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE_EXT, &glConfig2.maxRenderbufferSize ); glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &glConfig2.maxColorAttachments ); if ( r_ext_framebuffer_object->value ) { glConfig2.framebufferObjectAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_EXT_framebuffer_object\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_framebuffer_object\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_framebuffer_object not found\n" ); } GL_CheckErrors(); // GL_EXT_packed_depth_stencil glConfig2.framebufferPackedDepthStencilAvailable = qfalse; if ( GLEW_EXT_packed_depth_stencil && glConfig.driverType != GLDRV_MESA ) { if ( r_ext_packed_depth_stencil->integer ) { glConfig2.framebufferPackedDepthStencilAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_EXT_packed_depth_stencil\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_packed_depth_stencil\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_packed_depth_stencil not found\n" ); } // GL_EXT_framebuffer_blit glConfig2.framebufferBlitAvailable = qfalse; if ( GLEW_EXT_framebuffer_blit ) { if ( r_ext_framebuffer_blit->integer ) { glConfig2.framebufferBlitAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_EXT_framebuffer_blit\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_EXT_framebuffer_blit\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_EXT_framebuffer_blit not found\n" ); } // GL_EXTX_framebuffer_mixed_formats /* glConfig.framebufferMixedFormatsAvailable = qfalse; if(GLEW_EXTX_framebuffer_mixed_formats) { if(r_extx_framebuffer_mixed_formats->integer) { glConfig.framebufferMixedFormatsAvailable = qtrue; ri.Printf(PRINT_ALL, "...using GL_EXTX_framebuffer_mixed_formats\n"); } else { ri.Printf(PRINT_ALL, "...ignoring GL_EXTX_framebuffer_mixed_formats\n"); } } else { ri.Printf(PRINT_ALL, "...GL_EXTX_framebuffer_mixed_formats not found\n"); } */ // GL_ATI_separate_stencil if ( GLEW_ATI_separate_stencil ) { if ( r_ext_separate_stencil->value ) { ri.Printf( PRINT_ALL, "...using GL_ATI_separate_stencil\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_ATI_separate_stencil\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_ATI_separate_stencil not found\n" ); } // GL_SGIS_generate_mipmap glConfig2.generateMipmapAvailable = qfalse; if ( GLEW_SGIS_generate_mipmap ) { if ( r_ext_generate_mipmap->value ) { glConfig2.generateMipmapAvailable = qtrue; ri.Printf( PRINT_ALL, "...using GL_SGIS_generate_mipmap\n" ); } else { ri.Printf( PRINT_ALL, "...ignoring GL_SGIS_generate_mipmap\n" ); } } else { ri.Printf( PRINT_ALL, "...GL_SGIS_generate_mipmap not found\n" ); } // GL_GREMEDY_string_marker if ( GLEW_GREMEDY_string_marker ) { ri.Printf( PRINT_ALL, "...using GL_GREMEDY_string_marker\n" ); } else { ri.Printf( PRINT_ALL, "...GL_GREMEDY_string_marker not found\n" ); } #ifdef GLEW_ARB_get_program_binary if( GLEW_ARB_get_program_binary ) { int formats = 0; glGetIntegerv( GL_NUM_PROGRAM_BINARY_FORMATS, &formats ); if ( !formats ) { ri.Printf( PRINT_ALL, "...GL_ARB_get_program_binary found, but with no binary formats\n"); glConfig2.getProgramBinaryAvailable = qfalse; } else { ri.Printf( PRINT_ALL, "...using GL_ARB_get_program_binary\n"); glConfig2.getProgramBinaryAvailable = qtrue; } } else #endif { ri.Printf( PRINT_ALL, "...GL_ARB_get_program_binary not found\n"); glConfig2.getProgramBinaryAvailable = qfalse; } }
int main(int argc, char **argv) { SDL_Window *window; SDL_GLContext context; SDL_Event evt; MOJOSHADER_glContext *shaderContext; MOJOSHADER_effect *effect; MOJOSHADER_glEffect *glEffect; SDL_Surface *bitmap; GLuint texture; GLuint buffers[2]; FILE *fileIn; unsigned int fileLen; unsigned char *effectData; unsigned int passes; MOJOSHADER_effectStateChanges changes; Uint8 run = 1; /* Create the window and GL context */ SDL_Init(SDL_INIT_VIDEO); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); window = SDL_CreateWindow( "Sprite Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL ); context = SDL_GL_CreateContext(window); shaderContext = MOJOSHADER_glCreateContext( MOJOSHADER_PROFILE, GetGLProcAddress, NULL, NULL, NULL, NULL ); MOJOSHADER_glMakeContextCurrent(shaderContext); /* ARB_debug_output setup */ glDebugMessageCallbackARB(GLDebugCallback, NULL); glDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE ); /* Set up the viewport, create the texture/buffer data */ glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); 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); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.0f); bitmap = SDL_LoadBMP("../Sprite.bmp"); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, bitmap->w, bitmap->h, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap->pixels ); SDL_FreeSurface(bitmap); glGenBuffersARB(2, buffers); glBindBufferARB(GL_ARRAY_BUFFER, buffers[0]); glBufferDataARB( GL_ARRAY_BUFFER, sizeof(vertexstruct_t) * 4, vertex_array, GL_STATIC_DRAW ); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER, 12, index_array, GL_STATIC_DRAW ); /* Load and read the SpriteBatch effect file */ fileIn = fopen("../SpriteEffect.fxb", "rb"); fseek(fileIn, 0, SEEK_END); fileLen = ftell(fileIn); fseek(fileIn, 0, SEEK_SET); effectData = (unsigned char*) malloc(fileLen); fread(effectData, 1, fileLen, fileIn); fclose(fileIn); effect = MOJOSHADER_parseEffect( MOJOSHADER_PROFILE, effectData, fileLen, NULL, 0, NULL, 0, NULL, NULL, NULL ); free(effectData); glEffect = MOJOSHADER_glCompileEffect(effect); MOJOSHADER_effectSetRawValueName( effect, "MatrixTransform", transform_matrix, 0, 64 ); while (run) { while (SDL_PollEvent(&evt) > 0) { if (evt.type == SDL_QUIT) { run = 0; } } /* Clear the screen to black. */ glClear(GL_COLOR_BUFFER_BIT); /* Bind the effect */ MOJOSHADER_glEffectBegin(glEffect, &passes, 0, &changes); MOJOSHADER_glEffectBeginPass(glEffect, 0); /* Set the attrib pointers now, while the effect is bound */ MOJOSHADER_glSetVertexAttribute( MOJOSHADER_USAGE_POSITION, 0, 3, MOJOSHADER_ATTRIBUTE_FLOAT, 0, sizeof(vertexstruct_t), (void*) 0 ); MOJOSHADER_glSetVertexAttribute( MOJOSHADER_USAGE_COLOR, 0, 4, MOJOSHADER_ATTRIBUTE_UBYTE, 1, sizeof(vertexstruct_t), (void*) 12 ); MOJOSHADER_glSetVertexAttribute( MOJOSHADER_USAGE_TEXCOORD, 0, 2, MOJOSHADER_ATTRIBUTE_FLOAT, 0, sizeof(vertexstruct_t), (void*) 16 ); /* Flush all changes to the shader and constant buffers */ MOJOSHADER_glProgramReady(); /* Draw! */ glDrawRangeElements( GL_TRIANGLES, 0, 3, 6, GL_UNSIGNED_SHORT, NULL ); /* We've finished drawing. Present what we've drawn. */ MOJOSHADER_glEffectEndPass(glEffect); MOJOSHADER_glEffectEnd(glEffect); SDL_GL_SwapWindow(window); } /* Clean up. We out. */ glDeleteBuffersARB(2, buffers); glDeleteTextures(1, &texture); MOJOSHADER_glDeleteEffect(glEffect); MOJOSHADER_freeEffect(effect); MOJOSHADER_glMakeContextCurrent(NULL); MOJOSHADER_glDestroyContext(shaderContext); SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
void CApplication::OpenWindow(size_t iWidth, size_t iHeight, bool bFullscreen, bool bResizeable) { glfwInit(); m_bFullscreen = bFullscreen; if (HasCommandLineSwitch("--fullscreen")) m_bFullscreen = true; if (HasCommandLineSwitch("--windowed")) m_bFullscreen = false; m_iWindowWidth = iWidth; m_iWindowHeight = iHeight; glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 0); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); glfwOpenWindowHint(GLFW_WINDOW_RESIZABLE, bResizeable?GL_TRUE:GL_FALSE); if (m_bMultisampling) glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); if (HasCommandLineSwitch("--debug-gl")) { glfwOpenWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); if (!glDebugMessageCallbackARB) TMsg("Your drivers do not support GL_ARB_debug_output, so no GL debug output will be shown.\n"); } glfwOpenWindowHint(GLFW_DEPTH_BITS, 16); glfwOpenWindowHint(GLFW_RED_BITS, 8); glfwOpenWindowHint(GLFW_GREEN_BITS, 8); glfwOpenWindowHint(GLFW_BLUE_BITS, 8); glfwOpenWindowHint(GLFW_ALPHA_BITS, 8); TMsg(sprintf(tstring("Opening %dx%d %s %s window.\n"), iWidth, iHeight, bFullscreen?"fullscreen":"windowed", bResizeable?"resizeable":"fixed-size")); if (!(m_pWindow = (size_t)glfwOpenWindow(iWidth, iHeight, m_bFullscreen?GLFW_FULLSCREEN:GLFW_WINDOWED, WindowTitle().c_str(), NULL))) { glfwTerminate(); return; } int iScreenWidth; int iScreenHeight; GetScreenSize(iScreenWidth, iScreenHeight); if (!m_bFullscreen) { // The taskbar is at the bottom of the screen. Pretend the screen is smaller so the window doesn't clip down into it. // Also the window's title bar at the top takes up space. iScreenHeight -= 70; int iWindowX = (int)(iScreenWidth/2-m_iWindowWidth/2); int iWindowY = (int)(iScreenHeight/2-m_iWindowHeight/2); glfwSetWindowPos((GLFWwindow)m_pWindow, iWindowX, iWindowY); } glfwSetWindowCloseCallback(&CApplication::WindowCloseCallback); glfwSetWindowSizeCallback(&CApplication::WindowResizeCallback); glfwSetKeyCallback(&CApplication::KeyEventCallback); glfwSetCharCallback(&CApplication::CharEventCallback); glfwSetMousePosCallback(&CApplication::MouseMotionCallback); glfwSetMouseButtonCallback(&CApplication::MouseInputCallback); glfwSetScrollCallback(&CApplication::MouseWheelCallback); glfwSwapInterval( 1 ); glfwSetTime( 0.0 ); InitJoystickInput(); SetMouseCursorEnabled(true); GLenum err = gl3wInit(); if (0 != err) exit(0); DumpGLInfo(); if (glDebugMessageCallbackARB) { glDebugMessageCallbackARB(GLDebugCallback, nullptr); tstring sMessage("OpenGL Debug Output Activated"); glDebugMessageInsertARB(GL_DEBUG_SOURCE_APPLICATION_ARB, GL_DEBUG_TYPE_OTHER_ARB, 0, GL_DEBUG_SEVERITY_LOW_ARB, sMessage.length(), sMessage.c_str()); } glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glLineWidth(1.0); m_bIsOpen = true; m_pRenderer = CreateRenderer(); m_pRenderer->Initialize(); glgui::RootPanel()->SetSize((float)m_iWindowWidth, (float)m_iWindowHeight); }
WindowGL33::WindowGL33(std::string title, int width, int height, bool fullscreen, unsigned int multisampling) : m_title { title }, m_multisampling { multisampling } { if (fullscreen) { // Initialize window to default values m_windowedWidth = 800; m_windowedHeight = 600; // Initialize fullscreen resolution m_fullscreenWidth = width; m_fullscreenHeight = height; m_isFullscreen = true; } else { // Initialize window to default values m_windowedWidth = width; m_windowedHeight = height; // Initialize fullscreen resolution to screen resolution const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor()); m_fullscreenWidth = mode->width; m_fullscreenHeight = mode->height; m_isFullscreen = false; } glfwWindowHint(GLFW_VISIBLE, GL_FALSE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_SAMPLES, multisampling); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, 1); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if (fullscreen) m_pWndHandle = glfwCreateWindow(m_fullscreenWidth, m_fullscreenHeight, title.c_str(), glfwGetPrimaryMonitor(), nullptr); else m_pWndHandle = glfwCreateWindow(m_windowedWidth, m_windowedHeight, title.c_str(), nullptr, nullptr); if (!m_pWndHandle) { std::cerr << "Failed to create new window!"; glfwTerminate(); } // Remember window s_windows.insert( { m_pWndHandle, this }); m_windowedX = getX(); m_windowedY = getY(); makeCurrent(); // Initialize GLEW glewExperimental = true; // For core profile if (glewInit() != GLEW_OK) { std::cerr << "Failed to initialize GLEW!"; glfwTerminate(); } // Enable multisampling? if (m_multisampling > 0) m_rc.setMultisampling(true); // Wrap context in vao glGenVertexArrays(1, &m_vertexArrayId); glBindVertexArray(m_vertexArrayId); // Register OpenGL Debug callback if available if (GLEW_ARB_debug_output) glDebugMessageCallbackARB((GLDEBUGPROCARB)WindowGL33::debugCallback, nullptr); }
void init_gl(const opt_data *opt_data, int width, int height) { if(!ogl_LoadFunctions()) { fprintf(stderr, "ERROR: Failed to load GL extensions\n"); exit(EXIT_FAILURE); } CHECK_GL_ERR; if(!(ogl_GetMajorVersion() > 1 || ogl_GetMinorVersion() >= 4)) { fprintf(stderr, "ERROR: Your OpenGL Implementation is too old\n"); exit(EXIT_FAILURE); } opts = opt_data; GLboolean force_fixed = opts->gl_opts != NULL && strstr(opts->gl_opts, "fixed") != NULL; GLboolean res_boost = opts->gl_opts != NULL && strstr(opts->gl_opts, "rboost") != NULL; packed_intesity_pixels = opts->gl_opts != NULL && strstr(opts->gl_opts, "pintens") != NULL; scr_w = width; scr_h = height; if(opts->fullscreen) im_w = scr_w, im_h=scr_h; else im_w = IMAX(make_pow2(IMAX(scr_w, scr_h)), 128)<<res_boost; im_h = im_w; while(!check_res(im_w, im_h)) { // shrink textures until they work printf(" %ix%i Too big! Shrink texture\n", im_h, im_w); im_w = im_w/2; im_h = im_h/2; } printf("Using internel resolution of %ix%i\n\n", im_h, im_w); CHECK_GL_ERR; setup_viewport(scr_w, scr_h); CHECK_GL_ERR; //glEnable(GL_LINE_SMOOTH); CHECK_GL_ERR; glClear(GL_COLOR_BUFFER_BIT); CHECK_GL_ERR; glRasterPos2f(-1,1 - 20.0f/(scr_h*0.5f)); //draw_string("Loading... "); swap_buffers(); CHECK_GL_ERR; printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); printf("GL_VERSION: %s\n", glGetString(GL_VERSION)); if(ogl_ext_ARB_shading_language_100) printf("GL_SL_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION_ARB)); printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS)); printf("\n\n"); /* void DebugMessageControlARB(enum source, enum type, enum severity, sizei count, const uint* ids, boolean enabled); */ if(ogl_ext_ARB_debug_output) { glDebugMessageCallbackARB((GLDEBUGPROCARB)gl_debug_callback, NULL); #if DEBUG glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); #else glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, GL_DONT_CARE, 0, NULL, GL_TRUE); glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, GL_DONT_CARE, 0, NULL, GL_TRUE); #endif printf("Have ARB_debug_output: registered callback\n"); } CHECK_GL_ERR; // for ES we need: // EXT_blend_minmax // EXT_texture_format_BGRA8888 // optionally we should use // EXT_texture_rg + OES_texture_float/OES_texture_half_float // OES_mapbuffer /* if(!ogl_ext_EXT_blend_minmax) { // can stop checking for this, it's in OpenGL 1.4*/ /* printf("missing required gl extension EXT_blend_minmax!\n");*/ /* exit(1);*/ /* }*/ if(!ogl_ext_EXT_framebuffer_object && !ogl_ext_ARB_framebuffer_object) { printf("missing required gl extension EXT_framebuffer_object!\n"); exit(1); } // TODO: this should also pass if we have GL 2.0+ if(!ogl_ext_ARB_shading_language_100 && !(ogl_ext_ARB_fragment_shader && ogl_ext_ARB_vertex_shader && ogl_ext_ARB_shader_objects)) { if(!ogl_ext_ARB_pixel_buffer_object) printf("Missing GLSL and no pixel buffer objects, WILL be slow!\n"); else printf("No GLSL using all fixed function! (might be slow)\n"); } if(force_fixed) { printf("Fixed function code forced\n"); packed_intesity_pixels = GL_FALSE; } CHECK_GL_ERR; if(packed_intesity_pixels) printf("Packed intensity enabled\n"); glEnable(GL_TEXTURE_2D); CHECK_GL_ERR; init_mandel(); CHECK_GL_ERR; if(!force_fixed) glfract = fractal_glsl_init(opts, im_w, im_h, packed_intesity_pixels); if(!glfract) glfract = fractal_fixed_init(opts, im_w, im_h); CHECK_GL_ERR; if(!force_fixed) glmaxsrc = maxsrc_new_glsl(IMAX(im_w>>res_boost, 256), IMAX(im_h>>res_boost, 256), packed_intesity_pixels); if(!glmaxsrc) glmaxsrc = maxsrc_new_fixed(IMAX(im_w>>res_boost, 256), IMAX(im_h>>res_boost, 256)); CHECK_GL_ERR; if(!force_fixed) glpal = pal_init_glsl(packed_intesity_pixels); if(!glpal) glpal = pal_init_fixed(im_w, im_h); CHECK_GL_ERR; pd = new_point_data(opts->rational_julia?4:2); memset(frametimes, 0, sizeof(frametimes)); totframetime = frametimes[0] = MAX(10000000/opts->draw_rate, 1); memset(worktimes, 0, sizeof(worktimes)); totworktime = worktimes[0] = MIN(10000000/opts->draw_rate, 1); tick0 = uget_ticks(); }
/*----------------------------------------------------------------------------------------------- Description: Governs window creation, the initial OpenGL configuration (face culling, depth mask, even though this is a 2D demo and that stuff won't be of concern), the creation of geometry, and the creation of a texture. Parameters: argc (From main(...)) The number of char * items in argv. For glut's initialization. argv (From main(...)) A collection of argument strings. For glut's initialization. Returns: False if something went wrong during initialization, otherwise true; Exception: Safe Creator: John Cox (3-7-2016) -----------------------------------------------------------------------------------------------*/ bool init(int argc, char *argv[]) { glutInit(&argc, argv); // I don't know what this is doing, but it has been working, so I'll leave it be for now int windowWidth = 500; // square 500x500 pixels int windowHeight = 500; unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL; displayMode = defaults(displayMode, windowWidth, windowHeight); glutInitDisplayMode(displayMode); // create the window // ??does this have to be done AFTER glutInitDisplayMode(...)?? glutInitWindowSize(windowWidth, windowHeight); glutInitWindowPosition(300, 200); // X = 0 is screen left, Y = 0 is screen top int window = glutCreateWindow(argv[0]); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); // OpenGL 4.3 was where internal debugging was enabled, freeing the user from having to call // glGetError() and analyzing it after every single OpenGL call, complete with surrounding it // with #ifdef DEBUG ... #endif blocks // Note: https://blog.nobel-joergensen.com/2013/02/17/debugging-opengl-part-2-using-gldebugmessagecallback/ int glMajorVersion = 4; int glMinorVersion = 4; glutInitContextVersion(glMajorVersion, glMinorVersion); glutInitContextProfile(GLUT_CORE_PROFILE); #ifdef DEBUG glutInitContextFlags(GLUT_DEBUG); // if enabled, #endif // glload must load AFTER glut loads the context glload::LoadTest glLoadGood = glload::LoadFunctions(); if (!glLoadGood) // apparently it has an overload for "bool type" { printf("glload::LoadFunctions() failed\n"); return false; } else if (!glload::IsVersionGEQ(glMajorVersion, glMinorVersion)) { // the "is version" check is an "is at least version" check printf("Your OpenGL version is %i, %i. You must have at least OpenGL %i.%i to run this tutorial.\n", glload::GetMajorVersion(), glload::GetMinorVersion(), glMajorVersion, glMinorVersion); glutDestroyWindow(window); return 0; } else if (glext_ARB_debug_output) { // condition will be true if GLUT_DEBUG is a context flag glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glDebugMessageCallbackARB(DebugFunc, (void*)15); } // these OpenGL initializations are for 3D stuff, where depth matters and multiple shapes can // be "on top" of each other relative to the most distant thing rendered, and this barebones // code is only for 2D stuff, but initialize them anyway as good practice (??bad idea? only // use these once 3D becomes a thing??) glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL); glDepthRange(0.0f, 1.0f); // FreeType needs to load itself into particular variables // Note: FT_Init_FreeType(...) returns something called an FT_Error, which VS can't find. // Based on the useage, it is assumed that 0 is returned if something went wrong, otherwise // non-zero is returned. That is the only explanation for this kind of condition. if (FT_Init_FreeType(&gFtLib)) { fprintf(stderr, "Could not init freetype library\n"); return false; } // Note: FT_New_Face(...) also returns an FT_Error. const char *fontFilePath = "FreeSans.ttf"; // file path relative to solution directory if (FT_New_Face(gFtLib, fontFilePath, 0, &gFtFace)) { fprintf(stderr, "Could not open font '%s'\n", fontFilePath); return false; } gProgramId = CreateProgram(); // pick out the attributes and uniforms used in the FreeType GPU program char textTextureName[] = "textureSamplerId"; gUniformTextSamplerLoc = glGetUniformLocation(gProgramId, textTextureName); if (gUniformTextSamplerLoc == -1) { fprintf(stderr, "Could not bind uniform '%s'\n", textTextureName); return false; } //char textColorName[] = "color"; char textColorName[] = "textureColor"; gUniformTextColorLoc = glGetUniformLocation(gProgramId, textColorName); if (gUniformTextColorLoc == -1) { fprintf(stderr, "Could not bind uniform '%s'\n", textColorName); return false; } // start up the font texture atlas now that the program is created and uniforms are recorded gAtlasPtr = new atlas(gFtFace, 48); // create the vertex buffer that will be used to create quads as a base for the FreeType // glyph textures glGenBuffers(1, &gVbo); if (gVbo == -1) { fprintf(stderr, "could not generate vertex buffer object\n"); return false; } // all went well return true; }
/* * Called the first time a context is made current. */ void initContext() { glretrace::Context *currentContext = glretrace::getCurrentContext(); assert(currentContext); /* Ensure we have adequate extension support */ glprofile::Profile currentProfile = currentContext->actualProfile(); supportsTimestamp = currentProfile.versionGreaterOrEqual(glprofile::API_GL, 3, 3) || currentContext->hasExtension("GL_ARB_timer_query"); supportsElapsed = currentContext->hasExtension("GL_EXT_timer_query") || supportsTimestamp; supportsOcclusion = currentProfile.versionGreaterOrEqual(glprofile::API_GL, 1, 5); supportsARBShaderObjects = currentContext->hasExtension("GL_ARB_shader_objects"); currentContext->KHR_debug = currentContext->hasExtension("GL_KHR_debug"); if (currentContext->KHR_debug) { glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, ¤tContext->maxDebugMessageLength); assert(currentContext->maxDebugMessageLength > 0); } #ifdef __APPLE__ // GL_TIMESTAMP doesn't work on Apple. GL_TIME_ELAPSED still does however. // http://lists.apple.com/archives/mac-opengl/2014/Nov/threads.html#00001 supportsTimestamp = false; #endif /* Check for timer query support */ if (retrace::profilingGpuTimes) { if (!supportsTimestamp && !supportsElapsed) { std::cout << "error: cannot profile, GL_ARB_timer_query or GL_EXT_timer_query extensions are not supported." << std::endl; exit(-1); } GLint bits = 0; glGetQueryiv(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS, &bits); if (!bits) { std::cout << "error: cannot profile, GL_QUERY_COUNTER_BITS == 0." << std::endl; exit(-1); } } /* Check for occlusion query support */ if (retrace::profilingPixelsDrawn && !supportsOcclusion) { std::cout << "error: cannot profile, GL_ARB_occlusion_query extension is not supported (" << currentProfile << ")" << std::endl; exit(-1); } /* Setup debug message call back */ if (retrace::debug) { if (currentContext->KHR_debug) { if (currentProfile.desktop()) { glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallback(&debugOutputCallback, currentContext); } else { glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallbackKHR(&debugOutputCallback, currentContext); } if (DEBUG_OUTPUT_SYNCHRONOUS) { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } } else if (currentContext->hasExtension("GL_ARB_debug_output")) { glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallbackARB(&debugOutputCallback, currentContext); if (DEBUG_OUTPUT_SYNCHRONOUS) { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } } } /* Sync the gpu and cpu start times */ if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) { if (!retrace::profiler.hasBaseTimes()) { double cpuTimeScale = 1.0E9 / getTimeFrequency(); GLint64 currentTime = getCurrentTime() * cpuTimeScale; retrace::profiler.setBaseCpuTime(currentTime); retrace::profiler.setBaseGpuTime(currentTime); } } if (retrace::profilingMemoryUsage) { GLint64 currentVsize, currentRss; getCurrentVsize(currentVsize); retrace::profiler.setBaseVsizeUsage(currentVsize); getCurrentRss(currentRss); retrace::profiler.setBaseRssUsage(currentRss); } }
static void GLimp_InitExtensionsR2(void) { Ren_Print("Initializing OpenGL extensions\n"); // GL_ARB_multitexture if (glConfig.driverType != GLDRV_OPENGL3) { if (GLEW_ARB_multitexture) { glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &glConfig.maxActiveTextures); if (glConfig.maxActiveTextures > 1) { Ren_Print("...found OpenGL extension - GL_ARB_multitexture\n"); } else { Ren_Fatal(MSG_ERR_OLD_VIDEO_DRIVER "\nYour GL driver is missing support for: GL_ARB_multitexture, < 2 texture units"); } } else { Ren_Fatal(MSG_ERR_OLD_VIDEO_DRIVER "\nYour GL driver is missing support for: GL_ARB_multitexture"); } } // GL_ARB_depth_texture GLimp_CheckForVersionExtension("GL_ARB_depth_texture", 130, qtrue, NULL); if (GLimp_CheckForVersionExtension("GL_ARB_texture_cube_map", 130, qtrue, NULL)) { glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, &glConfig2.maxCubeMapTextureSize); } GL_CheckErrors(); GLimp_CheckForVersionExtension("GL_ARB_vertex_program", 210, qtrue, NULL); GLimp_CheckForVersionExtension("GL_ARB_vertex_buffer_object", 300, qtrue, NULL); // GL_ARB_occlusion_query glConfig2.occlusionQueryAvailable = qfalse; glConfig2.occlusionQueryBits = 0; if (GLimp_CheckForVersionExtension("GL_ARB_occlusion_query", 150, qfalse, r_ext_occlusion_query)) { glConfig2.occlusionQueryAvailable = qtrue; glGetQueryivARB(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &glConfig2.occlusionQueryBits); } GL_CheckErrors(); GLimp_CheckForVersionExtension("GL_ARB_shader_objects", 210, qtrue, NULL); if (GLimp_CheckForVersionExtension("GL_ARB_vertex_shader", 210, qtrue, NULL)) { int reservedComponents; GL_CheckErrors(); glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig2.maxVertexUniforms); GL_CheckErrors(); //glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &glConfig.maxVaryingFloats); GL_CheckErrors(); glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig2.maxVertexAttribs); GL_CheckErrors(); reservedComponents = 16 * 10; // approximation how many uniforms we have besides the bone matrices glConfig2.maxVertexSkinningBones = (int) Q_bound(0.0, (Q_max(glConfig2.maxVertexUniforms - reservedComponents, 0) / 16), MAX_BONES); glConfig2.vboVertexSkinningAvailable = (qboolean)(r_vboVertexSkinning->integer && ((glConfig2.maxVertexSkinningBones >= 12) ? qtrue : qfalse)); } GL_CheckErrors(); GLimp_CheckForVersionExtension("GL_ARB_fragment_shader", 210, qtrue, NULL); // GL_ARB_shading_language_100 if (GLimp_CheckForVersionExtension("GL_ARB_shading_language_100", 210, qtrue, NULL)) { Q_strncpyz(glConfig2.shadingLanguageVersion, (char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB), sizeof(glConfig2.shadingLanguageVersion)); sscanf(glConfig2.shadingLanguageVersion, "%d.%d", &glConfig2.glslMajorVersion, &glConfig2.glslMinorVersion); } GL_CheckErrors(); glConfig2.textureNPOTAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_ARB_texture_non_power_of_two", 300, qfalse, r_ext_texture_non_power_of_two)) { glConfig2.textureNPOTAvailable = qtrue; } glConfig2.drawBuffersAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_ARB_draw_buffers", /* -1 */ 300, qfalse, r_ext_draw_buffers)) { glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &glConfig2.maxDrawBuffers); glConfig2.drawBuffersAvailable = qtrue; } glConfig2.textureHalfFloatAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_ARB_half_float_pixel", 300, qfalse, r_ext_half_float_pixel)) { glConfig2.textureHalfFloatAvailable = qtrue; } glConfig2.textureFloatAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_ARB_texture_float", 300, qfalse, r_ext_texture_float)) { glConfig2.textureFloatAvailable = qtrue; } glConfig2.ARBTextureCompressionAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_ARB_texture_compression", 300, qfalse, r_ext_compressed_textures)) { glConfig2.ARBTextureCompressionAvailable = qtrue; glConfig.textureCompression = TC_NONE; } glConfig2.vertexArrayObjectAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_ARB_vertex_array_object", 300, qfalse, r_ext_vertex_array_object)) { glConfig2.vertexArrayObjectAvailable = qtrue; } // GL_EXT_texture_compression_s3tc if (GLimp_CheckForVersionExtension("GL_EXT_texture_compression_s3tc", -1, qfalse, r_ext_compressed_textures)) { glConfig.textureCompression = TC_S3TC; } glConfig2.texture3DAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_EXT_texture3D", 170, qfalse, NULL)) { glConfig2.texture3DAvailable = qtrue; } glConfig2.stencilWrapAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_EXT_stencil_wrap", 210, qfalse, r_ext_stencil_wrap)) { glConfig2.stencilWrapAvailable = qtrue; } glConfig2.textureAnisotropyAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_EXT_texture_filter_anisotropic", -1, qfalse, r_ext_texture_filter_anisotropic)) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig2.maxTextureAnisotropy); glConfig2.textureAnisotropyAvailable = qtrue; } GL_CheckErrors(); GLimp_CheckForVersionExtension("GL_EXT_stencil_two_side", 210, qfalse, r_ext_stencil_two_side); GLimp_CheckForVersionExtension("GL_EXT_depth_bounds_test", 170, qfalse, r_ext_depth_bounds_test); glConfig2.framebufferObjectAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_EXT_framebuffer_object", 300, qfalse, r_ext_packed_depth_stencil)) { glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &glConfig2.maxRenderbufferSize); glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &glConfig2.maxColorAttachments); glConfig2.framebufferObjectAvailable = qtrue; } GL_CheckErrors(); glConfig2.framebufferPackedDepthStencilAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_EXT_packed_depth_stencil", 300, qfalse, r_ext_packed_depth_stencil) && glConfig.driverType != GLDRV_MESA) { glConfig2.framebufferPackedDepthStencilAvailable = qtrue; } glConfig2.framebufferBlitAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_EXT_framebuffer_blit", 300, qfalse, r_ext_framebuffer_blit)) { glConfig2.framebufferBlitAvailable = qtrue; } // GL_EXTX_framebuffer_mixed_formats not used glConfig2.generateMipmapAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_SGIS_generate_mipmap", 140, qfalse, r_ext_generate_mipmap)) { glConfig2.generateMipmapAvailable = qtrue; } glConfig2.getProgramBinaryAvailable = qfalse; if (GLimp_CheckForVersionExtension("GL_ARB_get_program_binary", 410, qfalse, NULL)) { int formats = 0; glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats); if (formats) { glConfig2.getProgramBinaryAvailable = qtrue; } } // If we are in developer mode, then we will print out messages from the gfx driver if (GLimp_CheckForVersionExtension("GL_ARB_debug_output", 410, qfalse, NULL) && ri.Cvar_VariableIntegerValue("developer")) { #ifdef GL_DEBUG_OUTPUT glEnable(GL_DEBUG_OUTPUT); if (410 <= glConfig2.contextCombined) { glDebugMessageCallback(Glimp_DebugCallback, NULL); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); } else { glDebugMessageCallbackARB(Glimp_DebugCallback, NULL); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } #endif } }
//----------------------------------------------------------------------------- // Name: init() // Desc: //----------------------------------------------------------------------------- void initGL() { #ifdef OGLES2 // // OpenGL ES 2 : See http://www.khronos.org/opengles/documentation/opengles1_0/html/eglIntro.html // For Android, an example here : http://jiggawatt.org/badc0de/android/index.html // g_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(g_display, 0, 0); //CHECKEGLERRORS(); typedef struct { EGLint redSize; EGLint greenSize; EGLint blueSize; EGLint alphaSize; EGLint depthSize; EGLint stencilSize; } NvTglConfigRequest; NvTglConfigRequest request; memset(&request, 0, sizeof(request)); request.redSize = 5; request.greenSize = 6; request.blueSize = 5; request.alphaSize = 0; //if (hasDepth) request.depthSize = 1; // accept any size //if (hasStencil) // request.stencilSize = 1; // accept any size #define MAX_CONFIG_ATTRS_SIZE 32 #define MAX_MATCHING_CONFIGS 64 EGLint Attributes[] = { //EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //EGL_RED_SIZE, 8, //EGL_GREEN_SIZE, 8, //EGL_BLUE_SIZE, 8, //EGL_NONE EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_BUFFER_SIZE, request.redSize + request.greenSize + request.blueSize + request.alphaSize, EGL_RED_SIZE, request.redSize, EGL_GREEN_SIZE, request.greenSize, EGL_BLUE_SIZE, request.blueSize, EGL_ALPHA_SIZE, request.alphaSize, EGL_DEPTH_SIZE, request.depthSize, EGL_STENCIL_SIZE, request.stencilSize, EGL_NONE }; // choose configs EGLConfig matchingConfigs[MAX_MATCHING_CONFIGS]; EGLint numMatchingConfigs = 0; eglChooseConfig(g_display, Attributes, matchingConfigs, 1, &numMatchingConfigs); //CHECKEGLERRORS(); EGLConfig config; // look for exact match int i; for (i = 0; i < numMatchingConfigs; i++) { EGLConfig testConfig = matchingConfigs[i]; // query attributes from config NvTglConfigRequest cfg; EGLBoolean ok = EGL_TRUE; ok &= eglGetConfigAttrib(g_display, testConfig, EGL_RED_SIZE, &cfg.redSize); ok &= eglGetConfigAttrib(g_display, testConfig, EGL_GREEN_SIZE, &cfg.greenSize); ok &= eglGetConfigAttrib(g_display, testConfig, EGL_BLUE_SIZE, &cfg.blueSize); ok &= eglGetConfigAttrib(g_display, testConfig, EGL_ALPHA_SIZE, &cfg.alphaSize); ok &= eglGetConfigAttrib(g_display, testConfig, EGL_DEPTH_SIZE, &cfg.depthSize); ok &= eglGetConfigAttrib(g_display, testConfig, EGL_STENCIL_SIZE, &cfg.stencilSize); if (!ok) { printf("eglGetConfigAttrib failed!\n"); break; } // depthSize == 1 indicates to accept any non-zero depth EGLBoolean depthMatches = ((request.depthSize == 1) && (cfg.depthSize > 0)) || (cfg.depthSize == request.depthSize); // stencilSize == 1 indicates to accept any non-zero stencil EGLBoolean stencilMatches = ((request.stencilSize == 1) && (cfg.stencilSize > 0)) || (cfg.stencilSize == request.stencilSize); // compare to request if (cfg.redSize == request.redSize && cfg.greenSize == request.greenSize && cfg.blueSize == request.blueSize && cfg.alphaSize == request.alphaSize && depthMatches && stencilMatches) { config = testConfig; break; } } if (i >= numMatchingConfigs) { // no exact match was found //if (exactMatchOnly) //{ // printf("No exactly matching EGL configs found!\n"); // return false; //} // just return any matching config (ie, the first one) config = matchingConfigs[0]; } EGLint ContextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLContext Context = eglCreateContext(g_display, config, EGL_NO_CONTEXT, ContextAttributes); //CHECKEGLERRORS(); // In Windows System, EGLNativeWindowType == HWND g_surface = eglCreateWindowSurface(g_display, config, g_hWnd, NULL); //CHECKEGLERRORS(); eglMakeCurrent(g_display, g_surface, g_surface, Context); //CHECKEGLERRORS(); #else GLuint PixelFormat; PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 24; g_hDC = GetDC( g_hWnd ); if(!g_hDC) { nvFX::printf("Failed to get the Windows device context!\n"); exit(1); } PixelFormat = ChoosePixelFormat( g_hDC, &pfd ); SetPixelFormat( g_hDC, PixelFormat, &pfd); g_hRC = wglCreateContext( g_hDC ); if(!g_hRC) { nvFX::printf("Failed to create OpenGL context!\n"); exit(1); } wglMakeCurrent( g_hDC, g_hRC ); //wglSwapInterval(0); GLenum res = glewInit(); if(res) { nvFX::printf("Failed to initialize Glew\n"); exit(1); } GLboolean b = glewIsSupported("GL_ARB_texture_compression"); GETPROCADDRESS(PFNWGLCREATECONTEXTATTRIBSARB,wglCreateContextAttribsARB) if(wglCreateContextAttribsARB) { HGLRC hRC = NULL; int attribList[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 0, WGL_CONTEXT_FLAGS_ARB, //WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB| #ifdef _DEBUG WGL_CONTEXT_DEBUG_BIT_ARB #else 0 #endif ,0, 0 }; // First try creating an OpenGL 3.1 context. if (!(hRC = wglCreateContextAttribsARB(g_hDC, 0, attribList))) { // Fall back to an OpenGL 3.0 context. attribList[3] = 0; if (!(hRC = wglCreateContextAttribsARB(g_hDC, 0, attribList))) nvFX::printf("wglCreateContextAttribsARB() failed for OpenGL 4.2 context.\n"); } else if (!wglMakeCurrent(g_hDC, hRC)) { nvFX::printf("wglMakeCurrent() failed\n"); } else { g_hRC = hRC; #ifdef _DEBUG //GETPROCADDRESS(PFNGLDEBUGMESSAGECONTROLARB, glDebugMessageControlARB); //GETPROCADDRESS(PFNGLDEBUGMESSAGEINSERTARB, glDebugMessageInsertARB); //GETPROCADDRESS(PFNGLDEBUGMESSAGECALLBACKARB, glDebugMessageCallbackARB); //GETPROCADDRESS(PFNGLGETDEBUGMESSAGELOGARB, glGetDebugMessageLogARB); //GETPROCADDRESS(PFNWGLGETPOINTERV, glGetPointerv); if(glDebugMessageCallbackARB) { glDebugMessageCallbackARB((GLDEBUGPROCARB)myOpenGLCallback, NULL); } #endif } } #endif }
CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) { // safety if (!pWindow) return NULL; // create it CStdGLCtx *pCtx = new CStdGLCtx(); bool first_ctx = !pMainCtx; if (first_ctx) { pMainCtx = pCtx; LogF(" gl: Create first %scontext...", Config.Graphics.DebugOpenGL ? "debug " : ""); } bool success = pCtx->Init(pWindow, pApp); if (Config.Graphics.DebugOpenGL && glDebugMessageCallbackARB) { if (first_ctx) Log(" gl: Setting OpenGLDebugProc callback"); glDebugMessageCallbackARB(&OpenGLDebugProc, nullptr); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); #ifdef GL_KHR_debug if (GLEW_KHR_debug) glEnable(GL_DEBUG_OUTPUT); #endif } // First context: Log some information about hardware/drivers // Must log after context creation to get valid results if (first_ctx) { const char *gl_vendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR)); const char *gl_renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); const char *gl_version = reinterpret_cast<const char *>(glGetString(GL_VERSION)); LogF("GL %s on %s (%s)", gl_version ? gl_version : "", gl_renderer ? gl_renderer : "", gl_vendor ? gl_vendor : ""); if (Config.Graphics.DebugOpenGL) { // Dump extension list if (glGetStringi) { GLint gl_extension_count = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &gl_extension_count); if (gl_extension_count == 0) { LogSilentF("No available extensions."); } else { LogSilentF("%d available extensions:", gl_extension_count); for (GLint i = 0; i < gl_extension_count; ++i) { const char *gl_extension = (const char*)glGetStringi(GL_EXTENSIONS, i); LogSilentF(" %4d: %s", i, gl_extension); } } } else { const char *gl_extensions = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)); LogSilentF("GLExt: %s", gl_extensions ? gl_extensions : ""); } } } if (!success) { delete pCtx; Error(" gl: Error creating secondary context!"); return NULL; } // creation selected the new context - switch back to previous context RenderTarget = NULL; pCurrCtx = NULL; // done return pCtx; }
// ------------------------------------------------------------------------------------------ //! Function would be called on the global initialization step. //! @returns Non-negative value if the operation succeeded. GDAPI IResult IGraphicsOpenGL::OnRuntimeInitialize() { // _CheckNotInitialized(); ConsoleDevice->Log(GD_DLOG_CAT ": going to initialize graphics devices..."); IResult const _BaseResult = IGraphicsOpenGLPlatform::OnRuntimeInitialize(); if (IFailed(_BaseResult)) return _BaseResult; // Loading OpenGL core profile methods. glewExperimental = GL_TRUE; glewInit(); #if GD_DEBUG if (GLEW_ARB_debug_output) { // We have some good debugging extension running, so we do not need to check for OpenGL // errors after every single OpenGL API function call. // http://www.opengl.org/registry/specs/ARB/debug_output.txt glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glDebugMessageCallbackARB([](GLenum const Source, GLenum const Type, GLuint const ID, GLenum const Severity , GLsizei const Length, GLchar const* const Message, CHandle const UserParam) { CStr glDebugSeverity; switch (Severity) { default: glDebugSeverity = "Unknown severity"; break; case GL_DEBUG_SEVERITY_HIGH_ARB: glDebugSeverity = "High priority"; break; case GL_DEBUG_SEVERITY_MEDIUM_ARB: glDebugSeverity = "Medium priority"; break; case GL_DEBUG_SEVERITY_LOW_ARB: glDebugSeverity = "Low priority"; break; } CStr glDebugErrorType; switch (Type) { default: glDebugErrorType = "something"; break; case GL_DEBUG_TYPE_OTHER_ARB: glDebugErrorType = "other issue"; break; case GL_DEBUG_TYPE_ERROR_ARB: glDebugErrorType = "error"; break; case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: glDebugErrorType = "deprecated behavior issue"; break; case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: glDebugErrorType = "undefined behavior issue"; break; case GL_DEBUG_TYPE_PORTABILITY_ARB: glDebugErrorType = "portability issue"; break; case GL_DEBUG_TYPE_PERFORMANCE_ARB: glDebugErrorType = "performance issue"; break; } CStr glDebugErrorSource; switch (Source) { default: glDebugErrorSource = "unknown location"; break; case GL_DEBUG_SOURCE_API_ARB: glDebugErrorSource = "API call"; break; case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: glDebugErrorSource = "window system API all"; break; case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: glDebugErrorSource = "shader compiler"; break; case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: glDebugErrorSource = "third party API"; break; case GL_DEBUG_SOURCE_APPLICATION_ARB: glDebugErrorSource = "application"; break; case GL_DEBUG_SOURCE_OTHER_ARB: glDebugErrorSource = "other"; break; } GD_NOT_USED_L(UserParam, Length); switch (Severity) { default: case GL_DEBUG_SEVERITY_LOW_ARB: // Possibly, this is not an error: e.g. a log from NVidia driver. ConsoleDevice->LogFormat(GD_DLOG_CAT ": ... debug callback:\n\t%s %s #%x in %s:\n\t%s" , glDebugSeverity, glDebugErrorType, ID, glDebugErrorSource, Message ); break; case GL_DEBUG_SEVERITY_HIGH_ARB: case GL_DEBUG_SEVERITY_MEDIUM_ARB: // This is some kind of warning or error. ConsoleDevice->LogErrorFormat(GD_DLOG_CAT ": ... debug callback:\n\t%s %s #%x in %s:\n\t%s" , glDebugSeverity, glDebugErrorType, ID, glDebugErrorSource, Message ); GD_ASSERT_FALSE("Some issue inside OpenGL code."); // break; } }, nullptr); } else { ConsoleDevice->LogError(GD_DLOG_CAT ": ... no 'ARB_debug_output' extension was found. No log or error checking for OpenGL code " "would be provided."); } #endif // if GD_DEBUG // Enabling the back-face cooling. glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // We are using m_Left-handed math and clockwise triangles. glFrontFace(GL_CW); // Initially setting up the view-port and depth. glEnable(GL_DEPTH_TEST); glClearDepth(1.0f); glClearColor(0.3f, 0.275f, 1.0f, 1.0f); glViewport(0, 0, GfxResolutionSelected->Width, GfxResolutionSelected->Height); ConsoleDevice->Log(GD_DLOG_CAT ": ... initialized."); return IResult::Ok; }
void graphicssystem_initialize() { #ifdef DEBUG_MODE glDebugMessageCallbackARB((GLDEBUGPROCARB)&DebugCallbackARB, 0); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); printf("OpenGL version supported by this platform (%s): \n", glGetString(GL_VERSION)); GLuint other_ids[] = { 131185 }; glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_OTHER_ARB, GL_DONT_CARE, 1, other_ids, GL_FALSE); //Disable some notifications shown below: //OpenGL: Buffer detailed info: Buffer object 1 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations. [source=API type=OTHER severity=UNDEFINED (33387) id=131185] GLuint performance_ids[] = { 131218, 2 }; glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_PERFORMANCE_ARB, GL_DONT_CARE, 2, performance_ids, GL_FALSE); //Disable some notifications shown below: //OpenGL: Program/shader state performance warning: Vertex shader in program 9 is being recompiled based on GL state. [source=API type=PERFORMANCE severity=MEDIUM id=131218] - This is NVidia only and doesn't tell much #endif gl_screen_init(); glEnable(GL_SCISSOR_TEST); // constrain clear to viewport like D3D9 glDepthFunc(GL_LEQUAL); // to match GM8's D3D8 default init_shaders(); // read shaders into graphics system structure and compile and link them if needed for (size_t i = 0; i < shader_idmax; ++i) { ShaderStruct* shaderstruct = shaderdata[i]; //TODO(harijs): If precompile == false or ID's are not defragged, there is a segfault because we try to access invalid position in shader vector if (shaderstruct->precompile == false) { continue; } int vshader_id = enigma_user::glsl_shader_create(enigma_user::sh_vertex); enigma_user::glsl_shader_load_string(vshader_id, shaderstruct->vertex); int fshader_id = enigma_user::glsl_shader_create(enigma_user::sh_fragment); enigma_user::glsl_shader_load_string(fshader_id, shaderstruct->fragment); int prog_id = enigma_user::glsl_program_create(); enigma_user::glsl_program_set_name(prog_id, enigma_user::shader_get_name(i)); enigma_user::glsl_shader_compile(vshader_id); enigma_user::glsl_shader_compile(fshader_id); enigma_user::glsl_program_attach(prog_id, vshader_id); enigma_user::glsl_program_attach(prog_id, fshader_id); enigma_user::glsl_program_link(prog_id); enigma_user::glsl_program_validate(prog_id); } //ADD DEFAULT SHADER (emulates FFP) int vshader_id = enigma_user::glsl_shader_create(enigma_user::sh_vertex); enigma_user::glsl_shader_load_string(vshader_id, getDefaultVertexShader()); int fshader_id = enigma_user::glsl_shader_create(enigma_user::sh_fragment); enigma_user::glsl_shader_load_string(fshader_id, getDefaultFragmentShader()); int prog_id = enigma_user::glsl_program_create(); enigma_user::glsl_shader_compile(vshader_id); enigma_user::glsl_shader_compile(fshader_id); enigma_user::glsl_program_attach(prog_id, vshader_id); enigma_user::glsl_program_attach(prog_id, fshader_id); enigma_user::glsl_program_link(prog_id); enigma_user::glsl_program_validate(prog_id); enigma_user::glsl_program_set_name(prog_id, "DEFAULT_SHADER"); default_shader = prog_id; //Default shader for FFP main_shader = default_shader; //Main shader used to override the default one enigma_user::glsl_program_reset(); //Set the default program //END DEFAULT SHADER //In GL3.3 Core VAO is mandatory. So we create one and never change it GLuint vertexArrayObject; glGenVertexArrays(1, &vertexArrayObject); glBindVertexArray(vertexArrayObject); }
// Sets the pointer to user data void VSDebugLib::setUserParam(void *p) { spUserParam = p; glDebugMessageCallbackARB(DebugLog, VSDebugLib::spUserParam); }