• 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.

Kjell Andersson

  • Content count

  • Joined

  • Last visited

Community Reputation

657 Good

About Kjell Andersson

  • Rank

Personal Information

  • Location
  1. It's time for a game release again. This time it's going on Steam GreenLight (for as long as it's still available).   This is quite a different type of game in that it's not actually a game per se but more of an amusement experience for virtual reality that is playing with the feeling of personal connection. It's a virtual dance floor where you get to dance with virtual characters to your favourite music. I guarantee you that your dance partner will notice your presence!   Check it out on Steam: http://steamcommunity.com/sharedfiles/filedetails/?id=864584902      
  2. If you want to go all-in for a good implementation of text rendering you should look up the concept of "Signed Distance Field Text Rendering".   The original article that introduced the concept was written by Valve and can be found here: http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf
  3. The Caustics Generator is now also available in a Free version for all you Mac hobby developers.
  4. I like the one with the eyes more. It gives the character more personality.   You could go half way and keep a small shadow instead of going all black.
  5. Caustics Generator is now available for Mac OS X. This is the first release on the Mac platform of the software and has been longed for by the graphical artists and designers that love to work on their Mac. The Caustics Generator software allows artists to create faked water lighting by generating pre-calculated caustics textures that seamlessly tile and animate. These texture can be used for both real-time graphics such as games and simulations but are also very popular by the architect, movie and advertising industry as part of the rendering pipeline for creating computer graphics visualizations. The Caustics Generator software has previously only been available for Windows and Linux, but this release meets many artists on their choice of computer. More information about the Caustics Generator can be found at: https://www.dualheights.se/caustics  
  6. The following code provides you with vertices and face indices from a D3DXMesh. You will have to write the code that saves it to file yourself, but that should be easy. LPD3DXMESH m_pD3DMesh; void MeshXWrapper::GetMeshData(int *pMeshVertexCount, dVector3 **ppMeshVertices, int *pMeshIndexCount, int **ppMeshIndices) { LPDIRECT3DVERTEXBUFFER9 pVB = NULL; m_pD3DMesh->GetVertexBuffer(&pVB); struct MY_FVF { float x; float y; float z; }; void *pbVertexData; if (SUCCEEDED(pVB->Lock(0, 0, &pbVertexData, D3DLOCK_READONLY))) { DWORD numBytesPerVertex = m_pD3DMesh->GetNumBytesPerVertex(); int numVertices = m_pD3DMesh->GetNumVertices(); *ppMeshVertices = new dVector3[numVertices]; unsigned char *pVBDataPos = (unsigned char*)pbVertexData; for (int i=0; i < numVertices; i++) { (*ppMeshVertices)[i][0] = ((MY_FVF*)pVBDataPos)->x; (*ppMeshVertices)[i][1] = ((MY_FVF*)pVBDataPos)->y; (*ppMeshVertices)[i][2] = ((MY_FVF*)pVBDataPos)->z; (*ppMeshVertices)[i][3] = 0; pVBDataPos += numBytesPerVertex; } pVB->Unlock(); *pMeshVertexCount = m_pD3DMesh->GetNumVertices(); } // Index buffer LPDIRECT3DINDEXBUFFER9 pIB; m_pD3DMesh->GetIndexBuffer(&pIB); D3DINDEXBUFFER_DESC indexDesc; pIB->GetDesc(&indexDesc); LPVOID pbIndexData; if (SUCCEEDED(m_pD3DMesh->LockIndexBuffer(D3DLOCK_READONLY, &pbIndexData))) { *pMeshIndexCount = indexDesc.Size / sizeof(unsigned short); *ppMeshIndices = new int[*pMeshIndexCount]; for (int i=0; i<(*pMeshIndexCount)/3; i++) { unsigned short i0 = ((unsigned short*)pbIndexData)[i*3+0]; unsigned short i1 = ((unsigned short*)pbIndexData)[i*3+1]; unsigned short i2 = ((unsigned short*)pbIndexData)[i*3+2]; (*ppMeshIndices)[i*3+0] = i0; (*ppMeshIndices)[i*3+1] = i1; (*ppMeshIndices)[i*3+2] = i2; } m_pD3DMesh->UnlockIndexBuffer(); } pIB->Release(); pVB->Release(); }
  7. Oh, forgot to mention that it was the IOTD game I meant. Silly me. But it seems to be working now again so it's all right.
  8. The right side image is always broken and never loads (404).
  9. This is the code that I use to take screenshots in-app. Note that if run in windowed mode it captures the entire desktop and cuts out the window area. This means that if some other window is put in front of your window it will capture that data as well. LPDIRECT3DSURFACE9 CaptureScreen() { UINT width; UINT height; if (IsFullscreen()) { width = GetDisplayWidth(); height = GetDisplayHeight(); } else { width = GetSystemMetrics(SM_CXSCREEN); height = GetSystemMetrics(SM_CYSCREEN); } LPDIRECT3DSURFACE9 pCaptureSurface; HRESULT hr = GetD3DDevice()->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCaptureSurface, NULL); if (FAILED(hr)) { SAFE_RELEASE(pCaptureSurface); return NULL; } hr = GetD3DDevice()->GetFrontBufferData(0, pCaptureSurface); if (FAILED(hr)) { SAFE_RELEASE(pCaptureSurface); return NULL; } return pCaptureSurface; } bool TakeScreenshot(const std::wstring& filename) { LPDIRECT3DSURFACE9 pCaptureSurface = GetGraphicsDevice()->CaptureScreen(); HRESULT hr = E_FAIL; if (pCaptureSurface != NULL) { D3DXIMAGE_FILEFORMAT imageFileFormat = D3DXIFF_JPG; std::wstring fileExtention = GXFile::GetFileExtention(filename); if (GXString::CompareNoCase(fileExtention.c_str(), L"bmp")) { imageFileFormat = D3DXIFF_BMP; } else if (GXString::CompareNoCase(fileExtention.c_str(), L"png")) { imageFileFormat = D3DXIFF_PNG; } if (GetGraphicsDevice()->IsFullscreen()) { hr = D3DXSaveSurfaceToFile(filename.c_str(), imageFileFormat, pCaptureSurface, NULL, NULL); if (FAILED(hr)) { GXLOG_WARN_F(L"Failed to save fullscreen screenshot to %s", filename.c_str()); } } else { // Calculate the rectangle within the screen that the window is currently located. // I.e. 0,0 is top left of screen for all screens even on multi-monitor setups. RECT rcWindow; GetClientRect(m_hWnd, &rcWindow); POINT topPoint = {rcWindow.left, rcWindow.top}; POINT bottomPoint = {rcWindow.right, rcWindow.bottom}; ClientToScreen(m_hWnd, &topPoint); ClientToScreen(m_hWnd, &bottomPoint); rcWindow.left = topPoint.x; rcWindow.top = topPoint.y; rcWindow.right = bottomPoint.x; rcWindow.bottom = bottomPoint.y; for (unsigned int i = 0; i < m_displays.size(); i++) { RECT rcDest; if (IntersectRect(&rcDest, &m_displays[i].rect, &rcWindow)) { rcWindow.left -= m_displays[i].rect.left; rcWindow.top -= m_displays[i].rect.top; rcWindow.right -= m_displays[i].rect.left; rcWindow.bottom -= m_displays[i].rect.top; break; } } hr = D3DXSaveSurfaceToFile(filename.c_str(), imageFileFormat, pCaptureSurface, NULL, &rcWindow); if (FAILED(hr)) { GXLOG_WARN_F(L"Failed to save windowed screenshot to %s", filename.c_str()); } } SAFE_RELEASE(pCaptureSurface); } return SUCCEEDED(hr); }
  10. What is the best way of finding D3D9 resource leaks on a Windows 10 machine nowadays? I must add that the leak is not easily reproducible also.   I find it more and more difficult to work with legacy D3D9 applications since the debug version no longer works on a modern Windows. Are there any new tools available that can help me, like nSight or GPU PerfStudio or such?
  11. Thanks! I kind of liked the scattering of specular around the rim before multiplying with NdotL, but I guess that should not be part of the Blinn calculations but rather some subsurface scattering effect.
  12. I'm implementing Blinn-Phong lighting in a pixel shader and is getting an artifact that I don't like. I'm tossing out a screenshot here to ask if this is normal for Blinn-Phong or if I have gotten something wrong with my calculations. [attachment=29316:BlinnPhongArtifact.jpg]   The light source is coming from behind the sphere and is directed towards the viewer. It is supposed to be a directional light. On the screenshot to the left the specular light is barely visible on the rim, which is perfectly fine. The problem occurs when moving a bit further behind the sphere. The specular light then becomes a cone and is detached from the rim in an unnatural way. Moving further behind the sphere makes it fade away but it keeps moving inwards the sphere before it disappears.   Lets toss in the code here as well if you want to inspect it (beware, experimental code that is not production-worthy). struct VertDataIn { float4 Position : POSITION; float3 Normal : NORMAL; float4 Color : COLOR; float2 Texture : TEXCOORD0; }; struct VertDataOut { float4 Position : POSITION; float4 Color : COLOR; float2 Texture : TEXCOORD0; float3 Normal : TEXCOORD1; float3 WorldPosition : TEXCOORD2; }; VertDataOut VS_Main(VertDataIn In) { VertDataOut Out; Out.Texture = In.Texture.xy; In.Position.w = 1; Out.Position = mul(In.Position, g_worldViewProjectionTransform); Out.Color = In.Color * g_diffuseColor; Out.Normal = mul(In.Normal, g_worldTransform); Out.WorldPosition = mul(In.Position, g_worldTransform); return Out; } ColorPair CalculateDirectionalLightBlinnPhong(float3 N, float3 V, int i) { ColorPair Out; float3 L = -normalize(g_directionalLights[i].dir); float NdotL = dot(N, L); Out.ColorDiffuse = g_directionalLights[i].ambient; Out.ColorSpecular = 0; if (NdotL > 0.0f) { Out.ColorDiffuse += NdotL * g_directionalLights[i].diffuse; } float3 H = normalize(L + V); Out.ColorSpecular = pow(saturate(dot(H, N)), g_materialPower) * g_directionalLights[i].specular; return Out; } float4 PS_Main(VertDataOut Input) : COLOR { float4 col = Input.Color; if (g_hasDiffuseTexture) { col *= tex2D(Sampler, Input.Texture); } // Directional lights float4 diffuseColor = float4(0, 0, 0, 0); float4 specularColor = float4(0, 0, 0, 0); for(int i = 0; i < g_numDirectionalLights; i++) { ColorPair colorOut = CalculateDirectionalLightBlinnPhong(normalize(Input.Normal), normalize(g_cameraPosition - Input.WorldPosition), i); diffuseColor += colorOut.ColorDiffuse; specularColor += colorOut.ColorSpecular; } col.rgb *= (diffuseColor.rgb + specularColor.rgb); return col; }
  13. Great input that I should work towards a cbuffer friendly interface!
  14. I'm in the process of abstracting away the D3D9 usage in an application in order to be able to slowly migrate to a newer API in the future. The first step in this is to create a DX9 rendering back-end that supports the current functionality but without using the legacy D3DX interfaces.   My problem right now comes to the introspection of the shader code in order to map data into constant buffers, i.e. shader variables and texture input. I'm trying to use the D3DCompile(), CreateVertexShader(), SetVertexShaderConstant() interfaces instead of the D3DX and effect framework and thus need to be able to map variable names to register numbers that can be passed to the SetVertexShaderConstant() function.   If you don't specify any registers manually in your shader, the compiler automatically assigns them, but how do you get that information out from the compiled shader?   Is there a way to do this mapping table automatically instead of manually specifying register usage in the shader and then creating a mapping table outside of the shader?
  15. I finally got this... I forgot to reset the stream pointer in the overloaded Open() call even though it explicitly told me to do so in the doxygen comments for the method... A good night's sleep was the solution