programstudent1
programstudent1

Reputation: 35

trying to add a wave effect to a vertex plane

so what this is supposed to do it create a plane that moves in a sine wave pattern (code that has nothing to do with making it a wave is not shown as it all works fine) and while the plane renders fine it just stays as a flat plane. I'm assuming the problem is that the frame time isn't being called by the vertex shader so I'd like to know how to do that because I'm confused as to why this isn't working enter image description here the plane I'm trying to make into a wave ^

manipulation_shader_vs.hlsl

cbuffer TimeBufferType : register(b1)
{
    float time;
};

OutputType main(InputType input)
{
    OutputType output;
    input.position.y = sin(input.position.x + time);
    input.normal = float3(-cos(input.position.x + time), 1, 0);
    ...


timer.cpp

void Timer::frame()
{
    INT64 currentTime;
    float timeDifference;

    // Query the current time.
    QueryPerformanceCounter((LARGE_INTEGER*)&currentTime);
    timeDifference = (float)(currentTime - startTime);
    frameTime = timeDifference / ticksPerS;

    // Calc FPS
    frames += 1.f;
    elapsedTime += frameTime;
    if (elapsedTime > 1.0f)
    {
        fps = frames / elapsedTime;
        frames = 0.0f;
        elapsedTime = 0.0f;
    }
    
    // Restart the timer.
    startTime = currentTime;

    return;
}


float Timer::getTime()
{
    return frameTime;
}

manipulationshader.cpp

void ManipulationShader::setShaderParameters(ID3D11DeviceContext* deviceContext, const XMMATRIX& worldMatrix, const XMMATRIX& viewMatrix, const XMMATRIX& projectionMatrix, ID3D11ShaderResourceView* texture, Light* light, Timer* time)
{
    TimeBufferType* timePtr;
    deviceContext->Map(TimeBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
    timePtr = (TimeBufferType*)mappedResource.pData;
    timePtr->time = time->getTime();
    deviceContext->Unmap(TimeBuffer, 0);
    deviceContext->PSSetConstantBuffers(0, 1, &TimeBuffer);
}

Upvotes: 0

Views: 398

Answers (1)

Chuck Walbourn
Chuck Walbourn

Reputation: 41097

This is a classic "0 vs. 1 base" bug.

In your shader you have the constant buffer bound to slot 1.

cbuffer TimeBufferType : register(b1)

In your code, you are binding the constant buffer to slot 0.

deviceContext->PSSetConstantBuffers(0, 1, &TimeBuffer);

and as noted in the comments by another StackOverflow user, you are binding it only for the pixel shader, not the vertex shader. You are therefore missing this method call:

deviceContext->VSSetConstantBuffers(0, 1, &TimeBuffer);

It's also important in Direct3D coding to always check functions that return HRESULT for success or failure. It's very hard to debug complex programs otherwise. For many cases, a "fast-fatal" solution like ThrowIfFailed works well. You can also use a conditional like the following:

D3D11_MAPPED_SUBRESOURCE mappedResource = {};
if (SUCCEEDED(deviceContext->Map(TimeBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0,
    &mappedResource)))
{
    auto timePtr = reinterpret_cast<TimeBufferType*>(mappedResource.pData);
    timePtr->time = time->getTime();
    deviceContext->Unmap(TimeBuffer, 0);
}

See Microsoft Docs.

One additional recommendation: Take a look at StepTimer for your 'animation time' computation. Time computation is quite tricky, and there are quite a number of edge-cases you are not dealing with. For more, see this blog post.

Upvotes: 1

Related Questions