1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsGLPrerequisites.h"
6#include "RenderAPI/BsVertexDeclaration.h"
7#include "Debug/BsDebug.h"
8#include "Error/BsException.h"
9#include "RenderAPI/BsGpuParamDesc.h"
10
11namespace bs { namespace ct
12{
13 /** @addtogroup GL
14 * @{
15 */
16
17 /** Holds a GLSL program input attribute used in vertex programs. */
18 struct GLSLAttribute
19 {
20 /** Constructs a new attribute from a name and a semantic that represents in which way is the attribute used. */
21 GLSLAttribute(const String& name, VertexElementSemantic semantic)
22 :mName(name), mSemantic(semantic)
23 { }
24
25 /**
26 * Return true if attribute name matches the specified name and returns optional semantic index if it exists. Start
27 * of the two compared strings must match, and the remaining non-matching bit will be assumed to be the semantic
28 * index. Returns -1 if no match is made.
29 */
30 INT32 matchesName(const String& name);
31
32 /** Returns the semantic of this attribute. */
33 VertexElementSemantic getSemantic() const { return mSemantic; }
34
35 private:
36 String mName;
37 VertexElementSemantic mSemantic;
38 };
39
40 /** Helper class that is able to parse a GLSL GPU program and retrieve used uniforms and input attributes. */
41 class GLSLParamParser
42 {
43 public:
44 /**
45 * Parses a compiled OpenGL program and outputs a parameter description that contains information about used
46 * uniforms.
47 *
48 * @param[in] glProgram OpenGL handle to the GPU program.
49 * @param[in] type Type of the GPU program we're parsing.
50 * @param[out] returnParamDesc Output structure containing the parsed data.
51 */
52 void buildUniformDescriptions(GLuint glProgram, GpuProgramType type, GpuParamDesc& returnParamDesc);
53
54 /**
55 * Parses a compiled OpenGL program and outputs vertex element list that describes input attributes to the program.
56 * Only valid for vertex programs.
57 *
58 * @param[in] glProgram OpenGL handle to the GPU program.
59 */
60 Vector<VertexElement> buildVertexDeclaration(GLuint glProgram);
61
62 /**
63 * Calculates the size and alignment of a single element within a shader interface block using the std140 layout.
64 *
65 * @param[in] type Type of the element. Structs are not supported.
66 * @param[in] arraySize Number of array elements of the element (1 if it's not an array).
67 * @param[in, out] offset Current location in some parent buffer at which the element should be placed at. If the
68 * location doesn't match the element's alignment, the value will be modified to a valid
69 * alignment. In multiples of 4 bytes.
70 * @return Size of the element, in multiples of 4 bytes.
71 */
72 static UINT32 calcInterfaceBlockElementSizeAndOffset(GpuParamDataType type, UINT32 arraySize, UINT32& offset);
73 private:
74 /** Types of HLSL parameters. */
75 enum class ParamType
76 {
77 UniformBlock,
78 Texture,
79 Sampler,
80 Image,
81 StorageBlock,
82 Count // Keep at end
83 };
84
85 /**
86 * Populates information for uniform with the specified index into the provided structure.
87 *
88 * @param[in] desc Output structure containing the parsed data.
89 * @param[in] paramName Name of the uniform.
90 * @param[in] programHandle Internal OpenGL handle to the GPU program.
91 * @param[in] uniformIndex Unique uniform index to retrieve data from. Obtained from OpenGL parsing methods.
92 */
93 void determineParamInfo(GpuParamDataDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
94
95 /**
96 * Attempts to find out a vertex element semantic based on input parameter name. GLSL has no concept of semantics,
97 * so we require all shaders to use specific names for attributes so that we know what they are used for.
98 *
99 * Valid names and semantics:
100 * bs_position - VES_POSITION
101 * bs_normal - VES_NORMAL
102 * bs_tangent - VES_TANGENT
103 * bs_bitangent - VES_BITANGENT
104 * bs_texcoord - VES_TEXCOORD
105 * bs_color - VES_COLOR
106 * bs_blendweights - VES_BLEND_WEIGHTS
107 * bs_blendindices - VES_BLEND_INDICES
108 *
109 * You may append a number to the end of the name to specify semantic index.
110 *
111 * @return True if it succeeds, false if it fails.
112 */
113 bool attribNameToElementSemantic(const String& name, VertexElementSemantic& semantic, UINT16& index);
114
115 /** Converts an OpenGL type to vertex element type. */
116 VertexElementType glTypeToAttributeType(GLenum glType);
117
118 /** Maps a parameter in a specific shader stage, of a specific type to a unique set index. */
119 static UINT32 mapParameterToSet(GpuProgramType progType, ParamType paramType);
120 };
121
122 /** @} */
123}}