1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
26 // File: vogl_shader_utils.cpp
27 #include "vogl_shader_utils.h"
29 GLuint vogl_create_program(const char *pVertex_shader_source, const char *pFragment_shader_source)
31 GLuint program = 0, vert_shader = 0, frag_shader = 0;
35 vert_shader = GL_ENTRYPOINT(glCreateShader)(GL_VERTEX_SHADER);
38 frag_shader = GL_ENTRYPOINT(glCreateShader)(GL_FRAGMENT_SHADER);
41 if ((!vert_shader) || (!frag_shader))
44 // Compile vertex shader
45 GL_ENTRYPOINT(glShaderSource)(vert_shader, 1, (GLchar * const*)(&pVertex_shader_source), NULL);
46 if (vogl_check_gl_error())
49 GL_ENTRYPOINT(glCompileShader)(vert_shader);
50 if (vogl_check_gl_error())
53 GL_ENTRYPOINT(glGetShaderiv)(vert_shader, GL_COMPILE_STATUS, &status);
54 if ((vogl_check_gl_error()) || (status == GL_FALSE))
56 GL_ENTRYPOINT(glGetShaderInfoLog)(vert_shader, sizeof(msg), NULL, msg);
58 vogl_error_printf("%s: Error compiling vertex shader:\n%s\n", VOGL_FUNCTION_NAME, msg);
63 // Compile fragment shader
64 GL_ENTRYPOINT(glShaderSource)(frag_shader, 1, (GLchar * const*)(&pFragment_shader_source), NULL);
65 if (vogl_check_gl_error())
68 GL_ENTRYPOINT(glCompileShader)(frag_shader);
69 if (vogl_check_gl_error())
72 GL_ENTRYPOINT(glGetShaderiv)(frag_shader, GL_COMPILE_STATUS, &status);
73 if ((vogl_check_gl_error()) || (status == GL_FALSE))
75 GL_ENTRYPOINT(glGetShaderInfoLog)(frag_shader, sizeof(msg), NULL, msg);
77 vogl_error_printf("%s: Error compiling fragment shader:\n%s\n", VOGL_FUNCTION_NAME, msg);
82 // Create and link program
83 program = GL_ENTRYPOINT(glCreateProgram)();
84 if (vogl_check_gl_error())
87 GL_ENTRYPOINT(glAttachShader)(program, vert_shader);
88 if (vogl_check_gl_error())
91 GL_ENTRYPOINT(glAttachShader)(program, frag_shader);
92 if (vogl_check_gl_error())
95 GL_ENTRYPOINT(glLinkProgram)(program);
96 if (vogl_check_gl_error())
99 GL_ENTRYPOINT(glDeleteShader)(vert_shader);
103 GL_ENTRYPOINT(glDeleteShader)(frag_shader);
107 GL_ENTRYPOINT(glGetProgramiv)(program, GL_LINK_STATUS, &status);
108 if ((vogl_check_gl_error()) || (status == GL_FALSE))
110 GL_ENTRYPOINT(glGetProgramInfoLog)(program, sizeof(msg), NULL, msg);
112 vogl_error_printf("%s: Error linking program:\n%s\n", VOGL_FUNCTION_NAME, msg);
122 GL_ENTRYPOINT(glDeleteShader)(vert_shader);
128 GL_ENTRYPOINT(glDeleteShader)(frag_shader);
134 GL_ENTRYPOINT(glDeleteProgram)(program);
138 vogl_error_printf("%s: Failed creating program!\n", VOGL_FUNCTION_NAME);
144 vogl_simple_gl_program::vogl_simple_gl_program() :
149 vogl_simple_gl_program::~vogl_simple_gl_program()
154 void vogl_simple_gl_program::deinit()
158 GL_ENTRYPOINT(glDeleteProgram)(m_program);
165 bool vogl_simple_gl_program::init(const char *pVertex_shader, const char *pFragment_shader)
169 m_program = vogl_create_program(pVertex_shader, pFragment_shader);
171 return m_program != 0;
174 GLint vogl_simple_gl_program::get_uniform_location(const char *pName) const
182 return GL_ENTRYPOINT(glGetUniformLocation)(m_program, reinterpret_cast<const GLchar *>(pName));
185 bool vogl_simple_gl_program::has_uniform(const char *pName) const
187 return get_uniform_location(pName) != -1;
190 void vogl_simple_gl_program::set_uniform(const char *pName, int s)
198 vogl_scoped_program_binder prog_binder(m_program);
200 GL_ENTRYPOINT(glUniform1i)(get_uniform_location(pName), s);
204 void vogl_simple_gl_program::set_uniform(const char *pName, uint s)
212 vogl_scoped_program_binder prog_binder(m_program);
214 GL_ENTRYPOINT(glUniform1ui)(get_uniform_location(pName), s);
218 void vogl_simple_gl_program::set_uniform(const char *pName, float s)
226 vogl_scoped_program_binder prog_binder(m_program);
228 GL_ENTRYPOINT(glUniform1f)(get_uniform_location(pName), s);
232 void vogl_simple_gl_program::set_uniform(const char *pName, const vec2I &v)
240 vogl_scoped_program_binder prog_binder(m_program);
242 GL_ENTRYPOINT(glUniform2i)(get_uniform_location(pName), v[0], v[1]);
246 void vogl_simple_gl_program::set_uniform(const char *pName, const vec2F &v)
254 vogl_scoped_program_binder prog_binder(m_program);
256 GL_ENTRYPOINT(glUniform2f)(get_uniform_location(pName), v[0], v[1]);
260 void vogl_simple_gl_program::set_uniform(const char *pName, const vec3I &v)
268 vogl_scoped_program_binder prog_binder(m_program);
270 GL_ENTRYPOINT(glUniform3i)(get_uniform_location(pName), v[0], v[1], v[2]);
274 void vogl_simple_gl_program::set_uniform(const char *pName, const vec3F &v)
282 vogl_scoped_program_binder prog_binder(m_program);
284 GL_ENTRYPOINT(glUniform3f)(get_uniform_location(pName), v[0], v[1], v[2]);
288 void vogl_simple_gl_program::set_uniform(const char *pName, const vec4I &v)
296 vogl_scoped_program_binder prog_binder(m_program);
298 GL_ENTRYPOINT(glUniform4i)(get_uniform_location(pName), v[0], v[1], v[2], v[3]);
302 void vogl_simple_gl_program::set_uniform(const char *pName, const vec4F &v)
310 vogl_scoped_program_binder prog_binder(m_program);
312 GL_ENTRYPOINT(glUniform4f)(get_uniform_location(pName), v[0], v[1], v[2], v[3]);
316 void vogl_simple_gl_program::set_uniform(const char *pName, const matrix33F &m, bool transpose)
324 vogl_scoped_program_binder prog_binder(m_program);
326 GL_ENTRYPOINT(glUniformMatrix3fv)(get_uniform_location(pName), 1, transpose, m.get_ptr());
330 void vogl_simple_gl_program::set_uniform(const char *pName, const matrix44F &m, bool transpose)
338 vogl_scoped_program_binder prog_binder(m_program);
340 GL_ENTRYPOINT(glUniformMatrix4fv)(get_uniform_location(pName), 1, transpose, m.get_ptr());