2016-04-10 9 views
0

Я только начать работать с DirectX, поэтому я получаю эту проблему:Присвоить структуру C++ с переменным HLSL

Я пытаюсь нажать/отправить/назначить на структуру C++ в/в/с переменной HLSL которые имеют одинаковый тип данных со структурой из C++.

В C++:

struct Light 
{ 
    Light() { 
     ZeroMemory(this, sizeof(Light)); 
    } 
    D3DXVECTOR3 LightPos; 
    float ID; 
}; 
Light L1; 

/.../ 

ID3D10EffectVariable* L1Var = NULL; 

/.../ 

L1Var = Effect->GetVariableByName("L1")->AsVector(); 

/.../ 


L1Var->SetRawValue(&L1, 0, sizeof(Light)); 

код HLSL:

struct Light { 
    float3 LightPos; 
    float ID; 
}; 

Light L1; 

Я пытаюсь отправленной структуру из C++ в 'L1' в HLSL, но я не уверен, что с правильностью L1 введите HLSL. Этот код работает, но я также получаю 0 для всех параметров в L1 ... Я не знаю, как это исправить, я google его в течение 5 часов без результата ... PLS помощи.

Благодарим за помощь.

ответ

0

Прежде всего, если вы новичок в программировании DirectX, я бы предложил не, инвестируя в DirectX 10. Вам следует использовать DirectX 11, поскольку он намного лучше поддерживается, имеет гораздо более соответствующий код утилиты и поддерживается на каждой платформе который поддерживает DirectX 10. Кроме того, вы используете устаревшую математику D3DX, поэтому вам обязательно нужно перейти к более современной среде разработки. Сейчас очень мало оснований использовать устаревший SDK DirectX. Смотрите здесь this blog post и MSDN. Вы найдете DirectX Tool Kit, и это tutorials хорошая отправная точка. Если вы действительно хотите придерживаться системы эффектов, см. Effects 11.

Имейте в виду, что постоянные буферы HLSL используют упаковку и выравнивание по-разному, чем стандартные структуры C/C++. Вы получаете более интуитивное поведение, если по возможности придерживаетесь 4-векторных структур вместо 3-векторных версий. Теоретически ваши структуры C/C++ и HLSL являются «совпадением», которые упаковывают данные в один 4-вектор, но различные настройки компилятора и правила упаковки могут отбросить это. См. Packing Rules for Constant Variables. Хороший способ проверить, является использование static_assert:

static_assert(sizeof(L1) == 16, "CB/struct mismatch"); 

Проблема, скорее всего, ваше использование системы эффекта. L1Var, вероятно, является фиктивной переменной из-за неудачного поиска, поэтому ваш SetRawValue ничего не собирается делать. Из фрагмента HLSL, который вы предоставили, мне непонятно, что ваша переменная HLSL L1 является даже постоянным буфером. Попробуйте код отладки:

auto tempVar = Effect->GetVariableByName("L1"); 
if (tempVar->IsValid()) 
{ 
    D3DX10_EFFECT_VARIABLE_DESC desc={0}; 
    tempVar->GetDesc(desc); 
    OutputDebugStringA(desc.Name); // Set a breakpoint here and look at desc 
    OutputDebugStringA("\n"); 
} 
else 
{ 
    OutputDebugStringA("L1 is not valid!\n"); 
} 
+0

большое спасибо за ответ. Хотелось бы тоже помочь с еще одной вещью? : может помочь мне передать 2D-массив float3 с C++ на hlsl? –

+0

Вы не можете передавать блоки данных произвольной длины в шейдер. Вы должны выбрать максимальный размер и всегда отправлять столько. См. Шейдер для [SkinnedEffect] (https://github.com/Microsoft/DirectXTK/blob/master/Src/Shaders/SkinnedEffect.fx) для примера (см. Массив '' Bones''). Убедитесь, что ваш общий размер буфера поддерживается вашим целевым [уровнем аппаратных средств Direct3D] (https://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx). –