/plugins/OpenGL/shadercompilerdata.cpp

https://github.com/bigfug/Fugio · C++ · 253 lines · 188 code · 61 blank · 4 comment · 20 complexity · 0ced73e38e6ee3ba038931c3f5fb35ae MD5 · raw file

  1. #include "shadercompilerdata.h"
  2. #include <QOpenGLFunctions>
  3. #if !defined( QT_OPENGL_ES_2 )
  4. #include <QOpenGLFunctions_3_2_Core>
  5. #endif
  6. ShaderCompilerData::ShaderCompilerData()
  7. : mProgram( new QOpenGLShaderProgram() )
  8. {
  9. }
  10. ShaderCompilerData::~ShaderCompilerData()
  11. {
  12. clear();
  13. if( mProgram )
  14. {
  15. mProgram->deleteLater();
  16. }
  17. }
  18. ShaderCompilerData &ShaderCompilerData::operator =( ShaderCompilerData &&other )
  19. {
  20. std::swap( mProgram, other.mProgram );
  21. if( other.mProgram )
  22. {
  23. other.mProgram->removeAllShaders();
  24. }
  25. mShaderUniformTypes = std::move( other.mShaderUniformTypes );
  26. mShaderAttributeTypes = std::move( other.mShaderAttributeTypes );
  27. mUniformNames = std::move( other.mUniformNames );
  28. mAttributeNames = std::move( other.mAttributeNames );
  29. mFragmentOutputs = std::move( other.mFragmentOutputs );
  30. return( *this );
  31. }
  32. void ShaderCompilerData::process()
  33. {
  34. QOpenGLFunctions *GL = QOpenGLContext::currentContext()->functions();
  35. fugio::ShaderUniformData UniformData;
  36. memset( &UniformData, 0, sizeof( UniformData ) );
  37. mShaderUniformTypes.clear();
  38. mShaderAttributeTypes.clear();
  39. mUniformNames.clear();
  40. mAttributeNames.clear();
  41. mFragmentOutputs.clear();
  42. GLint TextureBinding = 0;
  43. GLint ActiveUniforms = 0;
  44. GL->glGetProgramiv( mProgram->programId(), GL_ACTIVE_UNIFORMS, &ActiveUniforms );
  45. if( ActiveUniforms > 0 )
  46. {
  47. GLint ActiveUniformsMaxLength;
  48. GL->glGetProgramiv( mProgram->programId(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &ActiveUniformsMaxLength );
  49. std::vector<GLchar> Name( ActiveUniformsMaxLength );
  50. for( GLint i = 0 ; i < ActiveUniforms ; i++ )
  51. {
  52. GLsizei NameLength;
  53. GL->glGetActiveUniform( mProgram->programId(), i, Name.size(), &NameLength, &UniformData.mSize, &UniformData.mType, &Name[ 0 ] );
  54. QString UniformName = QString::fromLocal8Bit( &Name[ 0 ] );
  55. UniformData.mLocation = mProgram->uniformLocation( Name.data() );
  56. if( UniformData.mLocation == -1 )
  57. {
  58. continue;
  59. }
  60. #if defined( QT_DEBUG )
  61. //qDebug() << mNode->name() << i << ":" << UniformName << "size =" << UniformData.mSize << "type =" << UniformData.mType << "bind =" << UniformData.mTextureBinding << "loc =" << UniformData.mLocation;
  62. #endif
  63. mUniformNames.append( UniformName );
  64. if( mShaderUniformTypes.contains( UniformName ) )//&& ( ShaderUniformTypes.value( UniformName ).first != UniformType || ShaderUniformTypes.value( UniformName ).first != UniformType )
  65. {
  66. continue;
  67. }
  68. switch( UniformData.mType )
  69. {
  70. #if !defined( QT_OPENGL_ES_2 )
  71. case GL_SAMPLER_1D:
  72. case GL_SAMPLER_1D_ARRAY:
  73. case GL_SAMPLER_1D_ARRAY_SHADOW:
  74. case GL_SAMPLER_1D_SHADOW:
  75. case GL_SAMPLER_2D_RECT:
  76. case GL_SAMPLER_CUBE_MAP_ARRAY:
  77. case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
  78. case GL_INT_SAMPLER_1D:
  79. case GL_INT_SAMPLER_1D_ARRAY:
  80. case GL_UNSIGNED_INT_SAMPLER_1D:
  81. case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
  82. case GL_SAMPLER_2D_RECT_SHADOW:
  83. case GL_SAMPLER_BUFFER:
  84. case GL_INT_SAMPLER_2D_RECT:
  85. case GL_INT_SAMPLER_BUFFER:
  86. case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
  87. case GL_UNSIGNED_INT_SAMPLER_BUFFER:
  88. case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
  89. case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
  90. case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
  91. case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
  92. case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
  93. #endif
  94. case GL_SAMPLER_2D_ARRAY:
  95. case GL_SAMPLER_2D_ARRAY_SHADOW:
  96. case GL_SAMPLER_2D_MULTISAMPLE:
  97. case GL_SAMPLER_2D_SHADOW:
  98. case GL_SAMPLER_3D:
  99. case GL_SAMPLER_2D:
  100. case GL_SAMPLER_CUBE:
  101. case GL_SAMPLER_CUBE_SHADOW:
  102. case GL_INT_SAMPLER_2D:
  103. case GL_INT_SAMPLER_3D:
  104. case GL_INT_SAMPLER_CUBE:
  105. case GL_INT_SAMPLER_2D_ARRAY:
  106. case GL_UNSIGNED_INT_SAMPLER_2D:
  107. case GL_UNSIGNED_INT_SAMPLER_3D:
  108. case GL_UNSIGNED_INT_SAMPLER_CUBE:
  109. case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
  110. case GL_INT_SAMPLER_2D_MULTISAMPLE:
  111. case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
  112. case GL_SAMPLER:
  113. UniformData.mSampler = true;
  114. UniformData.mTextureBinding = TextureBinding++;
  115. // fall through...
  116. case GL_FLOAT:
  117. case GL_FLOAT_VEC2:
  118. case GL_FLOAT_VEC3:
  119. case GL_FLOAT_VEC4:
  120. case GL_INT:
  121. case GL_INT_VEC2:
  122. case GL_INT_VEC3:
  123. case GL_INT_VEC4:
  124. case GL_BOOL:
  125. case GL_BOOL_VEC2:
  126. case GL_BOOL_VEC3:
  127. case GL_BOOL_VEC4:
  128. case GL_FLOAT_MAT2:
  129. case GL_FLOAT_MAT3:
  130. case GL_FLOAT_MAT4:
  131. mShaderUniformTypes.insert( UniformName, UniformData );
  132. break;
  133. }
  134. memset( &UniformData, 0, sizeof( UniformData ) );
  135. }
  136. }
  137. memset( &UniformData, 0, sizeof( UniformData ) );
  138. GLint ActiveAtrributes = 0;
  139. GL->glGetProgramiv( mProgram->programId(), GL_ACTIVE_ATTRIBUTES, &ActiveAtrributes );
  140. if( ActiveAtrributes > 0 )
  141. {
  142. GLint ActiveUniformsMaxLength;
  143. GL->glGetProgramiv( mProgram->programId(), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &ActiveUniformsMaxLength );
  144. std::vector<GLchar> Name( ActiveUniformsMaxLength );
  145. for( GLint i = 0 ; i < ActiveAtrributes ; i++ )
  146. {
  147. GLsizei NameLength;
  148. GL->glGetActiveAttrib( mProgram->programId(), i, Name.size(), &NameLength, &UniformData.mSize, &UniformData.mType, &Name[ 0 ] );
  149. QString AttributeName = QString::fromLocal8Bit( &Name[ 0 ] );
  150. UniformData.mLocation = mProgram->attributeLocation( Name.data() );
  151. if( UniformData.mLocation == -1 )
  152. {
  153. continue;
  154. }
  155. //qDebug() << mNode->name() << i << ":" << AttributeName << "(ATTRIBUTE) size =" << UniformData.mSize << "type =" << UniformData.mType << "loc =" << UniformData.mLocation;
  156. mAttributeNames.append( AttributeName );
  157. mShaderAttributeTypes.insert( AttributeName, UniformData );
  158. }
  159. }
  160. #if !defined( QT_OPENGL_ES_2 )
  161. QOpenGLFunctions_3_2_Core *GL32 = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
  162. if( GL32 && GL32->initializeOpenGLFunctions() )
  163. {
  164. GLint MaxDrawBuffers = 0;
  165. GL32->glGetIntegerv( GL_MAX_DRAW_BUFFERS, &MaxDrawBuffers );
  166. mFragmentOutputs.resize( MaxDrawBuffers );
  167. for( int i = 0 ; i < MaxDrawBuffers ; i++ )
  168. {
  169. const QString FragName = QString( "fug_Fragment%1" ).arg( i );
  170. GLint FragData = GL32->glGetFragDataLocation( mProgram->programId(), FragName.toLatin1().constData() );
  171. mFragmentOutputs[ i ] = ( FragData == -1 ? GL_NONE : GL_COLOR_ATTACHMENT0 + i );
  172. }
  173. while( !mFragmentOutputs.isEmpty() && mFragmentOutputs.last() == GL_NONE )
  174. {
  175. mFragmentOutputs.removeLast();
  176. }
  177. }
  178. #endif
  179. //emit updateUniformList( mUniformNames );
  180. }
  181. void ShaderCompilerData::clear()
  182. {
  183. if( mProgram )
  184. {
  185. mProgram->removeAllShaders();
  186. }
  187. mShaderAttributeTypes.clear();
  188. mShaderUniformTypes.clear();
  189. mUniformNames.clear();
  190. mAttributeNames.clear();
  191. mFragmentOutputs.clear();
  192. }