My main question is: "Why is it so difficult to add new variables in existing examples in both Appcode and Shader code?"
Some fresh eyes may help.
Code: Select all
// This was a "stripped down" version of Example 10 in which
// we tried converting it surgically from a good working GLSL shader into
// an (Irrlicht flavored) HLSL shader.
// We want it to do exactly the same things as the GLSL shader..
// It now resembles nothing like the Example 10 Shader code and
// was "morphed" more towards an HLSL example from FX Composer..
// (specifically one of the surface shaders in the Nissan Car example)
// So this HLSL now resembles an "FX Composer" Example.
// This specific shader deals with normal maps which is exactly what we want.
// Yes, the Hardware Channels "Semantics" for Tangent and Binormal is now "TEXCOORD_1" and "TEXCOORD_2"
// The "Cube" object was replaced with "FusionBall.x" (or *.b3d) skinned model.
// The goal here is to render this skinned mesh in the same way as is possible
// with an existing GLSL Shader.
// This existing GLSL shader happens to have a good grip on
// physical lighting and now serves as a basis and reference for all other shaders
// in other languages (for me, now)..
// The skinned model includes a Diffuse Map and an NSG Map which holds all the
// information needed to render a pretty realistic scene..
// It can be animated (by its bones), and obviously Rotated, Scaled and Translated
// making it a good skinned mesh to conduct tests with..
// If we have a light connected to the camera then it would be easy
// to see if the specular highlights or diffuse lighting has problems.
// We could also have lights placed in "definitive positions" like far down
// on the Y axis to check if it "Looks Right"..
// At this stage I still have a problem with:
// 1. Adding things like just a plain "mWorld" matrix
// 2. For some reason variables passed from appcode like "ColourSampler" is not accepted..
// and a message concerning this is displayed in the Irrlicht console..
// I've looked at the order by which I send these variables to the shader code
// prompted by the "[Begin: 7 Count: 1]" type of messages from the console.
// Order didn't seem to help..
// In the shader code itself I have a kind of "plug connector" set of lines where I
// tried various "Connections" between Incoming Matrices and Existing Matrices
// already in the FX, now HLSL example.
#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
// = = = = = = = = = = = = = = = = = = = = = =
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;
// = = = = = = = = = = = = = = = = = = = = = =
IrrlichtDevice* TheDevice = 0;
IrrlichtDevice* TheIRRNullDevice = 0; // is this "= 0" stil mandatory?
core::dimension2d<u32> TheDeskResolution;
core::matrix4 WorldVievProjectionMatrix;
core::matrix4 WorldMatrix;
core::matrix4 TransposedWorldMatrix;
core::matrix4 InverseWorldMatrix ;
// We need to know what GLSL's "gl_ModelViewProjectionMatrix" is in HLSL..
// I suspect that GLSL's "gl_Vertex" is "MyVertVar : POSITION" (semantically) in HLSL. ?
// - ANIMATED MODELS (DirectX or BLITZ BASIC) -
// scene::IAnimatedMeshSceneNode* TheNode;
scene::IAnimatedMesh* AniMesh0001;
scene::IAnimatedMeshSceneNode* AniMeshNode0001;
//
class OurShaderCallBackClass : public video::IShaderConstantSetCallBack
{
public:
virtual void OnSetConstants(video::IMaterialRendererServices* TheServices, s32 userData)
{video::IVideoDriver* TheDriver = TheServices->getVideoDriver();
WorldMatrix = TheDriver->getTransform(video::ETS_WORLD);
// Transformations..
// ETS_VIEW View transformation.
// ETS_WORLD World transformation.
// ETS_PROJECTION Projection transformation.
// OUR NEW ONES!!
// TheServices->setVertexShaderConstant("mWorld", WorldMatrix.pointer(), 16); // System complains..
/* // As the matrices exist in the HLSL shader code..
float4x4 mWorldViewProj; // WorldViewProjection [ Begin: 0 Count: 4 ]
float4x4 mTransWorld; // Transposed world matrix [ Begin: 4 Count: 3 ]
float3 mLightPos; // Light position [ Begin: 7 Count: 1 ]
// PROBLEMS: Cant send to the shader and getting error messages..
float4 mLightColor; // Light color [ ****************** ]
float4x4 mWorld; // Plain World Matrix [ ****************** ]
float4x4 mInvWorld; // Inverted world matrix [ ****************** ]
sampler2D ColorSampler; // Diffuse Image [ ****************** ]
*/
// ..
// [ Begin 0: Count: 4 ] O.K.
WorldVievProjectionMatrix = TheDriver->getTransform(video::ETS_PROJECTION);
WorldVievProjectionMatrix *= TheDriver->getTransform(video::ETS_VIEW);
WorldVievProjectionMatrix *= TheDriver->getTransform(video::ETS_WORLD);
TheServices->setVertexShaderConstant("mWorldViewProj", WorldVievProjectionMatrix.pointer(), 16);
// [ Begin 4: Count: 3 ] O.K.
WorldMatrix = TheDriver->getTransform(video::ETS_WORLD);
TransposedWorldMatrix = WorldMatrix.getTransposed();
TheServices->setVertexShaderConstant("mTransWorld", TransposedWorldMatrix.pointer(), 16);
// [ Begin 7: Count: 1 ] O.K.
core::vector3df CameraPosition = TheDevice->getSceneManager()->getActiveCamera()->getAbsolutePosition();
TheServices->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&CameraPosition), 3); // Light is Camera Pos..
// [ Begin XXX: Count: XXX ] NOT O.K!
// set Inverted World Matrix..
WorldMatrix = TheDriver->getTransform(video::ETS_WORLD);
TheServices->setVertexShaderConstant("mWorld", InverseWorldMatrix.pointer(), 16);
// [ Begin XXX: Count: XXX ] NOT O.K!
// set Inverted World Matrix..
InverseWorldMatrix = TheDriver->getTransform(video::ETS_WORLD);
InverseWorldMatrix.makeInverse();
TheServices->setVertexShaderConstant("mInvWorld", InverseWorldMatrix.pointer(), 16);
// [ Begin XXX: Count: XXX ] NOT O.K!
video::SColorf col(0.0f,1.0f,1.0f,0.0f);
TheServices->setVertexShaderConstant("mLightColor", reinterpret_cast<f32*>(&col), 4);
// [ Begin XXX: Count: XXX ] NOT O.K!
s32 TextureLayerID = 0;
TheServices->setPixelShaderConstant("ColorSampler", &TextureLayerID, 1); // Thankfully like GLSL to the Fragment Shader..
int AppShaderCommand = 0;
TheServices->setPixelShaderConstant("ShaderCommand001", reinterpret_cast<int*> (&AppShaderCommand), 1);
TheServices->setPixelShaderConstant("ShaderCommand002", reinterpret_cast<int*> (&AppShaderCommand), 1);
TheServices->setPixelShaderConstant("ShaderCommand003", reinterpret_cast<int*> (&AppShaderCommand), 1);
TheServices->setPixelShaderConstant("ShaderCommand004", reinterpret_cast<int*> (&AppShaderCommand), 1);
TheServices->setPixelShaderConstant("ShaderCommand005", reinterpret_cast<int*> (&AppShaderCommand), 1);
}
} ;
//----------------------------------------------------------- ------ ----- ---- --- -- -
int main()
{TheIRRNullDevice = createDevice(video::EDT_NULL); // Null Device for us to get our windows resolution..
TheDeskResolution = TheIRRNullDevice->getVideoModeList()->getDesktopResolution(); // As set by you in windows..
TheIRRNullDevice->drop(); // We got the desktop resolution, so drop the Null Device..
TheDevice = createDevice(video::EDT_DIRECT3D9,TheDeskResolution,32);
if (TheDevice == 0) return 1;
video::IVideoDriver* TheDriver = TheDevice->getVideoDriver();
scene::ISceneManager* TheSceneManager = TheDevice->getSceneManager();
io::path vsFileName;
io::path psFileName;
psFileName = "Shaders/d3d9.hlsl";
vsFileName = psFileName; // Both shaders are in the same file..
video::IGPUProgrammingServices* TheGPUProgrammingServices = TheDriver->getGPUProgrammingServices();
s32 OurShaderMaterial = 0;
if (TheGPUProgrammingServices)
{OurShaderCallBackClass* OurCallback = new OurShaderCallBackClass();
const video::E_GPU_SHADING_LANGUAGE shadingLanguage = video::EGSL_CG; // O.K.
/*
OurShaderMaterial
= TheGPUProgrammingServices->addHighLevelShaderMaterialFromFiles(vsFileName, "vertexMain", video::EVST_VS_3_0,
psFileName, "pixelMain", video::EPST_PS_3_0,
OurCallback, video::EMT_SOLID, 0, shadingLanguage);
*/
OurShaderMaterial
= TheGPUProgrammingServices->addHighLevelShaderMaterialFromFiles("Shaders/HLSL_0006_WAS_FX.hlsl",
"vertexMain",
EVST_VS_3_0, // Was 2 ..
"Shaders/HLSL_0006_WAS_FX.hlsl", // Ja.. Same name..
"pixelMain",
EPST_PS_3_0, // THIS HELPED!! (was 02)
OurCallback,
video::EMT_SOLID,
0,
shadingLanguage);
OurCallback->drop();
}
// TheNode = TheSceneManager->addCubeSceneNode(50);
AniMesh0001 = TheSceneManager ->getMesh("Data/0013_FUSION_BALL/X_001.x");
((ISkinnedMesh*)AniMesh0001)->convertMeshToTangents(); // Right Place?
AniMeshNode0001 = TheSceneManager->addAnimatedMeshSceneNode(AniMesh0001);
AniMeshNode0001->setDebugDataVisible(EDS_NORMALS);
AniMeshNode0001 -> setScale(vector3df( 10.0 , 10.0 , 10.0 )); // My modeller (Blender 2.75) likes things to be in a cube of 20 x 20 units..
float AniPlaySpeed = 0.0 ; // Default..
// AniPlayAtPause = AniPlaySpeed;
AniMeshNode0001 -> setAnimationSpeed (AniPlaySpeed) ; // Get this into command..
AniMeshNode0001 -> setFrameLoop ( 0.0 + 1.0 , AniMeshNode0001 -> getEndFrame () - 0.0 ); // Automate this..
AniMeshNode0001->setPosition(core::vector3df(0,0,0));
AniMeshNode0001->setMaterialTexture(0, TheDriver->getTexture("Data/0013_FUSION_BALL/NSG_MAP.tga"));
AniMeshNode0001->setMaterialFlag(video::EMF_LIGHTING, false);
AniMeshNode0001->setMaterialType((video::E_MATERIAL_TYPE) OurShaderMaterial);
scene::ISceneNodeAnimator* TheAnimator = TheSceneManager->createRotationAnimator(core::vector3df(0,0.0f,0));
AniMeshNode0001->addAnimator(TheAnimator);
TheAnimator->drop();
TheDriver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
// Add a camera and disable the mouse cursor..
scene::ICameraSceneNode* TheCamera = TheSceneManager->addCameraSceneNodeFPS();
TheCamera->setPosition(core::vector3df(-100,50,100));
TheCamera->setTarget(core::vector3df(0,0,0));
TheDevice->getCursorControl()->setVisible(false);
int lastFPS = -1;
while(TheDevice->run())
{
if (TheDevice->isWindowActive())
{TheDriver->beginScene(true, true, video::SColor( 255 , 207 , 211 , 192 ));
TheSceneManager->drawAll();
TheDriver->endScene();
int fps = TheDriver->getFPS();
if (lastFPS != fps)
{core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
str += TheDriver->getName();
str += "] FPS:";
str += fps;
TheDevice->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
}
TheDevice->drop();
return 0;
}