Torque3D Documentation / _generateds / shaderGenGLSL.cpp

shaderGenGLSL.cpp

Engine/source/shaderGen/GLSL/shaderGenGLSL.cpp

More...

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