Fix infinite loop detection when placing players randomly on the newer random map...
[0ad.git] / source / graphics / ShaderProgram.h
blobe67b24164cc83f3f99617fc4fe955d6078e9e994
1 /* Copyright (C) 2012 Wildfire Games.
2 * This file is part of 0 A.D.
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.
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.
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/>.
18 #ifndef INCLUDED_SHADERPROGRAM
19 #define INCLUDED_SHADERPROGRAM
21 #include "graphics/ShaderProgramPtr.h"
22 #include "graphics/Texture.h"
23 #include "lib/ogl.h"
24 #include "lib/file/vfs/vfs_path.h"
25 #include "lib/res/handle.h"
27 #include <map>
29 struct CColor;
30 class CMatrix3D;
31 class CVector3D;
32 class CShaderDefines;
33 class CStrIntern;
35 // Vertex data stream flags
36 enum
38 STREAM_POS = (1 << 0),
39 STREAM_NORMAL = (1 << 1),
40 STREAM_COLOR = (1 << 2),
41 STREAM_UV0 = (1 << 3),
42 STREAM_UV1 = (1 << 4),
43 STREAM_UV2 = (1 << 5),
44 STREAM_UV3 = (1 << 6),
45 STREAM_POSTOUV0 = (1 << 7),
46 STREAM_POSTOUV1 = (1 << 8),
47 STREAM_POSTOUV2 = (1 << 9),
48 STREAM_POSTOUV3 = (1 << 10)
51 /**
52 * A compiled vertex+fragment shader program.
53 * The implementation may use GL_ARB_{vertex,fragment}_program (ARB assembly syntax)
54 * or GL_ARB_{vertex,fragment}_shader (GLSL), or may use hard-coded fixed-function
55 * multitexturing setup code; the difference is hidden from the caller.
57 * Texture/uniform IDs are typically strings, corresponding to the names defined in
58 * the shader .xml file. Alternatively (and more efficiently, if used very frequently),
59 * call GetTextureBinding/GetUniformBinding and pass its return value as the ID.
60 * Setting uniforms that the shader .xml doesn't support is harmless.
62 * For a high-level overview of shaders and materials, see
63 * http://trac.wildfiregames.com/wiki/MaterialSystem
65 class CShaderProgram
67 NONCOPYABLE(CShaderProgram);
69 public:
70 typedef CStrIntern attrib_id_t;
71 typedef CStrIntern texture_id_t;
72 typedef CStrIntern uniform_id_t;
73 typedef std::pair<int, GLenum> frag_index_pair_t;
75 /**
76 * Construct based on ARB vertex/fragment program files.
78 static CShaderProgram* ConstructARB(const VfsPath& vertexFile, const VfsPath& fragmentFile,
79 const CShaderDefines& defines,
80 const std::map<CStrIntern, int>& vertexIndexes, const std::map<CStrIntern, frag_index_pair_t>& fragmentIndexes,
81 int streamflags);
83 /**
84 * Construct based on GLSL vertex/fragment shader files.
86 static CShaderProgram* ConstructGLSL(const VfsPath& vertexFile, const VfsPath& fragmentFile,
87 const CShaderDefines& defines,
88 const std::map<CStrIntern, int>& vertexAttribs,
89 int streamflags);
91 /**
92 * Construct an instance of a pre-defined fixed-function pipeline setup.
94 static CShaderProgram* ConstructFFP(const std::string& id, const CShaderDefines& defines);
96 /**
97 * Represents a uniform attribute or texture binding.
98 * For uniforms:
99 * - ARB shaders store vertex location in 'first', fragment location in 'second'.
100 * - GLSL shaders store uniform location in 'first', data type in 'second'.
101 * - FFP shaders store -1 in 'first', index in 'second'.
102 * For textures, all store texture target (e.g. GL_TEXTURE_2D) in 'first', texture unit in 'second'.
103 * Non-existent bindings must store -1 in both.
105 struct Binding
107 Binding(int a, int b) : first(a), second(b) { }
109 Binding() : first(-1), second(-1) { }
112 * Returns whether this uniform attribute is active in the shader.
113 * If not then there's no point calling Uniform() to set its value.
115 bool Active() { return first != -1 || second != -1; }
117 int first;
118 int second;
121 virtual ~CShaderProgram() { }
123 virtual void Reload() = 0;
126 * Returns whether this shader was successfully loaded.
128 bool IsValid() const;
131 * Binds the shader into the GL context. Call this before calling Uniform()
132 * or trying to render with it.
134 virtual void Bind() = 0;
137 * Unbinds the shader from the GL context. Call this after rendering with it.
139 virtual void Unbind() = 0;
142 * Returns bitset of STREAM_* value, indicating what vertex data streams the
143 * vertex shader needs (e.g. position, color, UV, ...).
145 int GetStreamFlags() const;
148 virtual Binding GetTextureBinding(texture_id_t id) = 0;
150 // Variants of texture binding:
151 void BindTexture(texture_id_t id, CTexturePtr tex);
152 virtual void BindTexture(texture_id_t id, Handle tex) = 0;
153 virtual void BindTexture(texture_id_t id, GLuint tex) = 0;
154 virtual void BindTexture(Binding id, Handle tex) = 0;
157 virtual Binding GetUniformBinding(uniform_id_t id) = 0;
159 // Uniform-setting methods that subclasses must define:
160 virtual void Uniform(Binding id, float v0, float v1, float v2, float v3) = 0;
161 virtual void Uniform(Binding id, const CMatrix3D& v) = 0;
162 virtual void Uniform(Binding id, size_t count, const CMatrix3D* v) = 0;
164 // Convenient uniform-setting wrappers:
166 void Uniform(Binding id, int v);
167 void Uniform(Binding id, float v);
168 void Uniform(Binding id, float v0, float v1);
169 void Uniform(Binding id, const CVector3D& v);
170 void Uniform(Binding id, const CColor& v);
172 void Uniform(uniform_id_t id, int v);
173 void Uniform(uniform_id_t id, float v);
174 void Uniform(uniform_id_t id, float v0, float v1);
175 void Uniform(uniform_id_t id, const CVector3D& v);
176 void Uniform(uniform_id_t id, const CColor& v);
177 void Uniform(uniform_id_t id, float v0, float v1, float v2, float v3);
178 void Uniform(uniform_id_t id, const CMatrix3D& v);
179 void Uniform(uniform_id_t id, size_t count, const CMatrix3D* v);
181 // Vertex attribute pointers (equivalent to glVertexPointer etc):
183 virtual void VertexPointer(GLint size, GLenum type, GLsizei stride, void* pointer);
184 virtual void NormalPointer(GLenum type, GLsizei stride, void* pointer);
185 virtual void ColorPointer(GLint size, GLenum type, GLsizei stride, void* pointer);
186 virtual void TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void* pointer);
187 virtual void VertexAttribPointer(attrib_id_t id, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void* pointer);
188 virtual void VertexAttribIPointer(attrib_id_t id, GLint size, GLenum type, GLsizei stride, void* pointer);
191 * Checks that all the required vertex attributes have been set.
192 * Call this before calling glDrawArrays/glDrawElements etc to avoid potential crashes.
194 void AssertPointersBound();
196 protected:
197 CShaderProgram(int streamflags);
199 bool m_IsValid;
200 int m_StreamFlags;
202 // Non-GLSL client state handling:
203 void BindClientStates();
204 void UnbindClientStates();
205 int m_ValidStreams; // which streams have been specified via VertexPointer etc since the last Bind
208 #endif // INCLUDED_SHADERPROGRAM