Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

77 Neutral

About codejockey

  • Rank
  1. This is getting annoying.  I only posted this because it shows how you can define the methods in a class to be threaded.  If you want it to be professionally used then I suggest doing all the changes that all these brilliant people pointed out to make it universally acceptable in the C++ programming community.  For me, it works, it does what I need, and isn't that actually what is important.  btw I wouldn't work anywhere that has C++ as its main programming language.  Get current with some managed code such as C# XNA or java.
  2. Ok with that being said.  Rewrite it in your way (going to have to assume that's the right way) so everyone can be clear on how it's supposed to be done.   If you know assembler then you'll know this is fine: memset(this, 0x00, sizeof(Server));   Perhaps constructive criticism instead of this type of verbosity: VERY_LARGE_RETARDATION   Did you guys even read the source in the class?   
  3. codejockey

    Question about RAM

    Here's your CPU  and based on what I see it's a 64-bit processor which means you have the minimum for it at 2GB of RAM.  When it starts "lagging" a little the OS (assuming Windows) is caching to the hard drive.  If you have a 64-bit OS and vid card then you can go as high as 8GB.  Why anyone would need more than that on a desk/lap top is beyond me.  64 bit means it can address a memory location in ram as high as 7FFFFFFFFFFFFFFF or 9,223,372,036,854,775,807 and that's a whole lot of bytes!
  4. If you look in the directory where your *.ico item is for your project you can make a new *.ico and just replace/rename your old one.  Remove it from your project and then re-add it back.  Finally, compile your project and your newly created *.exe should have the icon.   Online Icon Maker  works like a charm!   Visual C++ Express 2010 doesn't allow creating or updating its resource files.  It makes a standard one on the fly for the project.
  5. So I've looked around with Bing search as to how to thread a class.  I see lot's of nice wrappers with lots of heavy duty pointer stashing and caching and said there's got to be an easier way.  Well here it is, what you all have been waiting for ... threading a class!!  It's so simple your just going to want to do it in every class you write.  I'll just put my server class here and comment where the thread dependent items are.  (btw, it's still a work-in-process but it does get a listen server and a client connection with data being passed)  The includes are just windows stuff and some simple buffers and not necessary to discuss.   Header   #pragma once #include "includes.h" #include "ChatPacket.h" class Server { public: Server(void); ~Server(void); // some normal methods short Server::Initialize(short port); short Server::Disconnect(); short Server::Send(); void Server::Listening(); // these two methods are going to be the threads // notice the use of static and the (void* t) parameter static void Server::Accepting(void* t); static void Server::Receiver(void* t); char buffer[VERY_LARGE_STRING]; private: WSADATA wsaData; SOCKET listenSocket; SOCKET clientSocket; // some Booleans to keep track of which threads are active bool listenerIsActive; bool accepterIsActive; bool receiverIsActive; int receiveLength; int sendLength; // thread ID variables uintptr_t listenThread; uintptr_t acceptThread; uintptr_t receiveThread; uintptr_t sendThread; struct addrinfo *result, *ptr, hints; ChatPacket* chatPacket; }; Methods   #include "Server.h" Server::Server(void) { memset(this, 0x00, sizeof(Server)); } Server::~Server(void) { if (receiverIsActive) { //set the Boolean to false so the thread will stop receiverIsActive = false; // wait for 1 second so the thread can stop Sleep(1000); } if(accepterIsActive) { // and again accepterIsActive = false; Sleep(1000); closesocket(clientSocket); clientSocket = 0; } if(listenerIsActive) { // and again for this one listenerIsActive = false; Sleep(1000); closesocket(listenSocket); listenSocket = 0; } WSACleanup(); } short Server::Initialize(short port) { // initialize winsock r = WSAStartup(MAKEWORD(2, 2), &wsaData); if (FAILED(r)) { PrintDebugString("%s", DXGetErrorString(r)); return 0; } memset(&hints, 0x00, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // resolve this servers address and port // port has to be a character string ... who'da thought that! char p[6]; sprintf(p, "%i", port); r = getaddrinfo(NULL, p, &hints, &result); if (FAILED(r)) { PrintDebugString("%s", DXGetErrorString(r)); WSACleanup(); return 0; } // create a SOCKET for this server listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (listenSocket == INVALID_SOCKET) { freeaddrinfo(result); WSACleanup(); listenSocket = 0; return 0; } // bind the TCP listening socket r = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen); if (r == INVALID_SOCKET) { freeaddrinfo(result); closesocket(listenSocket); WSACleanup(); listenSocket = 0; return 0; } freeaddrinfo(result); // start the listen server for connect requests Server::Listening(); // start the accepting thread for connect requests acceptThread = _beginthread(&Server::Accepting, 0, this); // start the receiving thread for receiving data receiveThread = _beginthread(&Server::Receiver, 0, this); return 1; } void Server::Listening() { // thought this might need to be threaded but turns out it doesn't // so toss the boolean out listenerIsActive = true; r = listen(listenSocket, SOMAXCONN); if (r == INVALID_SOCKET) { closesocket(listenSocket); WSACleanup(); listenSocket = 0; } } void Server::Accepting(void* t) { // using this as a thread must cast the this pointer // to something usable Server* s = (Server*)t; // set the Boolean to true so we know the thread is running s->accepterIsActive = true; // infinite loop until the Boolean is changed to false somewhere else in the class // i.e the deconstructor or the disconnect method while(s->accepterIsActive) { s->clientSocket = accept(s->listenSocket, 0, 0); if (s->clientSocket == INVALID_SOCKET) { closesocket(s->clientSocket); WSACleanup(); s->clientSocket = 0; return; } // needed a spot to put a stopper for my debugger if (s->clientSocket > 0) { int zz = 0; zz++; // I put the stopper on this line } } } short Server::Send() { // note-to-self don't use strlen(buffer) as there could be 0x00 somewhere in the buffer // and will not send the entire buffer if there is sendLength = send(clientSocket, buffer, strlen(buffer), 0); if (sendLength == SOCKET_ERROR) { PrintDebugString("Server::Send failed with error: %d", WSAGetLastError()); closesocket(clientSocket); WSACleanup(); return 0; } return 1; } void Server::Receiver(void* t) { Server* s = (Server*)t; // set the Boolean to show the thread is running s->receiverIsActive = true; // loop until this Boolean is false while(s->receiverIsActive) { if (s->clientSocket > 0) { memset(s->buffer, 0x00, VERY_LARGE_STRING); s->receiveLength = recv(s->clientSocket, s->buffer, VERY_LARGE_STRING, 0); if (s->receiveLength > 0) { // doing my client receive logic here PrintDebugString("Server::Bytes received: %d", s->receiveLength); if ((s->buffer[0] == 'C') && (s->buffer[1] == 'H')) { s->chatPacket = new ChatPacket(); memcpy(s->chatPacket, s->buffer, s->receiveLength); PrintDebugString("Server::CH: %s", s->chatPacket->message); delete s->chatPacket; s->chatPacket = 0; } memset(s->buffer, 0x00, VERY_LARGE_STRING); } else if (s->receiveLength == 0) { PrintDebugString("Server::No Data..."); } else { PrintDebugString("Server::Recv failed: %d", WSAGetLastError()); closesocket(s->clientSocket); WSACleanup(); s->receiverIsActive = false; return; } } } } short Server::Disconnect() { receiverIsActive = false; if(accepterIsActive) { accepterIsActive = false; Sleep(1000); closesocket(clientSocket); clientSocket = 0; } if(listenerIsActive) { listenerIsActive = false; Sleep(1000); closesocket(listenSocket); listenSocket = 0; } WSACleanup(); return 1; } And that's all there is to threading with a class.  Don't bother with starting the thread outside of the class.  Too much chaos in doing that.  Simply call a method within the class to start the threading or do it in the class on its own with the constructor.  One final thought is that this server is set up to connect only one client so don't just cut and paste and assume its going to handle multiple clients (hint: s->clientSocket[x] or maybe put them in a link list?)   Microsoft's MSDN Links for Client Server Programming with Winsock   Getting Started With Winsock   Complete Server Code   Complete Client Code
  6. codejockey

    Terrain Blend With Pixel Shader

    "I gotten significant performance improvements from doing this." That one is using a sheet of seemless textures which is only ONE texture and they calulate the UV coords in the shader to arrive at the seemless texture. I'm new/noob to pixel shaders and the math so I'm sure mine won't ever be improved until I manage to get a further education in mathmatics and video game programming at a industry professional level. Just something to help the curious.
  7. Ok, I'm going to be quite generous with this post as I have seen this terrain blending question being asked repeatedly over and over and over. I found a good tutorial (http://www.innovativ...proved-terrain/) and I'm going to describe to you folks how to do it. It uses a pixel shader to do the texture blending. Only concern I have with it is that it is increadibly slow unless you have multiple channels for your video card. (check out bindless textures on the NVidia video cards http://www.geforce.c...paper-FINAL.pdf) However with the cards that run DX11 these days you'll have to tell me if its quicker because I get around 8 FPS. With that in mind here's what I have completed that works. First off your terrain model has to define its UV's to be from 0 to 1. This is accomplished by dividing the number of vertexes across by 1 and number of vertexes down by 1. My terrain is 128x128. So we get 0.0078125 and if we loop across starting at 0 when whe arrive at the 128th vertex we'll be at 1. We can take advantage of this in the pixel shader. Here's how: Set up a float value for how many times you want the texture to tile across the terrain. float uvScale01 = 1.0; in your program you'll have a handle set to this variable: htexture01MaskScale = shader->effect->GetParameterByName(NULL, "uvScale01"); and you can set the variable from your program: r = shader->effect->SetFloat(htexture01MaskScale, 1.0f); This is a mask in mine so I have it stretched across the whole terrain for the blending but if it were a texture you could make the scale something like 32 and it would tile across the whole terrain 32 times. I'll show you how in a little bit. Here is the sampler definition for the mask and a texture is just the same. texture texture01; sampler2D texture01Sampler = sampler_state { texture = texture01; }; Vertex shader definition: struct VertexShaderInput { float4 pos : POSITION; float3 norm : NORMAL; float4 diffuse : COLOR; float4 specular : COLOR1; float2 uv1 : TEXCOORD; float Depth : TEXCOORD1; float3 vpos : TEXCOORD2; }; Pixel shader definition: struct VertexShaderOutput { float4 pos : POSITION; float3 norm : NORMAL; float4 diffuse : COLOR; float4 specular : COLOR1; float2 uv1 : TEXCOORD; float Depth : TEXCOORD1; float3 vpos : TEXCOORD2; }; Not going to go into much detail here but this is how you pass the pixel from the primitive as it relates to the FVF to the pixel shader. Grabbing the elements to pass to the PS: VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; // directional lighting lightDir = normalize(lightDir); output.pos = mul(input.pos, WorldViewProj); output.vpos = input.pos; // lighting output.norm = normalize(mul(input.norm, World)); float d = dot(output.norm, lightDir); d = clamp(d, ambient, 1.0); output.diffuse = lightMaterial * d; output.diffuse.a = 1.0; output.specular = specularMaterial * d; output.specular.a = 1.0; // texture output.uv1 = input.uv1; // fog output.Depth = output.pos.z; return output; } Notice there are normals (vertex normal) and depth and things like that for more than just blending. Now for the actual blend: float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { float4 final = {0, 0, 0, 0}; float4 lightMap; float4 maskMap; float b1; float b2; float4 ts; // ================================================================================= // Base Terrain Layer 1 final = tex2D(texture16Sampler, input.uv1 * uvScale16); // ================================================================================= // Terrain Layer 1 maskMap = tex2D(texture01Sampler, input.uv1 * uvScale01); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture02Sampler, input.uv1 * uvScale02); final = (final * b1) + (ts * b2); } // ================================================================================= // Terrain Layer 2 maskMap = tex2D(texture03Sampler, input.uv1 * uvScale03); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture04Sampler, input.uv1 * uvScale04); final = (final * b1) + (ts * b2); } // ================================================================================= // Terrain Layer 3 maskMap = tex2D(texture05Sampler, input.uv1 * uvScale05); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture06Sampler, input.uv1 * uvScale06); final = (final * b1) + (ts * b2); } // ================================================================================= // Terrain Layer 4 maskMap = tex2D(texture07Sampler, input.uv1 * uvScale07); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture08Sampler, input.uv1 * uvScale08); final = (final * b1) + (ts * b2); } // ================================================================================= // Terrain Layer 5 maskMap = tex2D(texture09Sampler, input.uv1 * uvScale09); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture10Sampler, input.uv1 * uvScale10); final = (final * b1) + (ts * b2); } // ================================================================================= // Terrain Layer 6 maskMap = tex2D(texture11Sampler, input.uv1 * uvScale11); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture12Sampler, input.uv1 * uvScale12); final = (final * b1) + (ts * b2); } // ================================================================================= // Terrain Layer 7 maskMap = tex2D(texture13Sampler, input.uv1 * uvScale13); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture14Sampler, input.uv1 * uvScale14); final = (final * b1) + (ts * b2); } // ================================================================================= // Lightmap // no scaling needed here as it goes across the whole terrain lightMap = tex2D(texture15Sampler, input.uv1); final *= lightMap; // ================================================================================= // Fog #include "fog.fxh" // ================================================================================= // Return Color final.a = 1.0; return final; } technique terrainBlend { pass { #include "samplerStates.fxh" VertexShader = compile vs_3_0 VertexShaderFunction(); PixelShader = compile ps_3_0 PixelShaderFunction(); } } Yup 7 layers of textures and a lightmap to boot. Ok looks a little daunting at first but here is what it is doing. final is the returned pixel color and texture16 (0-15 samplers) is scaled (tiled) across the terrrain at scale16 times. This is the base texture for the whole terrain. final = tex2D(texture16Sampler, input.uv1 * uvScale16); Then blend texture02Sampler with a bitmap mask or whatever mask you have defined. The mask just needs to be 24 bit and I use bmp's for the mask even though I uploaded a jpg. IE just doesn't want to display a bmp. // ================================================================================= // Terrain Layer 1 maskMap = tex2D(texture01Sampler, input.uv1 * uvScale01); if (maskMap.r > 0.0) { b1 = 1.0 - maskMap.r; b2 = 1.0 - b1; ts = tex2D(texture02Sampler, input.uv1 * uvScale02); final = (final * b1) + (ts * b2); } Here's the code to get the shader script executed: r = shader->effect->Begin(&shader->passes, NULL); for (UINT x=0;x<shader->passes;x++) { r = shader->effect->BeginPass(x); r = graphics->device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, nbrVert, 0, count); r = shader->effect->EndPass(); } r = shader->effect->End(); I used an indexed list of vertexes but you can use drawprimitive if you like. Not sure what you application is. And thats all there is to it. It looks real nice when you get the shader script working and you don't need 12x128x2 triangles to do the blend. You can actually do it on 1 triangle so you should be able to apply this to any form of texture blending that you may need. PS. Fog way to cool. float fogStart = 256.0; float fogEnd = 4096.0; float fogDensity = 0; float minFog = 0.0; float maxFog = 1.0; float3 fogColor = {0.85, 0.85, 0.85}; if (fogDensity > 0) { float fog = (input.Depth - fogStart) / (fogEnd - fogStart); fog *= fogDensity; fog = clamp(fog, minFog, maxFog); final = lerp(final, float4(fogColor, 1.0), fog); } Oh and one final note, you don't have to do just textures for a terrain. You can use a normal map and do per pixel bump mapping for dynamic lighting. final = tex2D(texture01Sampler, input.uv1); normalMap = tex2D(texture02Sampler, input.uv1); NdL = dot(lightDir, normalMap); final *= NdL; let's not forget to make the alpha channel of the pixel 1 so it does't blend with itself. final.a = 1.0; And a really, really good texture artist is a must for making a real nice looking terrain so you don't get the fish net looking tiling from a semi-seemless texture pack. Way to go Id Software. http://www.moddb.com/games/enemy-territory-quake-wars/addons/mega-texture-media-pack and voila! Happy terraining!
  8. Hi, This is probably way late for your regression testing but it is one of the most asked about and not well documented topics so I thought I would answer it here. The way I resolved this was to create a surface area the size of the text to be displayed and then copied it to a texture. You can then apply the texture to some geometry and use it like a regular texture. I pass mine to a pixel shader so that I can do some effects with it. So here are some code snips so you can see how it works. // I define a font in order to get the texture dimensions in pixels [font=courier new,courier,monospace]D3DXCreateFont(device, size, // height of font 0, // average character width w, // font weight 1, // mip levels 0, // italic attribute option DEFAULT_CHARSET, // character set identifier OUT_DEFAULT_PRECIS, // output precision PROOF_QUALITY, // output quality DEFAULT_PITCH|FF_MODERN, // fPitch and family typeface, // typeface name &font );[/font] // Here's how you get the pixel width and height for the string: [font=courier new,courier,monospace]HDC hdc = font->GetDC(); GetTextExtentPoint32(hdc, str, strlen(str), &sz);[/font] // Here's the surface that the text will be drawn on // notice that it uses the system mem pool so be carefull if you have like thousands of name plates being rendered // if you are not threading memory shouldn't be a problem as this surface is freed at the end [font=courier new,courier,monospace]device->CreateOffscreenPlainSurface(sz->cx, sz->cy, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &pRenderTarget, 0);[/font] // Here's the texture where the surface is copied to [font=courier new,courier,monospace]D3DXCreateTexture(device, sz->cx, sz->cy, 1, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pRenderTargetTexture);[/font] // get the device context for the render target (the surface not the texture) [font=courier new,courier,monospace]pRenderTarget->GetDC(&hRenderTarget);[/font] // set up a log font [font=courier new,courier,monospace]logfont.lfWidth = font->GetDesc()->Width; logfont.lfHeight = font->GetDesc()->Height; logfont.lfWeight = font->GetDesc()->Weight; logfont.lfCharSet = font->GetDesc()->CharSet; logfont.lfOutPrecision = font->GetDesc()->OutputPrecision; logfont.lfQuality = font->GetDesc()->Quality; logfont.lfPitchAndFamily = font->GetDesc()->PitchAndFamily; strcpy(logfont.lfFaceName, font->GetDesc()->FaceName);[/font] // create the log font [font=courier new,courier,monospace]hFont = CreateFontIndirect(&logfont);[/font] // use the font for the text to be drawn [font=courier new,courier,monospace]SelectObject(hRenderTarget, hFont); SetBkMode(hRenderTarget, TRANSPARENT); SetBkMode(hRenderTarget, OPAQUE); SetBkColor(hRenderTarget, RGB(0, 0, 0)); SetTextColor(hRenderTarget, RGB(255, 0, 0));[/font] // draw the text to the render target (surface) [font=courier new,courier,monospace]DrawText(hRenderTarget, str, -1, &rect, DT_LEFT|DT_NOCLIP|DT_SINGLELINE);[/font] // release the surfaces device context [font=courier new,courier,monospace]pRenderTarget->ReleaseDC(hRenderTarget);[/font] // done with the log font [font=courier new,courier,monospace]DeleteObject(hFont);[/font] // rectangle for dimensions of the text [font=courier new,courier,monospace]rect.left = 0; rect.top = 0; rect.bottom = sz->cy; rect.right = sz->cx;[/font] // this gets the surface area of the texture [font=courier new,courier,monospace]pRenderTargetTexture->GetSurfaceLevel(0, &pRenderTargetTextureSurface);[/font] // then use UpdateSurface to copy the drawn text surface to the texture's surface [font=courier new,courier,monospace]device->UpdateSurface(pRenderTarget, &rect, pRenderTargetTextureSurface, &p);[/font] // release the render surface because you don't need it anymore [font=courier new,courier,monospace]if (pRenderTarget) { pRenderTarget->Release(); pRenderTarget = 0; }[/font] And that is all there is to making billboarded text with Directx9 and Windows. I do know that OGL has similar API's for setting up fonts, surfaces, and textures so it could be the same thought process. I don't know what the API's are in XNA C# so hope this helps to give some insight on what to do with that.
  • Advertisement

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!