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