Jump to content
  • Advertisement

Erik Rufelt

  • Content Count

  • Joined

  • Last visited

Community Reputation

5902 Excellent

1 Follower

About Erik Rufelt

  • Rank

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Is that FRAPS display always active?  If so, try disabling it.. it probably overrides a bunch of GL calls to put its overlay there.
  2. Try updating your graphics drivers if you don't have the newest stable one already.. From your images it seems clear that the OpenGL part stays right where it was in respect to the top-left corner of the window (not the just the client-area).. whereas I guess the top left part that was the border before gets the background-color.. Could be a difference in what theme is used in Windows or if there are any window-helper plugins or something that causes the difference in behavior on different computers.. Try dragging another window on top of the window with the error and see if the OpenGL drawn part is properly updated.. I guess you call PumpMessages from a loop and always do glClear and Swap after that? You could try only calling DefWindowProc always and skip any viewport and resize handling etc as glClear and Swap don't care about the viewport anyway, and maybe add a Sleep(10) or something in the loop to avoid insane update-rates..
  3. I don't get it.. does it not work?  I ran your program and see nothing strange.. maybe a difference between Windows versions or something.. You should post a single-file source code we can run instead of an exe if possible.   Anyway, I think your window styles look weird. Especially setting the style when going back to windowed mode.. save the style when you decide to switch to fullscreen and restore it to the saved style when going back to windowed.. removing the fullscreen style bits will break if the windowed mode has any of the same bits set. Many window-styles are combinations of several bits. Also it looks really complicated, too much code to combine the styles, very difficult to follow exactly what bits will remain in the end.. easy to miss things.   I don't get making the window area the same either.. if you want a particular window-area in client-mode then handle that.. but what is the point of a borderless window that doesn't cover the screen?   Also getting multiple WM_SIZE shouldn't matter, you could get that anyway if the window is resized, I don't think those messages are supposed to be relied on to send an exact size exactly once or things like that. I'm not sure a resize or especially a style-change is guaranteed to be in any way atomic with respect to the message queue.
  4. Show your game loop with PeekMessage as well as the WndProc.
  5.   Depends, it can have WS_VISIBLE and others added.. also many styles commonly used when creating a window are actually combinations of several sub-styles.
  6. I use this one, has some comments and TODOs that could be double-checked.. It has a check to (supposedly) only go to fullscreen on monitors connected to the primary GPU in case you have more than one, if not that part is unnecessary.. // Get device for monitor static bool getDeviceForMonitor(const MONITORINFOEX &monitorInfo, LPDISPLAY_DEVICE pOutDevice) {     DISPLAY_DEVICE displayDevice = {0};     displayDevice.cb = sizeof(displayDevice);          DWORD dwDevNum = 0;     BOOL bRet = EnumDisplayDevices(NULL, dwDevNum, &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME);     while(bRet != 0) {         if(wcscmp(monitorInfo.szDevice, displayDevice.DeviceName) == 0) {             *pOutDevice = displayDevice;                          return true;         }                  ++dwDevNum;         memset(&displayDevice, 0, sizeof(displayDevice));         displayDevice.cb = sizeof(displayDevice);         bRet = EnumDisplayDevices(NULL, dwDevNum, &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME);     }          return false; } // Toggle fullscreen // TODO try SetWindowPlacement instead? // TODO use maximized WS_POPUP to fill screen instead of manually setting rect?  check methods... static bool toggleFillscreen(HWND hWnd, bool setFillscreen) {     bool resultIsFullscreen = setFillscreen;          static LONG_PTR savedWindowStyle = 0;     static LONG_PTR savedWindowExStyle = 0;     static RECT savedWindowRect;          if(setFillscreen) {         resultIsFullscreen = false;                  int x = 0;         int y = 0;         int w = GetSystemMetrics(SM_CXSCREEN);         int h = GetSystemMetrics(SM_CYSCREEN);                  HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);         HMONITOR hPrimaryMonitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY);         if(hMonitor != NULL && hPrimaryMonitor != NULL) {             BOOL bRet;             bool switchToFullscreen = false;             bool gotPrimary = false;             bool gotTarget = false;                          MONITORINFOEX primaryInfo;             ZeroMemory(&primaryInfo, sizeof(primaryInfo));             primaryInfo.cbSize = sizeof(primaryInfo);             bRet = GetMonitorInfo(hPrimaryMonitor, &primaryInfo);             if(bRet != 0) {                 gotPrimary = true;             }                          MONITORINFOEX monitorInfo;             ZeroMemory(&monitorInfo, sizeof(monitorInfo));             monitorInfo.cbSize = sizeof(monitorInfo);             bRet = GetMonitorInfo(hMonitor, &monitorInfo);             if(bRet != 0) {                 x = monitorInfo.rcMonitor.left;                 y = monitorInfo.rcMonitor.top;                 w = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;                 h = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;                                  gotTarget = true;             }                          if(gotTarget && gotPrimary) {                 if(wcscmp(primaryInfo.szDevice, monitorInfo.szDevice) == 0) {                     switchToFullscreen = true;                 }                 else {                     DISPLAY_DEVICE primaryDevice;                     bool gotPrimaryDevice = getDeviceForMonitor(primaryInfo, &primaryDevice);                                          DISPLAY_DEVICE targetDevice;                     bool gotTargetDevice = getDeviceForMonitor(monitorInfo, &targetDevice);                                          if(gotPrimaryDevice && gotTargetDevice) {                         // always false for secondary monitors, even when connected the same GPU as the primary monitor..                         //bool isPrimaryDevice = ((primaryDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0);                         // according to docs for EDD_GET_DEVICE_INTERFACE_NAME DeviceID is supposed to contain 'something'.. seems to always be empty                         //if(wcscmp(primaryDevice.DeviceID, targetDevice.DeviceID) == 0)) {                         //    switchToFullscreen = true;                         //}                         // seems these registry key paths are per physical GPU apart from the last component which is an index                         // so this should probably match monitors on the same physical GPU                         for(size_t i = wcslen(primaryDevice.DeviceKey); i > 0; --i) {                             if(primaryDevice.DeviceKey[i - 1] == L'\\')                                 break;                             primaryDevice.DeviceKey[i - 1] = 0;                         }                         for(size_t i = wcslen(targetDevice.DeviceKey); i > 0; --i) {                             if(targetDevice.DeviceKey[i - 1] == L'\\')                                 break;                             targetDevice.DeviceKey[i - 1] = 0;                         }                         if(wcscmp(primaryDevice.DeviceKey, targetDevice.DeviceKey) == 0) {                             switchToFullscreen = true;                         }                         // this only compares the name of the graphics card, identical for 2 GPUs of the same type..                         //if(wcscmp(primaryDevice.DeviceString, targetDevice.DeviceString) == 0) {                         //    switchToFullscreen = true;                         //}                     }                 }             }             if(switchToFullscreen) {                 GetWindowRect(hWnd, &savedWindowRect);                 if(GetWindowLongPtr(hWnd, GWL_STYLE) & WS_MAXIMIZE) {                     savedWindowStyle = SetWindowLongPtr(hWnd, GWL_STYLE, WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPED | WS_VISIBLE | WS_MAXIMIZE);                     savedWindowExStyle = SetWindowLongPtr(hWnd, GWL_EXSTYLE, 0);                 }                 else {                     savedWindowStyle = SetWindowLongPtr(hWnd, GWL_STYLE, WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_OVERLAPPED | WS_VISIBLE);                     savedWindowExStyle = SetWindowLongPtr(hWnd, GWL_EXSTYLE, 0);                 }                 SetWindowPos(hWnd, HWND_TOPMOST, x, y, w, h, SWP_FRAMECHANGED | SWP_DRAWFRAME);                                  resultIsFullscreen = true;             }             else                 MessageBeep(MB_OK);         }     }     else {         SetWindowLongPtr(hWnd, GWL_STYLE, savedWindowStyle | WS_VISIBLE);         SetWindowLongPtr(hWnd, GWL_EXSTYLE, savedWindowExStyle);         HWND hWndInsertAfter = HWND_NOTOPMOST;         if((savedWindowExStyle & WS_EX_TOPMOST) == WS_EX_TOPMOST)             hWndInsertAfter = HWND_TOPMOST;         SetWindowPos(             hWnd,             hWndInsertAfter,             savedWindowRect.left,             savedWindowRect.top,             savedWindowRect.right-savedWindowRect.left,             savedWindowRect.bottom-savedWindowRect.top,             SWP_FRAMECHANGED | SWP_DRAWFRAME         );     }          return resultIsFullscreen; } And use like this: (Won't work for more than one window in it's current form as the toggleFillscreen function has statics to save the window placement..) bool currentFullscreen = false; ... if(toggleKeyPressed) currentFullscreen = toggleFillscreen(hWnd, !currentFullscreen); EDIT: added a retain topmost style
  7. Erik Rufelt

    responsiveness of main game loop designs

    In extreme cases you could improve perceived latency by drawing some things after the main game/simulation graphics, like if your game displays a mouse cursor. Even if your normal simulation and rendering was done as usual you could delay your swap/present and draw the cursor with an updated position right before the image is sent to the display, possibly with input data received several ms after the simulation was last updated. You could even buffer a few rendered frames, then go back and draw the cursor on top right before getting the image ready for presentation. For OpenGL there is https://www.opengl.org/registry/specs/NV/wgl_delay_before_swap.txt to achieve minimal latency.
  8. You should be able to smooth edges with alpha-blended lines or similar after all your regular geometry is drawn (using depth-testing but not depth-writes). I would imagine GL_LINE_SMOOTH could work fine there with depth-testing.. Your question is tagged with OpenGL ES but the title says Windows, do you do OpenGL ES on desktop or regular OpenGL?
  9. Erik Rufelt

    Screen tearing when using OpenGL on Windows

    VSync is often unreliable in windowed mode. If you create a window filling the entire screen with its client area and nothing obscuring it (WS_POPUP / WS_EX_TOPMOST) the Nvidia driver should switch to exclusive fullscreen mode. For perfect VSync you actually want pre-rendered frames, so it should not be set to 1, that would break VSync if even a single frame happened to lag behind because of some background process or similar that is out of application control
  10. Erik Rufelt

    Manually loading OpenGL functions on Windows

    I also use the fallback method to get pointers for the old functions.. I think that's what common extension libraries do as well, though I haven't actually checked.. If including a recent glcorearb.h header without the prototypes-define it won't define the old prototypes either, but will define the function pointer types for the 1.0 functions etc. as well. And with the prototypes-define it will add prototypes for all functions including newer ones. On Linux all function pointers can be obtained with glXGetProcAddress so there no fallback is required. If still linking to opengl32.lib one could of course do another fallback, something like mynamespace::glClear = ::glClear instead of GetProcAddress...
  11. Erik Rufelt

    bezier curve character

  12. Could be something with "index" as an integer in the shader. Try using a simpler shader that doesn't use array indexing and doesn't use integers to make sure. Did you enable the debug runtime properly? Go into the DirectX control panel and make sure you set the highest debug level under D3D9 and enable all the debug options, then run your app with the debugger and see what output you get.
  13. Erik Rufelt

    Weird Lesson 43 Problem

    I tried the code without modifications other than adding Qgjqp to the printed text and they look fine here.. try a different font or text-size and change the string you draw to make sure if it's really those characters that are missing and not certain positions in the string that disappear or similar.
  14. Erik Rufelt

    how good is rand() ?

      Correct.  In modern math notation this type of function works with [0,x)  meaning it includes zero but stops just short of x.  This is also common in many other systems.  Graphics, for example, typically draw segments in the [A,B) form, starting exactly at A and ending the instant before B.     I tried this in VS2015 and it does return RAND_MAX.. is it not supposed to? #include <iostream> int main() { for(int i = 0; i < 200000; ++i) { int r = rand(); if(r == RAND_MAX) std::cout << "MAX\n"; else if(r == (RAND_MAX - 1)) std::cout << "ALMOST\n"; else if(r == 0) std::cout << "ZERO\n"; } }
  15. Erik Rufelt

    how good is rand() ?

    Not too good.. If you Google for its implementation you get a few results. Something like next = (current * A) + B with overflow wrapping around.   EDIT: And it does return the value RAND_MAX at times, not just RAND_MAX-1.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!