--tk-median --> --track-median, etc.
[Ale.git] / gpu.h
blob21e495e9e945b18e70d2803d85a7c114088fb888
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
25 #ifndef __gpu_h__
26 #define __gpu_h__
28 #include <config.h>
30 #include <assert.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
35 #ifdef USE_GLEW
36 #include <GL/glew.h>
37 #endif
39 #ifdef USE_FREEGLUT
40 #include <GL/freeglut.h>
41 #elif USE_GLUT
42 #include <GL/glut.h>
43 #endif
45 #include "thread.h"
47 #define ALE_GLSL_ASSERT_INCLUDE \
48 "#define assert(x) { if ((x)); }\n"
50 class gpu {
51 static int gpu_initialized;
53 static void try_init_gpu() {
54 assert(!gpu_initialized);
56 #ifdef USE_GLUT
57 char program_name[20];
58 int fake_argc = 1;
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);
68 gpu_initialized = 1;
69 #else
70 gpu_initialized = 0;
71 #endif
73 #ifdef USE_GLEW
74 if (gpu_initialized) {
75 if (glewInit() != GLEW_OK) {
76 fprintf(stderr, "glewInit() returned an error.\n");
77 exit(1);
80 #endif
83 public:
85 static int is_ok() {
86 if (!gpu_initialized) {
87 try_init_gpu();
90 return gpu_initialized;
93 static int is_enabled();
95 class image {
96 #ifdef USE_GLUT
98 * For now, assume that the image fits in a single texture.
100 GLuint texture;
101 #endif
104 class program {
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);
118 if (program) {
119 fprintf(stderr, "Program text:\n");
120 for (int i = 0; i < program_lines; i++)
121 fprintf(stderr, "%s", program[i]);
123 exit(1);
127 #ifdef USE_GLEW
128 static void check_id(GLuint id) {
129 if (id == 0) {
130 fprintf(stderr, "GLSL object creation failed.\n");
131 exit(1);
135 GLuint id;
136 #endif
138 public:
139 class shader {
140 #ifdef USE_GLEW
141 GLuint id;
142 #endif
144 public:
145 void attach_to_program(const program *p) const {
146 #ifdef USE_GLEW
147 glAttachShader(p->id, id);
148 #endif
150 shader(const char *source) {
151 #ifdef USE_GLEW
153 assert(is_enabled());
155 program_buffer_size++;
156 size_program_buffer();
157 program_buffer[program_buffer_size - 1] = source;
159 char log[1000] = "";
160 id = glCreateShader(GL_FRAGMENT_SHADER_ARB);
161 check_id(id);
162 glShaderSource(id, program_buffer_size, program_buffer, NULL);
163 glCompileShader(id);
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();
169 #endif
171 shader (const shader &p) {
172 assert(0);
175 shader &operator=(const shader &p) {
176 assert(0);
179 ~shader() {
180 #ifdef USE_GLEW
181 glDeleteShader(id);
182 #endif
186 class library {
187 protected:
188 shader *gpu_shader;
189 public:
190 library() {
191 gpu_shader = NULL;
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 {
200 assert(p);
201 if (gpu_shader)
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);
215 #if 0
217 * XXX: This seems to generate link errors, for some reason.
219 snprintf(program_line, line_length, "const int %s = %d;\n", name, value);
220 #else
221 snprintf(program_line, line_length, "#define %s %d\n", name, value);
222 #endif
224 program_buffer[program_buffer_size - 1] = program_line;
227 program() {
228 #ifdef USE_GLEW
230 assert(is_enabled());
232 id = glCreateProgram();
233 check_id(id);
234 #endif
237 program (const program &p) {
238 assert(0);
241 program &operator=(const program &p) {
242 assert(0);
245 ~program() {
246 #ifdef USE_GLEW
247 glDeleteProgram(id);
248 #endif
251 void attach(const shader *s) {
252 s->attach_to_program(this);
255 void attach(const library *l) {
256 l->attach_shaders(this);
259 void link() {
260 #ifdef USE_GLEW
261 char log[1000] = "";
262 glLinkProgram(id);
263 glGetProgramInfoLog(id, 1000, NULL, log);
264 check_log("program linking", log);
265 #endif
271 #endif