Line data Source code
1 : /* Copyright (C) 2023 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_RENDERER_BACKEND_GL_SHADERPROGRAM
19 : #define INCLUDED_RENDERER_BACKEND_GL_SHADERPROGRAM
20 :
21 : #include "lib/ogl.h"
22 : #include "lib/file/vfs/vfs_path.h"
23 : #include "ps/containers/Span.h"
24 : #include "ps/CStrForward.h"
25 : #include "renderer/backend/Format.h"
26 : #include "renderer/backend/gl/Texture.h"
27 : #include "renderer/backend/IShaderProgram.h"
28 :
29 : #include <map>
30 : #include <vector>
31 :
32 : struct CColor;
33 : class CMatrix3D;
34 : class CVector3D;
35 : class CShaderDefines;
36 : class CStrIntern;
37 :
38 : namespace Renderer
39 : {
40 :
41 : namespace Backend
42 : {
43 :
44 : namespace GL
45 : {
46 :
47 : class CDevice;
48 :
49 : class CVertexInputLayout : public IVertexInputLayout
50 : {
51 : public:
52 0 : CVertexInputLayout(CDevice* device, const PS::span<const SVertexAttributeFormat> attributes)
53 0 : : m_Device(device), m_Attributes(attributes.begin(), attributes.end())
54 : {
55 0 : for (const SVertexAttributeFormat& attribute : m_Attributes)
56 : {
57 0 : ENSURE(attribute.format != Format::UNDEFINED);
58 0 : ENSURE(attribute.stride > 0);
59 : }
60 0 : }
61 :
62 0 : ~CVertexInputLayout() override = default;
63 :
64 : IDevice* GetDevice() override;
65 :
66 0 : const std::vector<SVertexAttributeFormat>& GetAttributes() const noexcept { return m_Attributes; }
67 :
68 : private:
69 : CDevice* m_Device = nullptr;
70 :
71 : std::vector<SVertexAttributeFormat> m_Attributes;
72 : };
73 :
74 : /**
75 : * A compiled vertex+fragment shader program.
76 : * The implementation may use GL_ARB_{vertex,fragment}_program (ARB assembly syntax)
77 : * or GL_ARB_{vertex,fragment}_shader (GLSL), or may use hard-coded fixed-function
78 : * multitexturing setup code; the difference is hidden from the caller.
79 : *
80 : * Texture/uniform IDs are typically strings, corresponding to the names defined in
81 : * the shader .xml file. Alternatively (and more efficiently, if used very frequently),
82 : * call GetBindingSlot and pass its return value as the ID.
83 : * Setting uniforms that the shader .xml doesn't support is harmless.
84 : *
85 : * For a high-level overview of shaders and materials, see
86 : * http://trac.wildfiregames.com/wiki/MaterialSystem
87 : */
88 0 : class CShaderProgram : public IShaderProgram
89 : {
90 : NONCOPYABLE(CShaderProgram);
91 :
92 : public:
93 : typedef CStrIntern attrib_id_t;
94 :
95 : static std::unique_ptr<CShaderProgram> Create(
96 : CDevice* device, const CStr& name, const CShaderDefines& baseDefines);
97 :
98 : ~CShaderProgram() override;
99 :
100 : /**
101 : * Binds the shader into the GL context. Call this before calling Uniform()
102 : * or trying to render with it.
103 : */
104 : virtual void Bind(CShaderProgram* previousShaderProgram) = 0;
105 :
106 : /**
107 : * Unbinds the shader from the GL context. Call this after rendering with it.
108 : */
109 : virtual void Unbind() = 0;
110 :
111 : struct TextureUnit
112 : {
113 : GLenum type;
114 : GLenum target;
115 : GLint unit;
116 : };
117 : virtual TextureUnit GetTextureUnit(const int32_t bindingSlot) = 0;
118 :
119 : virtual void SetUniform(
120 : const int32_t bindingSlot,
121 : const float value) = 0;
122 : virtual void SetUniform(
123 : const int32_t bindingSlot,
124 : const float valueX, const float valueY) = 0;
125 : virtual void SetUniform(
126 : const int32_t bindingSlot,
127 : const float valueX, const float valueY,
128 : const float valueZ) = 0;
129 : virtual void SetUniform(
130 : const int32_t bindingSlot,
131 : const float valueX, const float valueY,
132 : const float valueZ, const float valueW) = 0;
133 : virtual void SetUniform(
134 : const int32_t bindingSlot, PS::span<const float> values) = 0;
135 :
136 : // Vertex attribute pointers (equivalent to glVertexPointer etc).
137 : virtual void VertexAttribPointer(
138 : const VertexAttributeStream stream, const Format format,
139 : const uint32_t offset, const uint32_t stride,
140 : const VertexAttributeRate rate, const void* data);
141 :
142 : bool IsStreamActive(const VertexAttributeStream stream) const;
143 :
144 : /**
145 : * Checks that all the required vertex attributes have been set.
146 : * Call this before calling Draw/DrawIndexed etc to avoid potential crashes.
147 : */
148 : void AssertPointersBound();
149 :
150 : protected:
151 : CShaderProgram(int streamflags);
152 :
153 : void VertexPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
154 : void NormalPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
155 : void ColorPointer(const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
156 : void TexCoordPointer(GLenum texture, const Renderer::Backend::Format format, GLsizei stride, const void* pointer);
157 :
158 : int m_StreamFlags;
159 :
160 : // Non-GLSL client state handling:
161 : void BindClientStates();
162 : void UnbindClientStates();
163 : int m_ValidStreams; // which streams have been specified via VertexPointer etc since the last Bind
164 : };
165 :
166 : } // namespace GL
167 :
168 : } // namespace Backend
169 :
170 : } // namespace Renderer
171 :
172 : #endif // INCLUDED_RENDERER_BACKEND_GL_SHADERPROGRAM
|