Hey all,
This is my first post on this forum, I can't seem to figure out this issue I'm facing (might just have stared at it for too long but it has kept me up for 2 days now).
I am writing a cross platform - cross api engine. I come from opengl and have lots of experience writing code for opengl. DirectX is still very new to me, so I see this as a challenge.
Currently I'm in the process of writing the shader code, so I create an interface (as with every other class) and succesfully implemented the opengl implementation. My 4 main functions are, bind and unbind, and addshadervariable and set shader variable.
Inside my addshadervariable, I pass along the type of the variable, the name inside the shader and the name I can use in the c++ code to get it from the map it's stored in. In opengl this just gets the locationid and uses the type to call the correct gluniform call. In directx I've learned to use constant buffers, and I got those working when using the default tutorials, (create a struct with your data and map it to the buffer). Now since my data is not constant (every shader can have different input, and users can make their own shaders too). I have thought of this solution:
struct DXVar
{
void* data;
};
std::vector<DXVar*> vsVars;
std::vector<DXVar*> psVars;
This way I can add any kind of data to the vector array, (the size of the data is stored someplace else so I can create the buffer with the appropriate size.
This is what I am currently trying in the setshadervariable code
void DXShader::setShaderVariable(const std::string& name, void* data)
{
auto it = shaderUniforms.find(name);
if (it != shaderUniforms.end())
{
switch (it->second->shaderType)
{
case ShaderType::SHADER_VS:
{
DXVar* v = vsVars.at(it->second->id);
v->data = data;
vsVars[it->second->id] = v;
D3D11_MAPPED_SUBRESOURCE sub;
DXContext::DirectXContext->devcon->Map(vsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sub);
// Second try
DXVar** bufferpointer = (DXVar**)sub.pData;
for (int i = 0; i < vsVars.size(); i++)
{
bufferpointer[i] = vsVars.at(i);
}
// First try
std::memcpy(sub.pData, vsVars.data(), vsBufferSize);
DXContext::DirectXContext->devcon->Unmap(vsBuffer, 0);
break;
}
}
}
}
note that I only use one of the tries (not both).
I cannot get this to work, for some reason the buffer is not being filled with the right data. When I put it like this:
D3D11_MAPPED_SUBRESOURCE sub;
DXContext::DirectXContext->devcon->Map(vsBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &sub);
DefaultDXShaderInputStruct* inputvs = (DefaultDXShaderInputStruct*)sub.pData;
inputvs->projection = Math::Matrix4(mat);
inputvs->view = getDefaultShaderInput().view;
inputvs->model = getDefaultShaderInput().model;
DXContext::DirectXContext->devcon->Unmap(vsBuffer, 0);
(the very basic way) it does work.
Can anyone help me figure this out?
Sincerely,
Roderick
PS: this is a public open source engine, if you need to take a look at the rest of the code, be my guest: