Jump to content

  • Log In with Google      Sign In   
  • Create Account

DeadMG

Member Since 01 Jan 2010
Offline Last Active May 10 2012 04:08 PM

Posts I've Made

In Topic: Using D3DPT_LINELIST

01 April 2012 - 04:34 AM

Turns out that I forgot to set the shader to the device when drawing- a silly error.

In Topic: Camera rolling

30 March 2012 - 05:33 AM

Thanks for the tips guys. I decided to shelve this camera style for now but will be revisiting it in the future.

In Topic: Depth buffer doesn't write in Direct3D9

09 March 2012 - 06:35 PM

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:

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()));
}

In Topic: Depth buffer doesn't write in Direct3D9

09 March 2012 - 09:59 AM

Yes. I only cleared it to 0 to see if the test was being performed correctly.

In Topic: You can actually do that? Creating open-source fan-made games legally.

09 March 2012 - 07:39 AM

Yeah. WoW was such a copy paste, it utterly flattened everybody else by simply being the same as them. Nice personal feeling bro.

PARTNERS