HLSL and GLSL wraping again

Started by
11 comments, last by ongamex92 8 years, 10 months ago

I want to ask you guys, what is your approach on HLSL and GLSL wrapping. I have a solution that works, but its really ugly and really don't like it :


///////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////

#ifdef VERTEX_SHADER

@vertex-attrib float3 $a_pos a_position
@vertex-attrib float2 $a_uv a_uv

@varying float2 $v_uv;

@uniform float4x4 g_projView;
@uniform float4x4 g_world;

@shader-main-begin

    float4 worldPos = mul(g_world, float4($a_pos, 1.0));
    $vs_out = mul(g_projView,  worldPos);
    $v_uv = $a_uv;
    
@shader-main-end

#endif

///////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////
#ifdef PIXEL_SHADER

@varying float2 $v_uv
@ps-out $color 0

@uniform texture2D tex0

@shader-main-begin

    $color = sample2D(tex0, $v_uv);

@shader-main-end

#endif

This is later converted to HLSL/GLSL

Basically i use FCPP(really i don't recommend it) for marcos and pre-processing. and than some basic token matching + few macros. But all that $ @shader-main-begin are really awful... I really can't think of any other cleaner to basically wrap those two languages together.

What do you guys do?

Advertisement

I wrote a new shader language called LSSL (L. Spiro Shader Language).

It is a full language with semantics like in Cg or HLSL, and converts to Direct3D 9 HLSL, Direct3D 11 HLSL, GLSL, and ESSL, with Metal Shading Language support currently in progress. When I get home I can post examples.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

I wrote a new shader language called LSSL (L. Spiro Shader Language).

It is a full language with semantics like in Cg or HLSL, and converts to Direct3D 9 HLSL, Direct3D 11 HLSL, GLSL, and ESSL, with Metal Shading Language support currently in progress. When I get home I can post examples.

L. Spiro

Cant wait for the answer? ^_^

Here is the code I write:
[spoiler]
uniform vec4		g_vDiffuseMaterial : MATDIFFUSE;
uniform vec4		g_vEmissiveMaterial : MATEMISSIVE;
uniform vec4		g_vSpecularMaterial : MATSPECULAR;
uniform float		g_fReflectivity : REFLECTIVITY;
#ifndef LSE_VERTEX_LIGHTING
uniform float		g_fPower : MATPOWER;
uniform vec4		g_vRoughness : ROUGHNESS;
uniform vec4		g_vAshikFactors : ASHIKFACTORS;

uniform vec4		g_vDirLightDirs[LSE_MAX_LIGHTS] : DIRLIGHTDIRS;
uniform vec4		g_vDirLightColors[LSE_MAX_LIGHTS] : DIRLIGHTDIFFUSES;

uniform vec4		g_vPointLightPos[LSE_MAX_LIGHTS] : POINTLIGHTPOS;
uniform vec4		g_vPointLightColors[LSE_MAX_LIGHTS] : POINTLIGHTDIFFUSES;
uniform float		g_vPointLightSizes[LSE_MAX_LIGHTS] : POINTLIGHTSIZES;
#endif	// #ifndef LSE_VERTEX_LIGHTING
LSE_TEX_UNIFORMS

#include "LSDAshikhminShirley.lssl"
#include "LSDBlinnPhong.lssl"
#include "LSDCookTorrance.lssl"
#include "LSDEpic.lssl"
#include "LSDFresnel.lssl"
#include "LSDLightArgs.lssl"
#include "LSDOrenNayar.lssl"

#define LSE_PREMULTIPLY_ALPHA
#define LSE_LINEAR2SRGB( VAL )		(VAL) <= 0.0031308 ? (VAL) * 12.92 : 1.055 * pow( (VAL), 1.0f / 2.4 ) - 0.055

void Main( out vec4 _vOutColor : COLOR,
	lse_MainPsInputs,
	in vec4 _vInViewPos : LSE_TEXCOORD_USER0,
	in bool _bIsFrontFace : ISFRONTFACE	) {
	LSE_TEX_STORES	// Ensures each texture is read only once.
[/spoiler]

Output in GLSL:
[spoiler]
in vec4 LSG_VERT_OUT_PIXEL_IN_386_1/*_vInViewPos*/;
in vec3 LSG_VERT_OUT_PIXEL_IN_377_0/*_vInBinormal*/;
in vec3 LSG_VERT_OUT_PIXEL_IN_385_0/*_vInTangent*/;
in vec2 LSG_VERT_OUT_PIXEL_IN_386_0/*_vInTexCoord0*/;
in vec3 LSG_VERT_OUT_PIXEL_IN_381_0/*_vInNormal*/;
in vec4 LSG_VERT_OUT_PIXEL_IN_382_0/*_vInPosition*/;
out vec4 _vOutColor;

#line 0 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vDiffuseMaterial;

#line 1 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vEmissiveMaterial;

#line 2 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vSpecularMaterial;

#line 3 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform float g_fReflectivity;

#line 5 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform float g_fPower;

#line 6 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vRoughness;

#line 7 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vAshikFactors;

#line 9 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vDirLightDirs[8];

#line 10 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vDirLightColors[8];

#line 12 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vPointLightPos[8];

#line 13 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform vec4 g_vPointLightColors[8];

#line 14 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform float g_vPointLightSizes[8];

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform sampler2D g_tTex2d1;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
uniform sampler2D g_tTex2d0;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 13 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl

#line 17 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl

#line 21 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl
float SchlickFresnel_SG(float _F0,float _fU){
{
return (_F0+((1.0-_F0)*exp2((((_fU*-5.5547300000000002)-6.9831599999999998)*_fU))));}
}

#line 5 // e:/My Projects/LSEngine/LSTest/Data/LSDSqr.lssl
float Sqr(float _fF){
{
return (_fF*_fF);}
}

SKIP

#line 196 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
void main(){
{

#line 72 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vec4 vTex0=vec4(texture(g_tTex2d0,LSG_VERT_OUT_PIXEL_IN_386_0/*_vInTexCoord0*/));

#line 72 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vec4 vTex1=vec4(texture(g_tTex2d1,LSG_VERT_OUT_PIXEL_IN_386_0/*_vInTexCoord0*/));
[/spoiler]

Output in Direct3D 9 HLSL:
[spoiler]
#line 0 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vDiffuseMaterial;

#line 1 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vEmissiveMaterial;

#line 2 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vSpecularMaterial;

#line 3 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
float g_fReflectivity;

#line 5 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
float g_fPower;

#line 6 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vRoughness;

#line 7 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vAshikFactors;

#line 9 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vDirLightDirs[8];

#line 10 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vDirLightColors[8];

#line 12 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vPointLightPos[8];

#line 13 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>g_vPointLightColors[8];

#line 14 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
float g_vPointLightSizes[8];

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
sampler2D g_tTex2d1:register(s1);

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
sampler2D g_tTex2d0:register(s0);

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 13 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl

#line 17 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl

#line 21 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl
float SchlickFresnel_SG(float _F0,float _fU){
{
return (_F0+((1.0-_F0)*exp2((((_fU*-5.5547300000000002)-6.9831599999999998)*_fU))));}
}

#line 5 // e:/My Projects/LSEngine/LSTest/Data/LSDSqr.lssl
float Sqr(float _fF){
{
return (_fF*_fF);}
}

SKIP

#line 195 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
void Main(out vector<float,4>_vOutColor:COLOR0,in vector<float,4>_vInPosition:POSITION0,in vector<float,3>_vInNormal:NORMAL0,in vector<float,2>_vInTexCoord0:TEXCOORD0,in vector<float,3>_vInTangent:TANGENT0,in vector<float,3>_vInBinormal:BINORMAL0,in vector<float,4>_vInViewPos:TEXCOORD1,in bool _bIsFrontFace:VFACE){
{

#line 71 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>vTex0=tex2D(g_tTex2d0,_vInTexCoord0);

#line 71 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>vTex1=tex2D(g_tTex2d1,_vInTexCoord0);
[/spoiler]


Direct3D 11 HLSL:
[spoiler]
Texture2D g_tTex2d1:register(t1);
SamplerState g_sSampler1:register(s1);
Texture2D g_tTex2d0:register(t0);
SamplerState g_sSampler0:register(s0);
cbuffer cb0:register(b0){
vector<float,4>g_vDiffuseMaterial:packoffset(c0.x);
vector<float,4>g_vSpecularMaterial:packoffset(c1.x);
float g_fPower:packoffset(c2.x);
vector<float,4>g_vRoughness:packoffset(c3.x);
vector<float,4>g_vAshikFactors:packoffset(c4.x);
};
cbuffer cb1:register(b1){
vector<float,4>g_vDirLightDirs[8]:packoffset(c0.x);
vector<float,4>g_vPointLightPos[8]:packoffset(c8.x);
};
cbuffer cb2:register(b2){
};
cbuffer cb3:register(b3){
vector<float,4>g_vDirLightColors[8]:packoffset(c0.x);
vector<float,4>g_vPointLightColors[8]:packoffset(c8.x);
float g_vPointLightSizes[8]:packoffset(c16.x);
};

#line 0 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 1 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 2 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 3 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 5 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 6 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 7 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 9 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 10 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 12 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 13 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 14 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 16 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
;

#line 13 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl

#line 17 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl

#line 21 // e:/My Projects/LSEngine/LSTest/Data/LSDFresnel.lssl
float SchlickFresnel_SG(float _F0,float _fU){
{
return (_F0+((1.0-_F0)*exp2((((_fU*-5.5547300000000002)-6.9831599999999998)*_fU))));}
}

#line 5 // e:/My Projects/LSEngine/LSTest/Data/LSDSqr.lssl
float Sqr(float _fF){
{
return (_fF*_fF);}
}

SKIP

#line 196 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
void Main(out vector<float,4>_vOutColor:SV_Target0,in vector<float,4>_vInPosition:SV_POSITION0,in vector<float,3>_vInNormal:NORMAL0,in vector<float,2>_vInTexCoord0:TEXCOORD0,in vector<float,3>_vInTangent:TANGENT0,in vector<float,3>_vInBinormal:BINORMAL0,in vector<float,4>_vInViewPos:TEXCOORD1,in bool _bIsFrontFace:SV_ISFRONTFACE){
{

#line 72 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>vTex0=g_tTex2d0.Sample(g_sSampler0,_vInTexCoord0);

#line 72 // e:/My Projects/LSEngine/LSTest/Data/LSDPixelForwardDefaultPS.lssl
vector<float,4>vTex1=g_tTex2d1.Sample(g_sSampler1,_vInTexCoord0);
[/spoiler]


LSE_TEX_UNIFORMS is a macro generated by the engine. It expands to define each sampler/texture the model will access, but you are of course free to either not use it at all or manually define your own textures/samplers.

Basically the language itself is just a standard shading language, and the engine then also adds a ton of pre-defined macros you can use at your leisure. This includes lse_MainPsInputs and lse_MainVsInputs, which will define a position, normal, binormal, tangent, vertex color, etc., based on the flags you set when you use the model shader manager to create your shaders (by default the flags are set to match the model’s vertex buffer).

You can see a lot of #line pragmas with nothing following them. Unreferenced functions and globals are removed.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Thanks for the quick answer L. Spiro . !

But what libraries/tool do you use to analyze your LSSL ? I really cannot see how this is doable by just using macros?
For example are you parsing "by hand" the declaration of main?

I also wrote a custom language for my engine, I've posted an article with examples here:

http://www.gamedev.net/blog/1930/entry-2260794-acclimate-shading-language/

The way I'm handling parsing is by first processing the file and seperating it into blocks and lines as distinct entities. Later on, I simply iterate over all the blocks that are, like that:


if(auto pVertexBlock = effectSource.GetBlock("vertexShader"))
{
	shaderTypes |= VERTEX;
	
	m_pLanguage->OnVertexBegin(stShaderOut);

	for(auto pInputBlock : pVertexBlock->GetBlocks("input"))
	{
		ParseInput(*pInputBlock, stShaderOut, ShaderType::VERTEX);
	}

	if(auto pInBlock = pVertexBlock->GetBlock("in"))
		ParseInOut(*pInBlock, stShaderOut, InOut::I, ShaderType::VERTEX);
	if(auto pOutBlock = pVertexBlock->GetBlock("out"))
		ParseInOut(*pOutBlock, stShaderOut, InOut::O, ShaderType::VERTEX);
	if(auto pTextureBlock =  pVertexBlock->GetBlock("textures"))
		ParseTextures(*pTextureBlock, stShaderOut);
	if(auto pSamplerBlock = pVertexBlock->GetBlock("sampler"))
		ParseSamplerState(*pSamplerBlock, samplerState.vVertexSampler);
	if(auto pConstsBlock = pVertexBlock->GetBlock("constants"))
		ParseConstants(*pConstsBlock, stShaderOut);
	if(auto pFunctionBlock = pVertexBlock->GetBlock("functions"))
		ParseFunctions(*pFunctionBlock, stShaderOut);
	if(auto pMainBlock = pVertexBlock->GetBlock("main"))
		ParseVertexMain(*pMainBlock, stShaderOut);
}
else
{
	// error
}

The rest (all those ParseXXX) methods do plain text processing, and "m_pLanguage" is an implementation of an interface for the different languages, which produces the final shader output:


class HLSL11Parser :
	public gfx::IEffectLanguageParser
{
public:

	void OnVertexBegin(std::string& stOut) const override
	{
		stOut += "#pragma pack_matrix( row_major )\n";
		stOut += "#pragma ruledisable 0x0802405f\n"; // this is needed for tessellator not to generate cracks, wtf
	}

	void OnPixelBegin(std::string& stOut) const
	{
	}
	
	void OnVertexMainDeclaration(std::string& stOut) const
	{
		stOut += "VERTEX_OUT mainVS(VERTEX_IN In, uint VertexId : SV_VertexID, uint InstanceId : SV_InstanceID)"; // TODO: only generate VertexId and InstanceID when needed
	}

	void OnVertexMainTop(std::string& stOut) const
	{
		stOut += "VERTEX_OUT Out = (VERTEX_OUT)0;\n";
	}

	void OnVertexMainBottom(std::string& stOut) const
	{
		stOut += "return Out;\n";
	}
	
	// ...
	
}

I'm not claiming that my approach is especially sophisticated, since I'm no pro on text processing/compilation, but it gets the job done, and can hopefully give you a few ideas yourself.

The parser is Flex/Bison. The rest is all from scratch, including the preprocessor (since my parser does syntax checking, reference checking, etc., I need to fully expand macros, otherwise a variable declaration could be skipped etc.)

You can ignore the use of macros—they are just an extra layer of helpfulness. The real meat is in the actual parsing, as it understands types, various intrinsics, etc.
You will notice in Direct3D 11 it creates cbuffer’s and places members manually at the correct offsets inside those buffers. This is because it fully parsed the shader (by hand) and understands the sizes of all of your variables, plus array lengths, plus packing rules, etc. Similarly it works around the GLSL restriction where outputs from a vertex shader have to be named the same as the inputs to a pixel shader by (as you can see) creating a new consistent name.

It is not trivial, but it obviously is doable, and once you have the basic foundation for how it outputs code it is fairly easy to add support for new languages.
The base class for the output automatically handles things such as printing constant numbers. You just have to override a few virtual functions to add support for custom output for Metal Shading Language, for example.

The obvious advantage here is that I am in full control and I will never be left waiting for some 3rd party to add support for a language I want to support (Metal Shading Language, for example).


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

@Juliean you do this in a similar(a bit better) way as I do. Maybe this is the way to go, I'm not sure for myself.

I think I'm going set my hands on the Bison thing. If anyone has any good papers/articles/advices on how this problem should approached I'll be very thankful (as i have totally no experience in that area)

A bit of a feed back for those who are following...

it is certainly doable . Last weekend I've spend a couple of hours studying flex/bison.
Honestly I was really scared of that task, but it actually was not that hard. Actually the hardest thing was finding a good samples on how to use flex/bison. For those of you who doesn't know flex/bison is a pair of tools for (don't know the official word) token matching and syntax analysis. Basically you describe your language and those tools will produce a C/C++ functions that know how to parse the language.

So far i've got basic AST three for the most basic expressions and statements. Actually the only thing left is to be able to pack statements in a function and some minimal operators(unary operators).

If i have time to fix my code (because it's currently in a really messy state) i will create an actual "compiler" and I will try to share it with you guys. BTW there are already similar projects : for example https://github.com/aras-p/hlsl2glslfork but I'm not confident that this project is mainatainable.


PS :

Things that helped me learn FLEX/BISON(and their ancestors lex/yacc):
http://people.seas.harvard.edu/~bwaggoner/writeups/jumpstart/flexbison/jumpstart_flexbison.pdf
http://epaperpress.com/lexandyacc/download/LexAndYaccTutorial.pdf

I've been busy (doing nothing) these weeks so, I'm far away from done.

I've managed to create a re-entrant parser. Now i can parse almost all expressions(it still misses unary operators, I always forget about them...). Actually the hard work is almost done.

The parser works by generating a AST, and then generate the result based on that three. Currently the parser generate "glsl-ish" code( wanted to generate HLSL first by I've got few troubles).

There is one big trouble that I'm with generating HLSL. I want to use (mat * ?) to be the mathematical multiplication, not the component wise multiplication(* in HLSL is component wise). So for every (mat * ?)(or vice versa) I have to generate mul(mat, ?) .

The solutions that I currently have in my mind :

- Write mul() function for every type i know and generate mul's

- Determine the type of the expression. This looks a bit harder but it's doable. I can create a table(or in the best case a function) that can give me the type of the operator ( for example mat * vec is a vector, and mat * number is a number).

- Any suggestions?

You can track my progress here https://github.com/ongamex/playground/tree/master/lang Please keep in mind that this is just a playground project.

This topic is closed to new replies.

Advertisement