shaderGenGLSL.cpp
Engine/source/shaderGen/GLSL/shaderGenGLSL.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "shaderGen/GLSL/shaderGenGLSL.h" 26#include "shaderGen/GLSL/shaderCompGLSL.h" 27#include "shaderGen/featureMgr.h" 28#include "gfx/gl/tGL/tGL.h" 29 30 31void ShaderGenPrinterGLSL::printShaderHeader( Stream& stream ) 32{ 33 const char *header1 = "//*****************************************************************************\r\n"; 34 const char *header2 = "// Torque -- GLSL procedural shader\r\n"; 35 36 stream.write( dStrlen(header1), header1 ); 37 stream.write( dStrlen(header2), header2 ); 38 stream.write( dStrlen(header1), header1 ); 39 40 // Cheap HLSL compatibility. 41 String header3 = String("#include \"") + ShaderGen::smCommonShaderPath + String("/gl/hlslCompat.glsl\"\r\n"); 42 stream.write(dStrlen(header3), header3.c_str()); 43 44 const char* header4 = "\r\n"; 45 stream.write( dStrlen(header4), header4 ); 46} 47 48void ShaderGenPrinterGLSL::printMainComment( Stream& stream ) 49{ 50 // Print out main function definition 51 const char * header5 = "// Main \r\n"; 52 const char * line = "//-----------------------------------------------------------------------------\r\n"; 53 54 stream.write( dStrlen(line), line ); 55 stream.write( dStrlen(header5), header5 ); 56 stream.write( dStrlen(line), line ); 57} 58 59void ShaderGenPrinterGLSL::printVertexShaderCloser( Stream& stream ) 60{ 61 // We are render OpenGL upside down for use DX9 texture coords. 62 // Must be the last vertex feature. 63 const char *closer = " gl_Position.y *= -1;\r\n}\r\n"; 64 stream.write( dStrlen(closer), closer ); 65} 66 67void ShaderGenPrinterGLSL::printPixelShaderOutputStruct( Stream& stream, const MaterialFeatureData &featureData ) 68{ 69 // Determine the number of output targets we need 70 U32 numMRTs = 0; 71 for (U32 i = 0; i < FEATUREMGR->getFeatureCount(); i++) 72 { 73 const FeatureInfo &info = FEATUREMGR->getAt(i); 74 if (featureData.features.hasFeature(*info.type)) 75 numMRTs |= info.feature->getOutputTargets(featureData); 76 } 77 78 WRITESTR(avar("//Fragment shader OUT\r\n")); 79 WRITESTR(avar("out vec4 OUT_col;\r\n")); 80 for( U32 i = 1; i < 4; i++ ) 81 { 82 if( numMRTs & 1 << i ) 83 WRITESTR(avar("out vec4 OUT_col%d;\r\n", i)); 84 } 85 86 WRITESTR("\r\n"); 87 WRITESTR("\r\n"); 88} 89 90void ShaderGenPrinterGLSL::printPixelShaderCloser( Stream& stream ) 91{ 92 const char *closer = " \r\n}\r\n"; 93 stream.write( dStrlen(closer), closer ); 94} 95 96void ShaderGenPrinterGLSL::printLine(Stream& stream, const String& line) 97{ 98 stream.write(line.length(), line.c_str()); 99 const char* end = "\r\n"; 100 stream.write(dStrlen(end), end); 101} 102 103const char* ShaderGenComponentFactoryGLSL::typeToString( GFXDeclType type ) 104{ 105 switch ( type ) 106 { 107 default: 108 case GFXDeclType_Float: 109 return "float"; 110 111 case GFXDeclType_Float2: 112 return "vec2"; 113 114 case GFXDeclType_Float3: 115 return "vec3"; 116 117 case GFXDeclType_UByte4: 118 return "vec4"; 119 120 case GFXDeclType_Float4: 121 case GFXDeclType_Color: 122 return "vec4"; 123 } 124} 125 126ShaderComponent* ShaderGenComponentFactoryGLSL::createVertexInputConnector( const GFXVertexFormat &vertexFormat ) 127{ 128 AppVertConnectorGLSL *vertComp = new AppVertConnectorGLSL; 129 130 // Loop thru the vertex format elements. 131 for ( U32 i=0; i < vertexFormat.getElementCount(); i++ ) 132 { 133 const GFXVertexElement &element = vertexFormat.getElement( i ); 134 135 Var *var = NULL; 136 137 if ( element.isSemantic( GFXSemantic::POSITION ) ) 138 { 139 var = vertComp->getElement( RT_POSITION ); 140 var->setName( "position" ); 141 } 142 else if ( element.isSemantic( GFXSemantic::NORMAL ) ) 143 { 144 var = vertComp->getElement( RT_NORMAL ); 145 var->setName( "normal" ); 146 } 147 else if ( element.isSemantic( GFXSemantic::TANGENT ) ) 148 { 149 var = vertComp->getElement( RT_TANGENT ); 150 var->setName( "T" ); 151 } 152 else if ( element.isSemantic( GFXSemantic::TANGENTW ) ) 153 { 154 var = vertComp->getElement( RT_TANGENTW ); 155 var->setName( "tangentW" ); 156 } 157 else if ( element.isSemantic( GFXSemantic::BINORMAL ) ) 158 { 159 var = vertComp->getElement( RT_BINORMAL ); 160 var->setName( "B" ); 161 } 162 else if ( element.isSemantic( GFXSemantic::COLOR ) ) 163 { 164 var = vertComp->getElement( RT_COLOR ); 165 var->setName( "diffuse" ); 166 } 167 else if (element.isSemantic(GFXSemantic::BLENDINDICES)) 168 { 169 var = vertComp->getElement(RT_BLENDINDICES); 170 var->setName(String::ToString("vBlendIndex%d", element.getSemanticIndex())); 171 } 172 else if (element.isSemantic(GFXSemantic::BLENDWEIGHT)) 173 { 174 var = vertComp->getElement(RT_BLENDWEIGHT); 175 var->setName(String::ToString("vBlendWeight%d", element.getSemanticIndex())); 176 } 177 else if ( element.isSemantic( GFXSemantic::TEXCOORD ) ) 178 { 179 var = vertComp->getElement( RT_TEXCOORD ); 180 if ( element.getSemanticIndex() == 0 ) 181 var->setName( "texCoord" ); 182 else 183 var->setName( String::ToString( "texCoord%d", element.getSemanticIndex() + 1 ) ); 184 } 185 else 186 { 187 // Everything else is a texcoord! 188 var = vertComp->getElement( RT_TEXCOORD ); 189 var->setName( "tc" + element.getSemantic() ); 190 } 191 192 if ( !var ) 193 continue; 194 195 var->setStructName( "IN" ); 196 var->setType( typeToString( element.getType() ) ); 197 } 198 199 return vertComp; 200} 201 202ShaderComponent* ShaderGenComponentFactoryGLSL::createVertexPixelConnector() 203{ 204 VertPixelConnectorGLSL* comp = new VertPixelConnectorGLSL; 205 return comp; 206} 207 208ShaderComponent* ShaderGenComponentFactoryGLSL::createVertexParamsDef() 209{ 210 VertexParamsDefGLSL* comp = new VertexParamsDefGLSL; 211 return comp; 212} 213 214ShaderComponent* ShaderGenComponentFactoryGLSL::createPixelParamsDef() 215{ 216 PixelParamsDefGLSL* comp = new PixelParamsDefGLSL; 217 return comp; 218} 219 220