• Announcements

    • khawk

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

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

Psychopathetica

Members
  • Content count

    158
  • Joined

  • Last visited

Community Reputation

256 Neutral

About Psychopathetica

  • Rank
    Member
  1. DX11 forces you to use shaders which is not my strong point unfortunately. DX9 gives you the option to use either or. Yet I've been working with DirectX9 the longest so I'm more comfortable with it. It's the only reason I was testing my idea on DirectX9. On top of that, they screwed up the entire library. Now using anything D3DX is now deprecated. And you have to use another library of C++ and h files in a thing called DirectXTK, and finding code on working with that on the internet is pretty far fetched considering most of the websites, and even books out there still use the deprecated D3DX library. Hell the Windows SDK no longer even packages the d3dx lib. I didn't want to get into a struggle of even trying to draw one measly polygon by spending days on even getting the code working. With that said, I've played plenty of games where in the options menu gives you the choice of using DX9 or DX11 (notice they skipped DX10), World of Warcraft being a fine example. I don't wanna turn this thread into a DX war, but you must understand why I still use DirectX9 to test my idea. I will see if I can find anything on AABB to cull quadrants from the view frustum.
  2. i wasnt frustum culling individual polygons per sey, but instead was gonna cull quadrants of the terrain thats not in the view frustum just like the docs you shared. Its gonna have LOD like i did on my last terrain project. Only my harddrive died and i lost the code. Im practically doing it from scratch again to play around with this idea of mine.
  3. Well i was gonna port to dx11 just that i was gonna see if i could pull this off using dx9 for now since i know more of it than dx11   Basically im making a terrain engine, and im gonna cull sections of the terrain not necessarily individual triangles. So the quadrants of the terrain are treated as triangles. And with nifty special cases, i should be able to cull sections of the terrain as well as parts of the terrain involving height. Before i made these sections cull using invisible spheres but i figured its not practical due to certain heights of the terrain.
  4. I'm getting really close to being able to do real view frustum culling with triangle shaped or quad shaped polygons but need only one measly step to getting there. Basically when I wanted to add frustum culling I did a number of techniques. First I tried testing the vertices of a poly to see if they are all in or out of the view frustum. Works great! Except one problem. When a polygon is big or you are close to it, all the vertices are out of the view frustum but the polygon remains to be seen. So I tried testing to see if the sides of the polygons were in the view frustum by using a line plane collision algorithm as a third and forth case, which is if the lines of the polygon collide into any of the 6 planes of the view frustum, it will be visible, else, cull the polygon. I was basically using this: for (int i = 0; i < 6; i++) { //Check if any of the 4 lines of the quad cross any of the 6 view frustum planes. If the values fall between 0 and 1, then the line has crossed //the plane and the polygon is visible. t[0] = -((frustum_plane[i].a * vertex[0].x + frustum_plane[i].b * vertex[0].y + frustum_plane[i].c * vertex[0].z) + frustum_plane[i].d) / (frustum_plane[i].a * vector[0].x + frustum_plane[i].b * vector[0].y + frustum_plane[i].c * vector[0].z); t[1] = -((frustum_plane[i].a * vertex[1].x + frustum_plane[i].b * vertex[1].y + frustum_plane[i].c * vertex[1].z) + frustum_plane[i].d) / (frustum_plane[i].a * vector[1].x + frustum_plane[i].b * vector[1].y + frustum_plane[i].c * vector[1].z); t[2] = -((frustum_plane[i].a * vertex[2].x + frustum_plane[i].b * vertex[2].y + frustum_plane[i].c * vertex[2].z) + frustum_plane[i].d) / (frustum_plane[i].a * vector[2].x + frustum_plane[i].b * vector[2].y + frustum_plane[i].c * vector[2].z); t[3] = -((frustum_plane[i].a * vertex[0].x + frustum_plane[i].b * vertex[0].y + frustum_plane[i].c * vertex[0].z) + frustum_plane[i].d) / (frustum_plane[i].a * vector[3].x + frustum_plane[i].b * vector[3].y + frustum_plane[i].c * vector[3].z); if ((t[0] < 0.0f || t[0] > 1.0f) && (t[1] < 0.0f || t[1] > 1.0f) && (t[2] < 0.0f || t[2] > 1.0f) && (t[3] < 0.0f || t[3] > 1.0f)) { pierced[i] = false; } else { pierced[i] = true; } } Where the vector was literally all 4 sides of a quad. Works but ran into another problem. Even when the polygon is completely off screen, it still manages to collide into a frustum plane due to the fact it is literally 6 infinite planes. So I wanna test the frustum as six polygons rather than treat them as planes. How can I make the view frustum 6 polygonal quads? Thanks in advance.
  5. I'll look into using some SetTextureStageState calls but I think it's messed up that after all these years, I've been setting colors and alphas to polygons upon its creation for years. And all this time if I ever needed to change anything, it involved SetTextureStageState's this whole time. Now alls I gotta do is figure out the right states.   [EDIT] I fixed it after finding a similar post on gamedev:   DWORD AlphaValue; AlphaValue = D3DCOLOR_ARGB(100,255,255,255); mpDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); mpDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); mpDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); mpDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); mpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); mpDevice->SetTextureStageState(0, D3DTSS_CONSTANT, AlphaValue); mpDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CONSTANT); mpDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); mpDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);   works like a charm and you can dynamically change the alphas WITHOUT recreating the polygons
  6. I found an awesome method to create a sphere polygon with normals, as well as texture coordinates for tu and tv, but I severely modified it to support changing its color / alpha as well and made it my own thing. That way I don't have to resort to using D3DXCreateSphere() which doesnt support texture coords. Works great, but I wanted to fade from one sphere into another, similar to fading from day sky to night sky. Is there a way to change alpha values of a color without recreating the entire object every frame with the new colors? Note I'm not using HLSL, and just DirectX9 and C++. Thanks.
  7. I guess I'm gonna have to use it then, arent I
  8. Im pretty sure it can be avoided. Im trying to simulate this:   http://www.chadvernon.com/blog/wp-content/uploads/2007/07/strip.jpg   Basically I've written a terrain program, which works great, but with one fatal flaw...I'm using a trianglelist using 6 vertices per quad. I wanted to boost the speed by using trianglestrips at 4 vertices per quad. But it required something different, which was it going back and forth from the bottom to the top. So I written some small program to see what i can do, and it would suck if I would have to consider a line one primitive. I'm pretty sure if the order is changed a notch I may be able to eliminate that since my terrain will have many extra primitives per node =/
  9. Im trying to make a grid of quads starting with something small such as 2x2 to experiment working with TriangleStrips. It works, but it only works if I have one extra primitive in my drawing method, which doesnt make any sense. Clearly a 2x2 grid of quads has at least 8 triangle primitives, but putting 9 will draw all 8, whereas if I put 8, itll only draw 7 triangles. I started on the bottom of the grid, and worked my way towards the right till I reach the end, went up one row, and went from right to left. Can anyone explain why its only working with 9 rather than 8? Heres a sample of what I have setup: void Create_Polygon() {     Vertex_List[0] = Create_Custom_Vertex(0, 200, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[1] = Create_Custom_Vertex(0, 100, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[2] = Create_Custom_Vertex(100, 200, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[3] = Create_Custom_Vertex(100, 100, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[4] = Create_Custom_Vertex(200, 200, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[5] = Create_Custom_Vertex(200, 100, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[6] = Create_Custom_Vertex(200, 0, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[7] = Create_Custom_Vertex(100, 100, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[8] = Create_Custom_Vertex(100, 0, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[9] = Create_Custom_Vertex(0, 100, 0, 1, D3DCOLOR_XRGB(255, 255, 255));     Vertex_List[10] = Create_Custom_Vertex(0, 0, 0, 1, D3DCOLOR_XRGB(255, 255, 255)); } void Draw_Polygon() {     Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);     Device->SetFVF(CUSTOM_VERTEX_FORMAT);     Device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 9, Vertex_List, sizeof(CUSTOM_VERTEX)); }
  10. I'm trying to make the beginning of a game I'm working on, which normally, like any other game, consists of a video of a company logo intro, possibly a couple more company logos, an FMV intro, and the title which is done in the actual rendering rather than through videos. Right now I only have just a video of a company logo, and one measly textured quad in the actual rendering. I ran into what seems like an anomaly. With this current code, you dont see a video at all, but only hear the sound to it. Alt-Tabbing out and coming back you see a frame or two before it turns black again and continues to play. Also pressing escape goes directly into my DirectX rendering game loop just fine, although I had a black screen earlier. Pressing escape again exists the program: #include <windows.h> #include <d3d9.h> #include <d3dx9.h> #include <dshow.h> #include <string> using namespace std; #pragma comment(lib, "d3d9.lib") #pragma comment(lib, "d3dx9.lib") #pragma comment(lib, "strmiids.lib") #pragma comment(lib, "quartz.lib") #define WM_GRAPHEVENT    WM_USER struct CUSTOM_VERTEX {     float X, Y, Z, RHW;     DWORD Color;     float TU, TV; }; #define CUSTOM_VERTEX_FORMAT (D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE) LPDIRECT3D9 D3D = NULL; LPDIRECT3DDEVICE9 Device = NULL; D3DDISPLAYMODE Display_Mode; D3DPRESENT_PARAMETERS Screen; HWND hWnd; MSG msg; bool Running; CUSTOM_VERTEX Vertex_List[4]; HRESULT hr; LPDIRECT3DTEXTURE9 Texture = NULL; // DirectShow interfaces IGraphBuilder*    g_pGraphBuilder = NULL; IMediaControl*    g_pMediaControl = NULL; IMediaEventEx*    g_pMediaEvent = NULL; IMediaPosition*    g_pMediaPosition = NULL; IVideoWindow* g_pVideoWindow; BOOL        g_Looping = FALSE; bool render = false; CUSTOM_VERTEX Create_Custom_Vertex(); void Load_Texture(); void Render(); void Game_Loop(); void Main(); void Shutdown(); void DirectX_Initialize(); LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM); void directshow_load_media(); void OnGraphEvent(); void CleanUpDirectShow(); #define HELPER_RELEASE(x)   if (x != NULL) \ { \     x->Release(); \     x = NULL; \ } void DirectX_Initialize() {     D3D = Direct3DCreate9(D3D_SDK_VERSION);     memset(&Screen, 0, sizeof(D3DPRESENT_PARAMETERS));     Display_Mode.Width = 1920;     Display_Mode.Height = 1080;     Display_Mode.Format = D3DFMT_X8R8G8B8;     Screen.Windowed = FALSE;     Screen.BackBufferCount = 1;     Screen.BackBufferWidth = Display_Mode.Width;     Screen.BackBufferHeight = Display_Mode.Height;     Screen.hDeviceWindow = hWnd;     Screen.SwapEffect = D3DSWAPEFFECT_COPY;     Screen.BackBufferFormat = Display_Mode.Format;     D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &Screen, &Device);     Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);     Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);     Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);     Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);     Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);     Device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);     Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);     Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);     Device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);     Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);     Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); } CUSTOM_VERTEX Create_Custom_Vertex(float X, float Y, float Z, float RHW, DWORD Color, float TU, float TV) {     CUSTOM_VERTEX Vertex;     Vertex.X = X;     Vertex.Y = Y;     Vertex.Z = Z;     Vertex.RHW = RHW;     Vertex.Color = Color;     Vertex.TU = TU;     Vertex.TV = TV;     return Vertex; } void Load_Texture(LPDIRECT3DTEXTURE9 *T, char *File_Path, int Transparency_Color) {     D3DXCreateTextureFromFileEx(Device, File_Path, 2048, 2048, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, D3DX_FILTER_POINT, D3DX_FILTER_POINT, Transparency_Color, NULL, NULL, T); } void Create_Polygon() {     Vertex_List[0] = Create_Custom_Vertex(0, 0, 0, 1, D3DCOLOR_XRGB(255, 255, 255), 0, 0);     Vertex_List[1] = Create_Custom_Vertex(100, 0, 0, 1, D3DCOLOR_XRGB(255, 255, 255), 1, 0);     Vertex_List[2] = Create_Custom_Vertex(0, 100, 0, 1, D3DCOLOR_XRGB(255, 255, 255), 0, 1);     Vertex_List[3] = Create_Custom_Vertex(100, 100, 0, 1, D3DCOLOR_XRGB(255, 255, 255), 1, 1); } void Draw_Polygon() {     Device->SetFVF(CUSTOM_VERTEX_FORMAT);     Device->SetTexture(0, Texture);     Device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, Vertex_List, sizeof(CUSTOM_VERTEX)); } void Render() {     Device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);     Device->BeginScene();     Create_Polygon();     Draw_Polygon();     Device->EndScene();     Device->Present(NULL, NULL, NULL, NULL); } void Game_Loop() {     while (Running == true)     {         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)         {             if (WM_QUIT == msg.message) break;             TranslateMessage(&msg);             DispatchMessage(&msg);         }         else         {             hr = Device->TestCooperativeLevel();             if (hr != D3D_OK)             {                 if (hr == D3DERR_DEVICELOST)                 {                     Texture->Release();                     g_pMediaControl->Pause();                     Sleep(50); //Wait a bit so we don't burn through cycles for no reason                 }                 else if (hr == D3DERR_DEVICENOTRESET)                 {                                          hr = Device->Reset(&Screen);                                          if (SUCCEEDED(hr))                     {                         Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);                         Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);                         Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);                         Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);                         Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);                         Device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);                         Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);                         Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);                         Device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);                         Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);                         Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);                         Load_Texture(&Texture, "graphics\\stone.png", D3DCOLOR_XRGB(0, 0, 0));                     }                     if (render == false)                     {                         g_pMediaControl->Run();                         continue;                     }                 }             }             else if (hr == D3D_OK)             {                 if (render == true)                     Render();             }         }     } } void directshow_load_media(const char *File_Name) {     CleanUpDirectShow();     char buffer[MAX_PATH];     string Result;     GetModuleFileName(NULL, buffer, MAX_PATH);     string startuppath = string(buffer);     string filename = string(File_Name);     startuppath = startuppath.substr(0, startuppath.find_last_of("\\/"));     Result = startuppath + string("\\") + filename;     const char *File_Path = Result.c_str();     WCHAR *MediaFile = new WCHAR[strlen(File_Path) + 1];     MultiByteToWideChar(CP_ACP, 0, File_Path, -1, MediaFile, strlen(File_Path) + 1);     CoInitialize(NULL);     CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,(void**)&g_pGraphBuilder);          g_pGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&g_pMediaControl);     g_pGraphBuilder->RenderFile(MediaFile, NULL);     g_pGraphBuilder->QueryInterface(IID_IVideoWindow, (void**)&g_pVideoWindow);     g_pVideoWindow->put_Visible(true);     g_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);     g_pVideoWindow->put_Owner((OAHWND)hWnd);     g_pVideoWindow->SetWindowPosition(0, 0, 1920, 1080);     g_pGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&g_pMediaEvent);     g_pMediaEvent->SetNotifyWindow((OAHWND)hWnd, WM_GRAPHEVENT, 0);     g_pGraphBuilder->QueryInterface(IID_IMediaPosition, (void**)&g_pMediaPosition);          g_pMediaControl->Run(); } void CleanUpDirectShow() {     HELPER_RELEASE(g_pMediaPosition);     HELPER_RELEASE(g_pMediaEvent);     HELPER_RELEASE(g_pMediaControl);     HELPER_RELEASE(g_pGraphBuilder); } void Main() {     DirectX_Initialize();     directshow_load_media("videos\\Roman Software Logo.mpeg");     Load_Texture(&Texture, "graphics\\stone.png", D3DCOLOR_XRGB(0, 0, 0));     Running = true; } void Shutdown() {     Running = false;                 CleanUpDirectShow();     CoUninitialize();     HELPER_RELEASE(Texture);     HELPER_RELEASE(D3D);     HELPER_RELEASE(Device);     PostQuitMessage(0);     HANDLE Process;     Process = OpenProcess(PROCESS_ALL_ACCESS, true, GetCurrentProcessId());     TerminateProcess(Process, 0); } void OnGraphEvent() {     long EventCode, Param1, Param2;     while (g_pMediaEvent->GetEvent(&EventCode, &Param1, &Param2, 0) != E_ABORT)     {         switch (EventCode)         {         case EC_COMPLETE:             if (!g_Looping)             {                 if (g_pMediaControl != NULL)                     g_pMediaControl->Stop();                 if (g_pMediaEvent != NULL)                     g_pMediaEvent->SetNotifyWindow(NULL, 0, 0);                 render = true;             }             g_pMediaPosition->put_CurrentPosition(0);             break;         default:             break;         }         g_pMediaEvent->FreeEventParams(EventCode, Param1, Param2);     } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) {     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW | CS_OWNDC, WindowProcedure, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "GAME", NULL };     RegisterClassEx(&wc);     hWnd = CreateWindowEx(0, "GAME", "Game", WS_VISIBLE | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, 330, 250, HWND_DESKTOP, NULL, hInstance, NULL);     ShowWindow(hWnd, nCmdShow);     Main();     Game_Loop();     return msg.wParam; } LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {     switch (msg)     {     case WM_DESTROY:         Shutdown();         break;     case WM_KEYDOWN:         if (wParam == VK_ESCAPE)         {             if (render == false)             {                 if (g_pMediaControl != NULL)                     g_pMediaControl->Stop();                 if (g_pMediaEvent != NULL)                     g_pMediaEvent->SetNotifyWindow(NULL, 0, 0);                 render = true;             }             else             {                 DestroyWindow(hWnd);                 return(0);             }             break;                      }     case WM_GRAPHEVENT:         if (g_pGraphBuilder != NULL)         {             if (render == false)             {                 OnGraphEvent();                 break;             }         }     default:         return DefWindowProc(hWnd, msg, wParam, lParam);     }     return 0; } Now here is when it gets weird. If I reset the DirectX device like so: void Main() {     DirectX_Initialize();     directshow_load_media("videos\\Roman Software Logo.mpeg");     Load_Texture(&Texture, "graphics\\stone.png", D3DCOLOR_XRGB(0, 0, 0));     hr = Device->Reset(&Screen);     if (SUCCEEDED(hr))     {         Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);         Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);         Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);         Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);         Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);         Device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);         Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);         Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);         Device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);         Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);         Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);     }     Running = true; } the video comes up in my window just fine, however, I can't escape it, and it only shows a freeze frame after pressing the escape key. I couldn't for the life of me figure out how I can prevent it from freezing and going into my renderer.   This is the weirder part. If I load the texture file after I reset the device, its a black screen again thats escapable. And if I load the texture before before resetting the device (like the code above), it runs in the window just fine, yet it freezes when I attempt to escape out of it. Also note this whole time I have not had the video playing in a separate ActiveMovie window at all. It was all running within my one window. How can I have the video play without having to reset the directx device afterwards, and be escapable to the actual rendering code? Thanks in advance.
  11. Thanks for the feedback. But so far there has been no problems at all. So I'm gonna walk you guys through the code just to prove my point.   In the server, lets disregard the initialization process, as thats a given. In the actual loop in main(), I created a temporary variable SOCKETS incoming to be used to accept the next client.     while (1)     {         SOCKET incoming = INVALID_SOCKET;         incoming = accept(server_socket, NULL, NULL); That is where it gets caught and wont continue unless a client logs onto my server. When a client does, it checks if its an INVALID_SOCKET still. If it is, it skips all the code in the loop and starts the loop over to try accepting another client. When and if it succeeds, it can be put into my client array with an id and a socket by finding the next empty client. The for loop will also count the number of valid client sockets, giving me the proper number of clients.         if (incoming == INVALID_SOCKET) continue;         //Reset the number of clients         num_clients = -1;         //Create a temporary id for the next client         temp_id = -1;         for (int i = 0; i < MAX_CLIENTS; i++)         {             if (client[i].socket == INVALID_SOCKET && temp_id == -1)             {                 client[i].socket = incoming;                 client[i].id = i;                 temp_id = i;             }             if (client[i].socket != INVALID_SOCKET)                 num_clients++;             //std::cout << client[i].socket << std::endl;         } If the temp id is not -1, it can proceed in sending that id given to that client, which only happens once the client logs on. It can then run the other thread. If the temp id is still -1, then the server is full. On top of that, itll send the message using the "incoming" socket (my temp socket I used earlier) to that client that attempted to log on with the message "server is full".         if (temp_id != -1)         {             //Send the id to that client             std::cout << "Client #" << client[temp_id].id << " Accepted" << std::endl;             msg = std::to_string(client[temp_id].id);             send(client[temp_id].socket, msg.c_str(), strlen(msg.c_str()), 0);             //Create a thread process for that client             my_thread[temp_id] = std::thread(process_client, std::ref(client[temp_id]), std::ref(client), std::ref(my_thread[temp_id]));         }         else         {             msg = "Server is full";             send(incoming, msg.c_str(), strlen(msg.c_str()), 0);             std::cout << msg << std::endl;         }     } //end while My loop will cycle again, and once again get caught on accept. That is thread 1. It loops once and gets caught on accept() every time, and will only do so when a client logs on.   Now my other thread (which is actually an array of threads), is created for every new client. And those loop only once before getting caught on recv(). So lets say I have all 5 clients logged on:   [*]---[*]---[*]---[*]---[*] -0---1-----2----3----4   I have 5 different threads each receiving messages from those clients. It never has once gotten confused which socket to receive from because I'm using an array of threads, each corresponding to a particular client, and never a mishmash of data due do race conditions as you all propose would happen. Because each index of the thread array is working with each index of my client array. 0 is working with 0, 1 is working with 1, 2 is working with 2, etc. It is impossible for thread 0 to receive data from client 2, or thread 3 to receive data from client 1, or whatever the case may be, it has not happened nor will it ever happen. It is not continuous loop that goes for whatever frames per second, but rather a loop that loops once before getting caught, just like the loop in my main(). It will only cycle if it receives a message, all 5 of my threads. If a client disconnects, that thread will detach. And can be recreated if that particular client logs back on.   So with main() accepting clients on one thread while at the same time 5 other threads are receiving messages from public clients, I still cant see where a race condition would occur. Because my loops only begin to cycle when something happens, similar to an event. The only thing that could ever happen is during the console window, text from one client could potentially continue on from another if they sent their messages at the same time. This is unavoidable in a console window, but controllable in a windows GUI or even a DirectX game environment. And would probably look something like this:   2 messages being displayed simultaniously Hey hoHEY WHATS UP!w are you?   Unless of course I can capture the messages and shove them into a string array list of messages and display them appropriately. That is so far the only problem with it, but other than that, has worked flawlessly, mostly thanks to you guys for leading me in the right direction. I know I could use Select(), Event based, or even Asyncrounous sockets, but I wanted to see how possible it would be to attempt a multithread version of a simple chat program.
  12. I'm home from work. I was curious on everyone's opinion on my new code. This new code should be thread safe, and it works great. Like I said in the last post, I removed some variables from the thread function, counted my clients differently, and when the server is full, any new clients that log in get sent the message that the server is full. It runs flawlessly thus far.   Server: #include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <string> #include <thread> #include <vector> #pragma comment (lib, "Ws2_32.lib") #define IP_ADDRESS "192.168.56.1" #define DEFAULT_PORT "3504" #define DEFAULT_BUFLEN 512 struct client_type {     int id;     SOCKET socket; }; const char OPTION_VALUE = 1; const int MAX_CLIENTS = 5; //Function Prototypes int process_client(client_type &new_client, std::vector<client_type> &client_array, std::thread &thread); int main(); int process_client(client_type &new_client, std::vector<client_type> &client_array, std::thread &thread) {     std::string msg = "";     char tempmsg[DEFAULT_BUFLEN] = "";     //Session     while (1)     {         memset(tempmsg, 0, DEFAULT_BUFLEN);         if (new_client.socket != 0)         {             int iResult = recv(new_client.socket, tempmsg, DEFAULT_BUFLEN, 0);             if (iResult != SOCKET_ERROR)             {                 if (strcmp("", tempmsg))                     msg = "Client #" + std::to_string(new_client.id) + ": " + tempmsg;                 std::cout << msg.c_str() << std::endl;                 //Broadcast that message to the other clients                 for (int i = 0; i < MAX_CLIENTS; i++)                 {                     if (client_array[i].socket != INVALID_SOCKET)                         if (new_client.id != i)                             iResult = send(client_array[i].socket, msg.c_str(), strlen(msg.c_str()), 0);                 }             }             else             {                 msg = "Client #" + std::to_string(new_client.id) + " Disconnected";                 std::cout << msg << std::endl;                 closesocket(new_client.socket);                 closesocket(client_array[new_client.id].socket);                 client_array[new_client.id].socket = INVALID_SOCKET;                 //Broadcast the disconnection message to the other clients                 for (int i = 0; i < MAX_CLIENTS; i++)                 {                     if (client_array[i].socket != INVALID_SOCKET)                         iResult = send(client_array[i].socket, msg.c_str(), strlen(msg.c_str()), 0);                 }                 break;             }         }     } //end while     thread.detach();     return 0; } int main() {     WSADATA wsaData;     struct addrinfo hints;     struct addrinfo *server = NULL;     SOCKET server_socket = INVALID_SOCKET;     std::string msg = "";     std::vector<client_type> client(MAX_CLIENTS);     int num_clients = 0;     int temp_id = -1;     std::thread my_thread[MAX_CLIENTS];     //Initialize Winsock     std::cout << "Intializing Winsock..." << std::endl;     WSAStartup(MAKEWORD(2, 2), &wsaData);     //Setup hints     ZeroMemory(&hints, sizeof(hints));     hints.ai_family = AF_INET;     hints.ai_socktype = SOCK_STREAM;     hints.ai_protocol = IPPROTO_TCP;     hints.ai_flags = AI_PASSIVE;     //Setup Server     std::cout << "Setting up server..." << std::endl;     getaddrinfo(static_cast<LPCTSTR>(IP_ADDRESS), DEFAULT_PORT, &hints, &server);     //Create a listening socket for connecting to server     std::cout << "Creating server socket..." << std::endl;     server_socket = socket(server->ai_family, server->ai_socktype, server->ai_protocol);     //Setup socket options     setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &OPTION_VALUE, sizeof(int)); //Make it possible to re-bind to a port that was used within the last 2 minutes     setsockopt(server_socket, IPPROTO_TCP, TCP_NODELAY, &OPTION_VALUE, sizeof(int)); //Used for interactive programs     //Assign an address to the server socket.     std::cout << "Binding socket..." << std::endl;     bind(server_socket, server->ai_addr, (int)server->ai_addrlen);     //Listen for incoming connections.     std::cout << "Listening..." << std::endl;     listen(server_socket, SOMAXCONN);     //Initialize the client list     for (int i = 0; i < MAX_CLIENTS; i++)     {         client[i] = { -1, INVALID_SOCKET };     }     while (1)     {         SOCKET incoming = INVALID_SOCKET;         incoming = accept(server_socket, NULL, NULL);         if (incoming == INVALID_SOCKET) continue;         //Reset the number of clients         num_clients = -1;         //Create a temporary id for the next client         temp_id = -1;         for (int i = 0; i < MAX_CLIENTS; i++)         {             if (client[i].socket == INVALID_SOCKET && temp_id == -1)             {                 client[i].socket = incoming;                 client[i].id = i;                 temp_id = i;             }             if (client[i].socket != INVALID_SOCKET)                 num_clients++;             //std::cout << client[i].socket << std::endl;         }         if (temp_id != -1)         {             //Send the id to that client             std::cout << "Client #" << client[temp_id].id << " Accepted" << std::endl;             msg = std::to_string(client[temp_id].id);             send(client[temp_id].socket, msg.c_str(), strlen(msg.c_str()), 0);             //Create a thread process for that client             my_thread[temp_id] = std::thread(process_client, std::ref(client[temp_id]), std::ref(client), std::ref(my_thread[temp_id]));         }         else         {             msg = "Server is full";             send(incoming, msg.c_str(), strlen(msg.c_str()), 0);             std::cout << msg << std::endl;         }     } //end while     //Close listening socket     closesocket(server_socket);     //Close client socket     for (int i = 0; i < MAX_CLIENTS; i++)     {         my_thread[i].detach();         closesocket(client[i].socket);     }     //Clean up Winsock     WSACleanup();     std::cout << "Program has ended successfully" << std::endl;     system("pause");     return 0; }   Client: #include <winsock2.h> #include <ws2tcpip.h> #include <iostream> #include <string> #include <thread> using namespace std; #pragma comment (lib, "Ws2_32.lib") #define DEFAULT_BUFLEN 512             #define IP_ADDRESS "192.168.56.1" #define DEFAULT_PORT "3504" struct client_type {     SOCKET socket;     int id;     char received_message[DEFAULT_BUFLEN]; }; int process_client(client_type &new_client); int main(); int process_client(client_type &new_client) {     while (1)     {         memset(new_client.received_message, 0, DEFAULT_BUFLEN);         if (new_client.socket != 0)         {             int iResult = recv(new_client.socket, new_client.received_message, DEFAULT_BUFLEN, 0);             if (iResult != SOCKET_ERROR)                 cout << new_client.received_message << endl;             else             {                 cout << "recv() failed: " << WSAGetLastError() << endl;                 break;             }         }     }     if (WSAGetLastError() == WSAECONNRESET)         cout << "The server has disconnected" << endl;     return 0; } int main() {     WSAData wsa_data;     struct addrinfo *result = NULL, *ptr = NULL, hints;     string sent_message = "";     client_type client = { INVALID_SOCKET, -1, "" };     int iResult = 0;     string message;     cout << "Starting Client...\n";     // Initialize Winsock     iResult = WSAStartup(MAKEWORD(2, 2), &wsa_data);     if (iResult != 0) {         cout << "WSAStartup() failed with error: " << iResult << endl;         return 1;     }     ZeroMemory(&hints, sizeof(hints));     hints.ai_family = AF_UNSPEC;     hints.ai_socktype = SOCK_STREAM;     hints.ai_protocol = IPPROTO_TCP;     cout << "Connecting...\n";     // Resolve the server address and port     iResult = getaddrinfo(static_cast<LPCTSTR>(IP_ADDRESS), DEFAULT_PORT, &hints, &result);     if (iResult != 0) {         cout << "getaddrinfo() failed with error: " << iResult << endl;         WSACleanup();         system("pause");         return 1;     }     // Attempt to connect to an address until one succeeds     for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {         // Create a SOCKET for connecting to server         client.socket = socket(ptr->ai_family, ptr->ai_socktype,             ptr->ai_protocol);         if (client.socket == INVALID_SOCKET) {             cout << "socket() failed with error: " << WSAGetLastError() << endl;             WSACleanup();             system("pause");             return 1;         }         // Connect to server.         iResult = connect(client.socket, ptr->ai_addr, (int)ptr->ai_addrlen);         if (iResult == SOCKET_ERROR) {             closesocket(client.socket);             client.socket = INVALID_SOCKET;             continue;         }         break;     }     freeaddrinfo(result);     if (client.socket == INVALID_SOCKET) {         cout << "Unable to connect to server!" << endl;         WSACleanup();         system("pause");         return 1;     }     cout << "Successfully Connected" << endl;     //Obtain id from server for this client;     recv(client.socket, client.received_message, DEFAULT_BUFLEN, 0);     message = client.received_message;     if (message != "Server is full")     {         client.id = atoi(client.received_message);         thread my_thread(process_client, client);         while (1)         {             getline(cin, sent_message);             iResult = send(client.socket, sent_message.c_str(), strlen(sent_message.c_str()), 0);             if (iResult <= 0)             {                 cout << "send() failed: " << WSAGetLastError() << endl;                 break;             }         }         //Shutdown the connection since no more data will be sent         my_thread.detach();     }     else         cout << client.received_message << endl;     cout << "Shutting down socket..." << endl;     iResult = shutdown(client.socket, SD_SEND);     if (iResult == SOCKET_ERROR) {         cout << "shutdown() failed with error: " << WSAGetLastError() << endl;         closesocket(client.socket);         WSACleanup();         system("pause");         return 1;     }     closesocket(client.socket);     WSACleanup();     system("pause");     return 0; }
  13. To give clients on external machines the public ip address of my server to connect to.
  14. Ive been doing some research on how to pull this off, and come to find no solutions anywhere online. Winsock alone will only retrieve your local ip address and not your external ip address. Other solutions and recommendations were to rely on 3rd party websites such as whatismyip.com. Scripting was another way. And also found that it is possible to do in C++ but is very difficult and you would need to create your own function. Even though this has been mentioned, the solutions were not presented at all. And what would really suck is if i were to rely on assembly code. Could anyone point me in the right direction on the steps needed to pull this off without resorting to 3rd party websites? Thanks in advance
  15. I havent displayed the new code, but i removed a number of things from the process client thread from the server, such as tempid and numclients. I count the clients now through a for loop seeing how many active sockets exist, and it works. Im not sending/receiving at the same time as some of you claim because it would be impossible. Both loops iterate once and get caught, either on accept() or recv(). It only sends the id to that particular client after accepting. In my new code, i also made it to where itll send a server is full message to the client that over exceeded the max number of clients. It works great and i have no problems with it so far. Ill share the new code when i get home, as im at work at the moment.