/* ** GLW_MakeContext */ static int GLW_MakeContext( PIXELFORMATDESCRIPTOR *pPFD ) { int pixelformat; // // don't putz around with pixelformat if it's already set (e.g. this is a soft // reset of the graphics system) // if ( !glw_state.pixelFormatSet ) { // // choose, set, and describe our desired pixel format. If we're // using a minidriver then we need to bypass the GDI functions, // otherwise use the GDI functions. // if ( ( pixelformat = GLW_ChoosePFD( glw_state.hDC, pPFD ) ) == 0 ) { ri.Printf( PRINT_ALL, "...GLW_ChoosePFD failed\n" ); return TRY_PFD_FAIL_SOFT; } ri.Printf( PRINT_ALL, "...PIXELFORMAT %d selected\n", pixelformat ); if ( glConfig.driverType > GLDRV_ICD ) { qwglDescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD ); if ( qwglSetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE ) { ri.Printf( PRINT_ALL, "...qwglSetPixelFormat failed\n" ); return TRY_PFD_FAIL_SOFT; } } else { DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD ); if ( SetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE ) { ri.Printf( PRINT_ALL, "...SetPixelFormat failed\n", glw_state.hDC ); return TRY_PFD_FAIL_SOFT; } } glw_state.pixelFormatSet = qtrue; } // // startup the OpenGL subsystem by creating a context and making it current // if ( !glw_state.hGLRC ) { ri.Printf( PRINT_ALL, "...creating GL context: " ); if ( ( glw_state.hGLRC = qwglCreateContext( glw_state.hDC ) ) == 0 ) { ri.Printf( PRINT_ALL, "failed\n" ); return TRY_PFD_FAIL_HARD; } ri.Printf( PRINT_ALL, "succeeded\n" ); ri.Printf( PRINT_ALL, "...making context current: " ); if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) { qwglDeleteContext( glw_state.hGLRC ); glw_state.hGLRC = NULL; ri.Printf( PRINT_ALL, "failed\n" ); return TRY_PFD_FAIL_HARD; } ri.Printf( PRINT_ALL, "succeeded\n" ); } return TRY_PFD_SUCCESS; }
// Return a list of available and usable framebuffer configs // static GLboolean choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired, int* result) { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; int i, nativeCount, usableCount; if (window->wgl.ARB_pixel_format) { nativeCount = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB); } else { nativeCount = DescribePixelFormat(window->wgl.dc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); } if (!nativeCount) { _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found"); return GL_FALSE; } usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; for (i = 0; i < nativeCount; i++) { const int n = i + 1; _GLFWfbconfig* u = usableConfigs + usableCount; if (window->wgl.ARB_pixel_format) { // Get pixel format attributes through WGL_ARB_pixel_format if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) || !getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB) || !getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB)) { continue; } if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB) { continue; } if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB) { continue; } u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB); u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB); u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB); u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB); u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB); u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB); u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB); u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB); u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB); u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB); u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB); u->stereo = getPixelFormatAttrib(window, n, WGL_STEREO_ARB); if (window->wgl.ARB_multisample) u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB); if (window->wgl.ARB_framebuffer_sRGB) u->sRGB = getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); } else { PIXELFORMATDESCRIPTOR pfd; // Get pixel format attributes through old-fashioned PFDs if (!DescribePixelFormat(window->wgl.dc, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { continue; } if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL) || !(pfd.dwFlags & PFD_DOUBLEBUFFER)) { continue; } if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && (pfd.dwFlags & PFD_GENERIC_FORMAT)) { continue; } if (pfd.iPixelType != PFD_TYPE_RGBA) continue; u->redBits = pfd.cRedBits; u->greenBits = pfd.cGreenBits; u->blueBits = pfd.cBlueBits; u->alphaBits = pfd.cAlphaBits; u->depthBits = pfd.cDepthBits; u->stencilBits = pfd.cStencilBits; u->accumRedBits = pfd.cAccumRedBits; u->accumGreenBits = pfd.cAccumGreenBits; u->accumBlueBits = pfd.cAccumBlueBits; u->accumAlphaBits = pfd.cAccumAlphaBits; u->auxBuffers = pfd.cAuxBuffers; u->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; } u->wgl = n; usableCount++; } if (!usableCount) { _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: The driver does not appear to support OpenGL"); free(usableConfigs); return GL_FALSE; } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (!closest) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to find a suitable pixel format"); free(usableConfigs); return GL_FALSE; } *result = closest->wgl; free(usableConfigs); return GL_TRUE; }
/* * Find an appropriate pixel format */ static int findPixelFormatFromBPP(JNIEnv *env, HDC hdc, jobject pixel_format, int bpp, bool double_buffer) { jclass cls_pixel_format = (*env)->GetObjectClass(env, pixel_format); int alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "alpha", "I")); int depth = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "depth", "I")); int stencil = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stencil", "I")); int num_aux_buffers = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "num_aux_buffers", "I")); int accum_bpp = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_bpp", "I")); int accum_alpha = (int)(*env)->GetIntField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "accum_alpha", "I")); jboolean stereo = (*env)->GetBooleanField(env, pixel_format, (*env)->GetFieldID(env, cls_pixel_format, "stereo", "Z")); unsigned int flags = PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | (double_buffer ? PFD_DOUBLEBUFFER : 0) | (stereo ? PFD_STEREO : 0); PIXELFORMATDESCRIPTOR desc; int iPixelFormat; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number flags, // RGBA type PFD_TYPE_RGBA, (BYTE)bpp, 0, 0, 0, 0, 0, 0, // color bits ignored (BYTE)alpha, 0, // shift bit ignored accum_bpp + accum_alpha, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored (BYTE)depth, (BYTE)stencil, num_aux_buffers, PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; // get the best available match of pixel format for the device context iPixelFormat = ChoosePixelFormat(hdc, &pfd); if (iPixelFormat == 0) { throwException(env, "Failed to choose pixel format"); return -1; } if (DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desc) == 0) { throwException(env, "Could not describe pixel format"); return -1; } if (desc.cColorBits < bpp) { throwException(env, "Insufficient color precision"); return -1; } if (desc.cAlphaBits < alpha) { throwException(env, "Insufficient alpha precision"); return -1; } if (desc.cStencilBits < stencil) { throwException(env, "Insufficient stencil precision"); return -1; } if (desc.cDepthBits < depth) { throwException(env, "Insufficient depth buffer precision"); return -1; } if ((desc.dwFlags & PFD_GENERIC_FORMAT) != 0) { jboolean allowSoftwareOpenGL = getBooleanProperty(env, "org.lwjgl.opengl.Display.allowSoftwareOpenGL"); // secondary check for software override if(!allowSoftwareOpenGL) { throwException(env, "Pixel format not accelerated"); return -1; } } if ((desc.dwFlags & flags) != flags) { throwException(env, "Capabilities not supported"); return -1; } return iPixelFormat; }
/* Функция инициализации анимации. * АРГУМЕНТЫ: * - дескриптор окна: * HWND hWnd; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет. */ BOOL OK2_AnimInit( HWND hWnd ) { LARGE_INTEGER li; INT i; /* Init window parametrs */ OK2_Anim.hDC = GetDC(hWnd); OK2_Anim.hWnd = hWnd; OK2_Anim.W = 30; OK2_Anim.H = 30; OK2_Anim.NumOfUnits = 0; /*** Инициализация OpenGL ***/ /* описываем формат точки */ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; i = ChoosePixelFormat(OK2_Anim.hDC, &pfd); DescribePixelFormat(OK2_Anim.hDC, i, sizeof(pfd), &pfd); SetPixelFormat(OK2_Anim.hDC, i, &pfd); /* создаем контекст построения */ OK2_Anim.hRC = wglCreateContext(OK2_Anim.hDC); /* делаем текущими контексты */ wglMakeCurrent(OK2_Anim.hDC, OK2_Anim.hRC); /* инициализируем расширения */ if (glewInit() != GLEW_OK || !(GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)) { wglMakeCurrent(NULL, NULL); wglDeleteContext(OK2_Anim.hRC); ReleaseDC(OK2_Anim.hWnd, OK2_Anim.hDC); memset(&OK2_Anim, 0, sizeof(ok2ANIM)); return FALSE; } /* параметры OpenGL по-умолчанию */ /* инициализируем таймер */ QueryPerformanceFrequency(&li); TimeFreq = li.QuadPart; QueryPerformanceCounter(&li); TimeStart = TimeOld = TimeFPS = li.QuadPart; TimePause = 0; FrameCounter = 0; /* инициализируем захват сообщений от мыши */ SetWindowsHookEx(WH_MOUSE_LL, OK2_MouseHook, GetModuleHandle(NULL), 0); /* Параметры проецирования */ OK2_Anim.Wp = 4.0, OK2_Anim.Hp = 3.0, /* размеры обрасти проецирования */ OK2_Anim.ProjDist = 1.0, /* расстояние до плоскости проекции */ OK2_Anim.FarClip = 1000.0, OK2_Anim.ProjSize = 1.0; OK2_Anim.MatrWorld = /* матрица преобразования мировой СК */ OK2_Anim.MatrView = /* матрица преобразования видовой СК */ OK2_Anim.MatrProjection = MatrIdenity(); /* матрица проекции */ glEnable(GL_DEPTH_TEST); glEnable(GL_ALPHA_TEST); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); return TRUE; } /* End of 'OK2_AnimInit' function */
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Allocate program memory g_program_memory.start = malloc(MAX_INTERNAL_MEMORY_SIZE); g_program_memory.free_memory = g_program_memory.start; // TODO: add checks for overflow when allocating // Main program state Program_State *state = (Program_State *)g_program_memory.allocate(sizeof(Program_State)); state->init(&g_program_memory, &g_pixel_buffer, (Raytrace_Work_Queue *)&g_raytrace_queue); // Create window class WNDCLASS WindowClass = {}; WindowClass.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; WindowClass.lpfnWndProc = Win32WindowProc; WindowClass.hInstance = hInstance; WindowClass.lpszClassName = "VMWindowClass"; // Set target sleep resolution { TIMECAPS tc; UINT wTimerRes; if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) { OutputDebugStringA("Cannot set the sleep resolution\n"); exit(1); } wTimerRes = min(max(tc.wPeriodMin, 1), tc.wPeriodMax); // 1 ms timeBeginPeriod(wTimerRes); } QueryPerformanceFrequency(&gPerformanceFrequency); if (!RegisterClass(&WindowClass)) { // TODO: logging printf("Couldn't register window class\n"); exit(1); } // Create window so that its client area is exactly kWindowWidth/Height DWORD WindowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE; RECT WindowRect = {}; WindowRect.right = state->kWindowWidth; WindowRect.bottom = state->kWindowHeight; AdjustWindowRect(&WindowRect, WindowStyle, 0); int WindowWidth = WindowRect.right - WindowRect.left; int WindowHeight = WindowRect.bottom - WindowRect.top; HWND Window = CreateWindow(WindowClass.lpszClassName, 0, WindowStyle, CW_USEDEFAULT, CW_USEDEFAULT, WindowWidth, WindowHeight, 0, 0, hInstance, 0); if (!Window) { printf("Couldn't create window\n"); exit(1); } // We're not going to release it as we use CS_OWNDC HDC hdc = GetDC(Window); g_running = true; // Set proper buffer values based on actual client size Win32ResizeClientWindow(Window); // Init OpenGL { PIXELFORMATDESCRIPTOR DesiredPixelFormat = {}; DesiredPixelFormat.nSize = sizeof(DesiredPixelFormat); DesiredPixelFormat.nVersion = 1; DesiredPixelFormat.iPixelType = PFD_TYPE_RGBA; DesiredPixelFormat.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; DesiredPixelFormat.cColorBits = 32; DesiredPixelFormat.cAlphaBits = 8; DesiredPixelFormat.iLayerType = PFD_MAIN_PLANE; int SuggestedPixelFormatIndex = ChoosePixelFormat(hdc, &DesiredPixelFormat); PIXELFORMATDESCRIPTOR SuggestedPixelFormat; DescribePixelFormat(hdc, SuggestedPixelFormatIndex, sizeof(SuggestedPixelFormat), &SuggestedPixelFormat); SetPixelFormat(hdc, SuggestedPixelFormatIndex, &SuggestedPixelFormat); HGLRC OpenGLRC = wglCreateContext(hdc); if (wglMakeCurrent(hdc, OpenGLRC)) { // Success glGenTextures(1, &gTextureHandle); typedef BOOL WINAPI wgl_swap_interval_ext(int interval); wgl_swap_interval_ext *wglSwapInterval = (wgl_swap_interval_ext *)wglGetProcAddress("wglSwapIntervalEXT"); if (wglSwapInterval) { wglSwapInterval(1); } else { // VSync not enabled or not supported assert(false); } } else { // Something's wrong assert(false); } } Cursor_Type current_cursor = Cursor_Type_Arrow; HCURSOR win_cursors[Cursor_Type__COUNT]; win_cursors[Cursor_Type_Arrow] = LoadCursor(NULL, IDC_ARROW); win_cursors[Cursor_Type_Cross] = LoadCursor(NULL, IDC_CROSS); win_cursors[Cursor_Type_Hand] = LoadCursor(NULL, IDC_HAND); win_cursors[Cursor_Type_Resize_Vert] = LoadCursor(NULL, IDC_SIZENS); win_cursors[Cursor_Type_Resize_Horiz] = LoadCursor(NULL, IDC_SIZEWE); User_Input inputs[2]; User_Input *old_input = &inputs[0]; User_Input *new_input = &inputs[1]; *new_input = {}; LARGE_INTEGER last_timestamp = Win32GetWallClock(); // Create worker threads { const int kNumThreads = 4; // Init work queue g_raytrace_queue.next_entry_to_add = 0; g_raytrace_queue.next_entry_to_do = 0; u32 initial_num_threads = 0; g_raytrace_queue.semaphore = CreateSemaphoreEx( 0, initial_num_threads, kNumThreads, 0, 0, SEMAPHORE_ALL_ACCESS); Thread_Info threads[kNumThreads]; for (int i = 0; i < kNumThreads; i++) { threads[i].thread_num = i + 1; HANDLE thread_handle = CreateThread( 0, // LPSECURITY_ATTRIBUTES lpThreadAttributes, 0, // SIZE_T dwStackSize, RaytraceWorkerThread, // LPTHREAD_START_ROUTINE lpStartAddress, &threads[i], // LPVOID lpParameter, 0, // DWORD dwCreationFlags, NULL // LPDWORD lpThreadId ); threads[i].thread_handle = thread_handle; if (thread_handle == NULL) { printf("CreateThread error: %d\n", GetLastError()); exit(1); } } } // Event loop while (g_running) { // Process messages MSG message; while (PeekMessage(&message, 0, 0, 0, PM_REMOVE)) { // Get keyboard messages switch (message.message) { case WM_QUIT: { g_running = false; } break; case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: case WM_KEYUP: { u32 vk_code = (u32)message.wParam; bool was_down = ((message.lParam & (1 << 30)) != 0); bool is_down = ((message.lParam & (1 << 31)) == 0); bool alt_key_was_down = (message.lParam & (1 << 29)) != 0; if ((vk_code == VK_F4) && alt_key_was_down) { g_running = false; } if (was_down == is_down) { break; // nothing has changed } if (vk_code == VK_ESCAPE) { new_input->buttons[IB_escape] = is_down; } if (vk_code == VK_UP) { new_input->buttons[IB_up] = is_down; } if (vk_code == VK_DOWN) { new_input->buttons[IB_down] = is_down; } if (vk_code == VK_LEFT) { new_input->buttons[IB_left] = is_down; } if (vk_code == VK_RIGHT) { new_input->buttons[IB_right] = is_down; } if (vk_code == VK_SHIFT) { new_input->buttons[IB_shift] = is_down; } // Handle symbols int symbol = (int)vk_code; if (vk_code == VK_NUMPAD0) symbol = '0'; else if (vk_code == VK_NUMPAD1) symbol = '1'; else if (vk_code == VK_NUMPAD2) symbol = '2'; else if (vk_code == VK_NUMPAD3) symbol = '3'; else if (vk_code == VK_NUMPAD4) symbol = '4'; else if (vk_code == VK_NUMPAD5) symbol = '5'; else if (vk_code == VK_NUMPAD6) symbol = '6'; else if (vk_code == VK_NUMPAD7) symbol = '7'; else if (vk_code == VK_NUMPAD8) symbol = '8'; else if (vk_code == VK_NUMPAD9) symbol = '9'; if (('A' <= symbol && symbol <= 'Z') || ('0' <= symbol && symbol <= '9')) { new_input->buttons[IB_key] = is_down; new_input->symbol = symbol; } } break; case WM_MOUSEWHEEL: { int delta = (int)message.wParam / (65536 * WHEEL_DELTA); new_input->scroll += delta; } break; default: { TranslateMessage(&message); DispatchMessageA(&message); } break; } } // Get mouse input { POINT mouse_pointer; GetCursorPos(&mouse_pointer); ScreenToClient(Window, &mouse_pointer); new_input->mouse = {mouse_pointer.x, mouse_pointer.y}; new_input->buttons[IB_mouse_left] = (GetKeyState(VK_LBUTTON) & (1 << 15)) != 0; new_input->buttons[IB_mouse_right] = (GetKeyState(VK_RBUTTON) & (1 << 15)) != 0; new_input->buttons[IB_mouse_middle] = (GetKeyState(VK_MBUTTON) & (1 << 15)) != 0; } Update_Result result = update_and_render(&g_program_memory, state, new_input); #include "debug/ED_debug_draw.cpp" assert(0 <= result.cursor && result.cursor < Cursor_Type__COUNT); SetCursor(win_cursors[result.cursor]); Win32UpdateWindow(hdc); // Swap inputs User_Input *tmp = old_input; old_input = new_input; new_input = tmp; // Zero input *new_input = {}; new_input->old = old_input; // Save so we can refer to it later // Retain the button state for (size_t i = 0; i < COUNT_OF(new_input->buttons); i++) { new_input->buttons[i] = old_input->buttons[i]; } for (size_t i = 0; i < COUNT_OF(new_input->mouse_positions); i++) { new_input->mouse_positions[i] = old_input->mouse_positions[i]; } new_input->symbol = old_input->symbol; r32 ms_elapsed = Win32GetMillisecondsElapsed(last_timestamp, Win32GetWallClock()); g_FPS.value = (int)(1000.0f / ms_elapsed); last_timestamp = Win32GetWallClock(); } return 0; }
djvWglContext::djvWglContext(djvCoreContext * context) throw (djvError) : djvOpenGlContext(context), _p(new djvWglContextPrivate) { # if defined(DJV_WINDOWS) //DJV_DEBUG("djvWglContext::djvWglContext"); // Create a dummy window and OpenGL context for glewInit. // According to the docs, glewInit can be called just once per-process? DJV_LOG(context->debugLog(), "djvWglContext", "Creating dummy window..."); HINSTANCE hinstance = GetModuleHandle(0); if (! hinstance) { throw djvError( "djvWglContext", errorLabels()[ERROR_MODULE_HANDLE].arg(int(GetLastError()))); } static const char name [] = "djv"; WNDCLASS wc; if (! GetClassInfo(hinstance, name, &wc)) { wc.style = CS_OWNDC; //wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.lpfnWndProc = DefWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hinstance; wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = 0; wc.lpszMenuName = 0; wc.lpszClassName = name; if (! RegisterClass(&wc)) { throw djvError( "djvWglContext", errorLabels()[ERROR_REGISTER_CLASS].arg(int(GetLastError()))); } } _p->id = CreateWindow(name, 0, 0, 0, 0, 0, 0, 0, 0, hinstance, 0); if (! _p->id) { throw djvError( "djvWglContext", errorLabels()[ERROR_CREATE_WINDOW].arg(int(GetLastError()))); } _p->device = GetDC(_p->id); if (! _p->device) { throw djvError( "djvWglContext", errorLabels()[ERROR_GET_DC].arg(int(GetLastError()))); } PIXELFORMATDESCRIPTOR pixelFormatInfo; const int pixelFormatCount = DescribePixelFormat(_p->device, 0, 0, 0); //DJV_DEBUG_PRINT("pixel format count = " << pixelFormatCount); DJV_LOG(context->debugLog(), "djvWglContext", QString("Pixel format count: %1").arg(pixelFormatCount)); for (int i = 1; i < pixelFormatCount; ++i) { DescribePixelFormat( _p->device, i, sizeof(PIXELFORMATDESCRIPTOR), &pixelFormatInfo); //DJV_DEBUG_PRINT(" id " << i << ": " << // ((PFD_SUPPORT_OPENGL & pixelFormatInfo.dwFlags) ? "gl " : "") << // ((PFD_GENERIC_FORMAT & pixelFormatInfo.dwFlags) ? "" : "accel ") << // ((PFD_TYPE_RGBA == pixelFormatInfo.iPixelType) ? "rgba " : "") << // "depth = " << pixelFormatInfo.cColorBits << "/" << // pixelFormatInfo.cRedBits << "/" << // pixelFormatInfo.cGreenBits << "/" << // pixelFormatInfo.cBlueBits << "/" << // pixelFormatInfo.cAlphaBits << " "); QStringList tmp; if (PFD_SUPPORT_OPENGL & pixelFormatInfo.dwFlags) tmp += "gl"; if (! (PFD_GENERIC_FORMAT & pixelFormatInfo.dwFlags)) tmp += "accel"; if (PFD_TYPE_RGBA == pixelFormatInfo.iPixelType) tmp += "rgba"; DJV_LOG(context->debugLog(), "djvWglContext", QString("Pixel format %1: %2 %3/%4/%5/%6/%7"). arg(i). arg(tmp.join(" ")). arg(pixelFormatInfo.cColorBits). arg(pixelFormatInfo.cRedBits). arg(pixelFormatInfo.cGreenBits). arg(pixelFormatInfo.cBlueBits). arg(pixelFormatInfo.cAlphaBits)); } PIXELFORMATDESCRIPTOR pixelFormat = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; int pixelFormatId = ChoosePixelFormat(_p->device, &pixelFormat); //DJV_DEBUG_PRINT("pixel format = " << pixelFormatId); DJV_LOG(context->debugLog(), "djvWglContext", QString("Chosen pixel format: %1").arg(pixelFormatId)); if (! pixelFormatId) { throw djvError( "djvWglContext", errorLabels()[ERROR_GET_PIXEL_FORMAT].arg(int(GetLastError()))); } if (! SetPixelFormat(_p->device, pixelFormatId, &pixelFormat)) { throw djvError( "djvWglContext", errorLabels()[ERROR_SET_PIXEL_FORMAT].arg(int(GetLastError()))); } // Create OpengGL context. DJV_LOG(context->debugLog(), "djvWglContext", "Creating OpenGL context..."); _p->context = wglCreateContext(_p->device); if (! _p->context) { throw djvError( "djvWglContext", errorLabels()[ERROR_CREATE_CONTEXT].arg(int(GetLastError()))); } if (! wglMakeCurrent(_p->device, _p->context)) { throw djvError( "djvWglContext", errorLabels()[ERROR_BIND_CONTEXT].arg(int(GetLastError()))); } // Initialize GLEW. DJV_LOG(context->debugLog(), "djvWglContext", "Initializing GLEW..."); GLenum err = glewInit(); if (err != GLEW_OK) { throw djvError( "djvWglContext", errorLabels()[ERROR_INIT_GLEW].arg((char *)glewGetErrorString(err))); } setVendor(QString((const char *)glGetString(GL_VENDOR))); setRenderer(QString((const char *)glGetString(GL_RENDERER))); setVersion(QString((const char *)glGetString(GL_VERSION))); //DJV_DEBUG_PRINT("OpenGL vendor string = " << vendor()); //DJV_DEBUG_PRINT("OpenGL renderer string = " << renderer()); //DJV_DEBUG_PRINT("OpenGL version string = " << version()); //DJV_DEBUG_PRINT("OpenGL extensions = " << // (const char *)glGetString(GL_EXTENSIONS)); //DJV_DEBUG_PRINT("glu version = " << // (const char *)gluGetString(GLU_VERSION)); //DJV_DEBUG_PRINT("glu extensions = " << // (const char *)gluGetString(GLU_EXTENSIONS)); DJV_LOG(context->debugLog(), "djvWglContext", QString("GL vendor: \"%1\"").arg(vendor())); DJV_LOG(context->debugLog(), "djvWglContext", QString("GL renderer: \"%1\"").arg(renderer())); DJV_LOG(context->debugLog(), "djvWglContext", QString("GL version: \"%1\"").arg(version())); # endif // DJV_WINDOWS }
HPALETTE GetOpenGLPalette(HDC hDC) { HPALETTE hRetPal = NULL; // Handle to palette to be created PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor LOGPALETTE *pPal; // Pointer to memory for logical palette int nPixelFormat; // Pixel format index int nColors; // Number of entries in palette int i; // Counting variable BYTE RedRange, GreenRange, BlueRange; // Range for each color entry (7,7,and 3) // Get the pixel format index and retrieve the pixel format description nPixelFormat = GetPixelFormat(hDC); DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); // Does this pixel format require a palette? If not, do not create a // palette and just return NULL if (!(pfd.dwFlags & PFD_NEED_PALETTE)) return NULL; // Number of entries in palette. 8 bits yeilds 256 entries nColors = 1 << pfd.cColorBits; // Allocate space for a logical palette structure plus all the palette entries pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + nColors*sizeof(PALETTEENTRY)); // Fill in palette header pPal->palVersion = 0x300; // Windows 3.0 pPal->palNumEntries = nColors; // table size // Build mask of all 1's. This creates a number represented by having // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and // pfd.cBlueBits. RedRange = (1 << pfd.cRedBits) - 1; GreenRange = (1 << pfd.cGreenBits) - 1; BlueRange = (1 << pfd.cBlueBits) - 1; // Loop through all the palette entries for (i = 0; i < nColors; i++) { // Fill in the 8-bit equivalents for each component pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange; pPal->palPalEntry[i].peRed = (unsigned char)( (double)pPal->palPalEntry[i].peRed * 255.0 / RedRange); pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange; pPal->palPalEntry[i].peGreen = (unsigned char)( (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange); pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange; pPal->palPalEntry[i].peBlue = (unsigned char)( (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange); pPal->palPalEntry[i].peFlags = (unsigned char)NULL; } // Create the palette hRetPal = CreatePalette(pPal); // Go ahead and select and realize the palette for this device context SelectPalette(hDC, hRetPal, FALSE); RealizePalette(hDC); // Free the memory used for the logical palette structure free(pPal); // Return the handle to the new palette return hRetPal; }
BOOL GL11Window::Create(CONST WindowSettings& settings /*= {}*/) { m_settings = settings; CONST auto hInstance{GetModuleHandle(NULL)}; if (!hInstance) { DisplayError(TEXT("Failed to retrieve the application handle."), GetLastError()); return FALSE; } WNDCLASSEX wndClassEx{}; ZeroMemory(&wndClassEx, sizeof(WNDCLASSEX)); wndClassEx.cbSize = sizeof(WNDCLASSEX); wndClassEx.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClassEx.lpfnWndProc = WndProc; wndClassEx.cbClsExtra = 0; wndClassEx.cbWndExtra = sizeof(VOID*) + sizeof(INT); wndClassEx.hInstance = hInstance; wndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW); wndClassEx.hbrBackground = NULL; wndClassEx.lpszMenuName = NULL; wndClassEx.lpszClassName = TEXT("GL11WindowClass"); wndClassEx.hIconSm = NULL; if (FAILED(RegisterClassEx(&wndClassEx))) { DisplayError(TEXT("Failed to register the window class."), GetLastError()); return FALSE; } DWORD windowStyle{WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS}; DWORD windowStyleEx{WS_EX_ACCEPTFILES}; RECT windowRect{0, 0, m_settings.width, m_settings.height}; if (FAILED(AdjustWindowRectEx(&windowRect, windowStyle, FALSE, windowStyleEx))) { DisplayError(TEXT("Failed to adjust the window rect."), GetLastError()); return FALSE; } m_settings.x = (GetSystemMetrics(SM_CXSCREEN) / 2) - (m_settings.width / 2); m_settings.y = (GetSystemMetrics(SM_CYSCREEN) / 2) - (m_settings.height / 2); CONST auto FULL_TITLE{m_settings.title + m_settings.titleEx}; m_handle = CreateWindowEx(windowStyleEx, wndClassEx.lpszClassName, FULL_TITLE.c_str(), windowStyle, m_settings.x, m_settings.y, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, hInstance, this); if (!m_handle) { DisplayError(TEXT("Failed to create the window handle."), GetLastError()); return FALSE; } m_deviceContext = GetDC(m_handle); // Query a pixel format: PIXELFORMATDESCRIPTOR desiredPixelFormat{}; ZeroMemory(&desiredPixelFormat, sizeof(PIXELFORMATDESCRIPTOR)); desiredPixelFormat.nSize = sizeof(PIXELFORMATDESCRIPTOR); desiredPixelFormat.nVersion = 1; desiredPixelFormat.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL; desiredPixelFormat.iPixelType = PFD_TYPE_RGBA; desiredPixelFormat.cColorBits = 32; desiredPixelFormat.cDepthBits = 24; desiredPixelFormat.cStencilBits = 8; desiredPixelFormat.iLayerType = PFD_MAIN_PLANE; auto chosenPixelFormat{ChoosePixelFormat(m_deviceContext, &desiredPixelFormat)}; if (!chosenPixelFormat) { DisplayError(TEXT("Failed to choose a dummy pixel format."), GetLastError()); return FALSE; } if (FAILED(DescribePixelFormat(m_deviceContext, chosenPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &desiredPixelFormat))) { DisplayError(TEXT("Failed to fill the pixel format."), GetLastError()); return FALSE; } if (FAILED(SetPixelFormat(m_deviceContext, chosenPixelFormat, &desiredPixelFormat))) { DisplayError(TEXT("Failed to set the pixel format."), GetLastError()); return FALSE; } // Create the OpenGL context: m_renderingContext = wglCreateContext(m_deviceContext); if (!m_renderingContext) { DisplayError(TEXT("Failed to create the OpenGL context."), GetLastError()); return FALSE; } if (FAILED(wglMakeCurrent(m_deviceContext, m_renderingContext))) { DisplayError(TEXT("Failed to make the OpenGL context current."), GetLastError()); return FALSE; } ShowWindow(m_handle, SW_SHOWNORMAL); UpdateWindow(m_handle); if (!s_firstWindowInitialized) { s_firstWindowInitialized = TRUE; m_isFirstWindow = TRUE; } return TRUE; }
static int GLimp_InitGL( void ) { PIXELFORMATDESCRIPTOR pfd = { sizeof( PIXELFORMATDESCRIPTOR ), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 32, // 32-bit 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, // accum bits ignored 24, // 32-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; int pixelformat; if( r_stencilbits->integer == 8 || r_stencilbits->integer == 16 ) pfd.cStencilBits = r_stencilbits->integer; /* ** set PFD_STEREO if necessary */ if( glConfig.stereoEnabled ) { ri.Com_DPrintf( "...attempting to use stereo\n" ); pfd.dwFlags |= PFD_STEREO; } /* ** Get a DC for the specified window */ if( glw_state.hDC != NULL ) ri.Com_Printf( "GLimp_Init() - non-NULL DC exists\n" ); if( ( glw_state.hDC = GetDC( glw_state.hWnd ) ) == NULL ) { ri.Com_Printf( "GLimp_Init() - GetDC failed\n" ); return false; } if( ( pixelformat = ChoosePixelFormat( glw_state.hDC, &pfd ) ) == 0 ) { ri.Com_Printf( "GLimp_Init() - ChoosePixelFormat failed\n" ); return false; } if( SetPixelFormat( glw_state.hDC, pixelformat, &pfd ) == FALSE ) { ri.Com_Printf( "GLimp_Init() - SetPixelFormat failed\n" ); return false; } DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( pfd ), &pfd ); glConfig.stencilBits = pfd.cStencilBits; /* ** report if stereo is desired but unavailable */ if( !( pfd.dwFlags & PFD_STEREO ) && glConfig.stereoEnabled ) { ri.Com_Printf( "...failed to select stereo pixel format\n" ); glConfig.stereoEnabled = false; } /* ** startup the OpenGL subsystem by creating a context and making ** it current */ if( ( glw_state.hGLRC = qwglCreateContext( glw_state.hDC ) ) == 0 ) { ri.Com_Printf( "GLimp_Init() - qwglCreateContext failed\n" ); goto fail; } if( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) { ri.Com_Printf( "GLimp_Init() - qwglMakeCurrent failed\n" ); goto fail; } /* ** print out PFD specifics */ ri.Com_Printf( "GL PFD: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", ( int ) pfd.cColorBits, ( int ) pfd.cDepthBits, ( int )pfd.cStencilBits ); return true; fail: if( glw_state.hGLRC ) { qwglDeleteContext( glw_state.hGLRC ); glw_state.hGLRC = NULL; } if( glw_state.hDC ) { ReleaseDC( glw_state.hWnd, glw_state.hDC ); glw_state.hDC = NULL; } return false; }
const char* SingleOpenGLWindowImplT::Open(const std::string& Title_, unsigned int Width_, unsigned int Height_, char BPP_, bool FullScreen_) { #ifdef _WIN32 if (WindowIsOpen) return "OpenGLWindow is already open."; hInstance=GetModuleHandle(NULL); // 'GetModuleHandle(NULL)' entspricht 'hInstance' von 'WinMain()'. hWindow =NULL; hDC =NULL; hRC =NULL; Title =Title_; Width =Width_; Height =Height_; BPP =BPP_; FullScreen =FullScreen_; IsMinimized=false; for (unsigned int c=0; c<256; c++) KeyboardState[c]=false; // 1. Window-Klasse ausfüllen und registrieren // ******************************************* WNDCLASSEX MainWindowClass; MainWindowClass.cbSize =sizeof(WNDCLASSEX); // Größe dieser Struktur MainWindowClass.style =CS_VREDRAW | CS_HREDRAW | CS_OWNDC; // Fensterklassenstil MainWindowClass.lpfnWndProc =WinProc; // Zeiger auf Handler-Funktion MainWindowClass.cbClsExtra =0; // Zusätzlicher Platz für KlassenInfos MainWindowClass.cbWndExtra =0; // Zusätzlicher Platz für FensterInfos MainWindowClass.hInstance =hInstance; // Unsere Programm-ID MainWindowClass.hIcon =LoadIcon(NULL, IDI_APPLICATION); // Icon MainWindowClass.hIconSm =LoadIcon(NULL, IDI_APPLICATION); // Kleines Icon für Task-Bar MainWindowClass.hCursor =LoadCursor(NULL, IDC_ARROW); // Cursor MainWindowClass.hbrBackground=NULL; // Hintergrund-Brush MainWindowClass.lpszMenuName =NULL; // Menü MainWindowClass.lpszClassName="CafuMain"; // Name dieser Fensterklasse if (!RegisterClassEx(&MainWindowClass)) return "Unable to register the window class."; // 2. Display Settings ggf. anpassen // ********************************* if (FullScreen) { DEVMODE dmScreenSettings; memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); dmScreenSettings.dmSize =sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth =Width; dmScreenSettings.dmPelsHeight=Height; dmScreenSettings.dmBitsPerPel=BPP; dmScreenSettings.dmFields =DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; // CDS_FULLSCREEN gets rid of start bar. if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) { UnregisterClass("CafuMain", hInstance); return "Unable to change display settings."; } ShowCursor(false); } // 3. Window-Rectangle anpassen // **************************** unsigned int Style=FullScreen ? WS_POPUP : WS_OVERLAPPEDWINDOW; unsigned int ExStyle=WS_EX_APPWINDOW; RECT GLWindowRect; GLWindowRect.top =0; GLWindowRect.left =0; GLWindowRect.right =Width; GLWindowRect.bottom=Height; if (!AdjustWindowRectEx(&GLWindowRect, Style, false, ExStyle)) { Close(); return "Unable to adjust window rectangle."; } // 4. Window erzeugen // ****************** hWindow=CreateWindowEx(ExStyle, // Fensterstil (erweitert) "CafuMain", // Name der Fensterklasse Title.c_str(), // Fenstertitel Style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, // Fensterstil 0, // FullScreen ? 0 : CW_USEDEFAULT, // X-Position 0, // FullScreen ? 0 : CW_USEDEFAULT, // Y-Position GLWindowRect.right-GLWindowRect.left, // Breite GLWindowRect.bottom-GLWindowRect.top, // Höhe NULL, // Übergeordnetes Fenster NULL, // Menü hInstance, // Unsere Programm-ID NULL); // Zusätzliche Parameter if (!hWindow) { Close(); return "Unable to create window."; } // 5. Device Context erfragen // ************************** hDC=GetDC(hWindow); if (!hDC) { Close(); return "Unable to obtain a GL device context."; } // 6. PixelFormat abfragen und setzen // ********************************** PIXELFORMATDESCRIPTOR PFD; memset(&PFD, 0, 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 =BPP; PFD.cDepthBits =32; PFD.cStencilBits=8; PFD.iLayerType=PFD_MAIN_PLANE; int PixelFormat=ChoosePixelFormat(hDC, &PFD); if (!PixelFormat) { Close(); return "Unable to choose a pixel format."; } if (!DescribePixelFormat(hDC, PixelFormat, sizeof(PFD), &PFD)) { Close(); return "Unable to verify pixel format."; } static char ErrorMsg[1024]; const char* s1="Selected pixel format mismatches:\n"; const char* s2="\n\nThis is probably a problem with your video card (or its driver).\n" "Please make sure you have the latest drivers installed.\n" "If it still doesn't work, please let me know.\n" "(Email to [email protected], and please include the above message!)"; if ((PFD.dwFlags & PFD_DRAW_TO_WINDOW)!=PFD_DRAW_TO_WINDOW) { Close(); sprintf(ErrorMsg, "%sPFD_DRAW_TO_WINDOW is not supported. %s", s1, s2); return ErrorMsg; } if ((PFD.dwFlags & PFD_SUPPORT_OPENGL)!=PFD_SUPPORT_OPENGL) { Close(); sprintf(ErrorMsg, "%sOpenGL is not supported. %s", s1, s2); return ErrorMsg; } if ((PFD.dwFlags & PFD_DOUBLEBUFFER )!=PFD_DOUBLEBUFFER ) { Close(); sprintf(ErrorMsg, "%sDouble-buffering is not supported. %s", s1, s2); return ErrorMsg; } if (PFD.iPixelType!=PFD_TYPE_RGBA ) { Close(); sprintf(ErrorMsg, "%sPixel type RGBA is not supported. %s", s1, s2); return ErrorMsg; } // if (PFD.cColorBits<BPP ) { Close(); sprintf(ErrorMsg, "%sOnly %u color bits found (at least 15 are required). %s", s1, PFD.cColorBits , s2); return ErrorMsg; } if (PFD.cDepthBits<16 ) { Close(); sprintf(ErrorMsg, "%sOnly %u depth bits found (at least 16 are required). %s", s1, PFD.cDepthBits , s2); return ErrorMsg; } if (PFD.cStencilBits<8 ) { Close(); sprintf(ErrorMsg, "%sOnly %u stencil bits found (at least 8 are required).%s", s1, PFD.cStencilBits, s2); return ErrorMsg; } if (PFD.iLayerType!=PFD_MAIN_PLANE ) { Close(); sprintf(ErrorMsg, "%sLayer type PFD_MAIN_PLANE is not supported. %s", s1, s2); return ErrorMsg; } if(!SetPixelFormat(hDC, PixelFormat, &PFD)) { Close(); return "Unable to set the pixel format."; } // 7. Rendering Context erzeugen und aktivieren // ******************************************** hRC=wglCreateContext(hDC); if (!hRC) { Close(); return "Unable to create a GL rendering context."; } if(!wglMakeCurrent(hDC, hRC)) { Close(); return "Unable to activate the GL rendering context."; } // 8. Fenster anzeigen und einrichten // ********************************** ShowWindow(hWindow, SW_SHOW); // Show the window. SetForegroundWindow(hWindow); // Slightly higher priority. SetFocus(hWindow); // Sets keyboard focus to the window. // 8.1. DirectInput initialisieren // ******************************* HRESULT hResult=DirectInput.Initialize(hInstance, hWindow); if (hResult!=DI_OK) { static char ErrorMsg[80]; Close(); sprintf(ErrorMsg, "Unable to initialize DirectInput!\nhResult=%u", hResult); return ErrorMsg; } #else PostQuitMsgFlag=false; DisplayPtr =XOpenDisplay(NULL); if (!DisplayPtr) return "Cannot open display."; if (!glXQueryExtension(DisplayPtr, NULL, NULL)) return "No GLX extension."; #ifdef DEBUG int ExtVersionMajor=0; int ExtVersionMinor=0; if (glXQueryVersion(DisplayPtr, &ExtVersionMajor, &ExtVersionMinor)) printf("GLX version: %i.%i\n", ExtVersionMajor, ExtVersionMinor); else printf("GLX version could not be determined.\n"); #endif Title =Title_; Width =FullScreen_ ? DisplayWidth (DisplayPtr, DefaultScreen(DisplayPtr)) : Width_; Height =FullScreen_ ? DisplayHeight(DisplayPtr, DefaultScreen(DisplayPtr)) : Height_; BPP =BPP_; FullScreen =FullScreen_; IsMinimized=false; for (unsigned int c=0; c<256; c++) KeyboardState[c]=false; int VisualInfo_Features[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 16, GLX_STENCIL_SIZE, 8, GLX_DOUBLEBUFFER, None }; XVisualInfo* VisualInfo=glXChooseVisual(DisplayPtr, DefaultScreen(DisplayPtr), VisualInfo_Features); if (!VisualInfo) return "Cannot find visual. (You can possibly fix this by setting your desktop bit depth to 32 BPP. Just a guess.)"; RC=glXCreateContext(DisplayPtr, VisualInfo, None, True); if (!RC) return "Cannot create GLX context."; XSetWindowAttributes WinAttribs; WinAttribs.colormap =XCreateColormap(DisplayPtr, RootWindow(DisplayPtr, VisualInfo->screen), VisualInfo->visual, AllocNone); WinAttribs.border_pixel =0; WinAttribs.override_redirect=True; WinAttribs.event_mask =EventMask; Win=XCreateWindow(DisplayPtr, RootWindow(DisplayPtr, VisualInfo->screen), 0, 0, Width, Height, FullScreen ? 0 : 4, VisualInfo->depth, InputOutput, VisualInfo->visual, FullScreen ? CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect : CWColormap | CWEventMask, &WinAttribs); if (!Win) return "Cannot open window."; XSizeHints SizeHints; SizeHints.flags =PSize | PMaxSize | PMinSize; SizeHints.width =SizeHints.max_width =SizeHints.min_width =Width; SizeHints.height=SizeHints.max_height=SizeHints.min_height=Height; XSetStandardProperties(DisplayPtr, Win, Title.c_str(), NULL, None, NULL, 0, &SizeHints); glXMakeCurrent(DisplayPtr, Win, RC); XMapRaised(DisplayPtr, Win); XEvent Event; do { XMaskEvent(DisplayPtr, StructureNotifyMask, &Event); } while ((Event.type!=MapNotify) || (Event.xmap.event!=Win)); if (FullScreen) XSetInputFocus(DisplayPtr, Win, RevertToPointerRoot, CurrentTime); // Turn off auto-repeat. // XAutoRepeatOff(DisplayPtr); // Make the mouse cursor invisible. // This is necessary in order to have it not flickering it in mid-screen all the time. Pixmap CursorMask=XCreatePixmap(DisplayPtr, Win, 1, 1, 1); XGCValues xgc; xgc.function=GXclear; GC gc=XCreateGC(DisplayPtr, CursorMask, GCFunction, &xgc); XFillRectangle(DisplayPtr, CursorMask, gc, 0, 0, 1, 1); XColor DummyColor; DummyColor.pixel=0; DummyColor.red =0; DummyColor.flags=4; Cursor cursor=XCreatePixmapCursor(DisplayPtr, CursorMask, CursorMask, &DummyColor, &DummyColor, 0, 0); XFreePixmap(DisplayPtr, CursorMask); XFreeGC(DisplayPtr, gc); // XDefineCursor(DisplayPtr, Win, XCreateFontCursor(DisplayPtr, XC_tcross)); XDefineCursor(DisplayPtr, Win, cursor); #endif Resize(Width, Height); // Perspektivischen OpenGL Screen einrichten. // 9. OpenGL initialisieren // ************************ /* if (atof((char const*)glGetString(GL_VERSION))<1.2) { Close(); return "Need at least OpenGL version 1.2 to run. Please update your video board drivers."; } */ // glDepthFunc(GL_LEQUAL); // glPolygonOffset(1.0, 1.0); // glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glShadeModel(GL_SMOOTH); // Enables smooth shading. glClearColor(0.0, 0.0, 0.0, 0.0); // Black background. glClearDepth(1.0); // Depth Buffer setup. glEnable(GL_DEPTH_TEST); // Enables depth testing. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really nice perspective calculations. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SwapBuffers(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SwapBuffers(); // 10. Geschafft: Keine Initialisierungsfehler // ******************************************* WindowIsOpen=true; RenderingContextCounter++; return NULL; }
void GlContext::create(uint32_t /*_width*/, uint32_t /*_height*/) { m_opengl32dll = bx::dlopen("opengl32.dll"); BGFX_FATAL(NULL != m_opengl32dll, Fatal::UnableToInitialize, "Failed to load opengl32.dll."); wglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)bx::dlsym(m_opengl32dll, "wglGetProcAddress"); BGFX_FATAL(NULL != wglGetProcAddress, Fatal::UnableToInitialize, "Failed get wglGetProcAddress."); // If g_bgfxHwnd is NULL, the assumption is that GL context was created // by user (for example, using SDL, GLFW, etc.) BX_WARN(NULL != g_bgfxHwnd , "bgfx::winSetHwnd with valid window is not called. This might " "be intentional when GL context is created by the user." ); if (NULL != g_bgfxHwnd) { wglMakeCurrent = (PFNWGLMAKECURRENTPROC)bx::dlsym(m_opengl32dll, "wglMakeCurrent"); BGFX_FATAL(NULL != wglMakeCurrent, Fatal::UnableToInitialize, "Failed get wglMakeCurrent."); wglCreateContext = (PFNWGLCREATECONTEXTPROC)bx::dlsym(m_opengl32dll, "wglCreateContext"); BGFX_FATAL(NULL != wglCreateContext, Fatal::UnableToInitialize, "Failed get wglCreateContext."); wglDeleteContext = (PFNWGLDELETECONTEXTPROC)bx::dlsym(m_opengl32dll, "wglDeleteContext"); BGFX_FATAL(NULL != wglDeleteContext, Fatal::UnableToInitialize, "Failed get wglDeleteContext."); m_hdc = GetDC(g_bgfxHwnd); BGFX_FATAL(NULL != m_hdc, Fatal::UnableToInitialize, "GetDC failed!"); // Dummy window to peek into WGL functionality. // // An application can only set the pixel format of a window one time. // Once a window's pixel format is set, it cannot be changed. // MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd369049%28v=vs.85%29.aspx HWND hwnd = CreateWindowA("STATIC" , "" , WS_POPUP|WS_DISABLED , -32000 , -32000 , 0 , 0 , NULL , NULL , GetModuleHandle(NULL) , 0 ); HDC hdc = GetDC(hwnd); BGFX_FATAL(NULL != hdc, Fatal::UnableToInitialize, "GetDC failed!"); HGLRC context = createContext(hdc); wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB"); wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); if (NULL != wglGetExtensionsStringARB) { const char* extensions = (const char*)wglGetExtensionsStringARB(hdc); BX_TRACE("WGL extensions:"); dumpExtensions(extensions); } if (NULL != wglChoosePixelFormatARB && NULL != wglCreateContextAttribsARB) { int32_t attrs[] = { WGL_SAMPLE_BUFFERS_ARB, 0, WGL_SAMPLES_ARB, 0, WGL_SUPPORT_OPENGL_ARB, true, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_DRAW_TO_WINDOW_ARB, true, WGL_DOUBLE_BUFFER_ARB, true, WGL_COLOR_BITS_ARB, 32, WGL_DEPTH_BITS_ARB, 24, WGL_STENCIL_BITS_ARB, 8, 0 }; int result; int pixelFormat; uint32_t numFormats = 0; do { result = wglChoosePixelFormatARB(m_hdc, attrs, NULL, 1, &pixelFormat, &numFormats); if (0 == result || 0 == numFormats) { attrs[3] >>= 1; attrs[1] = attrs[3] == 0 ? 0 : 1; } } while (0 == numFormats); PIXELFORMATDESCRIPTOR pfd; DescribePixelFormat(m_hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); BX_TRACE("Pixel format:\n" "\tiPixelType %d\n" "\tcColorBits %d\n" "\tcAlphaBits %d\n" "\tcDepthBits %d\n" "\tcStencilBits %d\n" , pfd.iPixelType , pfd.cColorBits , pfd.cAlphaBits , pfd.cDepthBits , pfd.cStencilBits ); result = SetPixelFormat(m_hdc, pixelFormat, &pfd); // When window is created by SDL and SDL_WINDOW_OPENGL is set SetPixelFormat // will fail. Just warn and continue. In case it failed for some other reason // create context will fail and it will error out there. BX_WARN(result, "SetPixelFormat failed (last err: 0x%08x)!", GetLastError() ); uint32_t flags = BGFX_CONFIG_DEBUG ? WGL_CONTEXT_DEBUG_BIT_ARB : 0; BX_UNUSED(flags); int32_t contextAttrs[9] = { #if BGFX_CONFIG_RENDERER_OPENGL >= 31 WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 1, WGL_CONTEXT_FLAGS_ARB, flags, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, #else WGL_CONTEXT_MAJOR_VERSION_ARB, 2, WGL_CONTEXT_MINOR_VERSION_ARB, 1, 0, 0, 0, 0, #endif // BGFX_CONFIG_RENDERER_OPENGL >= 31 0 }; m_context = wglCreateContextAttribsARB(m_hdc, 0, contextAttrs); if (NULL == m_context) { // nVidia doesn't like context profile mask for contexts below 3.2? contextAttrs[6] = WGL_CONTEXT_PROFILE_MASK_ARB == contextAttrs[6] ? 0 : contextAttrs[6]; m_context = wglCreateContextAttribsARB(m_hdc, 0, contextAttrs); } BGFX_FATAL(NULL != m_context, Fatal::UnableToInitialize, "Failed to create context 0x%08x.", GetLastError() ); }
void VisualInfo(HDC hDC, int verbose) { int i, maxpf; PIXELFORMATDESCRIPTOR pfd; /* calling DescribePixelFormat() with NULL args return maximum number of pixel formats */ maxpf = DescribePixelFormat(hDC, 0, 0, NULL); if (!verbose) { printf(" visual x bf lv rg d st r g b a ax dp st accum buffs ms \n"); printf(" id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n"); printf("-----------------------------------------------------------------\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue; /* other criteria could be tested here for actual pixel format choosing in an application: for (...each pixel format...) { if (pfd.dwFlags & PFD_SUPPORT_OPENGL && pfd.dwFlags & PFD_DOUBLEBUFFER && pfd.cDepthBits >= 24 && pfd.cColorBits >= 24) { goto found; } } ... not found so exit ... found: ... found so use it ... */ /* print out the information for this pixel format */ printf("0x%02x ", i); printf("%2d ", pfd.cColorBits); if(pfd.dwFlags & PFD_DRAW_TO_WINDOW) printf("wn "); else if(pfd.dwFlags & PFD_DRAW_TO_BITMAP) printf("bm "); else printf(". "); /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ printf(" . "); printf("%2d ", pfd.cColorBits); /* bReserved field indicates number of over/underlays */ if(pfd.bReserved) printf(" %d ", pfd.bReserved); else printf(" . "); printf(" %c ", pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); printf("%c ", pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); printf(" %c ", pfd.dwFlags & PFD_STEREO ? 'y' : '.'); if(pfd.cRedBits && pfd.iPixelType == PFD_TYPE_RGBA) printf("%2d ", pfd.cRedBits); else printf(" . "); if(pfd.cGreenBits && pfd.iPixelType == PFD_TYPE_RGBA) printf("%2d ", pfd.cGreenBits); else printf(" . "); if(pfd.cBlueBits && pfd.iPixelType == PFD_TYPE_RGBA) printf("%2d ", pfd.cBlueBits); else printf(" . "); if(pfd.cAlphaBits && pfd.iPixelType == PFD_TYPE_RGBA) printf("%2d ", pfd.cAlphaBits); else printf(" . "); if(pfd.cAuxBuffers) printf("%2d ", pfd.cAuxBuffers); else printf(" . "); if(pfd.cDepthBits) printf("%2d ", pfd.cDepthBits); else printf(" . "); if(pfd.cStencilBits) printf("%2d ", pfd.cStencilBits); else printf(" . "); if(pfd.cAccumRedBits) printf("%2d ", pfd.cAccumRedBits); else printf(" . "); if(pfd.cAccumGreenBits) printf("%2d ", pfd.cAccumGreenBits); else printf(" . "); if(pfd.cAccumBlueBits) printf("%2d ", pfd.cAccumBlueBits); else printf(" . "); if(pfd.cAccumAlphaBits) printf("%2d ", pfd.cAccumAlphaBits); else printf(" . "); /* no multisample in Win32 */ printf(" . .\n"); } /* print table footer */ printf("-----------------------------------------------------------------\n"); printf(" visual x bf lv rg d st r g b a ax dp st accum buffs ms \n"); printf(" id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n"); printf("-----------------------------------------------------------------\n"); } else { /* verbose output. */ /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(hDC, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue; printf("Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); printf(" bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); printf(" rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); printf(" auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); printf(" accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); printf(" multiSample=%d multisampleBuffers=%d\n", 0, 0); printf(" Opaque.\n"); } } }
HWND CreateOpenGLWindow(char* title, int x, int y, int width, int height, BYTE type, DWORD flags) { int pf; HDC hDC; HWND hWnd; WNDCLASS wc; PIXELFORMATDESCRIPTOR pfd; static HINSTANCE hInstance = 0; /* only register the window class once - use hInstance as a flag. */ if (!hInstance) { hInstance = GetModuleHandle(NULL); wc.style = CS_OWNDC; wc.lpfnWndProc = (WNDPROC)WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL"; if (!RegisterClass(&wc)) { MessageBox(NULL, "RegisterClass() failed: " "Cannot register window class.", "Error", MB_OK); return NULL; } } hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, x, y, width, height, NULL, NULL, hInstance, NULL); if (hWnd == NULL) { MessageBox(NULL, "CreateWindow() failed: Cannot create a window.", "Error", MB_OK); return NULL; } hDC = GetDC(hWnd); /* there is no guarantee that the contents of the stack that become the pfd are zeroed, therefore _make sure_ to clear these bits. */ memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags; pfd.iPixelType = type; pfd.cColorBits = 32; pf = ChoosePixelFormat(hDC, &pfd); if (pf == 0) { MessageBox(NULL, "ChoosePixelFormat() failed: " "Cannot find a suitable pixel format.", "Error", MB_OK); return 0; } if (SetPixelFormat(hDC, pf, &pfd) == FALSE) { MessageBox(NULL, "SetPixelFormat() failed: " "Cannot set format specified.", "Error", MB_OK); return 0; } DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); ReleaseDC(hDC, hWnd); return hWnd; }
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct) { //Trace("CChildView::OnCreate - Initializing OpenGL"); if (CWnd::OnCreate(lpCreateStruct) == -1){ //Trace("CChildView::OnCreate - Failed"); return -1; } // Initialize OpenGL parameters PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Structure size 1, // Version number PFD_DRAW_TO_WINDOW | // Property flags PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // (remove if no double buf) PFD_TYPE_RGBA, // PixelType 24, // 24-bit color 0, 0, 0, 0, 0, 0, // Color bits and shift 0, 0, 0, 0, 0, 0, 0, // Alpha and accum buffer bits 32, // 32-bit depth buffer 0, 0, // No stencil or aux buffer PFD_MAIN_PLANE, // Layer type 0, // Reserved 0, 0, 0 // Unsupported }; // Tell GDI to convert device context from Win32 to OpenGL. CClientDC dcClient(this); int iPixelFormat = ChoosePixelFormat(dcClient.m_hDC,&pfd); if ( !iPixelFormat ) { // This system cannot run OpenGL //Trace("CChildView::OnCreate - Error retrieving pixel format index..."); ASSERT(FALSE); AfxMessageBox("Cannot initialize OpenGL...quitting.", MB_OK | MB_ICONERROR); return -1; // will fail new document creation... } // if //Trace("CChildView::OnCreate - OpenGL - Chosen Pixel Format"); if ( !SetPixelFormat(dcClient.m_hDC,iPixelFormat,&pfd) ) { // This system cannot run OpenGL //Trace("CChildView::OnCreate - Error setting new pixel format..."); ASSERT(FALSE); AfxMessageBox("Cannot initialize OpenGL...quitting.", MB_OK | MB_ICONERROR); return -1; // will fail new document creation... } // if //Trace("CChildView::OnCreate - OpenGL - Pixel Format is set"); // Update the PIXELFORMATDESCRIPTOR structure once // the device context has been modified. DescribePixelFormat(dcClient.m_hDC,iPixelFormat, sizeof(pfd),&pfd); // The PIXELFORMATDESCRIPTOR has been updated, so we now // determine whether to create and manage a custom // palette. if ( pfd.dwFlags & PFD_NEED_PALETTE ) { // We do, so build a new palette... //Trace("CChildView::OnCreate - Setting up palette..."); GLSetupPalette(); //Trace("CChildView::OnCreate - Palette is set..."); } // if // Create the OpenGL rendering context m_hRC = wglCreateContext(dcClient.m_hDC); if ( m_hRC == NULL ) { // This system cannot run OpenGL //Trace("CChildView::OnCreate - Error creating OpenGL rendering context...\n"); ASSERT(FALSE); AfxMessageBox("Cannot initialize OpenGL...quitting.", MB_OK | MB_ICONERROR); return -1; // will fail new document creation... } // if //Trace("CChildView::OnCreate - OpenGL - created rendering context"); // We now make it the current rendering context so // we might set our clear color glClearDepth(1.0); glEnable(GL_DEPTH_TEST); wglMakeCurrent(dcClient.m_hDC,m_hRC); GLLoadFont(); glClearColor(0.0,0.0,0.0,0.0); // black wglMakeCurrent(dcClient.m_hDC,NULL); //Trace("CChildView::OnCreate - Done"); return 0; }
void VisualInfoGDI (GLContext* ctx) { int i, maxpf; PIXELFORMATDESCRIPTOR pfd; /* calling DescribePixelFormat() with NULL pfd (!!!) return maximum number of pixel formats */ maxpf = DescribePixelFormat(ctx->dc, 1, 0, NULL); if (!verbose) { fprintf(file, "-----------------------------------------------------------------------------\n"); fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); fprintf(file, " id dep tp sp sz l ci b ro ne ac sz sz sz sz bf th cl sz r g b a ns b\n"); fprintf(file, "-----------------------------------------------------------------------------\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || (drawableonly && (pfd.dwFlags & PFD_DRAW_TO_BITMAP))) continue; /* other criteria could be tested here for actual pixel format choosing in an application: for (...each pixel format...) { if (pfd.dwFlags & PFD_SUPPORT_OPENGL && pfd.dwFlags & PFD_DOUBLEBUFFER && pfd.cDepthBits >= 24 && pfd.cColorBits >= 24) { goto found; } } ... not found so exit ... found: ... found so use it ... */ /* print out the information for this pixel format */ fprintf(file, "0x%02x ", i); fprintf(file, "%3d ", pfd.cColorBits); if(pfd.dwFlags & PFD_DRAW_TO_WINDOW) fprintf(file, "wn "); else if(pfd.dwFlags & PFD_DRAW_TO_BITMAP) fprintf(file, "bm "); else fprintf(file, "pb "); /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ fprintf(file, " . "); fprintf(file, "%3d ", pfd.cColorBits); /* bReserved field indicates number of over/underlays */ if(pfd.bReserved) fprintf(file, " %d ", pfd.bReserved); else fprintf(file, " . "); fprintf(file, " %c ", pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); fprintf(file, "%c ", pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); fprintf(file, " %c ", pfd.dwFlags & PFD_STEREO ? 'y' : '.'); /* added: */ fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_FORMAT ? 'y' : '.'); fprintf(file, " %c ", pfd.dwFlags & PFD_GENERIC_ACCELERATED ? 'y' : '.'); if(pfd.cRedBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cRedBits); else fprintf(file, " . "); if(pfd.cGreenBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cGreenBits); else fprintf(file, " . "); if(pfd.cBlueBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cBlueBits); else fprintf(file, " . "); if(pfd.cAlphaBits && pfd.iPixelType == PFD_TYPE_RGBA) fprintf(file, "%2d ", pfd.cAlphaBits); else fprintf(file, " . "); if(pfd.cAuxBuffers) fprintf(file, "%2d ", pfd.cAuxBuffers); else fprintf(file, " . "); if(pfd.cDepthBits) fprintf(file, "%2d ", pfd.cDepthBits); else fprintf(file, " . "); if(pfd.cStencilBits) fprintf(file, "%2d ", pfd.cStencilBits); else fprintf(file, " . "); if(pfd.cAccumBits) fprintf(file, "%3d ", pfd.cAccumBits); else fprintf(file, " . "); if(pfd.cAccumRedBits) fprintf(file, "%2d ", pfd.cAccumRedBits); else fprintf(file, " . "); if(pfd.cAccumGreenBits) fprintf(file, "%2d ", pfd.cAccumGreenBits); else fprintf(file, " . "); if(pfd.cAccumBlueBits) fprintf(file, "%2d ", pfd.cAccumBlueBits); else fprintf(file, " . "); if(pfd.cAccumAlphaBits) fprintf(file, "%2d ", pfd.cAccumAlphaBits); else fprintf(file, " . "); /* no multisample in win32 */ fprintf(file, " . .\n"); } /* print table footer */ fprintf(file, "-----------------------------------------------------------------------------\n"); fprintf(file, " visual x bf lv rg d st ge ge r g b a ax dp st accum buffs ms \n"); fprintf(file, " id dep tp sp sz l ci b ro ne ac sz sz sz sz bf th cl sz r g b a ns b\n"); fprintf(file, "-----------------------------------------------------------------------------\n"); } else /* verbose */ { fprintf(file, "\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%ld stereo=%ld\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); fprintf(file, " Opaque.\n"); } } }
/* * attrib_list is currently unused. This must be set to NULL or empty * (first attribute of None). See GLX 1.3 spec. */ GdkGLWindow * _gdk_win32_gl_window_impl_new (GdkGLWindow *glwindow, GdkGLConfig *glconfig, GdkWindow *window, const int *attrib_list) { GdkGLWindowImplWin32 *win32_impl; HWND hwnd; DWORD wndclass_style; gboolean need_release_dc; HDC hdc = NULL; PIXELFORMATDESCRIPTOR pfd; int pixel_format; GDK_GL_NOTE_FUNC (); g_return_val_if_fail (GDK_IS_WIN32_GL_WINDOW (glwindow), NULL); g_return_val_if_fail (GDK_IS_WIN32_GL_CONFIG (glconfig), NULL); g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); hwnd = (HWND) gdk_win32_window_get_handle (window); /* Private DC? */ wndclass_style = GetClassLong (hwnd, GCL_STYLE); if (wndclass_style & CS_OWNDC) { GDK_GL_NOTE (MISC, g_message (" -- Private DC")); need_release_dc = FALSE; } else { GDK_GL_NOTE (MISC, g_message (" -- Common DC")); need_release_dc = TRUE; } /* Get DC. */ hdc = GetDC (hwnd); if (hdc == NULL) { g_warning ("cannot get DC"); goto FAIL; } /* * Choose pixel format. */ pfd = *(GDK_GL_CONFIG_PFD (glconfig)); /* Draw to window */ pfd.dwFlags &= ~PFD_DRAW_TO_BITMAP; pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* Request pfd.cColorBits should exclude alpha bitplanes. */ pfd.cColorBits = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits; GDK_GL_NOTE_FUNC_IMPL ("ChoosePixelFormat"); pixel_format = ChoosePixelFormat (hdc, &pfd); if (pixel_format == 0) { g_warning ("cannot choose pixel format"); goto FAIL; } /* * Set pixel format. */ GDK_GL_NOTE_FUNC_IMPL ("SetPixelFormat"); if (!SetPixelFormat (hdc, pixel_format, &pfd)) { g_warning ("cannot set pixel format"); goto FAIL; } DescribePixelFormat (hdc, pixel_format, sizeof (pfd), &pfd); GDK_GL_NOTE (MISC, g_message (" -- impl->pixel_format = 0x%x", pixel_format)); GDK_GL_NOTE (MISC, _gdk_win32_gl_print_pfd (&pfd)); if (need_release_dc) { /* Release DC. */ ReleaseDC (hwnd, hdc); hdc = NULL; } /* * Instantiate the GdkGLWindowImplWin32 object. */ win32_impl = g_object_new (GDK_TYPE_GL_WINDOW_IMPL_WIN32, NULL); win32_impl->hwnd = hwnd; win32_impl->pfd = pfd; win32_impl->pixel_format = pixel_format; win32_impl->glconfig = glconfig; g_object_ref (G_OBJECT (win32_impl->glconfig)); win32_impl->hdc = hdc; win32_impl->need_release_dc = need_release_dc; win32_impl->is_destroyed = FALSE; glwindow->impl = GDK_GL_WINDOW_IMPL(win32_impl); glwindow->window = window; g_object_add_weak_pointer (G_OBJECT (glwindow->window), (gpointer *) &(glwindow->window)); return glwindow; FAIL: /* Release DC. */ if (need_release_dc && hdc != NULL) ReleaseDC (hwnd, hdc); return NULL; }
void OSGL_createOpenGLWindow(uintf width, uintf height) { // Create a temporary window so we can query some values from the video driver int nPF; HDC tmphDC; // Temporary device context HGLRC tmphRC; // Temporary Renderring Context WNDCLASS tmpWc; // Temporary Windows class structure HWND tmphWnd; // Temporary Window Handle uintf iMode; // Register Window style tmpWc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; tmpWc.lpfnWndProc = (WNDPROC) wgl_tmpWndProc; tmpWc.cbClsExtra = 0; tmpWc.cbWndExtra = 0; tmpWc.hInstance = winVars.hinst; tmpWc.hIcon = NULL; tmpWc.hCursor = LoadCursor(NULL, IDC_ARROW); tmpWc.hbrBackground = NULL; // No need for background brush for OpenGL window tmpWc.lpszMenuName = NULL; tmpWc.lpszClassName = "Windows GL Temp Window"; if(RegisterClass(&tmpWc) == 0) wglError(wgltxt_regClass1); tmphWnd = CreateWindowEx(WS_EX_TOPMOST, tmpWc.lpszClassName, tmpWc.lpszClassName, WS_POPUP, 0, 0, 400, 400, NULL, NULL, winVars.hinst, NULL); if(tmphWnd == NULL) wglError(wgltxt_noWindow1); ShowWindow(tmphWnd,SW_SHOW); UpdateWindow(tmphWnd); PIXELFORMATDESCRIPTOR pfd = // Not going to be too picky { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, // Full color 32, // Color depth 0,0,0,0,0,0,0, // Ignored 0,0,0,0, // Accumulation buffer 24, // Depth bits 8, // Stencil bits 0,0,0,0,0,0 }; // Some used, some not // Create a "temporary" OpenGL rendering context tmphDC = GetDC(tmphWnd); // Set pixel format one time.... nPF = ChoosePixelFormat(tmphDC, &pfd); SetPixelFormat(tmphDC, nPF, &pfd); DescribePixelFormat(tmphDC, nPF, sizeof(PIXELFORMATDESCRIPTOR), &pfd); // Create the GL context tmphRC = wglCreateContext(tmphDC); wglMakeCurrent(tmphDC, tmphRC); // Find a multisampled and non-multisampled pixel format wgl_FindBestPF(tmphDC, &wgl_PixelFormatSTD, &wgl_PixelFormatFSAA); iMode = 0; int bestMode = 0; int bestScore = 0x7FFFFFFF; while (EnumDisplaySettings(NULL, iMode, &wgl_devMode)) { int score = 1; if (wgl_devMode.dmBitsPerPel!=32) score *= 256; int xDif = abs((int)(wgl_devMode.dmPelsWidth - width))+1; int yDif = abs((int)(wgl_devMode.dmPelsHeight - height))+1; score *= xDif * yDif; if (score<bestScore) { bestScore = score; bestMode = iMode; } iMode++; } EnumDisplaySettings(NULL, bestMode, &wgl_devMode); wgl_PrefFSWidth = wgl_devMode.dmPelsWidth; // Preferred fullscreen width, height wgl_PrefFSHeight = wgl_devMode.dmPelsHeight; // ###!!!### The system is picking it's own window width and height! This HACK code fixed that wgl_PrefFSWidth = wgl_devMode.dmPelsWidth = width; // Preferred fullscreen width, height wgl_PrefFSHeight = wgl_devMode.dmPelsHeight = height; // Done with GL context wglMakeCurrent(tmphDC, NULL); wglDeleteContext(tmphRC); DestroyWindow(tmphWnd); // ***************** Now create the real OGL window wgl_createMyWindow(OSGL_isFullScreen, &winVars.mainWin); // If window was not created, quit if(winVars.mainWin == NULL) wglError(wgltxt_noWindow2); MSG msg; // Windows message structure while (applicationState!=AppState_running) { GetMessage(&msg, NULL, 0, 0); TranslateMessage(&msg); DispatchMessage(&msg); } OSGL_onWinCreate(winVars.mainWin); }
wglContext::wglContext(HWND WindowHandle) { hDC = GetDC(WindowHandle); int BestFormat = 0; // Antialiasing level > 0 /*if (0 > 0) { // Get the wglChoosePixelFormatARB function (it is an extension) PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(wglGetProcAddress("wglChoosePixelFormatARB")); int IntAttributes[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_SAMPLE_BUFFERS_ARB, (Params.AntialiasingLevel ? GL_TRUE : GL_FALSE), WGL_SAMPLES_ARB, Params.AntialiasingLevel, 0, 0 }; int Formats[128]; UINT NbFormats; float FloatAttributes[] = {0, 0}; bool IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0; if (!IsValid || (NbFormats == 0)) { // Antialiasing level > 2 if (0 > 2) { // No format matching our needs : reduce the multisampling level std::cerr << "Failed to find a pixel format supporting " << Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl; Params.AntialiasingLevel = IntAttributes[1] = 2; IsValid = wglChoosePixelFormatARB(myDeviceContext, IntAttributes, FloatAttributes, sizeof(Formats) / sizeof(*Formats), Formats, &NbFormats) != 0; } if (!IsValid || (NbFormats == 0)) { // Cannot find any pixel format supporting multisampling ; disabling antialiasing std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl; Params.AntialiasingLevel = 0; } } // Get the best format among the returned ones if (IsValid && (NbFormats > 0)) { int BestScore = 0xFFFF; for (UINT i = 0; i < NbFormats; ++i) { // Get the current format's attributes PIXELFORMATDESCRIPTOR Attribs; Attribs.nSize = sizeof(PIXELFORMATDESCRIPTOR); Attribs.nVersion = 1; DescribePixelFormat(myDeviceContext, Formats[i], sizeof(PIXELFORMATDESCRIPTOR), &Attribs); // Evaluate the current configuration int Color = Attribs.cRedBits + Attribs.cGreenBits + Attribs.cBlueBits + Attribs.cAlphaBits; int Score = EvaluateConfig(Mode, Params, Color, Attribs.cDepthBits, Attribs.cStencilBits, Params.AntialiasingLevel); // Keep it if it's better than the current best if (Score < BestScore) { BestScore = Score; BestFormat = Formats[i]; } } } }*/ // Find a pixel format with no antialiasing, if not needed or not supported if (BestFormat == 0) { /*typedef int (APIENTRY* PFNChoosePixelFormat)(HDC, const PIXELFORMATDESCRIPTOR*); PFNChoosePixelFormat wglChoosePixelFormat = reinterpret_cast<PFNChoosePixelFormat>(wglGetProcAddress("wglChoosePixelFormatARB"));*/ // Setup a pixel format descriptor from the rendering settings PIXELFORMATDESCRIPTOR PixelDescriptor = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | 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, 24, //Number of bits for the depthbuffer 8, //Number of bits for the stencilbuffer 0, //Number of Aux buffers in the framebuffer. PFD_MAIN_PLANE, 0, 0, 0, 0 }; /*PIXELFORMATDESCRIPTOR PixelDescriptor; //ZeroMemory(&PixelDescriptor, sizeof(PIXELFORMATDESCRIPTOR)); PixelDescriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR); PixelDescriptor.nVersion = 1; PixelDescriptor.iLayerType = PFD_MAIN_PLANE; PixelDescriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; PixelDescriptor.iPixelType = PFD_TYPE_RGBA; PixelDescriptor.cColorBits = static_cast<BYTE>(32); PixelDescriptor.cDepthBits = static_cast<BYTE>(32); PixelDescriptor.cStencilBits = static_cast<BYTE>(0);*/ // Get the pixel format that best matches our requirements BestFormat = ChoosePixelFormat(hDC, &PixelDescriptor); if (BestFormat == 0) { //std::cerr << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl; return; } } // Extract the depth and stencil bits from the chosen format PIXELFORMATDESCRIPTOR ActualFormat = {}; ActualFormat.nSize = sizeof(PIXELFORMATDESCRIPTOR); ActualFormat.nVersion = 1; DescribePixelFormat(hDC, BestFormat, sizeof(PIXELFORMATDESCRIPTOR), &ActualFormat); //Params.DepthBits = ActualFormat.cDepthBits; //Params.StencilBits = ActualFormat.cStencilBits; // Set the chosen pixel format if (!SetPixelFormat(hDC, BestFormat, &ActualFormat)) { //std::cerr << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl; return; } // Create the OpenGL context from the device context hRC = wglCreateContext(hDC); if (hRC == NULL) { //std::cerr << "Failed to create an OpenGL context for this window" << std::endl; return; } // Share display lists with other contexts HGLRC CurrentContext = wglGetCurrentContext(); if (CurrentContext) wglShareLists(CurrentContext, hRC); makeCurrent(); // Enable multisampling /*if (Params.AntialiasingLevel > 0) glEnable(GL_MULTISAMPLE_ARB);*/ }
int WIN_GL_SetupWindow(_THIS) { int retval; #if SDL_VIDEO_OPENGL int i; int iAttribs[64]; int *iAttr; float fAttribs[1] = { 0 }; const GLubyte *(WINAPI *glGetStringFunc)(GLenum); const char *wglext; /* load the gl driver from a default path */ if ( ! this->gl_config.driver_loaded ) { /* no driver has been loaded, use default (ourselves) */ if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) { return(-1); } } /* Set up the pixel format descriptor with our needed format */ SDL_memset(&GL_pfd, 0, sizeof(GL_pfd)); GL_pfd.nSize = sizeof(GL_pfd); GL_pfd.nVersion = 1; GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); if ( this->gl_config.double_buffer ) { GL_pfd.dwFlags |= PFD_DOUBLEBUFFER; } if ( this->gl_config.stereo ) { GL_pfd.dwFlags |= PFD_STEREO; } GL_pfd.iPixelType = PFD_TYPE_RGBA; GL_pfd.cColorBits = this->gl_config.buffer_size; GL_pfd.cRedBits = this->gl_config.red_size; GL_pfd.cGreenBits = this->gl_config.green_size; GL_pfd.cBlueBits = this->gl_config.blue_size; GL_pfd.cAlphaBits = this->gl_config.alpha_size; GL_pfd.cAccumRedBits = this->gl_config.accum_red_size; GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size; GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size; GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size; GL_pfd.cAccumBits = (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits + GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits); GL_pfd.cDepthBits = this->gl_config.depth_size; GL_pfd.cStencilBits = this->gl_config.stencil_size; /* setup WGL_ARB_pixel_format attribs */ iAttr = &iAttribs[0]; *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; *iAttr++ = GL_TRUE; *iAttr++ = WGL_ACCELERATION_ARB; *iAttr++ = WGL_FULL_ACCELERATION_ARB; *iAttr++ = WGL_RED_BITS_ARB; *iAttr++ = this->gl_config.red_size; *iAttr++ = WGL_GREEN_BITS_ARB; *iAttr++ = this->gl_config.green_size; *iAttr++ = WGL_BLUE_BITS_ARB; *iAttr++ = this->gl_config.blue_size; if ( this->gl_config.alpha_size ) { *iAttr++ = WGL_ALPHA_BITS_ARB; *iAttr++ = this->gl_config.alpha_size; } *iAttr++ = WGL_DOUBLE_BUFFER_ARB; *iAttr++ = this->gl_config.double_buffer; *iAttr++ = WGL_DEPTH_BITS_ARB; *iAttr++ = this->gl_config.depth_size; if ( this->gl_config.stencil_size ) { *iAttr++ = WGL_STENCIL_BITS_ARB; *iAttr++ = this->gl_config.stencil_size; } if ( this->gl_config.accum_red_size ) { *iAttr++ = WGL_ACCUM_RED_BITS_ARB; *iAttr++ = this->gl_config.accum_red_size; } if ( this->gl_config.accum_green_size ) { *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; *iAttr++ = this->gl_config.accum_green_size; } if ( this->gl_config.accum_blue_size ) { *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; *iAttr++ = this->gl_config.accum_blue_size; } if ( this->gl_config.accum_alpha_size ) { *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; *iAttr++ = this->gl_config.accum_alpha_size; } if ( this->gl_config.stereo ) { *iAttr++ = WGL_STEREO_ARB; *iAttr++ = GL_TRUE; } if ( this->gl_config.multisamplebuffers ) { *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; *iAttr++ = this->gl_config.multisamplebuffers; } if ( this->gl_config.multisamplesamples ) { *iAttr++ = WGL_SAMPLES_ARB; *iAttr++ = this->gl_config.multisamplesamples; } if ( this->gl_config.accelerated >= 0 ) { *iAttr++ = WGL_ACCELERATION_ARB; *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB); } *iAttr = 0; for ( i=0; ; ++i ) { /* Get the window device context for our OpenGL drawing */ GL_hdc = GetDC(SDL_Window); if ( GL_hdc == NULL ) { SDL_SetError("Unable to get DC for SDL_Window"); return(-1); } /* Choose and set the closest available pixel format */ pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs); if ( !pixel_format ) { pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); } if ( !pixel_format ) { SDL_SetError("No matching GL pixel format available"); return(-1); } if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) { if ( i == 0 ) { /* First time through, try resetting the window */ if ( WIN_GL_ResetWindow(this) < 0 ) { return(-1); } continue; } SDL_SetError("Unable to set HDC pixel format"); return(-1); } /* We either succeeded or failed by this point */ break; } DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd); GL_hrc = this->gl_data->wglCreateContext(GL_hdc); if ( GL_hrc == NULL ) { SDL_SetError("Unable to create GL context"); return(-1); } if ( WIN_GL_MakeCurrent(this) < 0 ) { return(-1); } gl_active = 1; /* Get the wglGetPixelFormatAttribivARB pointer for the context */ if ( this->gl_data->WGL_ARB_pixel_format ) { this->gl_data->wglGetPixelFormatAttribivARB = (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB"); } else { this->gl_data->wglGetPixelFormatAttribivARB = NULL; } /* Vsync control under Windows. Checking glGetString here is * somewhat a documented and reliable hack - it was originally * as a feature added by mistake, but since so many people rely * on it, it will not be removed. strstr should be safe here.*/ glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString"); if ( glGetStringFunc ) { wglext = (const char *)glGetStringFunc(GL_EXTENSIONS); } else { /* Uh oh, something is seriously wrong here... */ wglext = NULL; } if ( wglext && SDL_strstr(wglext, "WGL_EXT_swap_control") ) { this->gl_data->wglSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT"); this->gl_data->wglGetSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT"); } else { this->gl_data->wglSwapIntervalEXT = NULL; this->gl_data->wglGetSwapIntervalEXT = NULL; } if ( this->gl_config.swap_control >= 0 ) { if ( this->gl_data->wglSwapIntervalEXT ) { this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control); } } #else SDL_SetError("WIN driver not configured with OpenGL"); #endif if ( gl_active ) { retval = 0; } else { retval = -1; } return(retval); }
static int wGLCreateContext(Ihandle* ih, IGlControlData* gldata) { Ihandle* ih_shared; HGLRC shared_context = NULL; int number; int isIndex = 0; int pixelFormat; PIXELFORMATDESCRIPTOR test_pfd; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */ 1, /* version number */ PFD_DRAW_TO_WINDOW | /* support window */ PFD_SUPPORT_OPENGL, /* support OpenGL */ PFD_TYPE_RGBA, /* RGBA type */ 24, /* 24-bit 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, /* accum bits ignored */ 16, /* 32-bit z-buffer */ 0, /* no stencil buffer */ 0, /* no auxiliary buffer */ PFD_MAIN_PLANE, /* main layer */ 0, /* reserved */ 0, 0, 0 /* layer masks ignored */ }; /* the IupCanvas is already mapped, just initialize the OpenGL context */ /* double or single buffer */ if (iupStrEqualNoCase(iupAttribGetStr(ih,"BUFFER"), "DOUBLE")) pfd.dwFlags |= PFD_DOUBLEBUFFER; /* stereo */ if (iupAttribGetBoolean(ih,"STEREO")) pfd.dwFlags |= PFD_STEREO; /* rgba or index */ if (iupStrEqualNoCase(iupAttribGetStr(ih,"COLOR"), "INDEX")) { isIndex = 1; pfd.iPixelType = PFD_TYPE_COLORINDEX; pfd.cColorBits = 8; /* assume 8 bits when indexed */ number = iupAttribGetInt(ih,"BUFFER_SIZE"); if (number > 0) pfd.cColorBits = (BYTE)number; } /* red, green, blue bits */ number = iupAttribGetInt(ih,"RED_SIZE"); if (number > 0) pfd.cRedBits = (BYTE)number; pfd.cRedShift = 0; number = iupAttribGetInt(ih,"GREEN_SIZE"); if (number > 0) pfd.cGreenBits = (BYTE)number; pfd.cGreenShift = pfd.cRedBits; number = iupAttribGetInt(ih,"BLUE_SIZE"); if (number > 0) pfd.cBlueBits = (BYTE)number; pfd.cBlueShift = pfd.cRedBits + pfd.cGreenBits; number = iupAttribGetInt(ih,"ALPHA_SIZE"); if (number > 0) pfd.cAlphaBits = (BYTE)number; pfd.cAlphaShift = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits; /* depth and stencil size */ number = iupAttribGetInt(ih,"DEPTH_SIZE"); if (number > 0) pfd.cDepthBits = (BYTE)number; /* stencil */ number = iupAttribGetInt(ih,"STENCIL_SIZE"); if (number > 0) pfd.cStencilBits = (BYTE)number; /* red, green, blue accumulation bits */ number = iupAttribGetInt(ih,"ACCUM_RED_SIZE"); if (number > 0) pfd.cAccumRedBits = (BYTE)number; number = iupAttribGetInt(ih,"ACCUM_GREEN_SIZE"); if (number > 0) pfd.cAccumGreenBits = (BYTE)number; number = iupAttribGetInt(ih,"ACCUM_BLUE_SIZE"); if (number > 0) pfd.cAccumBlueBits = (BYTE)number; number = iupAttribGetInt(ih,"ACCUM_ALPHA_SIZE"); if (number > 0) pfd.cAccumAlphaBits = (BYTE)number; pfd.cAccumBits = pfd.cAccumRedBits + pfd.cAccumGreenBits + pfd.cAccumBlueBits + pfd.cAccumAlphaBits; /* get a device context */ { LONG style = GetClassLong(gldata->window, GCL_STYLE); gldata->is_owned_dc = (int) ((style & CS_OWNDC) || (style & CS_CLASSDC)); } gldata->device = GetDC(gldata->window); iupAttribSet(ih, "VISUAL", (char*)gldata->device); /* choose pixel format */ pixelFormat = ChoosePixelFormat(gldata->device, &pfd); if (pixelFormat == 0) { iupAttribSet(ih, "ERROR", "No appropriate pixel format."); iupAttribSetStr(ih, "LASTERROR", IupGetGlobal("LASTERROR")); return IUP_NOERROR; } SetPixelFormat(gldata->device,pixelFormat,&pfd); ih_shared = IupGetAttributeHandle(ih, "SHAREDCONTEXT"); if (ih_shared && IupClassMatch(ih_shared, "glcanvas")) /* must be an IupGLCanvas */ { IGlControlData* shared_gldata = (IGlControlData*)iupAttribGet(ih_shared, "_IUP_GLCONTROLDATA"); shared_context = shared_gldata->context; } /* create rendering context */ if (iupAttribGetBoolean(ih, "ARBCONTEXT")) { wglCreateContextAttribsARB_PROC CreateContextAttribsARB; HGLRC tempContext = wglCreateContext(gldata->device); HGLRC oldContext = wglGetCurrentContext(); HDC oldDC = wglGetCurrentDC(); wglMakeCurrent(gldata->device, tempContext); /* wglGetProcAddress only works with an active context */ CreateContextAttribsARB = (wglCreateContextAttribsARB_PROC)wglGetProcAddress("wglCreateContextAttribsARB"); if (CreateContextAttribsARB) { int attribs[9], a = 0; char* value; value = iupAttribGetStr(ih, "CONTEXTVERSION"); if (value) { int major, minor; if (iupStrToIntInt(value, &major, &minor, '.') == 2) { attribs[a++] = WGL_CONTEXT_MAJOR_VERSION_ARB; attribs[a++] = major; attribs[a++] = WGL_CONTEXT_MINOR_VERSION_ARB; attribs[a++] = minor; } } value = iupAttribGetStr(ih, "CONTEXTFLAGS"); if (value) { int flags = 0; if (iupStrEqualNoCase(value, "DEBUG")) flags = WGL_CONTEXT_DEBUG_BIT_ARB; else if (iupStrEqualNoCase(value, "FORWARDCOMPATIBLE")) flags = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; else if (iupStrEqualNoCase(value, "DEBUGFORWARDCOMPATIBLE")) flags = WGL_CONTEXT_DEBUG_BIT_ARB|WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (flags) { attribs[a++] = WGL_CONTEXT_FLAGS_ARB; attribs[a++] = flags; } } value = iupAttribGetStr(ih, "CONTEXTPROFILE"); if (value) { int profile = 0; if (iupStrEqualNoCase(value, "CORE")) profile = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; else if (iupStrEqualNoCase(value, "COMPATIBILITY")) profile = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; else if (iupStrEqualNoCase(value, "CORECOMPATIBILITY")) profile = WGL_CONTEXT_CORE_PROFILE_BIT_ARB|WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; if (profile) { attribs[a++] = WGL_CONTEXT_PROFILE_MASK_ARB; attribs[a++] = profile; } } attribs[a] = 0; /* terminator */ gldata->context = CreateContextAttribsARB(gldata->device, shared_context, attribs); if (!gldata->context) { DWORD error = GetLastError(); if (error == ERROR_INVALID_VERSION_ARB) iupAttribSetStr(ih, "LASTERROR", "Invalid ARB Version"); else if (error == ERROR_INVALID_PROFILE_ARB) iupAttribSetStr(ih, "LASTERROR", "Invalid ARGB Profile"); else iupAttribSetStr(ih, "LASTERROR", IupGetGlobal("LASTERROR")); iupAttribSet(ih, "ERROR", "Could not create a rendering context."); wglMakeCurrent(oldDC, oldContext); wglDeleteContext(tempContext); return IUP_NOERROR; } } wglMakeCurrent(oldDC, oldContext); wglDeleteContext(tempContext); if (!CreateContextAttribsARB) { gldata->context = wglCreateContext(gldata->device); iupAttribSet(ih, "ARBCONTEXT", "NO"); } } else gldata->context = wglCreateContext(gldata->device); if (!gldata->context) { iupAttribSet(ih, "ERROR", "Could not create a rendering context."); iupAttribSetStr(ih, "LASTERROR", IupGetGlobal("LASTERROR")); return IUP_NOERROR; } iupAttribSet(ih, "CONTEXT", (char*)gldata->context); if (shared_context) wglShareLists(shared_context, gldata->context); /* create colormap for index mode */ if (isIndex) { if (!gldata->palette) { LOGPALETTE lp = {0x300,1,{255,255,255,PC_NOCOLLAPSE}}; /* set first color as white */ gldata->palette = CreatePalette(&lp); ResizePalette(gldata->palette,1<<pfd.cColorBits); iupAttribSet(ih, "COLORMAP", (char*)gldata->palette); } SelectPalette(gldata->device,gldata->palette,FALSE); RealizePalette(gldata->device); } DescribePixelFormat(gldata->device, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &test_pfd); if ((pfd.dwFlags & PFD_STEREO) && !(test_pfd.dwFlags & PFD_STEREO)) { iupAttribSet(ih, "STEREO", "NO"); return IUP_NOERROR; } iupAttribSet(ih, "ERROR", NULL); return IUP_NOERROR; }
bool RenderContextWGL::Create(void* osWnd) { window = static_cast<HWND>(osWnd); int glmajor = 3; int glminor = 3; int colorBits = 32; int depthBits = 24; int stencilBits = 0; int samples = 0; InitGLEW(); int attrs[] = { WGL_SUPPORT_OPENGL_ARB, GL_TRUE, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, WGL_DOUBLE_BUFFER_ARB, GL_TRUE, WGL_SAMPLE_BUFFERS_ARB, samples > 0 ? GL_TRUE : GL_FALSE, WGL_SAMPLES_ARB, samples, WGL_COLOR_BITS_ARB, colorBits, WGL_DEPTH_BITS_ARB, depthBits, WGL_STENCIL_BITS_ARB, stencilBits, WGL_ALPHA_BITS_ARB, colorBits == 32 ? 8 : 0, 0 }; int pixelFormat; unsigned numFormats = 0; gdiDc = GetDC(window); int result = wglChoosePixelFormatARB(gdiDc, attrs, nullptr, 1, &pixelFormat, &numFormats); if (result == 0 || numFormats == 0) { Log::E("wglChoosePixelFormatARB failed"); } // info PIXELFORMATDESCRIPTOR pfd; DescribePixelFormat(gdiDc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); Log::V() << "Pixel format:\tcColorBits " << (int)pfd.cColorBits << ", cDepthBits " << (int)pfd.cDepthBits << "\n\t\t\tcAlphaBits " << (int)pfd.cAlphaBits << ", cStencilBits " << (int)pfd.cStencilBits; if (!SetPixelFormat(gdiDc, pixelFormat, &pfd)) { Log::E("SetPixelFormat"); } int contextAttrs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, glmajor, // OpenGL 3.3 provides full compatibility with OpenGL ES 3.0. WGL_CONTEXT_MINOR_VERSION_ARB, glminor, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, // WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB // WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // WGL_CONTEXT_DEBUG_BIT_ARB // WGL_CONTEXT_LAYER_PLANE_ARB, 0, 0 }; wglContext = wglCreateContextAttribsARB(gdiDc, 0, contextAttrs); if (!wglContext) { Log::E("wglContext"); } if (!wglMakeCurrent(gdiDc, wglContext)) { Log::E("wglMakeCurrent"); wglDeleteContext(wglContext); ReleaseDC(window, gdiDc); wglContext = nullptr; return false; } RECT rect; GetClientRect(window, &rect); mWidth = rect.right - rect.left; mHeight = rect.bottom - rect.top; return true; }
// // Creates a matching cen64_gl_config from a cen64_gl_hints struct. // // On error, CEN64_GL_CONFIG_BAD is returned. // cen64_gl_config *cen64_gl_config_create(cen64_gl_display display, cen64_gl_screen screen, const cen64_gl_hints *hints, int *matching) { struct cen64_gl_config *config; PIXELFORMATDESCRIPTOR pfd; // Do *NOT* use this hDC HANDLE outside this function. // It is the desktop window's hDC, and we shouldn't mess // with it. The only thing it's used for is to match a // PIXELFORMATDESCRIPTOR and expose success/failure. HDC screen_hdc; if ((config = malloc(sizeof(*config))) == NULL) return CEN64_GL_CONFIG_BAD; if ((screen_hdc = GetDC(screen)) == NULL) { free(config); return CEN64_GL_CONFIG_BAD; } memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(pfd); // As of 04/25/15, the MSDN documention (still) just says // to set this field to 1. So, uh, let's go with that. pfd.nVersion = 1; // Pack the structure using the provided hints-> pfd.dwFlags = PFD_SUPPORT_OPENGL; pfd.iLayerType = PFD_MAIN_PLANE; pfd.iPixelType |= (enum cen64_gl_context_type) hints->context_type; pfd.dwFlags |= (enum cen64_gl_drawable_type) hints->drawable_type; if (hints->double_buffered != -1) pfd.dwFlags |= PFD_DOUBLEBUFFER; if (hints->stereoscopic != -1) pfd.dwFlags |= PFD_STEREO; if (hints->rgb_color_depth != -1) pfd.cColorBits = hints->rgb_color_depth; if (hints->alpha_color_depth != -1) pfd.cAlphaBits = hints->alpha_color_depth; if (hints->depth_buffer_size != -1) pfd.cDepthBits = hints->depth_buffer_size; if (hints->num_aux_buffers != -1) pfd.cAuxBuffers = hints->num_aux_buffers; if (hints->stencil_buffer_size != -1) pfd.cStencilBits = hints->stencil_buffer_size; if (hints->accum_buffer_red_bits != -1) pfd.cAccumRedBits = hints->accum_buffer_red_bits; if (hints->accum_buffer_green_bits != -1) pfd.cAccumGreenBits = hints->accum_buffer_green_bits; if (hints->accum_buffer_blue_bits != -1) pfd.cAccumBlueBits = hints->accum_buffer_blue_bits; if (hints->accum_buffer_alpha_bits != -1) pfd.cAccumAlphaBits = hints->accum_buffer_alpha_bits; config->pixel_format = ChoosePixelFormat(screen_hdc, &pfd); DescribePixelFormat(screen_hdc, config->pixel_format, sizeof(config->pfd), &config->pfd); ReleaseDC(screen, screen_hdc); *matching = 1; return config; }
// Create the OpenGL or OpenGL ES context // int _glfwCreateContext(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig) { int attribs[40]; int pixelFormat = 0; PIXELFORMATDESCRIPTOR pfd; HGLRC share = NULL; if (ctxconfig->share) share = ctxconfig->share->wgl.context; window->wgl.dc = GetDC(window->win32.handle); if (!window->wgl.dc) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to retrieve DC for window"); return GL_FALSE; } if (!choosePixelFormat(window, fbconfig, &pixelFormat)) return GL_FALSE; if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd)) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to retrieve PFD for selected pixel format"); return GL_FALSE; } if (!SetPixelFormat(window->wgl.dc, pixelFormat, &pfd)) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to set selected pixel format"); return GL_FALSE; } if (window->wgl.ARB_create_context) { int index = 0, mask = 0, flags = 0; if (ctxconfig->api == GLFW_OPENGL_API) { if (ctxconfig->forward) flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; } else mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; if (ctxconfig->debug) flags |= WGL_CONTEXT_DEBUG_BIT_ARB; if (ctxconfig->robustness) { if (window->wgl.ARB_create_context_robustness) { if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) { setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, WGL_NO_RESET_NOTIFICATION_ARB); } else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) { setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, WGL_LOSE_CONTEXT_ON_RESET_ARB); } flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; } } if (ctxconfig->release) { if (window->wgl.ARB_context_flush_control) { if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) { setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); } else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) { setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB, WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); } } } // NOTE: Only request an explicitly versioned context when necessary, as // explicitly requesting version 1.0 does not always return the // highest version supported by the driver if (ctxconfig->major != 1 || ctxconfig->minor != 0) { setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); } if (flags) setWGLattrib(WGL_CONTEXT_FLAGS_ARB, flags); if (mask) setWGLattrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); setWGLattrib(0, 0); window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.dc, share, attribs); if (!window->wgl.context) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, "WGL: Failed to create OpenGL context"); return GL_FALSE; } } else { window->wgl.context = wglCreateContext(window->wgl.dc); if (!window->wgl.context) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, "WGL: Failed to create OpenGL context"); return GL_FALSE; } if (share) { if (!wglShareLists(share, window->wgl.context)) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to enable sharing with specified OpenGL context"); return GL_FALSE; } } } _glfwPlatformMakeContextCurrent(window); initWGLExtensions(window); return GL_TRUE; }
bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) { // safety if (!pGL || !pWindow) return false; std::unique_ptr<GLTempContext> tempContext; if (hrc == 0) { // Create a temporary context to be able to fetch GL extension pointers try { tempContext.reset(new GLTempContext); glewExperimental = GL_TRUE; GLenum err = glewInit(); if(err != GLEW_OK) { // Problem: glewInit failed, something is seriously wrong. pGL->Error(reinterpret_cast<const char*>(glewGetErrorString(err))); return false; } } catch (const WinAPIError &e) { pGL->Error((std::string(" gl: Unable to create temporary context: ") + e.what()).c_str()); return false; } } // store window this->pWindow = pWindow; // get DC hDC = GetDC(pWindow->renderwnd); if(!hDC) { pGL->Error(" gl: Error getting DC"); return false; } if (hrc) { SetPixelFormat(hDC, pGL->iPixelFormat, &pfd); } else { // Choose a good pixel format. int pixel_format; if((pixel_format = GetPixelFormatForMS(hDC, Config.Graphics.MultiSampling)) == 0) if((pixel_format = GetPixelFormatForMS(hDC, 0)) != 0) Config.Graphics.MultiSampling = 0; if (!pixel_format) { pGL->Error(" gl: Error choosing pixel format"); } else { ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); if(!DescribePixelFormat(hDC, pixel_format, sizeof(pfd), &pfd)) { pGL->Error(" gl: Error describing chosen pixel format"); } else if(!SetPixelFormat(hDC, pixel_format, &pfd)) { pGL->Error(" gl: Error setting chosen pixel format"); } else { // create context if (wglCreateContextAttribsARB) { const int attribs[] = { WGL_CONTEXT_FLAGS_ARB, Config.Graphics.DebugOpenGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, WGL_CONTEXT_MAJOR_VERSION_ARB, REQUESTED_GL_CTX_MAJOR, WGL_CONTEXT_MINOR_VERSION_ARB, REQUESTED_GL_CTX_MINOR, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, 0 }; hrc = wglCreateContextAttribsARB(hDC, 0, attribs); } else { DebugLog(" gl: wglCreateContextAttribsARB not available; creating default context."); hrc = wglCreateContext(hDC); } if(!hrc) { pGL->Error(" gl: Error creating gl context"); } pGL->iPixelFormat = pixel_format; } } } if (hrc) { Select(); // After selecting the new context, we have to reinitialize GLEW to // update its function pointers - the driver may elect to expose // different extensions depending on the context attributes glewExperimental = GL_TRUE; GLenum err = glewInit(); if (err != GLEW_OK) { // Uh. This is a problem. pGL->Error(reinterpret_cast<const char*>(glewGetErrorString(err))); return false; } this_context = contexts.insert(contexts.end(), this); return true; } ReleaseDC(pWindow->renderwnd, hDC); hDC = NULL; return false; }
/* Choose the closest pixel format that meets or exceeds the target. FIXME: Should we weight any particular attribute over any other? */ static int WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target) { PIXELFORMATDESCRIPTOR pfd; int count, index, best = 0; unsigned int dist, best_dist = ~0U; count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL); for (index = 1; index <= count; index++) { if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) { continue; } if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) { continue; } if (pfd.iLayerType != target->iLayerType) { continue; } if (pfd.iPixelType != target->iPixelType) { continue; } dist = 0; if (pfd.cColorBits < target->cColorBits) { continue; } else { dist += (pfd.cColorBits - target->cColorBits); } if (pfd.cRedBits < target->cRedBits) { continue; } else { dist += (pfd.cRedBits - target->cRedBits); } if (pfd.cGreenBits < target->cGreenBits) { continue; } else { dist += (pfd.cGreenBits - target->cGreenBits); } if (pfd.cBlueBits < target->cBlueBits) { continue; } else { dist += (pfd.cBlueBits - target->cBlueBits); } if (pfd.cAlphaBits < target->cAlphaBits) { continue; } else { dist += (pfd.cAlphaBits - target->cAlphaBits); } if (pfd.cAccumBits < target->cAccumBits) { continue; } else { dist += (pfd.cAccumBits - target->cAccumBits); } if (pfd.cAccumRedBits < target->cAccumRedBits) { continue; } else { dist += (pfd.cAccumRedBits - target->cAccumRedBits); } if (pfd.cAccumGreenBits < target->cAccumGreenBits) { continue; } else { dist += (pfd.cAccumGreenBits - target->cAccumGreenBits); } if (pfd.cAccumBlueBits < target->cAccumBlueBits) { continue; } else { dist += (pfd.cAccumBlueBits - target->cAccumBlueBits); } if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) { continue; } else { dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits); } if (pfd.cDepthBits < target->cDepthBits) { continue; } else { dist += (pfd.cDepthBits - target->cDepthBits); } if (pfd.cStencilBits < target->cStencilBits) { continue; } else { dist += (pfd.cStencilBits - target->cStencilBits); } if (dist < best_dist) { best = index; best_dist = dist; } } return best; }
// ChoosePFD // // Helper function that replaces ChoosePixelFormat. // static int GLW_ChoosePFD( HDC hDC, PIXELFORMATDESCRIPTOR *pPFD ) { #define MAX_PFDS 256 PIXELFORMATDESCRIPTOR pfds[MAX_PFDS+1]; int maxPFD = 0; int i; int bestMatch = 0; OutputDebugString( va("...GLW_ChoosePFD( %d, %d, %d )\n", ( int ) pPFD->cColorBits, ( int ) pPFD->cDepthBits, ( int ) pPFD->cStencilBits) ); // count number of PFDs // maxPFD = DescribePixelFormat( hDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[0] ); if ( maxPFD > MAX_PFDS ) { OutputDebugString( va( "...numPFDs > MAX_PFDS (%d > %d)\n", maxPFD, MAX_PFDS) ); maxPFD = MAX_PFDS; } OutputDebugString( va("...%d PFDs found\n", maxPFD - 1) ); FILE *handle = fopen("c:\\ModView_GL_report.txt","wt"); if ( !handle ) return 0; fprintf(handle,"Total PFDs: %d\n\n",maxPFD); // grab information for ( i = 1; i <= maxPFD; i++ ) { DescribePixelFormat( hDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[i] ); fprintf(handle,"PFD %d/%d\n",i,maxPFD); fprintf(handle,"=========\n"); #define FLAGDUMP(flag) if ( (pfds[i].dwFlags & flag ) != 0 ) fprintf(handle,"(flag: %s)\n",#flag); FLAGDUMP( PFD_DOUBLEBUFFER ); FLAGDUMP( PFD_STEREO ); FLAGDUMP( PFD_DRAW_TO_WINDOW ); FLAGDUMP( PFD_DRAW_TO_BITMAP ); FLAGDUMP( PFD_SUPPORT_GDI ); FLAGDUMP( PFD_SUPPORT_OPENGL ); FLAGDUMP( PFD_GENERIC_FORMAT ); FLAGDUMP( PFD_NEED_PALETTE ); FLAGDUMP( PFD_NEED_SYSTEM_PALETTE ); FLAGDUMP( PFD_SWAP_EXCHANGE ); FLAGDUMP( PFD_SWAP_COPY ); FLAGDUMP( PFD_SWAP_LAYER_BUFFERS ); FLAGDUMP( PFD_GENERIC_ACCELERATED ); FLAGDUMP( PFD_SUPPORT_DIRECTDRAW ); if ( pfds[i].iPixelType == PFD_TYPE_RGBA ) { // fprintf(handle,"RGBA mode\n"); } else { fprintf(handle,"NOT RGBA mode!!!!!!!!!!!!\n"); } fprintf(handle, "Colour bits: %d\n",pfds[i].cColorBits); fprintf(handle, "Depth bits: %d\n",pfds[i].cDepthBits); fprintf(handle,"\n"); } // look for a best match for ( i = 1; i <= maxPFD; i++ ) { fprintf(handle,"(bestMatch: %d)\n",bestMatch ); // // make sure this has hardware acceleration // if ( ( pfds[i].dwFlags & PFD_GENERIC_FORMAT ) != 0 ) { // if ( !r_allowSoftwareGL->integer ) { // if ( r_verbose->integer ) { fprintf(handle,//OutputDebugString( va ("...PFD %d rejected, software acceleration\n", i )); } continue; } } // verify pixel type if ( pfds[i].iPixelType != PFD_TYPE_RGBA ) { // if ( r_verbose->integer ) { fprintf(handle,//OutputDebugString( va("...PFD %d rejected, not RGBA\n", i) ); } continue; } // verify proper flags if ( ( ( pfds[i].dwFlags & pPFD->dwFlags ) & pPFD->dwFlags ) != pPFD->dwFlags ) { // if ( r_verbose->integer ) { fprintf(handle,//OutputDebugString( va("...PFD %d rejected, improper flags (0x%x instead of 0x%x)\n", i, pfds[i].dwFlags, pPFD->dwFlags) ); } continue; } // verify enough bits if ( pfds[i].cDepthBits < 15 ) { fprintf(handle,va("...PFD %d rejected, depth bits only %d (<15)\n", i, pfds[i].cDepthBits) ); continue; } /* if ( ( pfds[i].cStencilBits < 4 ) && ( pPFD->cStencilBits > 0 ) ) { continue; } */ // // selection criteria (in order of priority): // // PFD_STEREO // colorBits // depthBits // stencilBits // if ( bestMatch ) { /* // check stereo if ( ( pfds[i].dwFlags & PFD_STEREO ) && ( !( pfds[bestMatch].dwFlags & PFD_STEREO ) ) && ( pPFD->dwFlags & PFD_STEREO ) ) { bestMatch = i; continue; } if ( !( pfds[i].dwFlags & PFD_STEREO ) && ( pfds[bestMatch].dwFlags & PFD_STEREO ) && ( pPFD->dwFlags & PFD_STEREO ) ) { bestMatch = i; continue; } */ // check color if ( pfds[bestMatch].cColorBits != pPFD->cColorBits ) { // prefer perfect match if ( pfds[i].cColorBits == pPFD->cColorBits ) { bestMatch = i; continue; } // otherwise if this PFD has more bits than our best, use it else if ( pfds[i].cColorBits > pfds[bestMatch].cColorBits ) { bestMatch = i; continue; } } // check depth if ( pfds[bestMatch].cDepthBits != pPFD->cDepthBits ) { // prefer perfect match if ( pfds[i].cDepthBits == pPFD->cDepthBits ) { bestMatch = i; continue; } // otherwise if this PFD has more bits than our best, use it else if ( pfds[i].cDepthBits > pfds[bestMatch].cDepthBits ) { bestMatch = i; continue; } } /* // check stencil if ( pfds[bestMatch].cStencilBits != pPFD->cStencilBits ) { // prefer perfect match if ( pfds[i].cStencilBits == pPFD->cStencilBits ) { bestMatch = i; continue; } // otherwise if this PFD has more bits than our best, use it else if ( ( pfds[i].cStencilBits > pfds[bestMatch].cStencilBits ) && ( pPFD->cStencilBits > 0 ) ) { bestMatch = i; continue; } } */ } else { bestMatch = i; } } fprintf(handle,"Bestmode: %d\n",bestMatch); if ( !bestMatch ) { fprintf(handle,"No decent mode found!\n"); fclose(handle); return 0; } if ( ( pfds[bestMatch].dwFlags & PFD_GENERIC_FORMAT ) != 0 ) { // if ( !r_allowSoftwareGL->integer ) // { // ri.Printf( PRINT_ALL, "...no hardware acceleration found\n" ); // return 0; // } // else { fprintf(handle,//OutputDebugString( "...using software emulation\n" ); } } else if ( pfds[bestMatch].dwFlags & PFD_GENERIC_ACCELERATED ) { fprintf(handle,//OutputDebugString( "...MCD acceleration found\n" ); } else { fprintf(handle,//OutputDebugString( "...hardware acceleration found\n" ); } *pPFD = pfds[bestMatch]; fclose(handle); return bestMatch; }
// Prepare for creation of the OpenGL context // int _glfwCreateContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) { int attribs[40]; int pixelFormat = 0; PIXELFORMATDESCRIPTOR pfd; HGLRC share = NULL; if (wndconfig->share) share = wndconfig->share->wgl.context; window->wgl.dc = GetDC(window->win32.handle); if (!window->wgl.dc) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to retrieve DC for window"); return GL_FALSE; } if (!choosePixelFormat(window, fbconfig, &pixelFormat)) return GL_FALSE; if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd)) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to retrieve PFD for selected pixel " "format"); return GL_FALSE; } if (!SetPixelFormat(window->wgl.dc, pixelFormat, &pfd)) { _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set selected pixel format"); return GL_FALSE; } if (window->wgl.ARB_create_context) { int index = 0, mask = 0, flags = 0, strategy = 0; if (wndconfig->clientAPI == GLFW_OPENGL_API) { if (wndconfig->glForward) flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; if (wndconfig->glDebug) flags |= WGL_CONTEXT_DEBUG_BIT_ARB; if (wndconfig->glProfile) { if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE) mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE) mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; } } else mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; if (wndconfig->glRobustness) { if (window->wgl.ARB_create_context_robustness) { if (wndconfig->glRobustness == GLFW_NO_RESET_NOTIFICATION) strategy = WGL_NO_RESET_NOTIFICATION_ARB; else if (wndconfig->glRobustness == GLFW_LOSE_CONTEXT_ON_RESET) strategy = WGL_LOSE_CONTEXT_ON_RESET_ARB; flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; } } if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0) { setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor); setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor); } if (flags) setWGLattrib(WGL_CONTEXT_FLAGS_ARB, flags); if (mask) setWGLattrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask); if (strategy) setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy); setWGLattrib(0, 0); window->wgl.context = window->wgl.CreateContextAttribsARB(window->wgl.dc, share, attribs); if (!window->wgl.context) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, "WGL: Failed to create OpenGL context"); return GL_FALSE; } } else { window->wgl.context = wglCreateContext(window->wgl.dc); if (!window->wgl.context) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to create OpenGL context"); return GL_FALSE; } if (share) { if (!wglShareLists(share, window->wgl.context)) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to enable sharing with specified " "OpenGL context"); return GL_FALSE; } } } _glfwPlatformMakeContextCurrent(window); initWGLExtensions(window); return GL_TRUE; }
void VisualInfoARB (GLContext* ctx) { int attrib[32], value[32], n_attrib, n_pbuffer=0, n_float=0; int i, pf, maxpf; unsigned int c; /* to get pbuffer capable pixel formats */ attrib[0] = WGL_DRAW_TO_PBUFFER_ARB; attrib[1] = GL_TRUE; attrib[2] = 0; wglChoosePixelFormatARB(ctx->dc, attrib, 0, 1, &pf, &c); /* query number of pixel formats */ attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB; wglGetPixelFormatAttribivARB(ctx->dc, 0, 0, 1, attrib, value); maxpf = value[0]; for (i=0; i<32; i++) value[i] = 0; attrib[0] = WGL_SUPPORT_OPENGL_ARB; attrib[1] = WGL_DRAW_TO_WINDOW_ARB; attrib[2] = WGL_DRAW_TO_BITMAP_ARB; attrib[3] = WGL_ACCELERATION_ARB; /* WGL_NO_ACCELERATION_ARB, WGL_GENERIC_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB */ attrib[4] = WGL_SWAP_METHOD_ARB; /* WGL_SWAP_EXCHANGE_ARB, WGL_SWAP_COPY_ARB, WGL_SWAP_UNDEFINED_ARB */ attrib[5] = WGL_DOUBLE_BUFFER_ARB; attrib[6] = WGL_STEREO_ARB; attrib[7] = WGL_PIXEL_TYPE_ARB; /* WGL_TYPE_RGBA_ARB, WGL_TYPE_COLORINDEX_ARB, WGL_TYPE_RGBA_FLOAT_ATI (WGL_ATI_pixel_format_float) */ /* Color buffer information */ attrib[8] = WGL_COLOR_BITS_ARB; attrib[9] = WGL_RED_BITS_ARB; attrib[10] = WGL_GREEN_BITS_ARB; attrib[11] = WGL_BLUE_BITS_ARB; attrib[12] = WGL_ALPHA_BITS_ARB; /* Accumulation buffer information */ attrib[13] = WGL_ACCUM_BITS_ARB; attrib[14] = WGL_ACCUM_RED_BITS_ARB; attrib[15] = WGL_ACCUM_GREEN_BITS_ARB; attrib[16] = WGL_ACCUM_BLUE_BITS_ARB; attrib[17] = WGL_ACCUM_ALPHA_BITS_ARB; /* Depth, stencil, and aux buffer information */ attrib[18] = WGL_DEPTH_BITS_ARB; attrib[19] = WGL_STENCIL_BITS_ARB; attrib[20] = WGL_AUX_BUFFERS_ARB; /* Layer information */ attrib[21] = WGL_NUMBER_OVERLAYS_ARB; attrib[22] = WGL_NUMBER_UNDERLAYS_ARB; attrib[23] = WGL_SWAP_LAYER_BUFFERS_ARB; attrib[24] = WGL_SAMPLES_ARB; attrib[25] = WGL_SUPPORT_GDI_ARB; n_attrib = 26; if (WGLEW_ARB_pbuffer) { attrib[n_attrib] = WGL_DRAW_TO_PBUFFER_ARB; n_pbuffer = n_attrib; n_attrib++; } if (WGLEW_NV_float_buffer) { attrib[n_attrib] = WGL_FLOAT_COMPONENTS_NV; n_float = n_attrib; n_attrib++; } if (!verbose) { /* print table header */ fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { wglGetPixelFormatAttribivARB(ctx->dc, i, 0, n_attrib, attrib, value); /* only describe this format if it supports OpenGL */ if (!value[0]) continue; /* by default show only fully accelerated window or pbuffer capable visuals */ if (!showall && ((value[2] && !value[1]) || (!WGLEW_ARB_pbuffer || !value[n_pbuffer]) || (value[3] != WGL_FULL_ACCELERATION_ARB))) continue; /* print out the information for this visual */ /* visual id */ fprintf(file, " |% 4d | ", i); /* visual type */ if (value[1]) { if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "wp "); else fprintf(file, "wn "); } else { if (value[2]) fprintf(file, "bm "); else if (WGLEW_ARB_pbuffer && value[n_pbuffer]) fprintf(file, "pb "); } /* acceleration */ fprintf(file, "%s ", value[3] == WGL_FULL_ACCELERATION_ARB ? "fu" : value[3] == WGL_GENERIC_ACCELERATION_ARB ? "ge" : value[3] == WGL_NO_ACCELERATION_ARB ? "no" : ". "); /* gdi support */ fprintf(file, " %c ", value[25] ? 'y' : '.'); /* format */ if (WGLEW_NV_float_buffer && value[n_float]) fprintf(file, " f "); else if (WGLEW_ATI_pixel_format_float && value[7] == WGL_TYPE_RGBA_FLOAT_ATI) fprintf(file, " f "); else if (value[7] == WGL_TYPE_RGBA_ARB) fprintf(file, " i "); else if (value[7] == WGL_TYPE_COLORINDEX_ARB) fprintf(file, " c "); else if (value[7] == WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT) fprintf(file," p "); else fprintf(file," ? "); /* double buffer */ fprintf(file, " %c ", value[5] ? 'y' : '.'); /* swap method */ if (value[4] == WGL_SWAP_EXCHANGE_ARB) fprintf(file, " x "); else if (value[4] == WGL_SWAP_COPY_ARB) fprintf(file, " c "); else if (value[4] == WGL_SWAP_UNDEFINED_ARB) fprintf(file, " . "); else fprintf(file, " . "); /* stereo */ fprintf(file, " %c ", value[6] ? 'y' : '.'); /* multisample */ if (value[24] > 0) fprintf(file, "%2d | ", value[24]); else fprintf(file, " . | "); /* color size */ if (value[8]) fprintf(file, "%3d ", value[8]); else fprintf(file, " . "); /* red */ if (value[9]) fprintf(file, "%2d ", value[9]); else fprintf(file, " . "); /* green */ if (value[10]) fprintf(file, "%2d ", value[10]); else fprintf(file, " . "); /* blue */ if (value[11]) fprintf(file, "%2d ", value[11]); else fprintf(file, " . "); /* alpha */ if (value[12]) fprintf(file, "%2d | ", value[12]); else fprintf(file, " . | "); /* aux buffers */ if (value[20]) fprintf(file, "%2d ", value[20]); else fprintf(file, " . "); /* depth */ if (value[18]) fprintf(file, "%2d ", value[18]); else fprintf(file, " . "); /* stencil */ if (value[19]) fprintf(file, "%2d | ", value[19]); else fprintf(file, " . | "); /* accum size */ if (value[13]) fprintf(file, "%3d ", value[13]); else fprintf(file, " . "); /* accum red */ if (value[14]) fprintf(file, "%2d ", value[14]); else fprintf(file, " . "); /* accum green */ if (value[15]) fprintf(file, "%2d ", value[15]); else fprintf(file, " . "); /* accum blue */ if (value[16]) fprintf(file, "%2d ", value[16]); else fprintf(file, " . "); /* accum alpha */ if (value[17]) fprintf(file, "%2d | ", value[17]); else fprintf(file, " . | "); /* overlay */ if (value[21]) fprintf(file, "%2d ", value[21]); else fprintf(file, " . "); /* underlay */ if (value[22]) fprintf(file, "%2d ", value[22]); else fprintf(file, " . "); /* layer swap */ if (value[23]) fprintf(file, "y "); else fprintf(file, " . "); fprintf(file, "|\n"); } /* print table footer */ fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); fprintf(file, " | | visual | color | ax dp st | accum | layer |\n"); fprintf(file, " | id | tp ac gd fm db sw st ms | sz r g b a | bf th cl | sz r g b a | ov un sw |\n"); fprintf(file, " +-----+-------------------------+-----------------+----------+-----------------+----------+\n"); } else /* verbose */ { #if 0 fprintf(file, "\n"); /* loop through all the pixel formats */ for(i = 1; i <= maxpf; i++) { DescribePixelFormat(ctx->dc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd); /* only describe this format if it supports OpenGL */ if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL) || (drawableonly && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))) continue; fprintf(file, "Visual ID: %2d depth=%d class=%s\n", i, pfd.cDepthBits, pfd.cColorBits <= 8 ? "PseudoColor" : "TrueColor"); fprintf(file, " bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", pfd.cColorBits, pfd.bReserved, pfd.iPixelType == PFD_TYPE_RGBA ? "rgba" : "ci", pfd.dwFlags & PFD_DOUBLEBUFFER, pfd.dwFlags & PFD_STEREO); fprintf(file, " generic=%d generic accelerated=%d\n", (pfd.dwFlags & PFD_GENERIC_FORMAT) == PFD_GENERIC_FORMAT, (pfd.dwFlags & PFD_GENERIC_ACCELERATED) == PFD_GENERIC_ACCELERATED); fprintf(file, " rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cRedBits, pfd.cGreenBits, pfd.cBlueBits, pfd.cAlphaBits); fprintf(file, " auxBuffers=%d depthSize=%d stencilSize=%d\n", pfd.cAuxBuffers, pfd.cDepthBits, pfd.cStencilBits); fprintf(file, " accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", pfd.cAccumRedBits, pfd.cAccumGreenBits, pfd.cAccumBlueBits, pfd.cAccumAlphaBits); fprintf(file, " multiSample=%d multisampleBuffers=%d\n", 0, 0); fprintf(file, " Opaque.\n"); } #endif } }
static BOOL bSetupPixelFormatNormal( HDC hdc, GLbitfield visAttribs ) { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */ 1, /* version number */ PFD_DRAW_TO_WINDOW | /* support window */ PFD_SUPPORT_OPENGL, /* support OpenGL */ PFD_TYPE_RGBA, /* RGBA type */ 24, /* 24-bit 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, /* accum bits ignored */ 0, /* set depth buffer */ 0, /* set stencil buffer */ 0, /* no auxiliary buffer */ PFD_MAIN_PLANE, /* main layer */ 0, /* reserved */ 0, 0, 0 /* layer masks ignored */ }; PIXELFORMATDESCRIPTOR *ppfd = &pfd; char s[1000]; GLbitfield b = 0; int pixelformat; renderspuMakeVisString( visAttribs, s ); crDebug( "Render SPU: WGL wants these visual capabilities: %s", s); /* These really come into play with sort-last configs */ if (visAttribs & CR_DEPTH_BIT) ppfd->cDepthBits = 24; if (visAttribs & CR_ACCUM_BIT) ppfd->cAccumBits = 16; if (visAttribs & CR_RGB_BIT) ppfd->cColorBits = 24; if (visAttribs & CR_STENCIL_BIT) ppfd->cStencilBits = 8; if (visAttribs & CR_ALPHA_BIT) ppfd->cAlphaBits = 8; if (visAttribs & CR_DOUBLE_BIT) ppfd->dwFlags |= PFD_DOUBLEBUFFER; if (visAttribs & CR_STEREO_BIT) ppfd->dwFlags |= PFD_STEREO; /* * We call the wgl functions directly if the SPU was loaded * by our faker library, otherwise we have to call the GDI * versions. */ if (crGetenv( "CR_WGL_DO_NOT_USE_GDI" ) != NULL) { pixelformat = render_spu.ws.wglChoosePixelFormat( hdc, ppfd ); /* doing this twice is normal Win32 magic */ pixelformat = render_spu.ws.wglChoosePixelFormat( hdc, ppfd ); if ( pixelformat == 0 ) { crError( "render_spu.ws.wglChoosePixelFormat failed" ); } if ( !render_spu.ws.wglSetPixelFormat( hdc, pixelformat, ppfd ) ) { crError( "render_spu.ws.wglSetPixelFormat failed" ); } render_spu.ws.wglDescribePixelFormat( hdc, pixelformat, sizeof(*ppfd), ppfd ); } else { /* Okay, we were loaded manually. Call the GDI functions. */ pixelformat = ChoosePixelFormat( hdc, ppfd ); /* doing this twice is normal Win32 magic */ pixelformat = ChoosePixelFormat( hdc, ppfd ); if ( pixelformat == 0 ) { crError( "ChoosePixelFormat failed" ); } if ( !SetPixelFormat( hdc, pixelformat, ppfd ) ) { crError( "SetPixelFormat failed (Error 0x%x)", GetLastError() ); } DescribePixelFormat( hdc, pixelformat, sizeof(*ppfd), ppfd ); } if (ppfd->cDepthBits > 0) b |= CR_DEPTH_BIT; if (ppfd->cAccumBits > 0) b |= CR_ACCUM_BIT; if (ppfd->cColorBits > 8) b |= CR_RGB_BIT; if (ppfd->cStencilBits > 0) b |= CR_STENCIL_BIT; if (ppfd->cAlphaBits > 0) b |= CR_ALPHA_BIT; if (ppfd->dwFlags & PFD_DOUBLEBUFFER) b |= CR_DOUBLE_BIT; if (ppfd->dwFlags & PFD_STEREO) b |= CR_STEREO_BIT; renderspuMakeVisString( b, s ); crDebug( "Render SPU: WGL chose these visual capabilities: %s", s); return TRUE; }
static int GLW_ChoosePFD( HDC hDC, PIXELFORMATDESCRIPTOR *pPFD ) { PIXELFORMATDESCRIPTOR pfds[MAX_PFDS + 1]; int maxPFD = 0; int i; int bestMatch = 0; ri.Printf( PRINT_ALL, "...GLW_ChoosePFD( %d, %d, %d )\n", ( int ) pPFD->cColorBits, ( int ) pPFD->cDepthBits, ( int ) pPFD->cStencilBits ); // count number of PFDs if ( glConfig.driverType > GLDRV_ICD ) { maxPFD = qwglDescribePixelFormat( hDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[0] ); } else { maxPFD = DescribePixelFormat( hDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[0] ); } if ( maxPFD > MAX_PFDS ) { ri.Printf( PRINT_WARNING, "...numPFDs > MAX_PFDS (%d > %d)\n", maxPFD, MAX_PFDS ); maxPFD = MAX_PFDS; } ri.Printf( PRINT_ALL, "...%d PFDs found\n", maxPFD - 1 ); // grab information for ( i = 1; i <= maxPFD; i++ ) { if ( glConfig.driverType > GLDRV_ICD ) { qwglDescribePixelFormat( hDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[i] ); } else { DescribePixelFormat( hDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[i] ); } } // look for a best match for ( i = 1; i <= maxPFD; i++ ) { // // make sure this has hardware acceleration // if ( ( pfds[i].dwFlags & PFD_GENERIC_FORMAT ) != 0 ) { if ( !r_allowSoftwareGL->integer ) { if ( r_verbose->integer ) { ri.Printf( PRINT_ALL, "...PFD %d rejected, software acceleration\n", i ); } continue; } } // verify pixel type if ( pfds[i].iPixelType != PFD_TYPE_RGBA ) { if ( r_verbose->integer ) { ri.Printf( PRINT_ALL, "...PFD %d rejected, not RGBA\n", i ); } continue; } // verify proper flags if ( ( ( pfds[i].dwFlags & pPFD->dwFlags ) & pPFD->dwFlags ) != pPFD->dwFlags ) { if ( r_verbose->integer ) { ri.Printf( PRINT_ALL, "...PFD %d rejected, improper flags (%x instead of %x)\n", i, pfds[i].dwFlags, pPFD->dwFlags ); } continue; } // verify enough bits if ( pfds[i].cDepthBits < 15 ) { continue; } if ( ( pfds[i].cStencilBits < 4 ) && ( pPFD->cStencilBits > 0 ) ) { continue; } // // selection criteria (in order of priority): // // PFD_STEREO // colorBits // depthBits // stencilBits // if ( bestMatch ) { // check stereo if ( ( pfds[i].dwFlags & PFD_STEREO ) && ( !( pfds[bestMatch].dwFlags & PFD_STEREO ) ) && ( pPFD->dwFlags & PFD_STEREO ) ) { bestMatch = i; continue; } if ( !( pfds[i].dwFlags & PFD_STEREO ) && ( pfds[bestMatch].dwFlags & PFD_STEREO ) && ( pPFD->dwFlags & PFD_STEREO ) ) { bestMatch = i; continue; } // check color if ( pfds[bestMatch].cColorBits != pPFD->cColorBits ) { // prefer perfect match if ( pfds[i].cColorBits == pPFD->cColorBits ) { bestMatch = i; continue; } // otherwise if this PFD has more bits than our best, use it else if ( pfds[i].cColorBits > pfds[bestMatch].cColorBits ) { bestMatch = i; continue; } } // check depth if ( pfds[bestMatch].cDepthBits != pPFD->cDepthBits ) { // prefer perfect match if ( pfds[i].cDepthBits == pPFD->cDepthBits ) { bestMatch = i; continue; } // otherwise if this PFD has more bits than our best, use it else if ( pfds[i].cDepthBits > pfds[bestMatch].cDepthBits ) { bestMatch = i; continue; } } // check stencil if ( pfds[bestMatch].cStencilBits != pPFD->cStencilBits ) { // prefer perfect match if ( pfds[i].cStencilBits == pPFD->cStencilBits ) { bestMatch = i; continue; } // otherwise if this PFD has more bits than our best, use it else if ( ( pfds[i].cStencilBits > pfds[bestMatch].cStencilBits ) && ( pPFD->cStencilBits > 0 ) ) { bestMatch = i; continue; } } } else { bestMatch = i; } } if ( !bestMatch ) { return 0; } if ( ( pfds[bestMatch].dwFlags & PFD_GENERIC_FORMAT ) != 0 ) { if ( !r_allowSoftwareGL->integer ) { ri.Printf( PRINT_ALL, "...no hardware acceleration found\n" ); return 0; } else { ri.Printf( PRINT_ALL, "...using software emulation\n" ); } } else if ( pfds[bestMatch].dwFlags & PFD_GENERIC_ACCELERATED ) { ri.Printf( PRINT_ALL, "...MCD acceleration found\n" ); } else { ri.Printf( PRINT_ALL, "...hardware acceleration found\n" ); } *pPFD = pfds[bestMatch]; return bestMatch; }