Armion

Members
  • Content count

    9
  • Joined

  • Last visited

Community Reputation

272 Neutral

About Armion

  • Rank
    Newbie
  1. Sprite is resized

    Something else comes to my mind. Let's say your resolution is WxH. So you are creating a window with dimensions WxH and you are creating a backbuffer with size WxH. Then you are drawing the backbuffer to the client rect of the window. The catch is that the client area of the window is usually smaller than the window itself - the dimensions of the window also include the title bar and all the borders. This way you are trying to draw an image onto an area that can't contain it without distorting it first. If that's the case you want to resize the window and make it larger so that it can contain client area that has the exact same size of the backbuffer. To do it you call the [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ms632665%28v=vs.85%29.aspx"]AdjustWindowRect[/url] system function. Hope that helps [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]
  2. Elica and 3D graphics - is it worth it ?

    Hi, Getov [img]http://public.gamedev.net//public/style_emoticons/default/biggrin.png[/img] Judging from your name and the course you are asking about, I can tell you are most likely studying at FMI, Sofia University. If that's the case, I can assure you it's a complete waste of time if you are trying to learn something about computer graphics. I enrolled the course several years ago, because there was no one who could tell me that the name was quite inappropriate, given the things that one can learn from it - defining simple shapes and objects with certain properties(like texture and size) and applying simple operations to them. Keep in mind all of these things are not done in a general way that can help you in other situations. It's strongly Elica specific and Elica is a very high-level language/framework, so it certainly will not help you grasp the concepts of 3D programming. Ah, one more thing - Elica is slow, so it's very, very poor choice when it comes to game development. With that made clear, it still was an interesting experience, especially if you take into account the lack of gamedev-related courses at the Faculty [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img]
  3. [DX9] Vsync Lag

    I'm sorry i've misunderstood you :) Here is the code you asked for: POINT coords; ::GetCursorPos(&coords); ::ScreenToClient(handle, &coords); RECT client; GetClientRect(handle, &client); // This works correctly for windowed D3DXVECTOR3 pos(coords.x, coords.y, 0); sprite->Begin(D3DXSPRITE_ALPHABLEND); HRESULT test = sprite->Draw(texture, 0, 0, &pos, 0xFFFFFFFF); sprite->End(); [Edited by - Armion on August 21, 2010 5:10:59 PM]
  4. [DX9] Vsync Lag

    Hi Matias :) As you can see in the source code above i fill my D3DPRESENT_PARAMETERS structure with the following code: D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = width; d3dpp.BackBufferHeight = height; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; d3dpp.Windowed = windowed; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; d3dpp.Flags = 0; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; What part of it could be the problem? Checking the created device with PIX the only strange thing i see is that Windowed is set to true if we have specified fullscreen. Still i guess this interesting thing is happening because of the internal workings of PIX - even if i force Windowed to false Pix still tells me that Windowed is false. So i can't really see what could be messing with my application for i-don't-know-how-much-time. I tried playing with the settings and the once that gave me problems didn't return S_OK when creating the device so even if i wanted i couldn't use them. For your next assumption - yes, clamping the FPS through CPU remedies the problem in fullscreen. Windowed mode still lags but it's not as bad as before. As for how i'm rendering the cursor: The windows cursor is on. Additionally that's what i'm doing in my render procedure: // This source is almost the same as the in the book of Frank Luna, // called Introduction to 3D Game Programming With DirectX 9.0 // For complete source code see my first post - 3rd code file Device->Clear(some parameters); Device->BeginScene(); //Get the current cursor position according to screen coordinates //Render a texture representing a second cursor in that exact place Device->EndScene(); Device->Present(0, 0, 0, 0); No matter how i think about it in the worst case scenario the difference in the position should be at most 1/60 of the second. I don't see how the difference in time between moment 2 and 3 can be more that. moment 1: Present() at retrace period moment 2: Render cursor moment 3: Present() at retrace period And still the drawn cursor is lagging behind...
  5. [DX9] Vsync Lag

    Hi again and thanks for the replies :) @Scoob Droolins: One frame of lag is acceptable. The problem in the case is that there is much more delay(in my opinion). I tried the query method and the result was the same. Playing with "render frames ahead"... no improvement i can feel. @Matias Goldberg: Hmm... I will test if there is any error in my arguments when creating the fullscreen. Could this be related to the Ex version of interfaces and calls(IDirect3DDevice9Ex, PresentEx())? I don't think low fps is the problem - getting more than 4000 with D3DPRESENT_INTERVAL_IMMEDIATE - my app is just rendering its own cursor below the real one. I also tried one solution that was rumored to fix this lag in commercial games(Unreal Tournament, Battlefield 2 Bad Company) - limiting your fps to one or two below the refresh rate - let's say 58fps for 60Hz refresh rate... And it works like a charm. Can someone explain to me this STRANGE behavior? I also read there was some kind of bug in Win7 that was related to the difference between the actual refresh rate and the one that the OS reports to apps. I think i need to find a WinXP PC so i can test if things work the same way... Also i mistake on my part - i wanted to write "NOT USING MULTITHREADING", instead i wrote "now using multithreading" and this changes the thing a lot. I'm sorry for this silly mistake on my part. @Hazard_X: Dragging something in the interface with this method produces very unsatisfactory results. It's like the object i'm dragging is tied to the cursor with some kind of rubber leash - always lagging behind a lot. I know that this is true even when dragging something in windows, selecting text in Firefox or text editor or selecting multiple icons on the desktop with selection rectangle, but it certainly is MUCH LESS laggy than the simple app i wrote to demonstrate the problem... [Edited by - Armion on August 21, 2010 4:22:32 AM]
  6. [DX9] Vsync Lag

    I read the articles unbird mentioned but still can't find an answer to my questions... I hope it's not a bad practice bumping your own thread up again :) Edit: Changed "your thread" to "your own thread" :) [Edited by - Armion on August 20, 2010 1:00:59 PM]
  7. [DX9] Vsync Lag

    Thanks for the answers, guys :) I used the two cursors to show exactly what i mean by this lag. I don't plan on counting on them both in the future. If there was some input i guess it's alright, but in this case there isn't any. The application is not using windows messages like WM_MOUSEMOVE. It's only polling the cursor position and it's right before i call Draw on the Sprite object. I know that doesn't mean that the image of the cursor is drawn exactly at that moment i call Draw() - as far as i understand the command is queued for later drawing. But how much time can really pass between Draw() and actual drawing? Shouldn't the frame be ready by the time Present() returns? As far as i remember Present() takes a lot of time to complete in this case - actually it takes so much because it's waiting for the next vertical retrace period. So in the case of 60Hz refresh rate should the difference in time between Draw() and Present() be strictly less than 16.66ms? Maybe the buffering has something to do with it... Aren't we drawing to the back buffer and flipping them on Present()? Doesn't that mean that there should be no more than 1/60 second lag? And is 1/60 lag even noticeable? Is there a realistic way to measure how much time is lost in between doing something and seeing it on the screen? Can someone explain a bit more about DirectX caching frames on the commands buffer? How come it caches more than 60 frames when i only call Present() 60 times per second. How can it decide on its own to render more frames? Where does it get the data and commands for rendering from? Isn't this behavior connected the render-ahead, that i disabled through the NVidia Control Panel and RivaTuner? What does CPU is faster than the GPU means in my case? I'm NOT using multi-threading - isn't the CPU just waiting for Present() in this case? And some more questions... I hope someone has the time and is willing to answer them :D How are commercial games dealing with this problem? I don't remember there being any lag when i'm dragging items in my inventory when playing a random RPG or aiming headshots in some shooter. That said it's true that the Windows' cursor is not shown in the game and this certainly help maintain the illusion of smoothness and lagness(i'm not sure such word even exists...) And, as i mentioned, i don't think commercial, graphics-exacting games render a lot of frames(let's say 200-250)and still don't have this problem in such a severe case. Please note that i know it's just natural that they lag a bit, but it's not obvious for me... Even when only getting 40 fps for example... And the lag in my simple app is just making me... Let's say i don't like it at all :D If Aero is slowing my application down in windowed mode, why is it lagging more in fullscreen than in windowed with Aero disabled? I guess i forgot to put that fact in the previous post. And now to read the articles... Thanks again, guys :) [Edited by - Armion on August 21, 2010 4:27:22 AM]
  8. Hi guys, Before i get to the question i need to clarify some things. I'm a novice so don't be too harsh on me if i make some stupid mistake :) Also English is not my native language :) I spent the last two days trying to understand the extreme input lag(or at least i thought so at first) i get when using vsync (D3DPRESENT_INTERVAL_DEFAULT or D3DPRESENT_INTERVAL_ONE) or when having low fps(in the case below 240fps) in my simple 3d application. I read a lot of articles and posts in different forums and reached a conclusion that it's kind of normal because the specifics or vsync and buffering. Still i'm not sure that that much lag is normal. To be more precise it's not exactly input lag - more like something to do with presentation lag. I'm reading the book of Frank Luna about DirectX 9.0, so i modified the source of chapter one to show you what i mean. It's pretty basic stuff, but is perfect for demonstration. The idea is simple - you move the mouse around the window and a mouse texture is drawn at the current position of the mouse every frame... The two cursors should overlap perfectly... Or at least i want it to be that way, but it isn't. The DirectX drawn mouse always lags behind the Windows cursor and it's quite annoying for me. One more important thing - i'm using Windows 7 and disabling Aero almost fixes the problem. I don't have a Windows XP PC to test there. I was planning on doing a simple DirectX GUI Library to use in my future education projects, but when i came across this problem i just wonder what will dragging look like... I remember seeing some commercial games behave the same way with vsync enabled - can't recall any names at the moment. Still, the majority of them don't behave that way. I just don't believe that you have to render at least 240 frames for smooth feeling even if you don't have vsync enabled. To be honest i tried some solutions, but none of them gave me satisfactory results except disabling Aero - but i don't think that's the solution(I'm still interested why is that working at all). I also tried decreasing render ahead and even disabling it completely - still no improvement. I'm posting the source as i don't see an option for attaching files. FILENAME: d3dUtility.h ////////////////////////////////////////////////////////////////////////////////////////////////// // // File: d3dUtility.h // // Author: Frank Luna (C) All Rights Reserved // // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 // // Desc: Provides utility functions for simplifying common tasks. // ////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef __d3dUtilityH__ #define __d3dUtilityH__ #include <d3dx9.h> #include <string> namespace d3d { bool InitD3D( HINSTANCE hInstance, // [in] Application instance. int width, int height, // [in] Backbuffer dimensions. bool windowed, // [in] Windowed (true)or full screen (false). D3DDEVTYPE deviceType, // [in] HAL or REF IDirect3DDevice9** device);// [out]The created device. int EnterMsgLoop( bool (*ptr_display)(float timeDelta)); LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static HWND handle; HWND GetHandle(); template<class T> void Release(T t) { if( t ) { t->Release(); t = 0; } } template<class T> void Delete(T t) { if( t ) { delete t; t = 0; } } } #endif // __d3dUtilityH__ FILENAME: d3dUtility.cpp ////////////////////////////////////////////////////////////////////////////////////////////////// // // File: d3dUtility.cpp // // Author: Frank Luna (C) All Rights Reserved // // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 // // Desc: Provides utility functions for simplifying common tasks. // ////////////////////////////////////////////////////////////////////////////////////////////////// #include "d3dUtility.h" bool d3d::InitD3D( HINSTANCE hInstance, int width, int height, bool windowed, D3DDEVTYPE deviceType, IDirect3DDevice9** device) { // // Create the main application window. // WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)d3d::WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(0, IDI_APPLICATION); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = "Direct3D9App"; if( !RegisterClass(&wc) ) { ::MessageBox(0, "RegisterClass() - FAILED", 0, 0); return false; } HWND hwnd = 0; DWORD styles = WS_CAPTION | WS_SYSMENU | WS_EX_TRANSPARENT; RECT screenRect = {300, 300, 300 + width, 300 + height}; AdjustWindowRect(&screenRect, styles, false); hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App", WS_CAPTION | WS_SYSMENU | WS_EX_TRANSPARENT, screenRect.left, screenRect.top, screenRect.right - screenRect.left, screenRect.bottom - screenRect.top, 0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/); if( !hwnd ) { ::MessageBox(0, "CreateWindow() - FAILED", 0, 0); return false; } handle = hwnd; ::ShowWindow(hwnd, SW_SHOW); ::UpdateWindow(hwnd); // // Init D3D: // HRESULT hr = 0; // Step 1: Create the IDirect3D9 object. IDirect3D9* d3d9 = 0; d3d9 = Direct3DCreate9(D3D_SDK_VERSION); if( !d3d9 ) { ::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0); return false; } // Step 2: Check for hardware vp. D3DCAPS9 caps; d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps); int vp = 0; if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; else vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Step 3: Fill out the D3DPRESENT_PARAMETERS structure. D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = width; d3dpp.BackBufferHeight = height; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hwnd; d3dpp.Windowed = windowed; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; d3dpp.Flags = 0; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // Step 4: Create the device. hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, // primary adapter deviceType, // device type hwnd, // window associated with device vp, // vertex processing &d3dpp, // present parameters device); // return created device if( FAILED(hr) ) { // try again using a 16-bit depth buffer d3dpp.AutoDepthStencilFormat = D3DFMT_D16; hr = d3d9->CreateDevice( D3DADAPTER_DEFAULT, deviceType, hwnd, vp, &d3dpp, device); if( FAILED(hr) ) { d3d9->Release(); // done with d3d9 object ::MessageBox(0, "CreateDevice() - FAILED", 0, 0); return false; } } d3d9->Release(); // done with d3d9 object return true; } HWND d3d::GetHandle() { return handle; } int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) ) { MSG msg; ::ZeroMemory(&msg, sizeof(MSG)); static float lastTime = (float)timeGetTime(); while(msg.message != WM_QUIT) { if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } else { float currTime = (float)timeGetTime(); float timeDelta = (currTime - lastTime); ptr_display(timeDelta); lastTime = currTime; } } return msg.wParam; } FILENAME: d3dinit.cpp ////////////////////////////////////////////////////////////////////////////////////////////////// // // File: d3dinit.cpp // // Author: Frank Luna (C) All Rights Reserved // // System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0 // // Desc: Demonstrates how to initialize Direct3D, how to use the book's framework // functions, and how to clear the screen to black. Note that the Direct3D // initialization code is in the d3dUtility.h/.cpp files. // ////////////////////////////////////////////////////////////////////////////////////////////////// #include "d3dUtility.h" // // Globals // IDirect3DDevice9* Device = 0; LPDIRECT3DTEXTURE9 texture = 0; LPD3DXSPRITE sprite = 0; // // Framework Functions // bool Setup() { // Nothing to setup in this sample. HRESULT r1 = D3DXCreateTextureFromFile(Device, "C:\\Users\\Armion\\Desktop\\cursor.png", &texture); HRESULT r2 = D3DXCreateSprite(Device, &sprite); return true; } void Cleanup() { // Nothing to cleanup in this sample. texture->Release(); sprite->Release(); } bool Display(float timeDelta) { if( Device ) // Only use Device methods if we have a valid device. { // Instruct the device to set each pixel on the back buffer black - // D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on // the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f. static float totalTime = 0; static int frames = 0; totalTime += timeDelta; frames++; HWND handle = d3d::GetHandle(); if (totalTime > 1000) { char strFrames[10]; itoa(frames, strFrames, 10); char strFps[16]; strcpy(strFps, "FPS: "); strcat(strFps, strFrames); frames = 0; totalTime -= 1000; ::SetWindowTextA(handle, strFps); } Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0); Device->BeginScene(); POINT coords; ::GetCursorPos(&coords); ::ScreenToClient(handle, &coords); RECT client; GetClientRect(handle, &client); D3DXVECTOR3 pos(coords.x, coords.y, 0); sprite->Begin(D3DXSPRITE_ALPHABLEND); HRESULT test = sprite->Draw(texture, 0, 0, &pos, 0xFFFFFFFF); sprite->End(); //::SetWindowText(hwnd, Device->EndScene(); // Swap the back and front buffers. Device->Present(0, 0, 0, 0); } return true; } // // WndProc // LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY: ::PostQuitMessage(0); break; case WM_KEYDOWN: if( wParam == VK_ESCAPE ) ::DestroyWindow(hwnd); break; } return ::DefWindowProc(hwnd, msg, wParam, lParam); } // // WinMain // int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) { if(!d3d::InitD3D(hinstance, 640, 480, true, D3DDEVTYPE_HAL, &Device)) { ::MessageBox(0, "InitD3D() - FAILED", 0, 0); return 0; } if(!Setup()) { ::MessageBox(0, "Setup() - FAILED", 0, 0); return 0; } d3d::EnterMsgLoop( Display ); Cleanup(); Device->Release(); return 0; } Thanks in advance :)