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


  • Content count

  • Joined

  • Last visited

Community Reputation

100 Neutral

About DeadMG

  • Rank
  1. I'm developing an application in Direct3D9, and the Debug runtime spews the titular error when I attempt to set my projection matrix. I've got the following code: [color=#000000][code]D3DXMatrixPerspectiveFovLH( &Projection, D3DXToRadian(90), (float)GetDimensions().x / (float)GetDimensions().y, NearPlane, FarPlane ); D3DCALL(device->SetTransform( D3DTS_PROJECTION, &Projection ));[/code][/color] I checked in advance, and I have only one thread, the x and y values are 1920 and 1018 (the dimensions of the client area of my window), and the NearPlane is 0.1f and the FarPlane is 40.0f- I confirmed these values by breakpoint. The only times I've seen this error previously, and the only causes I could find via Google, were when the NearPlane is 0, which is not the case here. Edit: Never mind, my own silly fault. I accidentally used a bad pointer to call this function.
  2. Turns out that I forgot to set the shader to the device when drawing- a silly error.
  3. I've got some code that renders some triangle lists in 3D. Here is my vertex declaration: [code] D3DVERTEXELEMENT9 BasicMeshVertices[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {1, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1}, {1, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2}, {1, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3}, {1, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() };[/code] I use the code to pass the world matrix and colour to the shader per instance. This code works exactly how it should. However, when I attempt to use this to render a series of 3D lines using D3DPT_LINELIST, the D3D Debug Runtime tells me that my vertex declaration is wrong. I have a shader that works fine with this vertex input for the triangle list. Any suggestions as to what the problem could be? Here is my sample Draw code. The LineVerts are a simple {0, 0, 0} and {1, 0, 0} to represent a unit line on the X axis, and the indices are a simple {0, 1}. [code] D3DCALL(device->SetVertexDeclaration(VertexDecl)); D3DCALL(device->SetStreamSource(1, PerBoneBuffer.get(), 0, sizeof(PerInstanceData))); D3DCALL(device->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA | 1)); D3DCALL(device->SetStreamSource(0, LineVerts, 0, sizeof(D3DXVECTOR3))); D3DCALL(device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | lines.size())); D3DCALL(device->SetIndices(LineIndices)); PerInstanceData* data; std::vector<Wide::Render::Line*> lines_vec(lines.begin(), lines.end()); D3DCALL(PerBoneBuffer->Lock(0, lines.size() * sizeof(PerInstanceData), reinterpret_cast<void**>(&data), D3DLOCK_DISCARD)); std::for_each(lines.begin(), lines.end(), [&](Wide::Render::Line* ptr) { data->Color = D3DXColor(ptr->Colour); D3DXMATRIXA16 Translate, Scale, Rotate; D3DXMatrixTranslation(&Translate, ptr->Start.x, ptr->Start.y, ptr->Start.z); D3DXMatrixScaling(&Scale, ptr->Scale, 1, 1); D3DXMatrixRotationQuaternion(&Rotate, &D3DQuaternion(ptr->Rotation)); data->World = Scale * Rotate * Translate; }); D3DCALL(PerBoneBuffer->Unlock()); D3DCALL(device->DrawIndexedPrimitive(D3DPRIMITIVETYPE::D3DPT_LINELIST, 0, 0, 2, 0, 1));[/code]
  4. Thanks for the tips guys. I decided to shelve this camera style for now but will be revisiting it in the future.
  5. No. None of the pixels are being rejected- so you can see through parts of the model to parts which are supposed to be obscured. When I look at the depth buffer in PIX, it's all still got the original 1 value. I fixed the D3D Debug Runtime, found a few bugs but fixing them had no effect. Here's my code for rendering: [CODE] void Scene3D::Render( float dt, IDirect3DDevice9* device, IDirect3DVertexDeclaration9* VertexDecl, ID3DXEffect* RenderOnlyAmbientLightEffect ) const { bool first = true; auto SetRenderTargetToDevice = [&] { std::unique_ptr<IDirect3DSurface9, COMDeleter> RenderTargetSurface; D3DCALL(RenderTarget->GetSurfaceLevel(0, PointerToPointer(RenderTargetSurface))); D3DCALL(device->SetRenderTarget(0, RenderTargetSurface.get())); D3DCALL(device->SetDepthStencilSurface(DepthBuffer.get())); if (first) { D3DCALL(device->Clear(0, nullptr, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DColour(ClearColour), 1, 0)); first = false; } }; auto SetMeshSpecificDataToEffect = [&](ID3DXEffect* effect, const Direct3D9::Mesh* mesh) { auto RenData = mesh->GetRenderData(); /*if (auto handle = effect->GetParameterByName(0, "ColourMap")) { effect->SetTexture(handle, RenData.Texture); }*/ if (auto handle = effect->GetParameterByName(0, "AmbientMaterial")) { effect->SetVector(handle, reinterpret_cast<D3DXVECTOR4*>(&RenData.AmbientMaterial)); } if (auto handle = effect->GetParameterByName(0, "DiffuseMaterial")) { effect->SetVector(handle, reinterpret_cast<D3DXVECTOR4*>(&RenData.DiffuseMaterial)); } if (auto handle = effect->GetParameterByName(0, "SpecularMaterial")) { effect->SetVector(handle, reinterpret_cast<D3DXVECTOR4*>(&RenData.SpecularMaterial)); } }; auto SetCameraSpecificDataToEffect = [&](ID3DXEffect* effect) { if (auto handle = effect->GetParameterByName(0, "CameraVP")) { D3DXMATRIX Projection; D3DXMATRIX View; auto lookingat = D3DVector(camera.Position + camera.LookingAt); D3DXMatrixLookAtLH( &View, &D3DVector(camera.Position), &lookingat, &D3DVector(camera.Up) ); #pragma warning(disable : 4244) D3DXMatrixPerspectiveFovLH( &Projection, D3DXToRadian(90), GetDimensions().x / GetDimensions().y, camera.NearPlane, camera.FarPlane ); #pragma warning(default : 4244) effect->SetMatrix(handle, &(View * Projection)); } }; // Define a couple variables the helpers can use auto SendAllVerticesToPipeline = [&, this](ID3DXEffect* effect, const std::unordered_map<const Direct3D9::Mesh*, std::unordered_set<Object*>>& ObjectsByMesh) { std::for_each(ObjectsByMesh.begin(), ObjectsByMesh.end(), [&](const decltype(*ObjectsByMesh.begin())& group) { // Set all per-mesh data - first to the pipeline auto RenData = group.first->GetRenderData(); D3DCALL(device->SetStreamSource( 0, RenData.VertexBuffer, 0, sizeof(Render::InputMesh::Vertex) )); D3DCALL(device->SetStreamSource( 1, InstanceBuffer.get(), 0, sizeof(D3DXMATRIX) )); D3DCALL(device->SetIndices( RenData.IndexBuffer )); // then to the effect SetMeshSpecificDataToEffect(effect, group.first); auto handle = effect->GetTechniqueByName("PrimaryTechnique"); D3DCALL(effect->SetTechnique(handle)); D3DCALL(device->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | group.second.size())); auto bones = group.first->GetBones(); std::for_each(bones.begin(), bones.end(), [&](const decltype(*bones.begin())& bone) { std::vector<Direct3D9::Bone*> bones; std::for_each(group.second.begin(), group.second.end(), [&](const Wide::Direct3D9::Object* obj) { bones.push_back(obj->GetBoneByName(bone->Name)); }); D3DXMATRIXA16* matrices; D3DCALL(InstanceBuffer->Lock(0, bones.size() * sizeof(D3DXMATRIXA16), reinterpret_cast<void**>(&matrices), D3DLOCK_DISCARD)); std::for_each(bones.begin(), bones.end(), [&](Direct3D9::Bone* bone) { *matrices = bone->World; matrices++; // Guaranteed not to overflow because we already made the size as large as we needed it }); D3DCALL(InstanceBuffer->Unlock()); unsigned int passes; D3DCALL(effect->Begin(&passes, 0)); for(unsigned int i = 0; i < passes; i++) { D3DCALL(effect->BeginPass(i)); D3DCALL(device->DrawIndexedPrimitive( D3DPRIMITIVETYPE::D3DPT_TRIANGLELIST, 0, 0, bone->NumVerts, bone->IndexBegin, bone->NumIndices / 3 )); D3DCALL(effect->EndPass()); } D3DCALL(effect->End()); }); }); }; // Save the original back buffer and depth stencil std::unique_ptr<IDirect3DSurface9, COMDeleter> BackBuffer; std::unique_ptr<IDirect3DSurface9, COMDeleter> DepthStencil; D3DCALL(device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, PointerToPointer(BackBuffer))); D3DCALL(device->GetDepthStencilSurface(PointerToPointer(DepthStencil))); // Sort the objects by mesh, and compute the world matrices whilst you're at it. std::unordered_map<const Direct3D9::Mesh*, std::unordered_set<Object*>> ObjectsByMesh; std::for_each(Objects.begin(), Objects.end(), [&](Wide::Render::Object* ptr) { auto d3dptr = static_cast<Wide::Direct3D9::Object*>(ptr); d3dptr->ComputeWorldMatrices(); ObjectsByMesh[d3dptr->GetMesh().get()].insert(d3dptr); }); // Resize the buffer, if it's not big enough to hold what we're doin here. unsigned int maxsize = 0; std::for_each(ObjectsByMesh.begin(), ObjectsByMesh.end(), [&](const decltype(*ObjectsByMesh.begin())& group) { maxsize = std::max(maxsize, group.second.size()); }); if (InstanceBufferSize < maxsize) { InstanceBufferSize = maxsize; ResetInstanceBuffer(device); } // Set the mesh-independent stuff to the device D3DVIEWPORT9 vp = { 0, 0, GetDimensions().x, GetDimensions().y, 0, 1 }; D3DCALL(device->SetViewport(&vp)); D3DCALL(device->SetVertexDeclaration(VertexDecl)); D3DCALL(device->SetStreamSource(1, InstanceBuffer.get(), 0, sizeof(D3DXMATRIXA16))); D3DCALL(device->SetStreamSourceFreq(1, D3DSTREAMSOURCE_INSTANCEDATA | 1)); // If there is only ambient light, then just render directly to BB with no shadow mapping //if (Lights.empty()) { // Render ambient only- no shadowmapping needed SetRenderTargetToDevice(); SetCameraSpecificDataToEffect(RenderOnlyAmbientLightEffect); SendAllVerticesToPipeline(RenderOnlyAmbientLightEffect, ObjectsByMesh); //} // Restore the previous backbuffer and depth stencil D3DCALL(device->SetRenderTarget(0, BackBuffer.get())); D3DCALL(device->SetDepthStencilSurface(DepthStencil.get())); } [/CODE]
  6. Yes. I only cleared it to 0 to see if the test was being performed correctly.
  7. As the title says, my application will not write new depths to the depth buffer in D3D9. I've used PIX to confirm that the depth buffer is cleared and set to the device as it should be, and the depth test is even used- if I clear it to 0, then all the pixels are rejected against buffer. I've checked the return code of all D3D9 functions and got nothing. I even explicitly set the render states in the shader to the appropriate values to no avail. Any suggestions? In an unfortunately unrelated issue, the Direct3D debug runtime is not functioning correctly and I don't have it's output. I am trying to solve this issue as quickly as possible.
  8. I've asked about this before, but the topic appears to have gone doolally. I have a camera floating in 3D space. I'm trying to implement a relatively simple system where the user moves the mouse and the camera rotates in that direction, and they can push the keyboard to move the camera's position, so allowing free view of whatever's in said 3D space. Now I've got a small problem. The user can obviously only move the mouse in two dimensions- x and y, and the code only rotates around the x and y axis. To keep the rotations relative I also rotate all three axis by every rotation. This works fine in the short term- the camera moves exactly as expected. However, once the user starts to rotate the camera often, the camera starts to slowly roll. You can move the mouse in a circle and exaggerate the effect to produce purely rolling. I wish to eliminate this issue. I've used quaternions to represent each rotation in a sequence. I attach some hopefully easy C++ code in case I have made a simple mistake. [CODE] Math::AbsolutePoint previous; previous.x = 0; previous.y = 0; Math::Vector CameraXAxis = Math::Vector(1, 0, 0); Math::Vector CameraYAxis = Math::Vector(0, 1, 0); Math::Vector CameraZAxis = Math::Vector(0, 0, 1); auto RotateAxis = [&](Math::Quaternion q) { CameraXAxis = CameraXAxis * q; CameraYAxis = CameraYAxis * q; CameraZAxis = CameraZAxis * q; Scene3D->camera.LookingAt = CameraZAxis; Scene3D->camera.Up = CameraYAxis; }; window->OnKeyDown = [&](Wide::OS::Key k) { switch(k) { case OS::Key::DownArrow: Scene3D->camera.Position -= CameraYAxis; return; case OS::Key::UpArrow: Scene3D->camera.Position += CameraYAxis; return; case OS::Key::LeftArrow: Scene3D->camera.Position -= CameraXAxis; return; case OS::Key::RightArrow: Scene3D->camera.Position += CameraXAxis; return; } }; window->OnMouseScroll = [&](int scroll, Math::AbsolutePoint position) { if (scroll > 0) Scene3D->camera.Position.z -= 1; if (scroll < 0) Scene3D->camera.Position.z += 1; }; window->OnMouseMove = [&](Math::AbsolutePoint position) { if (previous.x == 0) { previous = position; return; } Math::Quaternion addrotation; if (previous.x > position.x) { addrotation = Math::RotateAxis(3, CameraYAxis); } else if (previous.x < position.x) { addrotation = Math::RotateAxis(-3, CameraYAxis); } if (previous.y > position.y) { addrotation = Math::RotateAxis(3, CameraXAxis); } else if (previous.y < position.y) { addrotation = Math::RotateAxis(-3, CameraXAxis); } RotateAxis(addrotation); previous = position; }; [/CODE] Any suggestions?
  9. Yeah. WoW was such a copy paste, it utterly flattened everybody else by simply being the same as them. Nice personal feeling bro.
  10. I'm having some problems with ID3DXSprite and ID3DXFont where text will silently fail to render. When two fonts are created, even when they are identical, rendering from the second font will silently fail. I'm running with Direct3D in full debug mode and it doesn't report any errors or warnings and I'm using a macro to check the return values of all Direct3D functions. The first font still works correctly (at least, notwithstanding the second issue). If the first font's creation is commented out, the second font will work correctly. I have fully re-entrant code, no global variables. When I render more than one texture to the sprite, rendering will silently fail. This is most obvious because I have some animated buttons where the texture will change when moused over. Both textures are created beforehand. When mousing over, the texture changes and the text disappears. When the mouse leaves the button, the previous texture and the text re-appear. This is also completely silent from the Direct3D runtime. I initially thought that it must be a problem with my use of ID3DXFont but when the second problem manifested, I'm looking more at ID3DXSprite. This is my main rendering code (the parts that relate to ID3DXSprite). [code] D3DCALL(D3DSprite->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DO_NOT_ADDREF_TEXTURE | D3DXSPRITE_SORT_DEPTH_BACKTOFRONT | D3DXSPRITE_SORT_TEXTURE )); decltype(GetPtrs<D3D9Sprite>()) sprites = GetPtrs<D3D9Sprite>(); std::for_each(sprites.begin(), sprites.end(), [&, this](D3D9Sprite* sprite) { //D3DXVECTOR3 spritepos = sprite->position + sprite->center; if (!sprite->Visible()) return; D3DCALL(D3DSprite->Draw( sprite->owner->D3DTexture.get(), nullptr, &sprite->center, &sprite->position, 0xFFFFFFFF )); }); decltype(GetPtrs<D3D9Text>()) texts = GetPtrs<D3D9Text>(); std::for_each(texts.begin(), texts.end(), [&, this](D3D9Text* ptr) { if (!ptr->Visible()) return; RECT textbox = {0}; unsigned int format = 0; textbox.top = ptr->PositionY(); textbox.left = ptr->PositionX(); textbox.bottom = textbox.top + ptr->SizeY(); textbox.right = textbox.left + ptr->SizeX(); D3DCALL(ptr->owner->D3DXFont->DrawTextW( D3DSprite.get(), ptr->Text().c_str(), ptr->Text().size(), &textbox, format, ptr->Colour() )); }); decltype(GetPtrs<D3D9Button>()) buttons = GetPtrs<D3D9Button>(); std::for_each(buttons.begin(), buttons.end(), [&, this](D3D9Button* button) { if (!button->Visible()) return; D3DCALL(D3DSprite->Draw( button->owner->D3DTexture.get(), nullptr, &button->center, &button->position, 0xFFFFFFFF )); RECT textbox = {0}; unsigned int format = DT_CENTER | DT_VCENTER; textbox.top = button->PositionY() - (button->Texture()->SizeY() / 2); textbox.left = button->PositionX() - (button->Texture()->SizeX() / 2); textbox.bottom = button->PositionY() + (button->Texture()->SizeY() / 2); textbox.right = button->PositionX() + (button->Texture()->SizeX() / 2); D3DCALL(button->font->D3DXFont->DrawTextW( D3DSprite.get(), button->Text().c_str(), button->Text().size(), &textbox, format, button->Colour() )); }); D3DCALL(D3DSprite->End());[/code] Just a note- I'm using a C++0x compiler so there may be some unfamiliar constructs in here like decltype and lambda functions. If any clarification is needed just ask.
  11. Ah, interesting. I guess it's so rare that you come across a game with such freedom of motion, I've never come across it in any game I played and therefore assumed that it was an error. I guess that it can just live how it is.
  12. Is it preventable? It's not that I find it particularly objectionable personally, and I provide for roll controls so it's not exactly a death sentence, I just feel that potential players won't understand and find it confusing. On the other hand, I guess that the exact maneuvers required to produce a noticable result won't exactly be standard fare in the game vision I have, so I doubt that it'll be a big deal. I'll just leave it how it is.
  13. They're all about the local axis- the camera is completely free-floating in 3D space and the world axis mean nothing to the intended rotations. Storing separate Quaternions didn't really work out.
  14. How can I store internal pitch/yaw counts? If I want the camera to rotate relative to itself, then the axis around which those pitch and yaw degrees make sense change. They can't just go around the world axis. Perhaps I should store separate Quaternions for each rotation?
  15. I've got a simple matrix (4x4) intended to store rotations for my camera (in 3D). In response to mouse input, I pitch or yaw the camera, and always pass in constant zero for roll. However, after some uses, the camera begins to roll if the mouse is moved in a circular fashion. I've posted both my camera translation and rotation functions below. [code]D3DXMATRIX CameraRotationMatrix; D3DXVECTOR3 CameraPosition; //D3DXVECTOR3 CameraRotation; inline D3DXMATRIX GetRotationMatrix() { return CameraRotationMatrix; } inline void TranslateCamera(float x, float y, float z) { D3DXVECTOR3 rvec, vec(x, y, z); #pragma warning(disable : 4238) D3DXVec3TransformNormal(&rvec, &vec, &GetRotationMatrix()); #pragma warning(default : 4238) CameraPosition += rvec; RecomputeVPMatrix(); } inline void RotateCamera(float x, float y, float z) { D3DXVECTOR3 RotationRequested(x, y, z); D3DXVECTOR3 XAxis, YAxis, ZAxis; D3DXMATRIX rotationx, rotationy, rotationz; XAxis = D3DXVECTOR3(1, 0, 0); YAxis = D3DXVECTOR3(0, 1, 0); ZAxis = D3DXVECTOR3(0, 0, 1); #pragma warning(disable : 4238) D3DXVec3TransformNormal(&XAxis, &XAxis, &GetRotationMatrix()); D3DXVec3TransformNormal(&YAxis, &YAxis, &GetRotationMatrix()); D3DXVec3TransformNormal(&ZAxis, &ZAxis, &GetRotationMatrix()); #pragma warning(default : 4238) D3DXMatrixRotationAxis(&rotationx, &XAxis, RotationRequested.x); D3DXMatrixRotationAxis(&rotationy, &YAxis, RotationRequested.y); D3DXMatrixRotationAxis(&rotationz, &ZAxis, RotationRequested.z); CameraRotationMatrix *= (rotationx * rotationy * rotationz); RecomputeVPMatrix(); }[/code] I appreciate that this is the generic forum and this code is written with D3DX Maths, but I'm fairly sure that this is generic enough to qualify. If anyone would like some explaining comments, just ask. I tried writing a RotateYZ function that never went near X rotations, and the problem still manifests. I also tried spamming calls to this function with 0,0,0 (1500/sec) and the problem remained the same. So I'm fairly confident that it doesn't originate from the use of an accumulated matrix or the use of constant zero. But as for what the problem actually is, I don't know. The roll is always camera relative roll, not a world axis.