1 // Copyright 2008 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@gmail.com>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * gpu.h: Graphics processor management
40 #include <GL/freeglut.h>
47 #define ALE_GLSL_ASSERT_INCLUDE \
48 "#define assert(x) { if ((x)); }\n"
51 static int gpu_initialized
;
53 static void try_init_gpu() {
54 assert(!gpu_initialized
);
57 char program_name
[20];
59 char *fake_argv
[] = { program_name
};
61 strcpy(program_name
, "ale");
63 glutInit(&fake_argc
, fake_argv
);
64 glutInitDisplayMode(GLUT_RGBA
| GLUT_DOUBLE
);
65 glutCreateWindow(PACKAGE_NAME
" " VERSION
);
74 if (gpu_initialized
) {
75 if (glewInit() != GLEW_OK
) {
76 fprintf(stderr
, "glewInit() returned an error.\n");
86 if (!gpu_initialized
) {
90 return gpu_initialized
;
93 static int is_enabled();
98 * For now, assume that the image fits in a single texture.
106 static const char **program_buffer
;
107 static int program_buffer_size
;
109 static void size_program_buffer() {
110 program_buffer
= (const char **) realloc(program_buffer
, sizeof(const char *) * program_buffer_size
);
111 assert(program_buffer
);
114 static void check_log(const char *description
, const char *log
, int program_lines
= 0, const char **program
= NULL
) {
115 if (strcmp(log
, "")) {
116 fprintf(stderr
, "GLSL %s error log:\n", description
);
117 fprintf(stderr
, "%s", log
);
119 fprintf(stderr
, "Program text:\n");
120 for (int i
= 0; i
< program_lines
; i
++)
121 fprintf(stderr
, "%s", program
[i
]);
128 static void check_id(GLuint id
) {
130 fprintf(stderr
, "GLSL object creation failed.\n");
145 void attach_to_program(const program
*p
) const {
147 glAttachShader(p
->id
, id
);
150 shader(const char *source
) {
153 assert(is_enabled());
155 program_buffer_size
++;
156 size_program_buffer();
157 program_buffer
[program_buffer_size
- 1] = source
;
160 id
= glCreateShader(GL_FRAGMENT_SHADER_ARB
);
162 glShaderSource(id
, program_buffer_size
, program_buffer
, NULL
);
164 glGetShaderInfoLog(id
, 1000, NULL
, log
);
165 check_log("shader compilation", log
, program_buffer_size
, program_buffer
);
167 program_buffer_size
--;
168 size_program_buffer();
171 shader (const shader
&p
) {
175 shader
&operator=(const shader
&p
) {
195 * For libraries containing multiple shaders, or
196 * referencing shaders not stored locally, this
197 * method can be overridden.
199 virtual void attach_shaders(program
*p
) const {
202 p
->attach(gpu_shader
);
206 static void set_constant(const char *name
, int value
) {
207 program_buffer_size
++;
208 size_program_buffer();
210 const int line_length
= 1000;
212 char *program_line
= (char *) malloc(line_length
* sizeof(char));
213 assert(program_line
);
217 * XXX: This seems to generate link errors, for some reason.
219 snprintf(program_line
, line_length
, "const int %s = %d;\n", name
, value
);
221 snprintf(program_line
, line_length
, "#define %s %d\n", name
, value
);
224 program_buffer
[program_buffer_size
- 1] = program_line
;
230 assert(is_enabled());
232 id
= glCreateProgram();
237 program (const program
&p
) {
241 program
&operator=(const program
&p
) {
251 void attach(const shader
*s
) {
252 s
->attach_to_program(this);
255 void attach(const library
*l
) {
256 l
->attach_shaders(this);
263 glGetProgramInfoLog(id
, 1000, NULL
, log
);
264 check_log("program linking", log
);