• Advertisement

DeadMG

Member
  • Content count

    31
  • Joined

  • Last visited

Community Reputation

100 Neutral

About DeadMG

  • Rank
    Member
  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. Using D3DPT_LINELIST

    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. Camera rolling

    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. Matrix Begins To Rotate Incorrectly

    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. Matrix Begins To Rotate Incorrectly

    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. Matrix Begins To Rotate Incorrectly

    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. Matrix Begins To Rotate Incorrectly

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