447 |
jab |
1 |
#ifndef __GLGRAPHICS_GLSL_SHADER_H__
|
|
|
2 |
#define __GLGRAPHICS_GLSL_SHADER_H__
|
369 |
jab |
3 |
|
|
|
4 |
#include <GL/glew.h>
|
|
|
5 |
#include <string>
|
|
|
6 |
|
|
|
7 |
/* It is a little tricky to make shader programs in C++ using GLSL but the problems are
|
502 |
jrf |
8 |
almost all silly little things. For instance, how do you robustly read from a text
|
|
|
9 |
file? How do you compile a shader and check for errors? In OpenGL What is the difference
|
|
|
10 |
between a GLSL program and a shader anyway?
|
369 |
jab |
11 |
|
502 |
jrf |
12 |
The short answer to the last question is this: A "shader" can be either a vertex shader,
|
|
|
13 |
a geometry shader (in OpenGL 2.0) or a fragment shader. A "program" is a linked combination
|
|
|
14 |
of these three types of shaders. Note that you don't have to have a geometry shader.
|
|
|
15 |
|
|
|
16 |
This API attempts to obviate the need for an answer to the first two questions by providing
|
|
|
17 |
an API for loading and compiling shaders and checking for errors. However, I don't
|
|
|
18 |
include functions for creating the program, attaching shaders and linking. Why not??!
|
|
|
19 |
|
|
|
20 |
Because the need for flexibility means that the API would be just as complex as just using
|
|
|
21 |
the OpenGL functions directly! However, loading shaders and checking for errors in compiled shaders
|
|
|
22 |
is different. It makes sense to wrap that. It also makes sense to wrap the error checking for
|
|
|
23 |
programs that are linked, so there is a function for that too.
|
|
|
24 |
|
|
|
25 |
Since shader loading and error check sandwhich the two calls needed for compilation, the most
|
|
|
26 |
important function in this API, create_glsl_shader, loads a shader, compiles it, checks for errors
|
|
|
27 |
and returns the shader handle. There is also a version which creates a shader from a string.
|
|
|
28 |
|
|
|
29 |
There is some code below to illustrate usage.
|
|
|
30 |
|
369 |
jab |
31 |
<code snippet>
|
502 |
jrf |
32 |
// Create shaders directly from file
|
|
|
33 |
GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, shader_path, "tri.vert");
|
|
|
34 |
GLuint gs = create_glsl_shader(GL_GEOMETRY_SHADER_EXT, shader_path, "tri.geom");
|
|
|
35 |
GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, shader_path, "tri.frag");
|
369 |
jab |
36 |
|
502 |
jrf |
37 |
// Create the program
|
|
|
38 |
prog_P0 = glCreateProgram();
|
|
|
39 |
|
|
|
40 |
// Attach all shaders
|
|
|
41 |
if(vs) glAttachShader(prog_P0, vs);
|
|
|
42 |
if(gs) glAttachShader(prog_P0, gs);
|
|
|
43 |
if(fs) glAttachShader(prog_P0, fs);
|
|
|
44 |
|
|
|
45 |
// Specify input and output for the geometry shader. Note that this must be
|
|
|
46 |
// done before linking the program.
|
|
|
47 |
glProgramParameteriEXT(prog_P0,GL_GEOMETRY_INPUT_TYPE_EXT,GL_TRIANGLES);
|
|
|
48 |
glProgramParameteriEXT(prog_P0,GL_GEOMETRY_VERTICES_OUT_EXT,3);
|
|
|
49 |
glProgramParameteriEXT(prog_P0,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_TRIANGLE_STRIP);
|
369 |
jab |
50 |
|
502 |
jrf |
51 |
// Link the program object and print out the info log
|
|
|
52 |
glLinkProgram(prog_P0);
|
|
|
53 |
print_glsl_program_log(prog_P0);
|
|
|
54 |
|
|
|
55 |
// Install program object as part of current state
|
|
|
56 |
glUseProgram(prog_P0);
|
369 |
jab |
57 |
|
502 |
jrf |
58 |
// Set the value of a uniform
|
|
|
59 |
glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), win_size_x/2.0, win_size_y/2.0);
|
369 |
jab |
60 |
</code snippet>
|
502 |
jrf |
61 |
|
|
|
62 |
Happy shader coding.
|
|
|
63 |
|
|
|
64 |
Andreas Būrentzen, 2007
|
|
|
65 |
|
|
|
66 |
*/
|
369 |
jab |
67 |
|
373 |
jrf |
68 |
namespace GLGraphics
|
|
|
69 |
{
|
502 |
jrf |
70 |
/// Print the info log for a program if the status is not OK.
|
|
|
71 |
void print_glsl_program_log(GLuint program);
|
|
|
72 |
|
|
|
73 |
/// Print the info log for a shader if the status is not OK.
|
|
|
74 |
void print_glsl_shader_log(GLuint shader);
|
|
|
75 |
|
|
|
76 |
/** The two arguments are concatenated to form the name with full path of a text file.
|
|
|
77 |
This file is read and returned as a string. */
|
|
|
78 |
const std::string read_glsl_source(const std::string& path, const std::string& file);
|
|
|
79 |
|
|
|
80 |
/** Create a shader of type specified by the first argument from a source string given
|
|
|
81 |
as second argument. Return shader handle. If there is a problem, the infolog is
|
|
|
82 |
printed and 0 is returned (unless the third argument is false). */
|
|
|
83 |
GLuint create_glsl_shader(GLuint stype, const std::string& src, bool print_log = true);
|
|
|
84 |
|
|
|
85 |
/** Create a shader of type specified as first argument from the file indicated by the
|
|
|
86 |
supplied path and file name (second and third arguments) and return a shader handle.
|
|
|
87 |
This function is only a convenience function wrapping read_glsl_source and
|
|
|
88 |
create_glsl_shader */
|
|
|
89 |
GLuint create_glsl_shader(GLuint stype, const std::string& path, const std::string& file);
|
373 |
jrf |
90 |
}
|
369 |
jab |
91 |
|
|
|
92 |
#endif
|