Sign in to follow this  

Combining Mouse Input and Rendering

This topic is 3629 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, this is my first post, nice to be here ;) So what i did was found two tutorials, one explaining how to display a rotating teapot, and one explaining mouse input... I tried to combine them so that the teapot is actually still, but the camera will move depending on the mouse position (DIMOUSESTATE)... I thought i got it so it would work straight out and there was no error message when builiding the solution :D But when i ran the file, i got the old "windows has encountered a problem etc" and it wouldnt work :( There is alot of code, but im sure you are all experienced and it will all look simple to you ;). Ive put "HERE" in two places: 1. Where the function which seems to be causing the error message (detect_mousepos()) is. 2. Where the function (get_cam_rotation())is run to get the camera rotation. So here's the code: // include the basic windows header files and the Direct3D header file #include <windows.h> #include <windowsx.h> #include <d3d9.h> #include <d3dx9.h> #include <dinput.h> // define the screen resolution and keyboard macros #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 480 #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) // include the Direct3D Library files #pragma comment (lib, "d3d9.lib") #pragma comment (lib, "d3dx9.lib") #pragma comment (lib, "dinput8.lib") #pragma comment (lib, "dxguid.lib") // global declarations LPDIRECT3D9 d3d; // the pointer to our Direct3D interface LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class DIMOUSESTATE mousestate; LPDIRECTINPUT8 din; // the pointer to our DirectInput interface LPDIRECTINPUTDEVICE8 dinmouse; // the pointer to the mouse device // mesh declarations LPD3DXMESH meshTeapot; // define the mesh pointer // function prototypes void initD3D(HWND hWnd); // sets up and initializes Direct3D void render_frame(void); // renders a single frame void cleanD3D(void); // closes Direct3D and releases memory void init_graphics(void); // 3D declarations void init_light(void); // sets up the light and the material float get_cam_rotation(void); void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput void detect_mousepos(void); // gets the mouse movement and updates the static variables void cleanDInput(void); // closes DirectInput and releases memory // the WindowProc function prototype LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // the entry point for any Windows program int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = L"WindowClass"; RegisterClassEx(&wc); hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our Direct3D Program", WS_EX_TOPMOST | WS_POPUP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); // set up and initialize Direct3D initD3D(hWnd); // enter the main loop: MSG msg; while(TRUE) { DWORD starting_point = GetTickCount(); if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } render_frame(); // check the 'escape' key if(KEY_DOWN(VK_ESCAPE)) PostMessage(hWnd, WM_DESTROY, 0, 0); while ((GetTickCount() - starting_point) < 25); } // clean up DirectX and COM cleanD3D(); return msg.wParam; } // this is the main message handler for the program LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_DESTROY: { PostQuitMessage(0); return 0; } break; } return DefWindowProc (hWnd, message, wParam, lParam); } // this function initializes and prepares Direct3D for use void initD3D(HWND hWnd) { d3d = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = FALSE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hWnd; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dpp.BackBufferWidth = SCREEN_WIDTH; d3dpp.BackBufferHeight = SCREEN_HEIGHT; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // create a device class using this information and the info from the d3dpp stuct d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); init_graphics(); // call the function to initialize the triangle init_light(); // call the function to initialize the light and material d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); // turn on the 3D lighting d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50)); // ambient light return; } void initDInput(HINSTANCE hInstance, HWND hWnd) { // create the DirectInput interface DirectInput8Create(hInstance, // the handle to the application DIRECTINPUT_VERSION, // the compatible version IID_IDirectInput8, // the DirectInput interface version (void**)&din, // the pointer to the interface NULL); // COM stuff, so we'll set it to NULL // create the mouse device din->CreateDevice(GUID_SysMouse, // the default mouse ID being used &dinmouse, // the pointer to the device interface NULL); // COM stuff, so we'll set it to NULL dinmouse->SetDataFormat(&c_dfDIMouse); // set the data format to mouse format // set the control you will have over the mouse dinmouse->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); dinmouse->Acquire(); // Acquire the mouse only once return; // return to WinMain() } void detect_mousepos(void) { static DIMOUSESTATE mousestate; // create a static storage for the mouse-states dinmouse->Acquire(); // get access if we don't have it already // fill the mousestate with values dinmouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate); return; } // this function will get the position of the camera float get_cam_rotation(void) { detect_mousepos(); // HERE static float index = mousestate.lY; return index; } // this is the function used to render a single frame void render_frame(void) { d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3ddev->BeginScene(); // set the view transform D3DXMATRIX matView; // the view transform matrix D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3 (0.0f, 3.0f, get_cam_rotation()), // the camera position << HERE &D3DXVECTOR3 (0.0f, 0.0f, 0.0f), // the look-at position &D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction d3ddev->SetTransform(D3DTS_VIEW, &matView); // set the view transform to matView // set the projection transform D3DXMATRIX matProjection; // the projection transform matrix D3DXMatrixPerspectiveFovLH(&matProjection, D3DXToRadian(45), // the horizontal field of view (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio 1.0f, // the near view-plane 100.0f); // the far view-plane d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection // draw the teapot meshTeapot->DrawSubset(0); d3ddev->EndScene(); d3ddev->Present(NULL, NULL, NULL, NULL); return; } // this is the function that cleans up Direct3D and COM void cleanD3D(void) { meshTeapot->Release(); // close and release the teapot mesh d3ddev->Release(); // close and release the 3D device d3d->Release(); // close and release Direct3D return; } // this is the function that puts the 3D models into video RAM void init_graphics(void) { D3DXCreateTeapot(d3ddev, &meshTeapot, NULL); // create the teapot return; } // this is the function that sets up the lights and materials void init_light(void) { D3DLIGHT9 light; // create the light struct D3DMATERIAL9 material; // create the material struct ZeroMemory(&light, sizeof(light)); // clear out the struct for use light.Type = D3DLIGHT_DIRECTIONAL; // make the light type 'directional light' light.Diffuse.r = 0.5f; // .5 red light.Diffuse.g = 0.5f; // .5 green light.Diffuse.b = 0.5f; // .5 blue light.Diffuse.a = 1.0f; // full alpha (we'll get to that soon) D3DVECTOR vecDirection = {-1.0f, -0.3f, -1.0f}; // the direction of the light light.Direction = vecDirection; // set the direction d3ddev->SetLight(0, &light); // send the light struct properties to light #0 d3ddev->LightEnable(0, TRUE); // turn on light #0 ZeroMemory(&material, sizeof(D3DMATERIAL9)); // clear out the struct for use material.Diffuse.r = material.Ambient.r = 1.0f; // set the material to full red material.Diffuse.g = material.Ambient.g = 1.0f; // set the material to full green material.Diffuse.b = material.Ambient.b = 1.0f; // set the material to full blue material.Diffuse.a = material.Ambient.a = 1.0f; // set the material to full alpha d3ddev->SetMaterial(&material); // set the globably-used material to &material return; } void cleanDInput(void) { dinmouse->Unacquire(); // make sure the mouse is unacquired din->Release(); // close DirectInput before exiting return; }

Share this post


Link to post
Share on other sites
yea i am, u must have missed it:

void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput

and remember, if it was something like that, there would be an error when compiling it right? which theres not :(

sorry that i put so much code up :D

Share this post


Link to post
Share on other sites
Actually, gamezo is right.

You have the initDInput() function and its prototype. But nowhere
in the code you have given us is it actually called.

In WinMain() you have 'initD3D(hWnd);', just add 'initDInput(hInstance,hWnd);'
after it.

-Twixn-

Share this post


Link to post
Share on other sites
Welcome to the forum!

You're new here so you probably haven't seen it happen, but very often we get questions here about DirectInput and we have to explain why you shouldn't be using DirectInput for mouse or keyboard input. So I'll tell you the reasons right now:

-On Windows XP and above, all DirectInput does is create a separate thread to process raw input messages (WM_INPUT) for the mouse and keyboard. If you want the high-resolution mouse input that raw input affords you, it's easier to just process the WM_INPUT messages yourself. It's less code, less hassle, and less overhead.

-Using DirectInput prevents you from receiving standard mouse messages. This means you have no access to a standard GUI mouse that has pointer ballistics applied. With menus and GUI usage, a pointer without ballistics feels really weird.

-DirectInput also prevents you from receiving standard keyboard messages. This means you get no key repeats, no shift/capslock, and no alternate character maps or international keysets.

-Microsoft recommends you don't do it.

Well that about sums it up. Oh and one more thing, in the future please use "source" tags when posting long passages of code, it will use monospace font and syntax highlighting to make it easier to read. You can also use the "code" tags for short bits of code. If you have any questions, feel free to ask! [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Twixn
Actually, gamezo is right.

You have the initDInput() function and its prototype. But nowhere
in the code you have given us is it actually called.

In WinMain() you have 'initD3D(hWnd);', just add 'initDInput(hInstance,hWnd);'
after it.

-Twixn-


void initDInput(HINSTANCE hInstance, HWND hWnd)


:D


Quote:
it's easier to just process the WM_INPUT messages yourself


ok, i'll look into how to do that, and if i can't find it or i have some problems i'll be back ;)

i like this forums already and i'll probably have more questions in the future :) thanks for the help guys ;)

NuclearCarnage



Share this post


Link to post
Share on other sites
Quote:
Original post by NuclearCarnage
Quote:
Original post by Twixn
Actually, gamezo is right.

You have the initDInput() function and its prototype. But nowhere
in the code you have given us is it actually called.

In WinMain() you have 'initD3D(hWnd);', just add 'initDInput(hInstance,hWnd);'
after it.

-Twixn-


void initDInput(HINSTANCE hInstance, HWND hWnd)


:D


Quote:
it's easier to just process the WM_INPUT messages yourself


ok, i'll look into how to do that, and if i can't find it or i have some problems i'll be back ;)

i like this forums already and i'll probably have more questions in the future :) thanks for the help guys ;)

NuclearCarnage


No thats the declaration of the function. You have to have something like this in your WinMain() function:

initDInput( hInstance, hWnd );

That means that your function is actually called, rather than declared and not used.

TIP: Rather than cutting and pasting source code together in an attempt to make a program, i strongly suggest you take the most simple example you can find and learn what each part of it does. This will reap huge rewards because you will be able to begin to invent your own solutions to problems, which is most of the fun of programming. Start with something so trivial it's almost embarassing, tweak bits, change bits and see what happens.

And most of all, don't forget to ask for help! :)

Share this post


Link to post
Share on other sites

This topic is 3629 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this