Mercurial > repos > blastem
comparison render_sdl.c @ 488:32f053ad9b02 opengl
Basic OpenGL rendering is working
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 27 Oct 2013 01:29:50 -0700 |
parents | c08a4efeee7f |
children | e97b80e3bd76 |
comparison
equal
deleted
inserted
replaced
487:c08a4efeee7f | 488:32f053ad9b02 |
---|---|
8 #include "render.h" | 8 #include "render.h" |
9 #include "blastem.h" | 9 #include "blastem.h" |
10 #include "io.h" | 10 #include "io.h" |
11 | 11 |
12 #ifndef DISABLE_OPENGL | 12 #ifndef DISABLE_OPENGL |
13 #define GL_GLEXT_PROTOTYPES | 13 #include <GL/glew.h> |
14 #include <GL/gl.h> | |
15 #include <GL/glext.h> | |
16 #endif | 14 #endif |
17 | 15 |
18 SDL_Surface *screen; | 16 SDL_Surface *screen; |
19 uint8_t render_dbg = 0; | 17 uint8_t render_dbg = 0; |
20 uint8_t debug_pal = 0; | 18 uint8_t debug_pal = 0; |
91 } | 89 } |
92 | 90 |
93 uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) | 91 uint32_t render_map_color(uint8_t r, uint8_t g, uint8_t b) |
94 { | 92 { |
95 if (render_gl) { | 93 if (render_gl) { |
96 return b << 24 | g << 16 | r << 8 | 255; | 94 return 255 << 24 | r << 16 | g << 8 | b; |
97 } else { | 95 } else { |
98 return SDL_MapRGB(screen->format, r, g, b); | 96 return SDL_MapRGB(screen->format, r, g, b); |
99 } | 97 } |
100 } | 98 } |
101 | 99 |
102 GLuint textures[3], buffers[2]; | 100 GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], at_pos; |
103 | 101 |
104 const GLfloat vertex_data[] = { | 102 const GLfloat vertex_data[] = { |
105 -1.0f, -1.0f, | 103 -1.0f, -1.0f, |
106 1.0f, -1.0f, | 104 1.0f, -1.0f, |
107 -1.0f, 1.0f, | 105 -1.0f, 1.0f, |
108 1.0f, 1.0f | 106 1.0f, 1.0f |
109 }; | 107 }; |
110 | 108 |
111 const GLushort element_data[] = {0, 1, 2, 3}; | 109 const GLushort element_data[] = {0, 1, 2, 3}; |
110 | |
111 GLuint load_shader(char * fname, GLenum shader_type) | |
112 { | |
113 FILE * f = fopen(fname, "r"); | |
114 if (!f) { | |
115 fprintf(stderr, "Failed to open shader file %s for reading\n", fname); | |
116 return 0; | |
117 } | |
118 fseek(f, 0, SEEK_END); | |
119 long fsize = ftell(f); | |
120 fseek(f, 0, SEEK_SET); | |
121 GLchar * text = malloc(fsize); | |
122 if (fread(text, 1, fsize, f) != fsize) { | |
123 fprintf(stderr, "Error reading from shader file %s\n", fname); | |
124 free(text); | |
125 return 0; | |
126 } | |
127 GLuint ret = glCreateShader(shader_type); | |
128 glShaderSource(ret, 1, (const GLchar **)&text, (const GLint *)&fsize); | |
129 free(text); | |
130 glCompileShader(ret); | |
131 GLint compile_status, loglen; | |
132 glGetShaderiv(ret, GL_COMPILE_STATUS, &compile_status); | |
133 if (!compile_status) { | |
134 fprintf(stderr, "Shader %s failed to compile\n", fname); | |
135 glGetShaderiv(ret, GL_INFO_LOG_LENGTH, &loglen); | |
136 text = malloc(loglen); | |
137 glGetShaderInfoLog(ret, loglen, NULL, text); | |
138 fputs(text, stderr); | |
139 free(text); | |
140 glDeleteShader(ret); | |
141 return 0; | |
142 } | |
143 return ret; | |
144 } | |
112 | 145 |
113 void render_alloc_surfaces(vdp_context * context) | 146 void render_alloc_surfaces(vdp_context * context) |
114 { | 147 { |
115 if (render_gl) { | 148 if (render_gl) { |
116 context->oddbuf = context->framebuf = malloc(320 * 240 * 4 * 2); | 149 context->oddbuf = context->framebuf = malloc(320 * 240 * 4 * 2); |
132 } | 165 } |
133 } | 166 } |
134 glGenBuffers(2, buffers); | 167 glGenBuffers(2, buffers); |
135 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); | 168 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); |
136 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); | 169 glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW); |
137 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[0]); | 170 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); |
138 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); | 171 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW); |
172 vshader = load_shader("default.v.glsl", GL_VERTEX_SHADER); | |
173 fshader = load_shader("default.f.glsl", GL_FRAGMENT_SHADER); | |
174 program = glCreateProgram(); | |
175 glAttachShader(program, vshader); | |
176 glAttachShader(program, fshader); | |
177 glLinkProgram(program); | |
178 GLint link_status; | |
179 glGetProgramiv(program, GL_LINK_STATUS, &link_status); | |
180 if (!link_status) { | |
181 fputs("Failed to link shader program\n", stderr); | |
182 exit(1); | |
183 } | |
184 un_textures[0] = glGetUniformLocation(program, "textures[0]"); | |
185 un_textures[1] = glGetUniformLocation(program, "textures[1]"); | |
186 at_pos = glGetAttribLocation(program, "pos"); | |
139 } else { | 187 } else { |
140 context->oddbuf = context->framebuf = malloc(320 * 240 * screen->format->BytesPerPixel * 2); | 188 context->oddbuf = context->framebuf = malloc(320 * 240 * screen->format->BytesPerPixel * 2); |
141 context->evenbuf = ((char *)context->oddbuf) + 320 * 240 * screen->format->BytesPerPixel; | 189 context->evenbuf = ((char *)context->oddbuf) + 320 * 240 * screen->format->BytesPerPixel; |
142 } | 190 } |
143 } | 191 } |
157 } | 205 } |
158 atexit(SDL_Quit); | 206 atexit(SDL_Quit); |
159 atexit(render_close_audio); | 207 atexit(render_close_audio); |
160 printf("width: %d, height: %d\n", width, height); | 208 printf("width: %d, height: %d\n", width, height); |
161 uint32_t flags = SDL_ANYFORMAT; | 209 uint32_t flags = SDL_ANYFORMAT; |
210 | |
162 #ifndef DISABLE_OPENGL | 211 #ifndef DISABLE_OPENGL |
163 if (use_gl) | 212 if (use_gl) |
164 { | 213 { |
165 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); | 214 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); |
166 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); | 215 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); |
186 if (!use_gl && screen->format->BytesPerPixel != 2 && screen->format->BytesPerPixel != 4) { | 235 if (!use_gl && screen->format->BytesPerPixel != 2 && screen->format->BytesPerPixel != 4) { |
187 fprintf(stderr, "BlastEm requires a 16-bit or 32-bit surface, SDL returned a %d-bit surface\n", screen->format->BytesPerPixel * 8); | 236 fprintf(stderr, "BlastEm requires a 16-bit or 32-bit surface, SDL returned a %d-bit surface\n", screen->format->BytesPerPixel * 8); |
188 exit(1); | 237 exit(1); |
189 } | 238 } |
190 #ifndef DISABLE_OPENGL | 239 #ifndef DISABLE_OPENGL |
191 //TODO: Fallback to plain SDL if OpenGL 2.0 not available | 240 //TODO: fallback on standard rendering if OpenGL 2.0 is unavailable or if init fails |
241 if (use_gl) | |
242 { | |
243 GLenum res = glewInit(); | |
244 if (res != GLEW_OK) | |
245 { | |
246 fprintf(stderr, "Initialization of GLEW failed with code %d\n", res); | |
247 exit(1); | |
248 } | |
249 if (!GLEW_VERSION_2_0) | |
250 { | |
251 fputs("OpenGL 2.0 is unable, falling back to standard SDL rendering\n", stderr); | |
252 exit(1); | |
253 } | |
254 } | |
192 render_gl = use_gl; | 255 render_gl = use_gl; |
193 #endif | 256 #endif |
194 SDL_WM_SetCaption(title, title); | 257 SDL_WM_SetCaption(title, title); |
195 caption = title; | 258 caption = title; |
196 min_delay = 0; | 259 min_delay = 0; |
260 glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); | 323 glBindTexture(GL_TEXTURE_2D, textures[context->framebuf == context->oddbuf ? 0 : 1]); |
261 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; | 324 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 320, 240, GL_BGRA, GL_UNSIGNED_BYTE, context->framebuf);; |
262 | 325 |
263 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | 326 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
264 glClear(GL_COLOR_BUFFER_BIT); | 327 glClear(GL_COLOR_BUFFER_BIT); |
328 | |
329 glUseProgram(program); | |
330 glActiveTexture(GL_TEXTURE0); | |
331 glBindTexture(GL_TEXTURE_2D, textures[0]); | |
332 glUniform1i(un_textures[0], 0); | |
333 | |
334 glActiveTexture(GL_TEXTURE1); | |
335 //TODO: Select appropriate texture based on status of interlace | |
336 glBindTexture(GL_TEXTURE_2D, textures[1]); | |
337 glUniform1i(un_textures[1], 1); | |
338 | |
339 glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); | |
340 glVertexAttribPointer(at_pos, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat[2]), (void *)0); | |
341 glEnableVertexAttribArray(at_pos); | |
342 | |
343 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); | |
344 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | |
345 | |
346 glDisableVertexAttribArray(at_pos); | |
347 | |
348 SDL_GL_SwapBuffers(); | |
265 | 349 |
266 } | 350 } |
267 | 351 |
268 uint32_t blankbuf[320*240]; | 352 uint32_t blankbuf[320*240]; |
269 | 353 |