18 #include "precompiled.h"
39 const std::map<CStrIntern, int>& vertexIndexes,
const std::map<CStrIntern, frag_index_pair_t>& fragmentIndexes,
58 bool Compile(GLuint target,
const char* targetName, GLuint program,
const VfsPath& file,
const CStr& code)
62 pglBindProgramARB(target, program);
66 pglProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)code.length(), code.c_str());
71 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errPos);
72 int errLine = std::count(code.begin(), code.begin() + std::min((
int)code.length(), errPos + 1),
'\n') + 1;
73 char* errStr = (
char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
74 LOGERROR(L
"Failed to compile %hs program '%ls' (line %d):\n%hs", targetName, file.
string().c_str(), errLine, errStr);
78 pglBindProgramARB(target, 0);
122 glEnable(GL_VERTEX_PROGRAM_ARB);
123 glEnable(GL_FRAGMENT_PROGRAM_ARB);
132 glDisable(GL_VERTEX_PROGRAM_ARB);
133 glDisable(GL_FRAGMENT_PROGRAM_ARB);
134 pglBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0);
135 pglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
152 std::map<CStrIntern, frag_index_pair_t>::iterator it =
m_FragmentIndexes.find(
id);
154 return std::make_pair(-1, 0);
161 int index = fPair.first;
165 return Binding((
int)fPair.second, index);
171 int index = fPair.first;
176 pglActiveTextureARB(GL_TEXTURE0+index);
177 glBindTexture(fPair.second, h);
184 int index = fPair.first;
187 pglActiveTextureARB(GL_TEXTURE0+index);
188 glBindTexture(fPair.second, tex);
194 int index =
id.second;
207 pglProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, (GLuint)
id.first, v0, v1, v2, v3);
210 pglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, (GLuint)
id.second, v0, v1, v2, v3);
217 pglProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, (GLuint)
id.first+0, v.
_11, v.
_12, v.
_13, v.
_14);
218 pglProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, (GLuint)
id.first+1, v.
_21, v.
_22, v.
_23, v.
_24);
219 pglProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, (GLuint)
id.first+2, v.
_31, v.
_32, v.
_33, v.
_34);
220 pglProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, (GLuint)
id.first+3, v.
_41, v.
_42, v.
_43, v.
_44);
225 pglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, (GLuint)
id.second+0, v.
_11, v.
_12, v.
_13, v.
_14);
226 pglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, (GLuint)
id.second+1, v.
_21, v.
_22, v.
_23, v.
_24);
227 pglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, (GLuint)
id.second+2, v.
_31, v.
_32, v.
_33, v.
_34);
228 pglProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, (GLuint)
id.second+3, v.
_41, v.
_42, v.
_43, v.
_44);
252 #endif // #if !CONFIG2_GLES
264 const std::map<CStrIntern, int>& vertexAttribs,
290 const char* code_string = code.c_str();
291 GLint code_length = code.length();
292 pglShaderSourceARB(shader, 1, &code_string, &code_length);
294 pglCompileShaderARB(shader);
297 pglGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
300 pglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
304 if (!ok && length == 0)
309 char* infolog =
new char[length];
310 pglGetShaderInfoLog(shader, length, NULL, infolog);
313 LOGMESSAGE(L
"Info when compiling shader '%ls':\n%hs", file.
string().c_str(), infolog);
315 LOGERROR(L
"Failed to compile shader '%ls':\n%hs", file.
string().c_str(), infolog);
322 return (ok ?
true :
false);
341 pglBindAttribLocationARB(
m_Program, it->second, it->first.c_str());
346 pglGetProgramiv(
m_Program, GL_LINK_STATUS, &ok);
349 pglGetProgramiv(
m_Program, GL_INFO_LOG_LENGTH, &length);
351 if (!ok && length == 0)
356 char* infolog =
new char[length];
357 pglGetProgramInfoLog(
m_Program, length, NULL, infolog);
379 GLint numUniforms = 0;
380 pglGetProgramiv(
m_Program, GL_ACTIVE_UNIFORMS, &numUniforms);
382 for (GLint i = 0; i < numUniforms; ++i)
384 char name[256] = {0};
385 GLsizei nameLength = 0;
391 GLint loc = pglGetUniformLocationARB(
m_Program, name);
394 m_Uniforms[nameIntern] = std::make_pair(loc, type);
397 if (type == GL_SAMPLER_2D
398 || type == GL_SAMPLER_CUBE
400 || type == GL_SAMPLER_2D_SHADOW
405 m_Samplers[nameIntern].first = (type == GL_SAMPLER_CUBE ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D);
407 pglUniform1iARB(loc, unit);
449 vertexCode.Replace(
"#version 110\n",
"#version 100\n");
450 vertexCode.Replace(
"#version 110\r\n",
"#version 100\n");
451 vertexCode.Replace(
"#version 120\n",
"#version 100\n");
452 vertexCode.Replace(
"#version 120\r\n",
"#version 100\n");
453 fragmentCode.Replace(
"#version 110\n",
"#version 100\nprecision mediump float;\n");
454 fragmentCode.Replace(
"#version 110\r\n",
"#version 100\nprecision mediump float;\n");
455 fragmentCode.Replace(
"#version 120\n",
"#version 100\nprecision mediump float;\n");
456 fragmentCode.Replace(
"#version 120\r\n",
"#version 100\nprecision mediump float;\n");
487 pglEnableVertexAttribArrayARB(it->second);
492 pglUseProgramObjectARB(0);
495 pglDisableVertexAttribArrayARB(it->second);
506 return Binding((
int)it->second.first, it->second.second);
517 pglActiveTextureARB(GL_TEXTURE0 + it->second.second);
518 glBindTexture(it->second.first, h);
527 pglActiveTextureARB(GL_TEXTURE0 + it->second.second);
528 glBindTexture(it->second.first, tex);
538 pglActiveTextureARB(GL_TEXTURE0 +
id.second);
539 glBindTexture(
id.first, h);
544 std::map<CStrIntern, std::pair<int, GLenum> >::iterator it =
m_Uniforms.find(
id);
548 return Binding(it->second.first, (
int)it->second.second);
555 if (
id.second == GL_FLOAT)
556 pglUniform1fARB(
id.first, v0);
557 else if (
id.second == GL_FLOAT_VEC2)
558 pglUniform2fARB(
id.first, v0, v1);
559 else if (
id.second == GL_FLOAT_VEC3)
560 pglUniform3fARB(
id.first, v0, v1, v2);
561 else if (
id.second == GL_FLOAT_VEC4)
562 pglUniform4fARB(
id.first, v0, v1, v2, v3);
564 LOGERROR(L
"CShaderProgramGLSL::Uniform(): Invalid uniform type (expected float, vec2, vec3, vec4)");
572 if (
id.second == GL_FLOAT_MAT4)
573 pglUniformMatrix4fvARB(
id.first, 1, GL_FALSE, &v.
_11);
575 LOGERROR(L
"CShaderProgramGLSL::Uniform(): Invalid uniform type (expected mat4)");
583 if (
id.second == GL_FLOAT_MAT4)
584 pglUniformMatrix4fvARB(
id.first, count, GL_FALSE, &v->
_11);
586 LOGERROR(L
"CShaderProgramGLSL::Uniform(): Invalid uniform type (expected mat4)");
593 virtual void VertexPointer(GLint size, GLenum type, GLsizei stride,
void* pointer)
595 pglVertexAttribPointerARB(0, size, type, GL_FALSE, stride, pointer);
601 pglVertexAttribPointerARB(2, 3, type, GL_TRUE, stride, pointer);
605 virtual void ColorPointer(GLint size, GLenum type, GLsizei stride,
void* pointer)
607 pglVertexAttribPointerARB(3, size, type, GL_TRUE, stride, pointer);
611 virtual void TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride,
void* pointer)
613 pglVertexAttribPointerARB(8 + texture - GL_TEXTURE0, size, type, GL_FALSE, stride, pointer);
622 pglVertexAttribPointerARB(it->second, size, type, normalized, stride, pointer);
632 debug_warn(L
"glVertexAttribIPointer not supported on GLES");
634 pglVertexAttribIPointerEXT(it->second, size, type, stride, pointer);
656 : m_IsValid(false), m_StreamFlags(streamflags), m_ValidStreams(0)
663 const std::map<CStrIntern, int>&
UNUSED(vertexIndexes),
const std::map<CStrIntern, int>&
UNUSED(fragmentIndexes),
666 LOGERROR(L
"CShaderProgram::ConstructARB: '%ls'+'%ls': ARB shaders not supported on this device",
667 vertexFile.
string().c_str(), fragmentFile.
string().c_str());
673 const std::map<CStrIntern, int>& vertexIndexes,
const std::map<CStrIntern, frag_index_pair_t>& fragmentIndexes,
676 return new CShaderProgramARB(vertexFile, fragmentFile, defines, vertexIndexes, fragmentIndexes, streamflags);
682 const std::map<CStrIntern, int>& vertexAttribs,
685 return new CShaderProgramGLSL(vertexFile, fragmentFile, defines, vertexAttribs, streamflags);
705 Uniform(
id, (
float)v, (
float)v, (
float)v, (
float)v);
715 Uniform(
id, v0, v1, 0.0f, 0.0f);
775 debug_warn(
"Shader type doesn't support VertexAttribPointer");
781 debug_warn(
"Shader type doesn't support VertexAttribIPointer");
791 debug_warn(
"CShaderProgram::VertexPointer should be overridden");
795 debug_warn(
"CShaderProgram::NormalPointer should be overridden");
799 debug_warn(
"CShaderProgram::ColorPointer should be overridden");
803 debug_warn(
"CShaderProgram::TexCoordPointer should be overridden");
814 glVertexPointer(size, type, stride, pointer);
820 glNormalPointer(type, stride, pointer);
826 glColorPointer(size, type, stride, pointer);
832 pglClientActiveTextureARB(texture);
833 glTexCoordPointer(size, type, stride, pointer);
834 pglClientActiveTextureARB(GL_TEXTURE0);
850 pglClientActiveTextureARB(GL_TEXTURE0);
851 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
856 pglClientActiveTextureARB(GL_TEXTURE1);
857 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
858 pglClientActiveTextureARB(GL_TEXTURE0);
875 pglClientActiveTextureARB(GL_TEXTURE0);
876 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
881 pglClientActiveTextureARB(GL_TEXTURE1);
882 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
883 pglClientActiveTextureARB(GL_TEXTURE0);
887 #endif // !CONFIG2_GLES
virtual void VertexPointer(GLint size, GLenum type, GLsizei stride, void *pointer)
virtual void ColorPointer(GLint size, GLenum type, GLsizei stride, void *pointer)
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
void BindTexture(texture_id_t id, CTexturePtr tex)
GLhandleARB m_FragmentShader
int GetStreamFlags() const
Returns bitset of STREAM_* value, indicating what vertex data streams the vertex shader needs (e...
virtual Binding GetUniformBinding(uniform_id_t id)=0
frag_index_pair_t GetUniformFragmentIndex(CStrIntern id)
const PSRETURN PSRETURN_OK
Reads a file, then gives read-only access to the contents.
bool IsValid() const
Returns whether this shader was successfully loaded.
virtual void VertexAttribIPointer(attrib_id_t id, GLint size, GLenum type, GLsizei stride, void *pointer)
virtual void ColorPointer(GLint size, GLenum type, GLsizei stride, void *pointer)
virtual void Unbind()
Unbinds the shader from the GL context.
std::map< CStrIntern, int > m_VertexIndexes
virtual void Unbind()
Unbinds the shader from the GL context.
CShaderProgramARB(const VfsPath &vertexFile, const VfsPath &fragmentFile, const CShaderDefines &defines, const std::map< CStrIntern, int > &vertexIndexes, const std::map< CStrIntern, frag_index_pair_t > &fragmentIndexes, int streamflags)
virtual void BindTexture(texture_id_t id, GLuint tex)
void UnbindClientStates()
virtual void TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void *pointer)
virtual void BindTexture(texture_id_t id, GLuint tex)
static CShaderProgram * ConstructARB(const VfsPath &vertexFile, const VfsPath &fragmentFile, const CShaderDefines &defines, const std::map< CStrIntern, int > &vertexIndexes, const std::map< CStrIntern, frag_index_pair_t > &fragmentIndexes, int streamflags)
Construct based on ARB vertex/fragment program files.
virtual void VertexAttribIPointer(attrib_id_t id, GLint size, GLenum type, GLsizei stride, void *pointer)
bool ogl_SquelchError(GLenum err_to_ignore)
ignore and reset the specified OpenGL error.
void AssertPointersBound()
Checks that all the required vertex attributes have been set.
int GetUniformVertexIndex(CStrIntern id)
virtual void Uniform(Binding id, size_t count, const CMatrix3D *v)
#define TIMER_ACCRUE(client)
Measure the time taken to execute code up until end of the current scope; bill it to the given TimerC...
Status ogl_tex_bind(Handle ht, size_t unit)
Bind texture to the specified unit in preparation for using it in rendering.
CStr GetAsString() const
Returns contents of file as a string.
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
virtual void Uniform(Binding id, size_t count, const CMatrix3D *v)
std::map< CStrIntern, frag_index_pair_t > m_FragmentIndexes
std::map< CStrIntern, std::pair< int, GLenum > > m_Uniforms
virtual void TexCoordPointer(GLenum texture, GLint size, GLenum type, GLsizei stride, void *pointer)
bool Compile(GLhandleARB shader, const VfsPath &file, const CStr &code)
const String & string() const
virtual Binding GetTextureBinding(texture_id_t id)
virtual void BindTexture(Binding id, Handle tex)
virtual void Uniform(Binding id, float v0, float v1, float v2, float v3)
bool Compile(GLuint target, const char *targetName, GLuint program, const VfsPath &file, const CStr &code)
i64 Handle
`handle' representing a reference to a resource (sound, texture, etc.)
virtual void VertexPointer(GLint size, GLenum type, GLsizei stride, void *pointer)
CShaderProgram(int streamflags)
CShaderProgramGLSL(const VfsPath &vertexFile, const VfsPath &fragmentFile, const CShaderDefines &defines, const std::map< CStrIntern, int > &vertexAttribs, int streamflags)
std::map< CStrIntern, int > m_VertexAttribs
virtual Binding GetUniformBinding(uniform_id_t id)
virtual void VertexAttribPointer(attrib_id_t id, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void *pointer)
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
CStr Preprocess(const CStr &input)
virtual void Uniform(Binding id, const CMatrix3D &v)
virtual void BindTexture(Binding id, Handle tex)
std::map< CStrIntern, std::pair< GLenum, int > > m_Samplers
void AddDefines(const CShaderDefines &defines)
#define TIMER_ADD_CLIENT(id)
"allocate" a new TimerClient that will keep track of the total time billed to it, along with a descri...
Status ogl_tex_get_texture_id(Handle ht, GLuint *id)
Return the GL handle of the loaded texture in *id, or 0 on failure.
PSRETURN Load(const PIVFS &vfs, const VfsPath &filename)
Returns either PSRETURN_OK or PSRETURN_CVFSFile_LoadFailed.
virtual void Uniform(Binding id, float v0, float v1, float v2, float v3)=0
Represents a uniform attribute or texture binding.
virtual void BindTexture(texture_id_t id, Handle tex)
virtual void NormalPointer(GLenum type, GLsizei stride, void *pointer)
virtual void NormalPointer(GLenum type, GLsizei stride, void *pointer)
std::pair< int, GLenum > frag_index_pair_t
virtual void Uniform(Binding id, float v0, float v1, float v2, float v3)
virtual Binding GetTextureBinding(texture_id_t id)
void AddDefine(const char *name, const char *value)
GLhandleARB m_VertexShader
void ogl_WarnIfError()
raise a warning (break into the debugger) if an OpenGL error is pending.
#define debug_warn(expr)
display the error dialog with the given text.
virtual void Bind()
Binds the shader into the GL context.
Convenience wrapper around CPreprocessor.
virtual void BindTexture(texture_id_t id, Handle tex)
virtual void Uniform(Binding id, const CMatrix3D &v)
A compiled vertex+fragment shader program.
static CShaderProgram * ConstructGLSL(const VfsPath &vertexFile, const VfsPath &fragmentFile, const CShaderDefines &defines, const std::map< CStrIntern, int > &vertexAttribs, int streamflags)
Construct based on GLSL vertex/fragment shader files.
virtual void Bind()
Binds the shader into the GL context.
virtual Binding GetUniformBinding(uniform_id_t id)
virtual void VertexAttribPointer(attrib_id_t id, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void *pointer)
shared_ptr< CTexture > CTexturePtr