// WinProc LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { switch(message) { case WM_SYSKEYDOWN: // Toggle on ALT + ENTER if(wparam == VK_RETURN && (lparam & (1 << 29))) { g3D->toggleFullScreen(); // We need to reset our view g3D->setViewMatrix(CPos(0.0f, 0.0f, -5.0f), CPos(0.0f, 0.0f, 0.0f)); } break; // Allow other system keys to be handled by DefWindowProc() case WM_KEYDOWN: // If the user presses ESC, close the app if(wparam == VK_ESCAPE) SendMessage(hwnd, WM_CLOSE, 0, 0); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wparam, lparam); }
// WinProc LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { // Constant amounts to move the origin of the ray by const CVector kXAxisMoveAmt(0.05f, 0.0f, 0.0f); const CVector kYAxisMoveAmt(0.0f, 0.05f, 0.0f); switch(message) { case WM_SYSKEYDOWN: // Toggle on ALT + ENTER if(wparam == VK_RETURN && (lparam & (1 << 29))) { g3D->toggleFullScreen(); g3D->setViewMatrix(CPos(0,1,-3.0f), CPos(0,0,0)); // Reset the view of our scene return 0; } break; // Allow other system keys to be handled by DefWindowProc() case WM_KEYDOWN: // If we get a key down message, do stuff switch(wparam) { case VK_ESCAPE: // If they push ESC, close the app SendMessage(hwnd, WM_CLOSE, 0, 0); break; case VK_LEFT: // Move the origin of the ray to the left (-X axis) gRay.setOrigin(gRay.getOrigin() - kXAxisMoveAmt); break; case VK_RIGHT: // Move the origin of the ray to the right (+X axis) gRay.setOrigin(gRay.getOrigin() + kXAxisMoveAmt); break; case VK_DOWN: // Move the origin of the ray down (-Y axis) gRay.setOrigin(gRay.getOrigin() - kYAxisMoveAmt); break; case VK_UP: // Move the origin of the ray up (+Y axis) gRay.setOrigin(gRay.getOrigin() + kYAxisMoveAmt); break; } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wparam, lparam); }
CPos IGUIObject::GetMousePos() const { if (GetGUI()) return GetGUI()->m_MousePos; return CPos(); }
CPos CAxisAlgnBB::getCorner(int which) { // Make sure "which" is valid assert((which >= 0) && (which < kNumCorners)); // Return the corner return CPos((which & 1) ? mMax.x : mMin.x, (which & 2) ? mMax.y : mMin.y, (which & 4) ? mMax.z : mMin.z); }
bool CMiniMap::MouseOver() { // Get the mouse position. CPos mousePos = GetMousePos(); // Get the position of the center of the minimap. CPos minimapCenter = CPos(m_CachedActualSize.left + m_CachedActualSize.GetWidth() / 2.0, m_CachedActualSize.bottom - m_CachedActualSize.GetHeight() / 2.0); // Take the magnitude of the difference of the mouse position and minimap center. double distFromCenter = sqrt(pow((mousePos.x - minimapCenter.x), 2) + pow((mousePos.y - minimapCenter.y), 2)); // If the distance is less then the radius of the minimap (half the width) the mouse is over the minimap. if (distFromCenter < m_CachedActualSize.GetWidth() / 2.0) return true; else return false; }
// WinProc LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { const float kMoveAmt = 0.05f; // Amount to move light by switch(message) { case WM_SYSKEYDOWN: // Toggle on ALT + ENTER if(wparam == VK_RETURN && (lparam & (1 << 29))) { // Shut down are render texture and render target gRenderTarget.deinit(); g3D->toggleFullScreen(); // Toggle! // Reinitialize the render texture and target gRenderTarget.init(256, 256, D3DFMT_A8R8G8B8, D3DFMT_D24S8); g3D->setViewMatrix(kEyePos, CPos(0.0f, 0.0f, 0.0f)); // Reset the view of our scene return 0; } break; // Allow other system keys to be handled by DefWindowProc() case WM_KEYDOWN: switch(wparam) { case VK_ESCAPE: SendMessage(hwnd, WM_CLOSE, 0, 0); break; case VK_F8: gToggle = !gToggle; break; } return 0; case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, message, wparam, lparam); }
void CParticle::process(float dt) { // If particle is dead, reset it's position if(isAlive() == false) { mLife = RAND(0.0f, 2.0f); // Make it alive again mPos = CPos(0,0,0); // Reposition to the emission point return; } // Apply velocity mPos.x += mVel.x * dt; mPos.y += mVel.y * dt; mPos.z += mVel.z * dt; // Apply gravity mPos.y += kParticleGravity * dt; mLife -= dt; // Decrease particle's life span // Apply rotation by "angle" per second if applicable if(mAngle != 0.0f) mTexture.setRotation(mTexture.getRotAngle() + (mAngle * dt)); }
SGUIText CGUI::GenerateText(const CGUIString &string, const CStrW& FontW, const float &Width, const float &BufferZone, const IGUIObject *pObject) { SGUIText Text; // object we're generating CStrIntern Font(FontW.ToUTF8()); if (string.m_Words.size() == 0) return Text; float x=BufferZone, y=BufferZone; // drawing pointer int from=0; bool done=false; bool FirstLine = true; // Necessary because text in the first line is shorter // (it doesn't count the line spacing) // Images on the left or the right side. std::vector<SGenerateTextImage> Images[2]; int pos_last_img=-1; // Position in the string where last img (either left or right) were encountered. // in order to avoid duplicate processing. // Easier to read. bool WordWrapping = (Width != 0); // get the alignment type for the control we are computing the text for since // we are computing the horizontal alignment in this method in order to not have // to run through the TextCalls a second time in the CalculateTextPosition method again EAlign align; GUI<EAlign>::GetSetting(pObject, "text_align", align); // Go through string word by word for (int i=0; i<(int)string.m_Words.size()-1 && !done; ++i) { // Pre-process each line one time, so we know which floating images // will be added for that line. // Generated stuff is stored in Feedback. CGUIString::SFeedback Feedback; // Preliminary line_height, used for word-wrapping with floating images. float prelim_line_height=0.f; // Width and height of all text calls generated. string.GenerateTextCall(Feedback, Font, string.m_Words[i], string.m_Words[i+1], FirstLine); // Loop through our images queues, to see if images has been added. // Check if this has already been processed. // Also, floating images are only applicable if Word-Wrapping is on if (WordWrapping && i > pos_last_img) { // Loop left/right for (int j=0; j<2; ++j) { for (std::vector<CStr>::const_iterator it = Feedback.m_Images[j].begin(); it != Feedback.m_Images[j].end(); ++it) { SGUIText::SSpriteCall SpriteCall; SGenerateTextImage Image; // Y is if no other floating images is above, y. Else it is placed // after the last image, like a stack downwards. float _y; if (!Images[j].empty()) _y = std::max(y, Images[j].back().m_YTo); else _y = y; // Get Size from Icon database SGUIIcon icon = GetIcon(*it); CSize size = icon.m_Size; Image.SetupSpriteCall((j==CGUIString::SFeedback::Left), SpriteCall, Width, _y, size, icon.m_SpriteName, BufferZone, icon.m_CellID); // Check if image is the lowest thing. Text.m_Size.cy = std::max(Text.m_Size.cy, Image.m_YTo); Images[j].push_back(Image); Text.m_SpriteCalls.push_back(SpriteCall); } } } pos_last_img = std::max(pos_last_img, i); x += Feedback.m_Size.cx; prelim_line_height = std::max(prelim_line_height, Feedback.m_Size.cy); // If Width is 0, then there's no word-wrapping, disable NewLine. if ((WordWrapping && (x > Width-BufferZone || Feedback.m_NewLine)) || i == (int)string.m_Words.size()-2) { // Change 'from' to 'i', but first keep a copy of its value. int temp_from = from; from = i; static const int From=0, To=1; //int width_from=0, width_to=width; float width_range[2]; width_range[From] = BufferZone; width_range[To] = Width - BufferZone; // Floating images are only applicable if word-wrapping is enabled. if (WordWrapping) { // Decide width of the line. We need to iterate our floating images. // this won't be exact because we're assuming the line_height // will be as our preliminary calculation said. But that may change, // although we'd have to add a couple of more loops to try straightening // this problem out, and it is very unlikely to happen noticeably if one // structures his text in a stylistically pure fashion. Even if not, it // is still quite unlikely it will happen. // Loop through left and right side, from and to. for (int j=0; j<2; ++j) { for (std::vector<SGenerateTextImage>::const_iterator it = Images[j].begin(); it != Images[j].end(); ++it) { // We're working with two intervals here, the image's and the line height's. // let's find the union of these two. float union_from, union_to; union_from = std::max(y, it->m_YFrom); union_to = std::min(y+prelim_line_height, it->m_YTo); // The union is not empty if (union_to > union_from) { if (j == From) width_range[From] = std::max(width_range[From], it->m_Indentation); else width_range[To] = std::min(width_range[To], Width - it->m_Indentation); } } } } // Reset X for the next loop x = width_range[From]; // Now we'll do another loop to figure out the height and width of // the line (the height of the largest character and the width is // the sum of all of the individual widths). This // couldn't be determined in the first loop (main loop) // because it didn't regard images, so we don't know // if all characters processed, will actually be involved // in that line. float line_height=0.f; float line_width=0.f; for (int j=temp_from; j<=i; ++j) { // We don't want to use Feedback now, so we'll have to use // another. CGUIString::SFeedback Feedback2; // Don't attach object, it'll suppress the errors // we want them to be reported in the final GenerateTextCall() // so that we don't get duplicates. string.GenerateTextCall(Feedback2, Font, string.m_Words[j], string.m_Words[j+1], FirstLine); // Append X value. x += Feedback2.m_Size.cx; if (WordWrapping && x > width_range[To] && j!=temp_from && !Feedback2.m_NewLine) break; // Let line_height be the maximum m_Height we encounter. line_height = std::max(line_height, Feedback2.m_Size.cy); line_width += Feedback2.m_Size.cx; if (WordWrapping && Feedback2.m_NewLine) break; } float dx = 0.f; // compute offset based on what kind of alignment switch (align) { case EAlign_Left: // don't add an offset dx = 0.f; break; case EAlign_Center: dx = ((width_range[To] - width_range[From]) - line_width) / 2; break; case EAlign_Right: dx = width_range[To] - line_width; break; default: debug_warn(L"Broken EAlign in CGUI::GenerateText()"); break; } // Reset x once more x = width_range[From]; // Move down, because font drawing starts from the baseline y += line_height; // Do the real processing now for (int j=temp_from; j<=i; ++j) { // We don't want to use Feedback now, so we'll have to use // another one. CGUIString::SFeedback Feedback2; // Defaults string.GenerateTextCall(Feedback2, Font, string.m_Words[j], string.m_Words[j+1], FirstLine, pObject); // Iterate all and set X/Y values // Since X values are not set, we need to make an internal // iteration with an increment that will append the internal // x, that is what x_pointer is for. float x_pointer=0.f; std::vector<SGUIText::STextCall>::iterator it; for (it = Feedback2.m_TextCalls.begin(); it != Feedback2.m_TextCalls.end(); ++it) { it->m_Pos = CPos(dx + x + x_pointer, y); x_pointer += it->m_Size.cx; if (it->m_pSpriteCall) { it->m_pSpriteCall->m_Area += it->m_Pos - CSize(0,it->m_pSpriteCall->m_Area.GetHeight()); } } // Append X value. x += Feedback2.m_Size.cx; Text.m_Size.cx = std::max(Text.m_Size.cx, x+BufferZone); // The first word overrides the width limit, what we // do, in those cases, are just drawing that word even // though it'll extend the object. if (WordWrapping) // only if word-wrapping is applicable { if (Feedback2.m_NewLine) { from = j+1; // Sprite call can exist within only a newline segment, // therefore we need this. Text.m_SpriteCalls.insert(Text.m_SpriteCalls.end(), Feedback2.m_SpriteCalls.begin(), Feedback2.m_SpriteCalls.end()); break; } else if (x > width_range[To] && j==temp_from) { from = j+1; // do not break, since we want it to be added to m_TextCalls } else if (x > width_range[To]) { from = j; break; } } // Add the whole Feedback2.m_TextCalls to our m_TextCalls. Text.m_TextCalls.insert(Text.m_TextCalls.end(), Feedback2.m_TextCalls.begin(), Feedback2.m_TextCalls.end()); Text.m_SpriteCalls.insert(Text.m_SpriteCalls.end(), Feedback2.m_SpriteCalls.begin(), Feedback2.m_SpriteCalls.end()); if (j == (int)string.m_Words.size()-2) done = true; } // Reset X x = 0.f; // Update height of all Text.m_Size.cy = std::max(Text.m_Size.cy, y+BufferZone); FirstLine = false; // Now if we entered as from = i, then we want // i being one minus that, so that it will become // the same i in the next loop. The difference is that // we're on a new line now. i = from-1; } } return Text; }
// WinMain int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WinProc; wndclassex.hInstance = hinstance; wndclassex.lpszClassName = kClassName; wndclassex.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED); RegisterClassEx(&wndclassex); // Register the WNDCLASSEX RECT rect = { 0, 0, kWinWid, kWinHgt }; // Desired window client rect DWORD winStyleEx = WS_EX_CLIENTEDGE; DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; // Adjust window rect so it gives us our desired client rect when we // create the window AdjustWindowRectEx(&rect, winStyle, false, winStyleEx); // Create the window hwnd = CreateWindowEx(winStyleEx, // Window extended style kClassName, "www.GameTutorials.com -- Ray and Plane Collision", winStyle, // Window style CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, // Window width rect.bottom - rect.top, // Window height NULL, NULL, hinstance, NULL); // Init our global 3D object if(g3D->init(hwnd) == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint // Get the client rect and make sure our client is the size we want GetClientRect(hwnd, &rect); assert(rect.right == kWinWid && rect.bottom == kWinHgt); // We set up our projection matrix once because it will never change g3D->setProjMatrix(DEG2RAD(60), (float)rect.right / (float)rect.bottom, 1.0f, 8192.0f); // We set our view matrix once because it will never change g3D->setViewMatrix(CPos(0,1,-3.0f), CPos(0,0,0)); ShowWindow(hwnd, ishow); UpdateWindow(hwnd); // While the app is running while(1) { // If the OS has messages for us, handle them if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else if(LockFrameRate()) // If it is time to draw, do so { g3D->begin(); // Begin drawing g3D->clear(); // Clear the screen // Draw our ray gRay.render(D3DCOLOR_ARGB(255,225,225,0)); // Draw our plane in GREEN if our ray intersects with it if(gPlane.intersect(gRay)) gPlane.render(D3DCOLOR_ARGB(255,25,225,25)); else // Otherwise draw it in RED gPlane.render(D3DCOLOR_ARGB(255,225,25,25)); g3D->end(); // Finish drawing } else Sleep(1); // Give the OS a little bit of time to process other things } // end of while(1) g3D->deinit(); // Free up CD3DObj UnregisterClass(kClassName,hinstance); // Free up WNDCLASSEX return EXIT_SUCCESS; // Application was a success }
CPos CRect::TopLeft() const { return CPos(left, top); }
CPos CRect::BottomLeft() const { return CPos(left, bottom); }
// Standard WinMain int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WinProc; wndclassex.hInstance = hinstance; wndclassex.lpszClassName = kClassName; wndclassex.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED); RegisterClassEx(&wndclassex); // Register WNDCLASSEX RECT rect = { 0, 0, kWinWid, kWinHgt }; // Desired window client rect DWORD winStyleEx = WS_EX_CLIENTEDGE; DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; // Adjust window rect so it gives us our desired client rect when we // create the window AdjustWindowRectEx(&rect, winStyle, false, winStyleEx); // Create the window hwnd = CreateWindowEx(winStyleEx, // Window extended style kClassName, "www.GameTutorials.com -- Rotating Cube", winStyle, // Window style CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hinstance, NULL); // Init our global 3D object if(g3D->init(hwnd) == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint // Get the client rect and make sure our client is the size we want GetClientRect(hwnd, &rect); assert(rect.right == kWinWid && rect.bottom == kWinHgt); // Set up our projection matrix once because it will not change g3D->setProjMatrix(DEG2RAD(60), (float)kWinWid / (float)kWinHgt, 1.0f, 8192.0f); // We set up our view matrix once because it will never change g3D->setViewMatrix(CPos(0.0f, 0.0f, -5.0f), CPos(0.0f, 0.0f, 0.0f)); ShowWindow(hwnd, ishow); UpdateWindow(hwnd); while(1) // While the app is running... { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Handle messages from the OS { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else if(LockFrameRate()) // If it's time to render, do so { DrawAndRotateCube(); } else Sleep(1); // Otherwise give the OS some time to process other things } // end of while(1) g3D->deinit(); // Free up the D3D object UnregisterClass(kClassName,hinstance); // Free up WNDCLASSEX return EXIT_SUCCESS; // Application was a success }
// WinProc LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { const float kMoveAmt = 0.05f; // Amount to move light by switch(message) { case WM_SYSKEYDOWN: // Toggle on ALT + ENTER if(wparam == VK_RETURN && (lparam & (1 << 29))) { // Shut down are render texture and render target gShadowMap.deinit(); gRenderTarget.deinit(); g3D->toggleFullScreen(); // Toggle! // Reinitialize the render texture and target gShadowMap.createRenderTexture(512, 512, D3DFMT_R32F); gRenderTarget.init(512, 512, D3DFMT_R32F, D3DFMT_D24S8); g3D->setViewMatrix(kEyePos, CPos(0.0f, 0.0f, 0.0f)); // Reset the view of our scene return 0; } break; // Allow other system keys to be handled by DefWindowProc() case WM_KEYDOWN: switch(wparam) { case VK_LEFT: // Move the light along the -X axis gLightPos.x -= kMoveAmt; break; case VK_RIGHT: // Move the light along the +X axis gLightPos.x += kMoveAmt; break; case VK_UP: // Move the light along the +Z axis gLightPos.z += kMoveAmt; break; case VK_DOWN: // Move the light along the -Z axis gLightPos.z -= kMoveAmt; break; case VK_ESCAPE: SendMessage(hwnd, WM_CLOSE, 0, 0); break; } return 0; case WM_DESTROY: { PostQuitMessage(0); return 0; } } return DefWindowProc(hwnd, message, wparam, lparam); }
// Main program int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WinProc; wndclassex.hInstance = hinstance; wndclassex.lpszClassName = kClassName; wndclassex.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED); RegisterClassEx(&wndclassex); // Register the WNDCLASSEX RECT rect = { 0, 0, kWinWid, kWinHgt }; // Desired window client rect DWORD winStyleEx = WS_EX_CLIENTEDGE; DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; // Adjust window rect so it gives us our desired client rect when we // create the window AdjustWindowRectEx(&rect, winStyle, false, winStyleEx); // Create the window hwnd = CreateWindowEx(winStyleEx, // Window extended style kClassName, "www.GameTutorials.com -- DirectX Mesh", winStyle, // Window style CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hinstance, NULL); // Get the client rect and make sure our client is the size we want GetClientRect(hwnd, &rect); assert(rect.right == kWinWid && rect.bottom == kWinHgt); // Init our global 3D object if(g3D->init(hwnd) == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint // Create the sphere if(!CreateSphere(0.5f, D3DCOLOR_XRGB(0,25,225), &gSphere)) return false; // Couldn't create the sphere... Something very bad happened... // Create the torus if(!CreateTorus(0.5f, 1.0f, D3DCOLOR_XRGB(225,25,25), &gTorus)) return false; // Couldn't create the sphere... Something very bad happened... // Set up our projection matrix once because it will not change g3D->setProjMatrix(DEG2RAD(60), (float)kWinWid / (float)kWinHgt, 1.0f, 8192.0f); // We set up our view matrix once because it will never change g3D->setViewMatrix(CPos(0.0f, 0.0f, -5.0f), CPos(0.0f, 0.0f, 0.0f)); ShowWindow(hwnd, ishow); UpdateWindow(hwnd); // While the app is running... while(1) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // If the OS has a message for us { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else if(LockFrameRate()) // Else, if it's time to draw { g3D->begin(); // Begin the frame g3D->clear(); // Clear the back buffer static float angle = 0; D3DXMATRIX wMat; // Set "wMat" to the identity matrix, then set the world matrix // to "wMat" so the sphere is centered in the world D3DXMatrixIdentity(&wMat); g3D->setWorldMatrix(&wMat); g3D->render(gSphere); // Draw the sphere // Set "wMat" to a rotation around the X, Y, and Z axis, then // set the world matrix to "wMat" so the torus rotates around all // three axises D3DXMatrixRotationYawPitchRoll(&wMat, DEG2RAD(angle), DEG2RAD(angle), DEG2RAD(angle)); g3D->setWorldMatrix(&wMat); g3D->render(gTorus); // Draw the torus ++angle; // Update the amount to rotate the torus by g3D->end(); // End the frame } else Sleep(1); // Otherwise, give the OS some time to process other programs } // end of while(1) gSphere->Release(); // Free up the sphere gTorus->Release(); // Free up the torus g3D->deinit(); // Free up the D3D object UnregisterClass(kClassName,hinstance); // Free up WNDCLASSEX return EXIT_SUCCESS; // Application was a success }
// - CPos CPos::operator - (const CSize& a) const { return CPos(x-a.cx, y-a.cy); }
// - CPos CPos::operator - (const CPos& a) const { return CPos(x-a.x, y-a.y); }
// + CPos CPos::operator + (const CSize& a) const { return CPos(x+a.cx, y+a.cy); }
// + CPos CPos::operator + (const CPos& a) const { return CPos(x+a.x, y+a.y); }
// - (the unary operator) CPos CPos::operator - (void) const { return CPos(-x, -y); }
CPos CRect::CenterPoint() const { return CPos((left+right)/2.f, (top+bottom)/2.f); }
CPos CRect::BottomRight() const { return CPos(right, bottom); }
InReaction CGUI::HandleEvent(const SDL_Event_* ev) { InReaction ret = IN_PASS; if (ev->ev.type == SDL_HOTKEYDOWN) { const char* hotkey = static_cast<const char*>(ev->ev.user.data1); std::map<CStr, std::vector<IGUIObject*> >::iterator it = m_HotkeyObjects.find(hotkey); if (it != m_HotkeyObjects.end()) { for (size_t i = 0; i < it->second.size(); ++i) { it->second[i]->SendEvent(GUIM_PRESSED, "press"); } } } else if (ev->ev.type == SDL_MOUSEMOTION) { // Yes the mouse position is stored as float to avoid // constant conversions when operating in a // float-based environment. m_MousePos = CPos((float)ev->ev.motion.x, (float)ev->ev.motion.y); SGUIMessage msg(GUIM_MOUSE_MOTION); GUI<SGUIMessage>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject, &IGUIObject::HandleMessage, msg); } // Update m_MouseButtons. (BUTTONUP is handled later.) else if (ev->ev.type == SDL_MOUSEBUTTONDOWN) { switch (ev->ev.button.button) { case SDL_BUTTON_LEFT: case SDL_BUTTON_RIGHT: case SDL_BUTTON_MIDDLE: m_MouseButtons |= Bit<unsigned int>(ev->ev.button.button); break; default: break; } } // Update m_MousePos (for delayed mouse button events) CPos oldMousePos = m_MousePos; if (ev->ev.type == SDL_MOUSEBUTTONDOWN || ev->ev.type == SDL_MOUSEBUTTONUP) { m_MousePos = CPos((float)ev->ev.button.x, (float)ev->ev.button.y); } // Only one object can be hovered IGUIObject *pNearest = NULL; // TODO Gee: (2004-09-08) Big TODO, don't do the below if the SDL_Event is something like a keypress! try { PROFILE( "mouse events" ); // TODO Gee: Optimizations needed! // these two recursive function are quite overhead heavy. // pNearest will after this point at the hovered object, possibly NULL pNearest = FindObjectUnderMouse(); // Is placed in the UpdateMouseOver function //if (ev->ev.type == SDL_MOUSEMOTION && pNearest) // pNearest->ScriptEvent("mousemove"); // Now we'll call UpdateMouseOver on *all* objects, // we'll input the one hovered, and they will each // update their own data and send messages accordingly GUI<IGUIObject*>::RecurseObject(GUIRR_HIDDEN | GUIRR_GHOST, m_BaseObject, &IGUIObject::UpdateMouseOver, pNearest); if (ev->ev.type == SDL_MOUSEBUTTONDOWN) { switch (ev->ev.button.button) { case SDL_BUTTON_LEFT: // Focus the clicked object (or focus none if nothing clicked on) SetFocusedObject(pNearest); if (pNearest) ret = pNearest->SendEvent(GUIM_MOUSE_PRESS_LEFT, "mouseleftpress"); break; case SDL_BUTTON_RIGHT: if (pNearest) ret = pNearest->SendEvent(GUIM_MOUSE_PRESS_RIGHT, "mouserightpress"); break; #if !SDL_VERSION_ATLEAST(2, 0, 0) case SDL_BUTTON_WHEELDOWN: // wheel down if (pNearest) ret = pNearest->SendEvent(GUIM_MOUSE_WHEEL_DOWN, "mousewheeldown"); break; case SDL_BUTTON_WHEELUP: // wheel up if (pNearest) ret = pNearest->SendEvent(GUIM_MOUSE_WHEEL_UP, "mousewheelup"); break; #endif default: break; } } #if SDL_VERSION_ATLEAST(2, 0, 0) else if (ev->ev.type == SDL_MOUSEWHEEL) { if (ev->ev.wheel.y < 0) { if (pNearest) ret = pNearest->SendEvent(GUIM_MOUSE_WHEEL_DOWN, "mousewheeldown"); } else if (ev->ev.wheel.y > 0) { if (pNearest) ret = pNearest->SendEvent(GUIM_MOUSE_WHEEL_UP, "mousewheelup"); } } #endif else if (ev->ev.type == SDL_MOUSEBUTTONUP) { switch (ev->ev.button.button) { case SDL_BUTTON_LEFT: if (pNearest) { double timeElapsed = timer_Time() - pNearest->m_LastClickTime[SDL_BUTTON_LEFT]; pNearest->m_LastClickTime[SDL_BUTTON_LEFT] = timer_Time(); //Double click? if (timeElapsed < SELECT_DBLCLICK_RATE) { ret = pNearest->SendEvent(GUIM_MOUSE_DBLCLICK_LEFT, "mouseleftdoubleclick"); } else { ret = pNearest->SendEvent(GUIM_MOUSE_RELEASE_LEFT, "mouseleftrelease"); } } break; case SDL_BUTTON_RIGHT: if (pNearest) { double timeElapsed = timer_Time() - pNearest->m_LastClickTime[SDL_BUTTON_RIGHT]; pNearest->m_LastClickTime[SDL_BUTTON_RIGHT] = timer_Time(); //Double click? if (timeElapsed < SELECT_DBLCLICK_RATE) { ret = pNearest->SendEvent(GUIM_MOUSE_DBLCLICK_RIGHT, "mouserightdoubleclick"); } else { ret = pNearest->SendEvent(GUIM_MOUSE_RELEASE_RIGHT, "mouserightrelease"); } } break; } // Reset all states on all visible objects GUI<>::RecurseObject(GUIRR_HIDDEN, m_BaseObject, &IGUIObject::ResetStates); // It will have reset the mouse over of the current hovered, so we'll // have to restore that if (pNearest) pNearest->m_MouseHovering = true; } } catch (PSERROR_GUI& e) { UNUSED2(e); debug_warn(L"CGUI::HandleEvent error"); // TODO Gee: Handle } // BUTTONUP's effect on m_MouseButtons is handled after // everything else, so that e.g. 'press' handlers (activated // on button up) see which mouse button had been pressed. if (ev->ev.type == SDL_MOUSEBUTTONUP) { switch (ev->ev.button.button) { case SDL_BUTTON_LEFT: case SDL_BUTTON_RIGHT: case SDL_BUTTON_MIDDLE: m_MouseButtons &= ~Bit<unsigned int>(ev->ev.button.button); break; default: break; } } // Restore m_MousePos (for delayed mouse button events) if (ev->ev.type == SDL_MOUSEBUTTONDOWN || ev->ev.type == SDL_MOUSEBUTTONUP) { m_MousePos = oldMousePos; } // Handle keys for input boxes if (GetFocusedObject()) { if ( (ev->ev.type == SDL_KEYDOWN && ev->ev.key.keysym.sym != SDLK_ESCAPE && !g_keys[SDLK_LCTRL] && !g_keys[SDLK_RCTRL] && !g_keys[SDLK_LALT] && !g_keys[SDLK_RALT]) || ev->ev.type == SDL_HOTKEYDOWN ) { ret = GetFocusedObject()->ManuallyHandleEvent(ev); } // else will return IN_PASS because we never used the button. } return ret; }
// Main window program int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WinProc; wndclassex.hInstance = hinstance; wndclassex.lpszClassName = kClassName; wndclassex.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED); RegisterClassEx(&wndclassex); // Register the WNDCLASSEX RECT rect = { 0, 0, kWinWid, kWinHgt }; // Desired window client rect DWORD winStyleEx = WS_EX_CLIENTEDGE; DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; // Adjust window rect so it gives us our desired client rect when we // create the window AdjustWindowRectEx(&rect, winStyle, false, winStyleEx); // Create the window hwnd = CreateWindowEx(winStyleEx, // Window extended style kClassName, "www.GameTutorials.com -- D3D Vertex Buffers", winStyle, // Window style CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hinstance, NULL); // Get the client rect and make sure our client is the size we want GetClientRect(hwnd, &rect); assert(rect.right == kWinWid && rect.bottom == kWinHgt); // Init our global 3D object if(g3D->init(hwnd) == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint if(gTexture.load("Texture.jpg") == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint // Create and set the vertex buffer in our CD3DMesh object if(gQuad.setVertexData(gQuadVertexData, kMaxVerts) == false) return EXIT_FAILURE; // This is bad! The tutorial is officially broken // Set the perspective matrix once because it will never change g3D->setProjMatrix(DEG2RAD(60), (float)rect.right / (float)rect.bottom, 1.0f, 8192.0f); // We set up our view matrix once because it will never change g3D->setViewMatrix(CPos(0.0f, 0.0f, -5.0f), CPos(0.0f, 0.0f, 0.0f)); ShowWindow(hwnd, ishow); UpdateWindow(hwnd); while(1) // While the app is running { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Handle messages from the OS { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else if(LockFrameRate()) // If it is time to draw, do so { g3D->begin(); // Begin the scene g3D->clear(); // Clear the Z-buffer gTexture.select(); // Select the texture to be used // Render the textured quad gQuad.render(); g3D->end(); // End the scene } else Sleep(1); // Give the OS a slice of time to process other things } // end of while(1) g3D->deinit(); // Free up CD3DObj UnregisterClass(kClassName, hinstance); // Free up WNDCLASSEX return EXIT_SUCCESS; // Application was a success }
// Our Win32 main int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; // Handle to our window MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WinProc; wndclassex.hInstance = hinstance; wndclassex.lpszClassName = kClassName; wndclassex.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED); RegisterClassEx(&wndclassex); // Register the WNDCLASSEX RECT rect = { 0, 0, kWinWid, kWinHgt }; // Desired window client rect DWORD winStyleEx = WS_EX_CLIENTEDGE; DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; // Adjust window rect so it gives us our desired client rect when we // create the window AdjustWindowRectEx(&rect, winStyle, false, winStyleEx); // Create the window hwnd = CreateWindowEx(winStyleEx, kClassName, "www.GameTutorials.com -- Render Targets", winStyle, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hinstance, NULL); // Get the client rect and make sure our client is the size we want GetClientRect(hwnd, &rect); assert(rect.right == kWinWid && rect.bottom == kWinHgt); // Init our global 3D object if(g3D->init(hwnd) == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint if(!gBlurTexture1.createRenderTexture(256, 256, D3DFMT_A8R8G8B8)) return false; // Couldn't create a off screen texture to render to if(!gBlurTexture2.createRenderTexture(256, 256, D3DFMT_A8R8G8B8)) return false; // Couldn't create a off screen texture to render to if(!gDiffTex.load("texture.jpg")) return false; if(!gRenderTarget.init(256, 256, D3DFMT_A8R8G8B8, D3DFMT_D24S8)) return false; // Couldn't create a render texture... Does your video card support this? Make3x3GuassianDistribution(); // Set up our projection matrix once because it will not change g3D->setProjMatrix(DEG2RAD(60), 1.0f, 2048.0f); // We set up our view matrix once because it will never change g3D->setViewMatrix(kEyePos, CPos(0.0f, 0.0f, 0.0f)); g3D->mShader->SetFloatArray("gEyePos", &kEyePos.x, 3); // Set the camera's eye position g3D->mShader->SetFloatArray("gBlurWeights", gBlurWeights, 9); // Gaussian blur weights // Show and update the window ShowWindow(hwnd, ishow); UpdateWindow(hwnd); while(1) // While the app is alive { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // If the OS has a message for us { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else if(LockFrameRate()) // Else, if it's time to draw { // Render the off screen texture (created directly above) to another // off screen texture using a Gaussian blur if(gToggle) Combined(); else RenderSobelFilter(); // Render the two textures to the screen RenderScene(); } else Sleep(1); // Otherwise, give the OS some time to process other programs } // end of while(1) g3D->deinit(); // Free up the D3D object UnregisterClass(kClassName,hinstance); // Free up WNDCLASSEX return EXIT_SUCCESS; // Application was a success }
// Our Win32 main int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; // Handle to our window MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WinProc; wndclassex.hInstance = hinstance; wndclassex.lpszClassName = kClassName; wndclassex.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED); RegisterClassEx(&wndclassex); // Register the WNDCLASSEX RECT rect = { 0, 0, kWinWid, kWinHgt }; // Desired window client rect DWORD winStyleEx = WS_EX_CLIENTEDGE; DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME; // Adjust window rect so it gives us our desired client rect when we // create the window AdjustWindowRectEx(&rect, winStyle, false, winStyleEx); // Create the window hwnd = CreateWindowEx(winStyleEx, kClassName, "www.GameTutorials.com -- Shadow Mapping (HLSL)", winStyle, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hinstance, NULL); // Get the client rect and make sure our client is the size we want GetClientRect(hwnd, &rect); assert(rect.right == kWinWid && rect.bottom == kWinHgt); // Init our global 3D object if(g3D->init(hwnd) == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint if(!CreateSphere(0.05f, D3DCOLOR_XRGB(255,255,0), &gLight)) return false; // Couldn't create the sphere... Something very bad happened... if(!CreateSphere(0.75f, D3DCOLOR_XRGB(0,128,64), &gSphere)) return false; // Couldn't create the sphere... Something very bad happened... if(!CreateBox(1.0f, 2.0f, 1.0f, D3DCOLOR_XRGB(0, 128, 64), &gBox)) return false; // Couldn't create the box... This isn't good! if(!CreateBox(16.0f, 0.05f, 16.0f, D3DCOLOR_XRGB(225, 225, 255), &gGround)) return false; // Couldn't create the ground... Time to bail if(!gShadowMap.createRenderTexture(512, 512, D3DFMT_R32F)) return false; // Couldn't create a shadow map texture. Your video card // probably doesn't support the D3DFMT_R32F format. You will need a beefier card to // run this tutorial if(!gRenderTarget.init(512, 512, D3DFMT_R32F, D3DFMT_D24S8)) return false; // Couldn't create a shadow map texture. Your video card doesn't support render // targets or it probably doesn't support the D3DFMT_R32F format. You will need // a beefier card to run this tutorial // Set up our projection matrix once because it will not change g3D->setProjMatrix(DEG2RAD(60), 1.0f, 2048.0f); // We set up our view matrix once because it will never change g3D->setViewMatrix(kEyePos, CPos(0.0f, 0.0f, 0.0f)); D3DXMATRIXA16 projMat; // Create texture projection matrix D3DXMatrixPerspectiveFovLH(&projMat, DEG2RAD(60), 1.0f, 0.1f, 100.0f); // Set data in our shader that will never change g3D->mShader->SetFloatArray("gLightProjMat", &projMat._11, 16); g3D->mShader->SetFloatArray("gEyePos", &kEyePos.x, 3); // Set the camera's eye position g3D->mShader->SetFloatArray("gDiffuse", &kDiffuse.r, 3); // Lights diffuse color g3D->mShader->SetFloatArray("gSpecular", &kSpecular.r, 3); // Lights specular color g3D->mShader->SetFloatArray("gAmbient", &kAmbient.r, 3); // Lights ambient color // Show and update the window ShowWindow(hwnd, ishow); UpdateWindow(hwnd); while(1) // While the app is alive { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // If the OS has a message for us { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else if(LockFrameRate()) // Else, if it's time to draw { static int angle = 0; // Stores the amount rotated in degrees D3DXMATRIX tMat, rMat; // This will hold translation and rotation matrices D3DXMATRIX wMat; // This will hold the world matrix of objects we want rendered D3DXMATRIX shadowMat; // The matrix for projecting the shadow to a plane // The light is going to potentially move, so we need to // set it's position every frame g3D->mShader->SetFloatArray("gLightPos", &gLightPos.x, 3); // Render the shadow map RenderShadowMap(); // Render the ground, box and sphere with shadows RenderScene(); } else Sleep(1); // Otherwise, give the OS some time to process other programs } // end of while(1) gLight->Release(); // Free up the light gSphere->Release(); // Free up the sphere gBox->Release(); // Free up the box gGround->Release(); // Free up the ground g3D->deinit(); // Free up the D3D object UnregisterClass(kClassName,hinstance); // Free up WNDCLASSEX return EXIT_SUCCESS; // Application was a success }
// Constants // ////////////// const TCHAR kClassName[] = "GT_RayAABBCollision"; // WNDCLASSEX name // Width and height of the window (specifically the client rect) const int kWinWid = 800; const int kWinHgt = 600; ////////////// // Globals // //////////// // Ray and plane used in the program CRay gRay(CVector(0,0,0), CVector(0,1,0)); CAxisAlgnBB gAABB(CPos(-1,-1,-1), CPos(1,1,1)); bool LockFrameRate(int frameRate = 60); // Locks the frame rate // The WinProc LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); // WinMain int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX
void CList::DrawList(const int& selected, const CStr& _sprite, const CStr& _sprite_selected, const CStr& _textcolor) { float bz = GetBufferedZ(); // First call draw on ScrollBarOwner bool scrollbar; GUI<bool>::GetSetting(this, "scrollbar", scrollbar); if (scrollbar) IGUIScrollBarOwner::Draw(); if (GetGUI()) { CRect rect = GetListRect(); CGUISpriteInstance* sprite = NULL; CGUISpriteInstance* sprite_selectarea = NULL; int cell_id; GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite, sprite); GUI<CGUISpriteInstance>::GetSettingPointer(this, _sprite_selected, sprite_selectarea); GUI<int>::GetSetting(this, "cell_id", cell_id); CGUIList* pList; GUI<CGUIList>::GetSettingPointer(this, "list", pList); GetGUI()->DrawSprite(*sprite, cell_id, bz, rect); float scroll = 0.f; if (scrollbar) scroll = GetScrollBar(0).GetPos(); if (selected != -1) { ENSURE(selected >= 0 && selected+1 < (int)m_ItemsYPositions.size()); // Get rectangle of selection: CRect rect_sel(rect.left, rect.top + m_ItemsYPositions[selected] - scroll, rect.right, rect.top + m_ItemsYPositions[selected+1] - scroll); if (rect_sel.top <= rect.bottom && rect_sel.bottom >= rect.top) { if (rect_sel.bottom > rect.bottom) rect_sel.bottom = rect.bottom; if (rect_sel.top < rect.top) rect_sel.top = rect.top; if (scrollbar) { // Remove any overlapping area of the scrollbar. if (rect_sel.right > GetScrollBar(0).GetOuterRect().left && rect_sel.right <= GetScrollBar(0).GetOuterRect().right) rect_sel.right = GetScrollBar(0).GetOuterRect().left; if (rect_sel.left >= GetScrollBar(0).GetOuterRect().left && rect_sel.left < GetScrollBar(0).GetOuterRect().right) rect_sel.left = GetScrollBar(0).GetOuterRect().right; } GetGUI()->DrawSprite(*sprite_selectarea, cell_id, bz+0.05f, rect_sel); } } CColor color; GUI<CColor>::GetSetting(this, _textcolor, color); for (size_t i = 0; i < pList->m_Items.size(); ++i) { if (m_ItemsYPositions[i+1] - scroll < 0 || m_ItemsYPositions[i] - scroll > rect.GetHeight()) continue; // Clipping area (we'll have to substract the scrollbar) CRect cliparea = GetListRect(); if (scrollbar) { if (cliparea.right > GetScrollBar(0).GetOuterRect().left && cliparea.right <= GetScrollBar(0).GetOuterRect().right) cliparea.right = GetScrollBar(0).GetOuterRect().left; if (cliparea.left >= GetScrollBar(0).GetOuterRect().left && cliparea.left < GetScrollBar(0).GetOuterRect().right) cliparea.left = GetScrollBar(0).GetOuterRect().right; } DrawText(i, color, rect.TopLeft() - CPos(0.f, scroll - m_ItemsYPositions[i]), bz+0.1f, cliparea); } } }
// Constants // ////////////// const char kClassName[] = "GT_RayPlaneCollision"; // WNDCLASSEX name // Width and height of the window (specifically the client rect) const int kWinWid = 800; const int kWinHgt = 600; ////////////// // Globals // //////////// // Ray and plane used in the program CRay gRay(CVector(0,-1,0), CVector(0,1,0)); CPlane gPlane(CVector(0.0f, -1.0f, 0.0f), CPos(0, 0, 0)); bool LockFrameRate(int frame_rate = 60); // Locks the frame rate // The WinProc LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); // WinMain int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX
// Main window program int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprev, PSTR cmdline, int ishow) { HWND hwnd = NULL; MSG msg = {0}; WNDCLASSEX wndclassex = {0}; // Init fields we care about wndclassex.cbSize = sizeof(WNDCLASSEX); // Always set to size of WNDCLASSEX wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WinProc; wndclassex.hInstance = hinstance; wndclassex.lpszClassName = kClassName; wndclassex.hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_SHARED); RegisterClassEx(&wndclassex); // Register the WNDCLASSEX RECT rect = { 0, 0, kWinWid, kWinHgt }; // Desired window client rect DWORD winStyleEx = WS_EX_CLIENTEDGE; DWORD winStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; // Adjust window rect so it gives us our desired client rect when we // create the window AdjustWindowRectEx(&rect, winStyle, false, winStyleEx); // Create the window hwnd = CreateWindowEx(winStyleEx, // Window extended style kClassName, "www.GameTutorials.com -- D3D Fog", winStyle, // Window style CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hinstance, NULL); // Init our global 3D object if(g3D->init(hwnd) == false) return EXIT_FAILURE; // There's been an error, lets get out of this joint // Get the client rect and make sure our client is the size we want GetClientRect(hwnd, &rect); assert(rect.right == kWinWid && rect.bottom == kWinHgt); // We set up our projection matrix once because it will never change g3D->setProjMatrix(DEG2RAD(60), (float)rect.right / (float)rect.bottom, 1.0f, 8192.0f); // If we can initialize the fog, exit the application if(!InitFog()) return EXIT_FAILURE; ShowCursor(FALSE); // Hide cursor ShowWindow(hwnd, ishow); UpdateWindow(hwnd); // Slam the cursor to the middle of the screen SetCursorPos(GetSystemMetrics(SM_CXSCREEN) >> 1, GetSystemMetrics(SM_CYSCREEN) >> 1); // While the app is running... while(1) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Handle messages from the OS { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } else if(LockFrameRate()) // Otherwise if it's time to draw { static float angle = 0; // Angle of rotation D3DXMATRIX wMat; // World matrix CameraMouseInput(); // Move camera via the mouse // Set the world view to the current camera view g3D->setViewMatrix(gCamera); g3D->begin(); // Begin drawing g3D->clear(kFogColor); // Clear the screen to the fog color // Rotate around the Y-axis g3D->setWorldMatrix(D3DXMatrixRotationY(&wMat, DEG2RAD(++angle))); // Draw 4 cubes DrawCube(CPos(2,0,0), 0.5f, D3DCOLOR_ARGB(255, 255, 0, 0)); DrawCube(CPos(-2,0,0), 0.5f, D3DCOLOR_ARGB(255, 255, 0, 0)); DrawCube(CPos(0,0,2), 0.5f, D3DCOLOR_ARGB(255, 255, 0, 0)); DrawCube(CPos(0,0,-2), 0.5f, D3DCOLOR_ARGB(255, 255, 0, 0)); // Draw the grid g3D->setWorldMatrix(D3DXMatrixIdentity(&wMat)); DrawGrid(CPos(0,-2,0), 32, D3DCOLOR_ARGB(255, 0, 200, 0)); g3D->end(); // Finish drawing } else Sleep(1); // Give the OS a tiny bit of time to process other things } // end of while(1) ShowCursor(TRUE); // Reshow cursor g3D->deinit(); // Free up CD3DObj UnregisterClass(kClassName,hinstance); // Free up WNDCLASSEX return EXIT_SUCCESS; // Application was a success }
CPos CRect::TopRight() const { return CPos(right, top); }