Jump to content
  • Advertisement
Sign in to follow this  

OpenGL Linker errors

This topic is 4679 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

I've downloaded some of the tutorials from : http://triplebuffer.devmaster.net/tutorials/stepping1.php (Tutorial 2 - Creating a triangle) And I'm having trouble compiling them. I've downloaded and installed the directx 9.0 sdk, and linked to the includes and libs, but I get the following errors. Oh and by the way, I've just finished learning c++ and this is my first time trying out directx, so I'd appreciate it if I could have the dumbed down explanation :) Anyway, the errors are: [Linker error] undefined reference to `_Z20MainMessageProcedureP6HWND__jjl@16' [Linker error] undefined reference to `Direct3DCreate9@4' [Linker error] undefined reference to `WinMain@16' And the errors are in MyApplication.h Incase they're needed, here are the files: MyApplication.cpp: ----- #include "MyApplication.h" LRESULT WINAPI MainMessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); CMyApplication::CMyApplication() { // Initialize all the member variables m_hWnd = NULL; m_bPaused = FALSE; m_bAlive = TRUE; m_bActive = TRUE; m_bWindowed = FALSE; m_iWndWidth = 500; m_iWndHeight = 400; strcpy(m_strTitle, "Triple Buffer FVFs, Vertex Buffers"); strcpy(m_strClass, "TripleBuffer"); m_pD3D = NULL; m_pD3DDevice = NULL; ZeroMemory(&m_d3dpp, sizeof(D3DPRESENT_PARAMETERS)); ZeroMemory(&m_d3ddcp, sizeof(D3DDEVICE_CREATION_PARAMETERS)); } CMyApplication::~CMyApplication() { SAFE_RELEASE(m_pD3DDevice); SAFE_RELEASE(m_pD3D); if(m_hWnd) DestroyWindow(m_hWnd); UnregisterClass(m_strClass, GetModuleHandle(NULL)); } BOOL CMyApplication::InitializeWindow(int iWidth, int iHeight, BOOL bWindowed) { WNDCLASSEX wc; // Fill in the members wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_CLASSDC; wc.lpfnWndProc = MainMessageProcedure; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = GetModuleHandle(NULL); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); wc.lpszClassName = m_strClass; wc.lpszMenuName = NULL; RegisterClassEx(&wc); if(!bWindowed) { iWidth = GetSystemMetrics(SM_CXFULLSCREEN); iHeight = GetSystemMetrics(SM_CYFULLSCREEN); } m_hWnd = CreateWindow(m_strClass, m_strTitle, ((bWindowed)?WS_OVERLAPPEDWINDOW:WS_POPUPWINDOW), 0, 0, iWidth, iHeight, NULL, NULL, wc.hInstance, NULL); if(m_hWnd == NULL) return FALSE; ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); ShowCursor(TRUE); return TRUE; } BOOL CMyApplication::InitializeD3D(D3DDEVICE_CREATION_PARAMETERS dcp, BOOL bWindowed, int iWidth, int iHeight) { D3DDISPLAYMODE d3ddm; m_bWindowed = bWindowed; m_d3ddcp.hFocusWindow = dcp.hFocusWindow; m_d3ddcp.AdapterOrdinal = dcp.AdapterOrdinal; m_d3ddcp.DeviceType = dcp.DeviceType; m_d3ddcp.BehaviorFlags = dcp.BehaviorFlags; m_pD3D = Direct3DCreate9(D3D_SDK_VERSION); if(m_pD3D == NULL) return FALSE; if(FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) return FALSE; m_d3dpp.BackBufferCount = 1; m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; m_d3dpp.EnableAutoDepthStencil = TRUE; m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // If we are windowed if(m_bWindowed) { m_d3dpp.BackBufferWidth = iWidth; m_d3dpp.BackBufferHeight = iHeight; m_d3dpp.BackBufferFormat = d3ddm.Format; m_d3dpp.Windowed = TRUE; } else {// We are not in windowed mode m_d3dpp.BackBufferWidth = d3ddm.Width; m_d3dpp.BackBufferHeight = d3ddm.Height; m_d3dpp.BackBufferFormat = d3ddm.Format; m_d3dpp.Windowed = FALSE; m_d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; } // Store the official window width and height now, cause // we are not going to change it after this point m_iWndWidth = m_d3dpp.BackBufferWidth; m_iWndHeight = m_d3dpp.BackBufferHeight; if(FAILED(m_pD3D->CreateDevice(dcp.AdapterOrdinal, dcp.DeviceType, dcp.hFocusWindow, dcp.BehaviorFlags, &m_d3dpp, &m_pD3DDevice))) return FALSE; return TRUE; } BOOL CMyApplication::IsDeviceThere() { HRESULT hr; hr = m_pD3DDevice->TestCooperativeLevel(); if(FAILED(hr)) return FALSE; return TRUE; } BOOL CMyApplication::ResetDevice() { if(FAILED(m_pD3DDevice->Reset(&m_d3dpp))) return FALSE; return TRUE; } BOOL CMyApplication::CanReset() { HRESULT hr; hr = m_pD3DDevice->TestCooperativeLevel(); if(hr == D3DERR_DEVICENOTRESET) return TRUE; return FALSE; } void CMyApplication::Run() { if(!InitializeWindow(m_iWndWidth, m_iWndHeight, FULLSCREEN?FALSE:TRUE)) return; D3DDEVICE_CREATION_PARAMETERS dcp; dcp.AdapterOrdinal = D3DADAPTER_DEFAULT; dcp.DeviceType = D3DDEVTYPE_HAL; dcp.hFocusWindow = m_hWnd; dcp.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; if(!InitializeD3D(dcp, FULLSCREEN?FALSE:TRUE, m_iWndWidth, m_iWndHeight)) return; if(!FirstInitialize()) return; MyGameLoop(); FinalCleanup(); } void CMyApplication::MyGameLoop() { MSG msg; ZeroMemory(&msg, sizeof(MSG)); while(msg.message != WM_QUIT && m_bAlive != FALSE) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { if(m_bActive) { if(IsDeviceThere()) { if(!m_bPaused) { if(!PreRender()) break; if(!Render()) break; } } else { if(CanReset()) { InvalidateObjects(); ResetDevice(); RestoreObjects(); } } } } } } LRESULT WINAPI CMyApplication::MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) { case WM_ACTIVATE: switch(wParam) { case WA_ACTIVE: m_bActive = TRUE; break; case WA_CLICKACTIVE: m_bActive = TRUE; break; case WA_INACTIVE: m_bActive = FALSE; break; } return 0; break; case WM_DESTROY: PostQuitMessage(0); return 0; break; case WM_SIZE: switch(wParam) { case SIZE_MINIMIZED: m_bActive = FALSE; break; case SIZE_RESTORED: m_bActive = TRUE; break; case SIZE_MAXIMIZED: m_bActive = TRUE; break; } return 0; break; case WM_KEYDOWN: switch(wParam) { case VK_ESCAPE: PostQuitMessage(0); break; case VK_PAUSE: m_bPaused = !m_bPaused; break; } return 0; break; default: return DefWindowProc(hWnd, iMsg, wParam, lParam); } } ////////////////////////////////////////////////////////////////////////////////////////////// // This file is copyright © Triple Buffer Software. // // Terms and conditions of code usage are specified at: // http://triplebuffer.devmaster.net/license.php // // Send any questions/comments to triplebuffer@devmaster.net, or visit the forums. // // Written by: Ali Fareed - k9eks@hotmail.com ///////////////////////////////////////////////////////////////////////////////////////////// ---- My Application.h //------------------------------------------------------------------------------------- // This stuff is generated by MS Visual C++ when you go to Menu->Insert->New Class #if !defined(AFX_MYAPPLICATION_H__143B0E6B_546C_4B77_BF3C_4B5797349D77__INCLUDED_) #define AFX_MYAPPLICATION_H__143B0E6B_546C_4B77_BF3C_4B5797349D77__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif //------------------------------------------------------------------------------------- // Link in the required libraries #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") // We link this so we can use the function timeGetTime() #pragma comment(lib, "winmm.lib") // include necessary headers #include <windows.h> #include <d3dx9.h> #define SAFE_RELEASE(i) if(i != NULL) { i->Release(); i = NULL; } class CMyApplication { public: CMyApplication(); virtual ~CMyApplication(); void Run(); virtual LRESULT WINAPI MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); protected: BOOL InitializeD3D(D3DDEVICE_CREATION_PARAMETERS dcp, BOOL bWindowed, int iWidth, int iHeight); BOOL IsDeviceThere(); BOOL CanReset(); BOOL ResetDevice(); BOOL InitializeWindow(int iWidth, int iHeight, BOOL bWindowed); void MyGameLoop(); virtual BOOL FirstInitialize() { return TRUE; } virtual BOOL FinalCleanup() { return TRUE; } virtual BOOL InvalidateObjects() { return TRUE; } virtual BOOL RestoreObjects() { return TRUE; } virtual BOOL PreRender() { return TRUE; } virtual BOOL Render() { return TRUE; } HWND m_hWnd; BOOL m_bPaused; BOOL m_bActive; BOOL m_bAlive; BOOL m_bWindowed; UINT m_iWndWidth; UINT m_iWndHeight; char m_strTitle[128]; char m_strClass[128]; IDirect3D9* m_pD3D; IDirect3DDevice9* m_pD3DDevice; D3DPRESENT_PARAMETERS m_d3dpp; D3DDEVICE_CREATION_PARAMETERS m_d3ddcp; }; #endif // !defined(AFX_MYAPPLICATION_H__143B0E6B_546C_4B77_BF3C_4B5797349D77__INCLUDED_) ////////////////////////////////////////////////////////////////////////////////////////////// // This file is copyright © Triple Buffer Software. // // Terms and conditions of code usage are specified at: // http://triplebuffer.devmaster.net/license.php // // Send any questions/comments to triplebuffer@devmaster.net, or visit the forums. // // Written by: Ali Fareed - k9eks@hotmail.com ///////////////////////////////////////////////////////////////////////////////////////////// -- Game.cpp /*-------------------------------------------------------------------- This is where all the magic is going to take place. This is our main file, and everything is going to happen through here Tutorial #2.5 Changes - Added vertex buffer creation and deletion function - functions to set the camera position, the objects' position, and the projection (perspective/non-perpective) - Added the vertex buffer object that holds the vertex data - A structure that is used for each vertex - An FVF that will be used by DirectX to know what kind of vertex you're giving it - RestoreObjects() and InvalidateObjects() are being used for the first time, and so is FirstInitialize() ---------------------------------------------------------------------*/ #include "Game.h" // The CGame class definition CGame::CGame() { // Initialize the pointer to NULL m_pVertexBuffer = NULL; } CGame::~CGame() { KillTriangle(); } BOOL CGame::KillTriangle() { // This is a macro defined in the base class that // safely releases an interface. MS uses it so we'll // use it too :P SAFE_RELEASE(m_pVertexBuffer); return TRUE; } BOOL CGame::CustomSetup() { // Turn off lighting cause we arent using any lights // and we made th vertex buffer without normals, so if // you turned lighting on, everything would be black // or just unlit if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE))) return FALSE; // We set teh CULLMODE to NONE because if we leave itr at default // DirectX will get rid of all the polygons that are not stored // in a counter-clock-wise order. We store our vertices in a ransom // order, because we are drawing flat quad, and we dont need any // polygons to be hidden. But say that we were drawing a cube, Then // you would want the inside polygons of the cube (the polygons that // no one can see) gotten rid of. In that kind of situation Setting // the cull mode is good for optimizations. When you are in your // program press F1 and see what happens. I turn Culling back on // after you press F1 if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE))) return FALSE; // Now you can set the projection matrix. The projection matrix // is like a your eye's pupil, you can focus your eye, to see close // objects, or you can focus your eye to see farther away objects. It would // be better to compare the projection to a camera lens. you can zoom in // and zoom out. You can do the same thig with the projection. Go into your // DirectX folder and go to the Direct3D Samples, go into the bin folder // and click on FishEye.exe. That is the effect a projection matrix can have. // We will use the perspective matrix. You can also use the orthogonal // function. If you use Ortho, you get rid of 3D effects, When you are running // The program, press F2 when your object is on the far left or right, and see // what happens. Also try moving the quads back a bit, and they reach a point where // they just dissapear. This is because we set our last parameter to 100.0. so anything // that goes past 100 units in the positive z direction (away from you) will // dissapear. make the value higher, say 1000, and you can go much farther before // the object dissapears, but then you get other problems as you go farther. // try it and you'll notive the problem, and then you can ask me why it happens :) if(FAILED(D3DXMatrixPerspectiveFovLH(&m_matProjection, D3DX_PI/4.0f, (float)(m_iWndWidth/m_iWndHeight), 1.0f, 1000.0f))) return FALSE; // On FAIL // Now set our created projection matrix as the projection // matrix that DirectX should use. You set all matrices ie: // world, projection and view with a call to SetTransform(); if(FAILED(m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &m_matProjection))) return FALSE; // On FAIL // Now we can set the view matrix. The view matrix is where yuor camera // is. We can just set to to an identity matrix so that its at origin, // but I want to show you a function that's very useful for setting the view matrix. // The following function is just one call and it will set up the // - Position of your camera // - The position of what the camera is looking at // - And, Which direction is considered UP in this scene // So our setting are if(FAILED(D3DXMatrixLookAtLH(&m_matView, &D3DXVECTOR3(0.0f, 00.0f, -50.0f), //Position 50 units back. &D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look at the origin &D3DXVECTOR3(0.0f, 1.0f, .0f)))) //Up is the positive Y-Axis return FALSE; // On FAIL // Now set the view matrix just like you set the projection matrix if(FAILED(m_pD3DDevice->SetTransform(D3DTS_VIEW, &m_matView))) return FALSE; // On FAIL return TRUE; } BOOL CGame::FirstInitialize() { // Set all the matrices to identity matrices // this is just like setting a number to 0 ... starting fresh D3DXMatrixIdentity(&m_matWorld); D3DXMatrixIdentity(&m_matView); D3DXMatrixIdentity(&m_matProjection); // Set up all our custom device setup stuff if(!CustomSetup()) return FALSE; // Now create our vertex buffer if(!CreateTriangle()) return FALSE; return TRUE; } BOOL CGame::CreateTriangle() { // Declare a pointer to a MY_CUSTOM_VERTEX structure. We are going to do stuff // to this pointer that will have it pointing to our vertex buffer that will // eventually be stored somewhere in memory. pVertices will eventually point to // that area in memory. Once pVertices points to our vertex buffer, we can change // stuff in our vertex buffer. The stuff we can change in the vertex buffer depends // on the type of vertex buffer we make. We are going to make a vertex buffer that // will store 8 vertices, and each of the vertices will be of the type // MY_CUSTOM_VERTEX. MY_CUSTOM_VERTEX *pVertices = NULL; // This function is used to initialize our vertex buffer // interface. It is a straight forward function, which gives // you back a pointer to your initialized vertex buffer if(FAILED(m_pD3DDevice->CreateVertexBuffer( 3*(sizeof(MY_CUSTOM_VERTEX)), // The first parameter wants the size of the vertex // buffer that you want to create. We are going to be // storing 3 verices in our vertex buffer. and each // vertex is of type 'MY_CUSTOM_VERTEX', so the total // size of the vertex buffer is the number of vertices // times the size of their type (and they are of type // MY_CUSTOM_VERTEX). 3 vertices for 3 points in a // triangle D3DUSAGE_WRITEONLY, // This second param, is used to tel DirectX how you are // going to use your vertex buffer. All we are going to // do is write to it, so we specify the flag D3DUSGAE_WRITEONLY. // Also this vertex buffer will be a static one. Meaning // that we are not going to be changing it's contents. If // you wanted it to be a dynamic buffer, all you'd do is // specify D3DUSAGE_DYNAMIC. The difference is that static // buffers will be placed in video memory (directly accessible) // and dynamic buffers will be placed in AGP memory. If you // dont specify D3DUSAGE_DYNAMIC, DirectX automatically // assumes that the buffer is static (and that's what we want) MY_CUSTOM_VERTEX_FVF, // This is the Flexible Vertex Format that we give to // DirectX, to let it know what type of structure we are // using to store our vertices. We are using a structure // with x,y,z position, and a color. So that's what our // FVF says, and that's what we pass to CreateVertexBuffer() D3DPOOL_DEFAULT, // This parameter tells DirectX where to place the vertex // buffer. DEFAULT tells DirectX to choose the most efficiet // place for it. This is usually your 3D cards memory. but // not necessarily. It could be place in SYSTEMMEM or in // MANAGED. DEFAULT should be used with VertexBuffers, but // when you're using textures, it's advisable to place them // in the MANAGED POOL (D3DPOOL_MANAGAED). Also anything // you place in D3DPOOL_DEFAULT must be released before // resetting the device, and then reinitialized after the // device is reset. &m_pVertexBuffer, // The initialized vertex buffer NULL ))) // Last parameter has to be NULL cause it's reserved. return FALSE; //FAIL // Now we have to fill in the vertex buffer. To do that we have to // lock the vertex buffer, then we fill in the vertex buffer, then we // unlock it, so ... if(FAILED(m_pVertexBuffer->Lock(0, // This is where we want to start locking. // Meaning that the vertex buffer will be // locked starting from '0' (so from the // beginning). 0, // This is how much of the vertex buffer you // want to lock, (starting from the first // parameter). 0 tells DiretcX that you want // the whole thing. Alternatively you can give // it the size by telling that you want to lock // number of vertices * sizeof(MY_CUSTOM_VERTEX) // but specifying 0 is easier and just the same. (void**)&pVertices, // This is a pointer to our vertices in the // vertex buffer. After teh Lock() function // returns. This pointer will point to our // vertex buffer (wherever it is). And we can // use it to chenge stuff. 0))) // This parameter takes a few flags that could // enable optimization. For example if you were // only going to read from the vertex buffer // you could specify D3DLOCK_READONLY, to say // that you only want to read. But when we // created our vertex buffer we specified // D3DUSAGE_WRITEONLY, so we're going to be // writing to it. If we specified D3DLOCK_READONLY // this function would FAIL because there would be // a conflict in DirectX return FALSE; // Now we use pVertices to access our vertex buffer, and change it // Set our 3 vertices pVertices[0].position = D3DXVECTOR3(0.0f, 5.0f, 0.0f); pVertices[1].position = D3DXVECTOR3(-2.0f, -2.0f, 0.0f); pVertices[2].position = D3DXVECTOR3(2.0f, -2.0f, 0.0f); // Ok we finished fixing the vertices' positions // now we'll give them color pVertices[0].color = D3DCOLOR_XRGB(255,255,255); // White pVertices[1].color = D3DCOLOR_XRGB(255,255,0); // Yellow pVertices[2].color = D3DCOLOR_XRGB(0,0,255); // Blue // Ok, we are done with the vertex buffer. now unlock it m_pVertexBuffer->Unlock(); return TRUE; } BOOL CGame::Render() { // This function will tell direct3D what part of the Fixed Function Pipeline // you are going to be using. Our FVF has XYZ, and DIFFUSE, so DirectX knows // that you are using vertices that have position and color. m_pD3DDevice->SetFVF(MY_CUSTOM_VERTEX_FVF); // This function binds a vertex buffer to a stream. in this call we are // binding m_pVertexBuffer to stream 0, and telling the function that all // the vertices are of the 'MY_CUSTOM_VERTEX' size. The second 0 tells direct3D // how far forward it must move from the start of the stream to out vertex data. // We specified stream 0, and we want to start sending vertices from our first vertex // so we put 0 in the third param too m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(MY_CUSTOM_VERTEX)); m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,30), 1.0f, 0); m_pD3DDevice->BeginScene(); // Set the world matrix. This decides where the tri wil be draw // we havn't done anything so just set it to an identity that we // made in the CustomSetup function m_pD3DDevice->SetTransform(D3DTS_WORLD, &m_matWorld); m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, // Type of stuff we're drawing // we are drawing a triangle list. // triangle lists are made up of 3 // vertices each. So we have 1 // triangle list 0, // From where to start drawing in the VB 1); // How many D3DPTs will we draw? m_pD3DDevice->EndScene(); m_pD3DDevice->Present(NULL, NULL, NULL, NULL); // Setting the StreamSource back to NULL after you use it is good // practice. If you dont set it back to NULL. It's possible // that when you exit the program, the vertex buffer isnt totally // released and you will get a memory leak. This is highly unlikely // but it's possible, so just play it safe. m_pD3DDevice->SetStreamSource(0, NULL, 0, sizeof(MY_CUSTOM_VERTEX)); return TRUE; } BOOL CGame::FinalCleanup() { return KillTriangle(); } // When the device is lost this function is called // before the device is reset, and RestoreObjects() // is called after teh device is reset. You have to // release stuff that you created with D3DPOOL_DEFAULT // before resetting the device. andwe just happened to // create our vertex buffer using D3DPOOL_DEFAULT, so // we release it before trying to reset the device. // Then we reinitialize our vertex buffer from the // RestoreObjects() function BOOL CGame::InvalidateObjects() { return KillTriangle(); } BOOL CGame::RestoreObjects() { // Call CustomSetup() to customize the // way teh direct3D device behaves; CustomSetup(); return CreateTriangle(); } LRESULT WINAPI CGame::MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { return CMyApplication::MessageProcedure(hWnd, iMsg, wParam, lParam); } //------------------------------------------------------------------------------// // Application execution starts here // //------------------------------------------------------------------------------// CGame *g_pGame = NULL; int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pstrCmdLine, int iShowCmd) { g_pGame = new CGame; g_pGame->Run(); delete g_pGame; return 0; } LRESULT WINAPI MainMessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { return g_pGame->MessageProcedure(hWnd, iMsg, wParam, lParam); } /* **Culling** (a render state is exactly what it says, it is the state in which DirectX will) (render objects to the screen. You can change many things with render states. ) In the CustomSetup() function we set the renderstate called CULLMODE to NONE. We set it to NONE so that DirectX does not do any back-face culling. When it's on, DirectX will cull out any polygons that are facing away from the user. This is one of the optimization techniques that DirectX uses. But we just rendered some flat squares. So there are'nt any polygons that are not possible to see. If we were rendering a cube, then all the polygons inside the cube are unseeable by the user, and should therefor be culled. If you want the back of a polygon culled, you have to define the polygon in a certain direction. Meaning that the order that the verices are stored in matter. So if we wanted a triange with it's back culled we would define the vertices in a counter-clock wise direction. (I think it's clock wise for OpenGL) here... 1 see how the vertices go in a counter clock wise direction around |\ the polygon. If we were to define it like this | \ 1 | \ |\ then the fron of our polygon 2---3 | \ would never be seen. Granted | \ we turned culling on. 3---2 **Transformations** Before a vertex is shown on the screen it has to go through 3 transformations. We set 2 of the transformations in the CustomSetup() function, and we set the last transformation is in the Render() function. They are -The Projection -The View -The World You can think of the first 2 transformations as a camera. The first one is the camera's lense. It sets the perspective, and the field of view. You can make things appear farther and closer. You know that effect in games with a sniper?! you can do that with the projection. The second transformation is the view, which can be compared to the rest of the camera. It has a position, it has a "look at" point (the point it's looking at). And it has an "up" direction, which tells the camera which way is up in the world. The 3rd transformation is the world. We use the world to place objects in different positions. So if you wanted to move an object to an area in you world, you would set the world matrix to that area, then draw your object. Also because of the nature of matices, the order in which you multiply your transformations in make a different. the order for matrix multiplication is S*R*T (scaling x rotations x translations). In our Render() function, try changing the order to S*T*R, and you'll get an orbiting effect. ************************************RECAP*************************************** To draw something on screen we have to 1: Create the d3d device 2: Set a few default render states 3: Set the view and projection matrices 4: Fill a vertex bufer with vertex data 5: Set the world matrix 6: Draw what's in the vertex buffer 7: Destroy all our interfaces, and delete any memory we created 7 steps to drawing a quad on the screen with directx! */ ////////////////////////////////////////////////////////////////////////////////////////////// // This file is copyright © Triple Buffer Software. // // Terms and conditions of code usage are specified at: // http://triplebuffer.devmaster.net/license.php // // Send any questions/comments to triplebuffer@devmaster.net, or visit the forums. // // Written by: Ali Fareed - k9eks@hotmail.com ///////////////////////////////////////////////////////////////////////////////////////////// --- Game.h #if !defined(AFX_GAME_H__5E41AB7E_7E69_406D_B870_7BC766BE96C0__INCLUDED_) #define AFX_GAME_H__5E41AB7E_7E69_406D_B870_7BC766BE96C0__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif #include "MyApplication.h" // This structure will hold our data for each vertex. We want to have a position // and a color for each vertex so I made this structure to hold that information // After our structure we have to tell DirectX what our structure is made up of // That is where the Flexible Vertex Format (FVF) comes in. Our FVF is defined // under the structure struct MY_CUSTOM_VERTEX { D3DXVECTOR3 position; D3DCOLOR color; }; // This is our FVF. For a complete list of valid FVFs check teh sdk docs // But here we are using XYZ, which tells DX we have position, and we are // using DIFFUSE, which tells DX that we have color. #define MY_CUSTOM_VERTEX_FVF (D3DFVF_XYZ|D3DFVF_DIFFUSE) class CGame : public CMyApplication { public: CGame(); ~CGame(); // These are all the virtual functions in the base class. LRESULT WINAPI MessageProcedure(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); BOOL FirstInitialize(); BOOL FinalCleanup(); // These two function will be used for // resetting the vertex buffers when device // is lost BOOL InvalidateObjects(); BOOL RestoreObjects(); BOOL Render(); // These two functions explain themselves :) BOOL CreateTriangle(); BOOL KillTriangle(); // This function sets stuff up. namely the view and projection matices BOOL CustomSetup(); private: // This variable will hold our vertex buffer IDirect3DVertexBuffer9 *m_pVertexBuffer; // These three variables will be used to // set the vertices in their final position D3DXMATRIX m_matWorld; D3DXMATRIX m_matView; D3DXMATRIX m_matProjection; }; #endif ////////////////////////////////////////////////////////////////////////////////////////////// // This file is copyright © Triple Buffer Software. // // Terms and conditions of code usage are specified at: // http://triplebuffer.devmaster.net/license.php // // Send any questions/comments to triplebuffer@devmaster.net, or visit the forums. // // Written by: Ali Fareed - k9eks@hotmail.com ///////////////////////////////////////////////////////////

Share this post

Link to post
Share on other sites
From what I've heard DexC++ and DirectX don't mesh well. Haven't tried myself so I don't have any solutions beyond getting Visual Studio instead.

Also, for large chunks of code like that, try to use the 'source' tags.

Matt Hughson

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Similar Content

    • By nOoNEE
      hello guys , i have some questions  what does glLinkProgram  and  glBindAttribLocation do?  i searched but there wasnt any good resource 
    • By owenjr
      Hi, I'm a Multimedia Engineering student. I am about to finish my dergree and I'm already thinking about what topic to cover in my final college project.
      I'm interested in the procedural animation with c++ and OpenGL of creatures, something like a spider for example. Can someone tell me what are the issues I should investigate to carry it out? I understand that it has some dependence on artificial intelligence but I do not know to what extent. Can someone help me to find information about it? Thank you very much.
      - Procedural multi-legged walking animation
      - Procedural Locomotion of Multi-Legged Characters in Dynamic Environments
    • By Lewa
      So, i'm still on my quest to unterstanding the intricacies of HDR and implementing this into my engine. Currently i'm at the step to implementing tonemapping. I stumbled upon this blogposts:
      and tried to implement some of those mentioned tonemapping methods into my postprocessing shader.
      The issue is that none of them creates the same results as shown in the blogpost which definitely has to do with the initial range in which the values are stored in the HDR buffer. For simplicity sake i store the values between 0 and 1 in the HDR buffer (ambient light is 0.3, directional light is 0.7)
      This is the tonemapping code:
      vec3 Uncharted2Tonemap(vec3 x) { float A = 0.15; float B = 0.50; float C = 0.10; float D = 0.20; float E = 0.02; float F = 0.30; return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; } This is without the uncharted tonemapping:
      This is with the uncharted tonemapping:
      Which makes the image a lot darker.
      The shader code looks like this:
      void main() { vec3 color = texture2D(texture_diffuse, vTexcoord).rgb; color = Uncharted2Tonemap(color); //gamma correction (use only if not done in tonemapping code) color = gammaCorrection(color); outputF = vec4(color,1.0f); } Now, from my understanding is that tonemapping should bring the range down from HDR to 0-1.
      But the output of the tonemapping function heavily depends on the initial range of the values in the HDR buffer. (You can't expect to set the sun intensity the first time to 10 and the second time to 1000 and excpect the same result if you feed that into the tonemapper.) So i suppose that this also depends on the exposure which i have to implement?
      To check this i plotted the tonemapping curve:
      You can see that the curve goes only up to around to a value of 0.21 (while being fed a value of 1) and then basically flattens out. (which would explain why the image got darker.)
      My guestion is: In what range should the values in the HDR buffer be which then get tonemapped? Do i have to bring them down to a range of 0-1 by multiplying with the exposure?
      For example, if i increase the values of the light by 10 (directional light would be 7 and ambient light 3) then i would need to divide HDR values by 10 in order to get a value range of 0-1 which then could be fed into the tonemapping curve. Is that correct?
    • By nOoNEE
      i am reading this book : link
      in the OpenGL Rendering Pipeline section there is a picture like this: link
      but the question is this i dont really understand why it is necessary to turn pixel data in to fragment and then fragment into pixel could please give me a source or a clear Explanation that why it is necessary ? thank you so mu
    • By Inbar_xz
      I'm using the OPENGL with eclipse+JOGL.
      My goal is to create movement of the camera and the player.
      I create main class, which create some box in 3D and hold 
      an object of PlayerAxis.
      I create PlayerAxis class which hold the axis of the player.
      If we want to move the camera, then in the main class I call to 
      the func "cameraMove"(from PlayerAxis) and it update the player axis.
      That's work good.
      The problem start if I move the camera on 2 axis, 
      for example if I move with the camera right(that's on the y axis)
      and then down(on the x axis) -
      in some point the move front is not to the front anymore..
      In order to move to the front, I do
      player.playerMoving(0, 0, 1);
      And I learn that in order to keep the front move, 
      I need to convert (0, 0, 1) to the player axis, and then add this.
      I think I dont do the convert right.. 
      I will be glad for help!

      Here is part of my PlayerAxis class:
      //player coordinate float x[] = new float[3]; float y[] = new float[3]; float z[] = new float[3]; public PlayerAxis(float move_step, float angle_move) { x[0] = 1; y[1] = 1; z[2] = -1; step = move_step; angle = angle_move; setTransMatrix(); } public void cameraMoving(float angle_step, String axis) { float[] new_x = x; float[] new_y = y; float[] new_z = z; float alfa = angle_step * angle; switch(axis) { case "x": new_z = addVectors(multScalar(z, COS(alfa)), multScalar(y, SIN(alfa))); new_y = subVectors(multScalar(y, COS(alfa)), multScalar(z, SIN(alfa))); break; case "y": new_x = addVectors(multScalar(x, COS(alfa)), multScalar(z, SIN(alfa))); new_z = subVectors(multScalar(z, COS(alfa)), multScalar(x, SIN(alfa))); break; case "z": new_x = addVectors(multScalar(x, COS(alfa)), multScalar(y, SIN(alfa))); new_y = subVectors(multScalar(y, COS(alfa)), multScalar(x, SIN(alfa))); } x = new_x; y = new_y; z = new_z; normalization(); } public void playerMoving(float x_move, float y_move, float z_move) { float[] move = new float[3]; move[0] = x_move; move[1] = y_move; move[2] = z_move; setTransMatrix(); float[] trans_move = transVector(move); position[0] = position[0] + step*trans_move[0]; position[1] = position[1] + step*trans_move[1]; position[2] = position[2] + step*trans_move[2]; } public void setTransMatrix() { for (int i = 0; i < 3; i++) { coordiTrans[0][i] = x[i]; coordiTrans[1][i] = y[i]; coordiTrans[2][i] = z[i]; } } public float[] transVector(float[] v) { return multiplyMatrixInVector(coordiTrans, v); }  
      and in the main class i have this:
      public void keyPressed(KeyEvent e) { if (e.getKeyCode()== KeyEvent.VK_ESCAPE) { System.exit(0); //player move } else if (e.getKeyCode()== KeyEvent.VK_W) { //front //moveAmount[2] += -0.1f; player.playerMoving(0, 0, 1); } else if (e.getKeyCode()== KeyEvent.VK_S) { //back //moveAmount[2] += 0.1f; player.playerMoving(0, 0, -1); } else if (e.getKeyCode()== KeyEvent.VK_A) { //left //moveAmount[0] += -0.1f; player.playerMoving(-1, 0, 0); } else if (e.getKeyCode()== KeyEvent.VK_D) { //right //moveAmount[0] += 0.1f; player.playerMoving(1, 0, 0); } else if (e.getKeyCode()== KeyEvent.VK_E) { //moveAmount[0] += 0.1f; player.playerMoving(0, 1, 0); } else if (e.getKeyCode()== KeyEvent.VK_Q) { //moveAmount[0] += 0.1f; player.playerMoving(0, -1, 0); //camera move } else if (e.getKeyCode()== KeyEvent.VK_I) { //up player.cameraMoving(1, "x"); } else if (e.getKeyCode()== KeyEvent.VK_K) { //down player.cameraMoving(-1, "x"); } else if (e.getKeyCode()== KeyEvent.VK_L) { //right player.cameraMoving(-1, "y"); } else if (e.getKeyCode()== KeyEvent.VK_J) { //left player.cameraMoving(1, "y"); } else if (e.getKeyCode()== KeyEvent.VK_O) { //right round player.cameraMoving(-1, "z"); } else if (e.getKeyCode()== KeyEvent.VK_U) { //left round player.cameraMoving(1, "z"); } }  
      finallt found it.... i confused with the transformation matrix row and col. thanks anyway!
    • By Lewa
      So, i'm currently trying to implement an SSAO shader from THIS tutorial and i'm running into a few issues here.
      Now, this SSAO method requires view space positions and normals. I'm storing the normals in my deferred renderer in world-space so i had to do a conversion and reconstruct the position from the depth buffer.
      And something there goes horribly wrong (which has probably to do with worldspace to viewspace transformations).
      (here is the full shader source code if someone wants to take a look at it)
      Now, i suspect that the normals are the culprit.
      vec3 normal = ((uNormalViewMatrix*vec4(normalize(texture2D(sNormals, vTexcoord).rgb),1.0)).xyz); "sNormals" is a 2D texture which stores the normals in world space in a RGB FP16 buffer.
      Now i can't use the camera viewspace matrix to transform the normals into viewspace as the cameras position isn't set at (0,0,0), thus skewing the result.
      So what i did is to create a new viewmatrix specifically for this normal without the position at vec3(0,0,0);
      //"camera" is the camera which was used for rendering the normal buffer renderer.setUniform4m(ressources->shaderSSAO->getUniform("uNormalViewMatrix"), glmExt::createViewMatrix(glm::vec3(0,0,0),camera.getForward(),camera.getUp())//parameters are (position,forwardVector,upVector) ); Though i have the feeling this is the wrong approach. Is this right or is there a better/correct way of transforming a world space normal into viewspace?
    • By HawkDeath
      I'm trying mix two textures using own shader system, but I have a problem (I think) with uniforms.
      Code: https://github.com/HawkDeath/shader/tree/test
      To debug I use RenderDocs, but I did not receive good results. In the first attachment is my result, in the second attachment is what should be.
      PS. I base on this tutorial https://learnopengl.com/Getting-started/Textures.

    • By norman784
      I'm having issues loading textures, as I'm clueless on how to handle / load images maybe I missing something, but the past few days I just google a lot to try to find a solution. Well theres two issues I think, one I'm using Kotlin Native (EAP) and OpenGL wrapper / STB image, so I'm not quite sure wheres the issue, if someone with more experience could give me some hints on how to solve this issue?
      The code is here, if I'm not mistaken the workflow is pretty straight forward, stbi_load returns the pixels of the image (as char array or byte array) and you need to pass those pixels directly to glTexImage2D, so a I'm missing something here it seems.
    • By Hashbrown
      I've noticed in most post processing tutorials several shaders are used one after another: one for bloom, another for contrast, and so on. For example: 
      postprocessing.quad.bind() // Effect 1 effect1.shader.bind(); postprocessing.texture.bind(); postprocessing.quad.draw(); postprocessing.texture.unbind(); effect1.shader.unbind(); // Effect 2 effect2.shader.bind(); // ...and so on postprocessing.quad.unbind() Is this good practice, how many shaders can I bind and unbind before I hit performance issues? I'm afraid I don't know what the good practices are in open/webGL regarding binding and unbinding resources. 
      I'm guessing binding many shaders at post processing is okay since the scene has already been updated and I'm just working on a quad and texture at that moment. Or is it more optimal to put shader code in chunks and bind less frequently? I'd love to use several shaders at post though. 
      Another example of what I'm doing at the moment:
      1) Loop through GameObjects, bind its phong shader (send color, shadow, spec, normal samplers), unbind all.
      2) At post: bind post processor quad, and loop/bind through different shader effects, and so on ...
      Thanks all! 
    • By phil67rpg
      void collision(int v) { collision_bug_one(0.0f, 10.0f); glutPostRedisplay(); glutTimerFunc(1000, collision, 0); } void coll_sprite() { if (board[0][0] == 1) { collision(0); flag[0][0] = 1; } } void erase_sprite() { if (flag[0][0] == 1) { glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3f(0.0f, 10.0f, 0.0f); glVertex3f(0.0f, 9.0f, 0.0f); glVertex3f(1.0f, 9.0f, 0.0f); glVertex3f(1.0f, 10.0f, 0.0f); glEnd(); } } I am using glutTimerFunc to wait a small amount of time to display a collision sprite before I black out the sprite. unfortunately my code only blacks out the said sprite without drawing the collision sprite, I have done a great deal of research on the glutTimerFunc and  animation.
  • Advertisement
  • Popular Now

  • Forum Statistics

    • Total Topics
    • Total Posts

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!