collada_scene: implement directional lighting
This commit is contained in:
parent
4d952b0a90
commit
b9cfcde9c7
Binary file not shown.
@ -9,6 +9,7 @@
|
|||||||
#include "new.hpp"
|
#include "new.hpp"
|
||||||
|
|
||||||
extern ID3D10Device * g_pd3dDevice;
|
extern ID3D10Device * g_pd3dDevice;
|
||||||
|
extern XMVECTOR g_Eye;
|
||||||
extern XMMATRIX g_View;
|
extern XMMATRIX g_View;
|
||||||
extern XMMATRIX g_Projection;
|
extern XMMATRIX g_Projection;
|
||||||
|
|
||||||
@ -22,6 +23,11 @@ namespace collada_scene {
|
|||||||
ID3D10EffectMatrixVariable * g_pViewVariable = NULL;
|
ID3D10EffectMatrixVariable * g_pViewVariable = NULL;
|
||||||
ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL;
|
ID3D10EffectMatrixVariable * g_pProjectionVariable = NULL;
|
||||||
|
|
||||||
|
ID3D10EffectVectorVariable * g_pViewEyeVariable = NULL;
|
||||||
|
ID3D10EffectVectorVariable * g_pLightPosVariable = NULL;
|
||||||
|
ID3D10EffectVectorVariable * g_pLightDirVariable = NULL;
|
||||||
|
ID3D10EffectVectorVariable * g_pLightColorVariable = NULL;
|
||||||
|
|
||||||
ID3D10EffectVectorVariable * g_pEmissionVariable = NULL;
|
ID3D10EffectVectorVariable * g_pEmissionVariable = NULL;
|
||||||
ID3D10EffectVectorVariable * g_pAmbientVariable = NULL;
|
ID3D10EffectVectorVariable * g_pAmbientVariable = NULL;
|
||||||
ID3D10EffectVectorVariable * g_pDiffuseVariable = NULL;
|
ID3D10EffectVectorVariable * g_pDiffuseVariable = NULL;
|
||||||
@ -67,8 +73,52 @@ namespace collada_scene {
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scene_state::update_light_instance_vectors(light const& light,
|
||||||
|
node_instance const& node_instance,
|
||||||
|
int light_index)
|
||||||
|
{
|
||||||
|
const XMVECTOR position = XMVectorSet(0, 0, 0, 1);
|
||||||
|
const XMVECTOR direction = XMVectorSet(0, 0, -1, 0);
|
||||||
|
XMVECTOR light_position = XMVector3Transform(position, node_instance.world);
|
||||||
|
XMVECTOR light_direction = XMVector3TransformNormal(direction, node_instance.world);
|
||||||
|
XMVECTOR light_color = XMLoadFloat3((XMFLOAT3 *)&light.color);
|
||||||
|
|
||||||
|
XMStoreFloat4(&m_lightPositions[light_index], light_position);
|
||||||
|
XMStoreFloat4(&m_lightDirections[light_index], light_direction);
|
||||||
|
XMStoreFloat4(&m_lightColors[light_index], light_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scene_state::update_light_instances()
|
||||||
|
{
|
||||||
|
int light_index = 0;
|
||||||
|
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||||
|
node const& node = *m_descriptor->nodes[i];
|
||||||
|
node_instance const& node_instance = m_nodeInstances[i];
|
||||||
|
for (int j = 0; j < node.instance_lights_count; j++) {
|
||||||
|
light const& light = *node.instance_lights[j].light;
|
||||||
|
update_light_instance_vectors(light, node_instance, light_index);
|
||||||
|
light_index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void scene_state::allocate_light_instances()
|
||||||
|
{
|
||||||
|
// count light instances
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||||
|
count += m_descriptor->nodes[i]->instance_lights_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate
|
||||||
|
m_lightInstancesCount = count;
|
||||||
|
m_lightPositions = New<XMFLOAT4>(m_lightInstancesCount);
|
||||||
|
m_lightDirections = New<XMFLOAT4>(m_lightInstancesCount);
|
||||||
|
m_lightColors = New<XMFLOAT4>(m_lightInstancesCount);
|
||||||
|
}
|
||||||
|
|
||||||
static void initialize_node_transforms(node const * const node,
|
static void initialize_node_transforms(node const * const node,
|
||||||
node_instance * node_instance)
|
node_instance * const node_instance)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < node->transforms_count; i++) {
|
for (int i = 0; i < node->transforms_count; i++) {
|
||||||
transform& transform = node_instance->transforms[i];
|
transform& transform = node_instance->transforms[i];
|
||||||
@ -98,7 +148,7 @@ namespace collada_scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void scene_state::allocate_node_instance(node const * const node,
|
void scene_state::allocate_node_instance(node const * const node,
|
||||||
node_instance * node_instance)
|
node_instance * const node_instance)
|
||||||
{
|
{
|
||||||
node_instance->transforms = New<transform>(node->transforms_count);
|
node_instance->transforms = New<transform>(node->transforms_count);
|
||||||
initialize_node_transforms(node, node_instance);
|
initialize_node_transforms(node, node_instance);
|
||||||
@ -133,6 +183,7 @@ namespace collada_scene {
|
|||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
allocate_node_instances();
|
allocate_node_instances();
|
||||||
|
allocate_light_instances();
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@ -143,6 +194,7 @@ namespace collada_scene {
|
|||||||
|
|
||||||
D3D10_INPUT_ELEMENT_DESC layout[inputs.elements_count];
|
D3D10_INPUT_ELEMENT_DESC layout[inputs.elements_count];
|
||||||
|
|
||||||
|
assert(inputs.elements_count == 3);
|
||||||
int byte_offset = 0;
|
int byte_offset = 0;
|
||||||
for (int i = 0; i < inputs.elements_count; i++) {
|
for (int i = 0; i < inputs.elements_count; i++) {
|
||||||
layout[i].SemanticName = inputs.elements[i].semantic;
|
layout[i].SemanticName = inputs.elements[i].semantic;
|
||||||
@ -200,6 +252,11 @@ namespace collada_scene {
|
|||||||
g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix();
|
g_pViewVariable = g_pEffect->GetVariableByName("View")->AsMatrix();
|
||||||
g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix();
|
g_pProjectionVariable = g_pEffect->GetVariableByName("Projection")->AsMatrix();
|
||||||
|
|
||||||
|
g_pViewEyeVariable = g_pEffect->GetVariableByName("ViewEye")->AsVector();
|
||||||
|
g_pLightPosVariable = g_pEffect->GetVariableByName("LightPos")->AsVector();
|
||||||
|
g_pLightDirVariable = g_pEffect->GetVariableByName("LightDir")->AsVector();
|
||||||
|
g_pLightColorVariable = g_pEffect->GetVariableByName("LightColor")->AsVector();
|
||||||
|
|
||||||
g_pEmissionVariable = g_pEffect->GetVariableByName("Emission")->AsVector();
|
g_pEmissionVariable = g_pEffect->GetVariableByName("Emission")->AsVector();
|
||||||
g_pAmbientVariable = g_pEffect->GetVariableByName("Ambient")->AsVector();
|
g_pAmbientVariable = g_pEffect->GetVariableByName("Ambient")->AsVector();
|
||||||
g_pDiffuseVariable = g_pEffect->GetVariableByName("Diffuse")->AsVector();
|
g_pDiffuseVariable = g_pEffect->GetVariableByName("Diffuse")->AsVector();
|
||||||
@ -559,28 +616,59 @@ namespace collada_scene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scene_state::render(float t)
|
void scene_state::update(float t)
|
||||||
{
|
{
|
||||||
g_pViewVariable->SetMatrix((float *)&g_View);
|
|
||||||
g_pProjectionVariable->SetMatrix((float *)&g_Projection);
|
|
||||||
|
|
||||||
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
|
||||||
|
|
||||||
t = loop(t / 2.0f, 3.333333f);
|
t = loop(t / 2.0f, 3.333333f);
|
||||||
|
|
||||||
|
// animate and update all world transforms
|
||||||
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||||
node const& node = *m_descriptor->nodes[i];
|
node const& node = *m_descriptor->nodes[i];
|
||||||
node_instance& node_instance = m_nodeInstances[i];
|
node_instance& node_instance = m_nodeInstances[i];
|
||||||
|
|
||||||
animate_node(node, node_instance, t);
|
animate_node(node, node_instance, t);
|
||||||
node_world_transform(node, node_instance);
|
node_world_transform(node, node_instance);
|
||||||
|
}
|
||||||
|
|
||||||
g_pWorldVariable->SetMatrix((float *)&node_instance.world);
|
// update all lights (after world transforms are computed)
|
||||||
|
update_light_instances();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int min(int a, int b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scene_state::render()
|
||||||
|
{
|
||||||
|
XMFLOAT4 eye;
|
||||||
|
XMFLOAT4X4 projection;
|
||||||
|
XMFLOAT4X4 view;
|
||||||
|
XMStoreFloat4(&eye, g_Eye);
|
||||||
|
XMStoreFloat4x4(&view, g_View);
|
||||||
|
XMStoreFloat4x4(&projection, g_Projection);
|
||||||
|
|
||||||
|
g_pViewVariable->SetMatrix((float *)&view);
|
||||||
|
g_pProjectionVariable->SetMatrix((float *)&projection);
|
||||||
|
|
||||||
|
g_pViewEyeVariable->SetFloatVector((float *)&eye);
|
||||||
|
|
||||||
|
int lights = min(2, m_lightInstancesCount);
|
||||||
|
g_pLightPosVariable->SetFloatVectorArray((float *)m_lightPositions, 0, lights);
|
||||||
|
g_pLightDirVariable->SetFloatVectorArray((float *)m_lightDirections, 0, lights);
|
||||||
|
g_pLightColorVariable->SetFloatVectorArray((float *)m_lightColors, 0, lights);
|
||||||
|
|
||||||
|
g_pd3dDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_descriptor->nodes_count; i++) {
|
||||||
|
node const& node = *m_descriptor->nodes[i];
|
||||||
|
node_instance& node_instance = m_nodeInstances[i];
|
||||||
|
|
||||||
// joints aren't rendered
|
// joints aren't rendered
|
||||||
if (node.type != node_type::NODE)
|
if (node.type != node_type::NODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
g_pWorldVariable->SetMatrix((float *)&node_instance.world);
|
||||||
|
|
||||||
render_geometries(node.instance_geometries, node.instance_geometries_count);
|
render_geometries(node.instance_geometries, node.instance_geometries_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,12 @@ cbuffer cbEveryFrame
|
|||||||
{
|
{
|
||||||
matrix View;
|
matrix View;
|
||||||
matrix Projection;
|
matrix Projection;
|
||||||
|
|
||||||
|
float4 ViewEye;
|
||||||
|
|
||||||
|
float4 LightPos[2];
|
||||||
|
float4 LightDir[2];
|
||||||
|
float4 LightColor[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
cbuffer cbMultiplePerFrame
|
cbuffer cbMultiplePerFrame
|
||||||
@ -30,30 +36,39 @@ struct PS_INPUT
|
|||||||
float4 Pos : SV_POSITION;
|
float4 Pos : SV_POSITION;
|
||||||
float3 Norm : NORMAL;
|
float3 Norm : NORMAL;
|
||||||
float2 Tex : TEXCOORD0;
|
float2 Tex : TEXCOORD0;
|
||||||
|
float4 WPos : POSITION;
|
||||||
};
|
};
|
||||||
|
|
||||||
PS_INPUT VS(VS_INPUT input)
|
PS_INPUT VS(VS_INPUT input)
|
||||||
{
|
{
|
||||||
PS_INPUT output;
|
PS_INPUT output;
|
||||||
|
|
||||||
output.Pos = mul(float4(input.Pos, 1), World);
|
float4 world_pos = mul(float4(input.Pos, 1), World);
|
||||||
output.Pos = mul(output.Pos, View);
|
output.Pos = mul(world_pos, View);
|
||||||
output.Pos = mul(output.Pos, Projection);
|
output.Pos = mul(output.Pos, Projection);
|
||||||
|
|
||||||
output.Norm = mul(input.Norm, (float3x3)World);
|
output.Norm = mul(input.Norm, (float3x3)World);
|
||||||
output.Tex = input.Tex;
|
output.Tex = input.Tex;
|
||||||
|
|
||||||
|
output.WPos = world_pos;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 PS(PS_INPUT input) : SV_Target
|
float4 PS(PS_INPUT input) : SV_Target
|
||||||
{
|
{
|
||||||
float4 color = Emission + Diffuse * 1.0 + Specular * 0.0;
|
float3 normal = normalize(input.Norm);
|
||||||
|
float3 view_dir = normalize(ViewEye.xyz - input.Pos.xyz);
|
||||||
|
|
||||||
|
float3 color = Emission.xyz;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
float3 light_dir = normalize(-LightDir[i].xyz);
|
||||||
|
float diffuse_intensity = max(dot(normal, light_dir), 0.0);
|
||||||
|
color += Diffuse.xyz * diffuse_intensity * LightColor[i].xyz;
|
||||||
|
}
|
||||||
|
|
||||||
return float4(color.xyz, 1);
|
return float4(color.xyz, 1);
|
||||||
|
|
||||||
//return float4(input.Normal * 0.5 + 0.5, 1);
|
|
||||||
//return float4(input.Tex.xy, 0, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlendState DisableBlending
|
BlendState DisableBlending
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
#include "collada.hpp"
|
#include "collada.hpp"
|
||||||
#include "collada_scene.hpp"
|
#include "collada_scene.hpp"
|
||||||
|
|
||||||
#include "scenes/curve_interpolation.hpp"
|
#include "scenes/curve_interpolation/curve_interpolation.hpp"
|
||||||
|
|
||||||
HINSTANCE g_hInstance = NULL;
|
HINSTANCE g_hInstance = NULL;
|
||||||
HWND g_hWnd = NULL;
|
HWND g_hWnd = NULL;
|
||||||
@ -1843,7 +1843,8 @@ void Render(float t, float dt)
|
|||||||
|
|
||||||
//collada::Render(t);
|
//collada::Render(t);
|
||||||
|
|
||||||
g_SceneState.render(t);
|
g_SceneState.update(t);
|
||||||
|
g_SceneState.render();
|
||||||
|
|
||||||
RenderFont(dt);
|
RenderFont(dt);
|
||||||
|
|
||||||
|
|||||||
@ -1008,8 +1008,8 @@ instance_light const instance_lights_node_cube[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
channel const * const node_channels_node_cube[] = {
|
channel const * const node_channels_node_cube[] = {
|
||||||
&node_channel_node_cube_translation_x,
|
|
||||||
&node_channel_node_cube_translation_y,
|
&node_channel_node_cube_translation_y,
|
||||||
|
&node_channel_node_cube_translation_x,
|
||||||
};
|
};
|
||||||
|
|
||||||
node const node_node_cube = {
|
node const node_node_cube = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user