• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

Erik Rufelt

  • Content count

  • Joined

  • Last visited

Community Reputation

5901 Excellent

About Erik Rufelt

  • Rank
  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. 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. 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. 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. No.
  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. 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.   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. 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.