#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include "gl_platform.h"
#include "gl.h"
-static EGLDisplay edpy;
-static EGLSurface esfc;
-static EGLContext ectxt;
+static EGLDisplay edpy = EGL_NO_DISPLAY;
+static EGLSurface esfc = EGL_NO_SURFACE;
+static EGLContext ectxt = EGL_NO_CONTEXT;
static GLuint texture_name;
EGLint num_config;
int retval = -1;
int ret;
- EGLint attr[] =
+ EGLint config_attr[] =
{
EGL_NONE
};
fprintf(stderr, "OOM\n");
goto out;
}
+ memset(tex_mem, 0, tex_w * tex_h * 2);
edpy = eglGetDisplay((EGLNativeDisplayType)display);
if (edpy == EGL_NO_DISPLAY) {
goto out;
}
- if (!eglChooseConfig(edpy, attr, &ecfg, 1, &num_config)) {
+ if (!eglChooseConfig(edpy, config_attr, &ecfg, 1, &num_config)) {
fprintf(stderr, "Failed to choose config (%x)\n", eglGetError());
goto out;
}
if (ectxt == EGL_NO_CONTEXT) {
fprintf(stderr, "Unable to create EGL context (%x)\n",
eglGetError());
- goto out;
+ // on mesa, some distros disable ES1.x but compat GL still works
+ ret = eglBindAPI(EGL_OPENGL_API);
+ if (!ret) {
+ fprintf(stderr, "eglBindAPI: %x\n", eglGetError());
+ goto out;
+ }
+ ectxt = eglCreateContext(edpy, ecfg, EGL_NO_CONTEXT, NULL);
+ if (ectxt == EGL_NO_CONTEXT) {
+ fprintf(stderr, "giving up on EGL context (%x)\n",
+ eglGetError());
+ goto out;
+ }
}
- eglMakeCurrent(edpy, esfc, esfc, ectxt);
+ ret = eglMakeCurrent(edpy, esfc, esfc, ectxt);
+ if (!ret) {
+ fprintf(stderr, "eglMakeCurrent: %x\n", eglGetError());
+ goto out;
+ }
+ // 1.x (fixed-function) only
glEnable(GL_TEXTURE_2D);
+ glGetError();
- if (texture_name)
- glDeleteTextures(1, &texture_name);
+ assert(!texture_name);
glGenTextures(1, &texture_name);
+ if (gl_have_error("glGenTextures"))
+ goto out;
glBindTexture(GL_TEXTURE_2D, texture_name);
+ if (gl_have_error("glBindTexture"))
+ goto out;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_w, tex_h, 0, GL_RGB,
GL_UNSIGNED_SHORT_5_6_5, tex_mem);
gl_es_surface = (void *)esfc;
retval = 0;
out:
+ if (retval && edpy != EGL_NO_DISPLAY)
+ gl_finish();
return retval;
}
void gl_announce(void)
{
printf("GL_RENDERER: %s\n", (char *)glGetString(GL_RENDERER));
+ printf("GL_VERSION: %s\n", (char *)glGetString(GL_VERSION));
}
-static float vertices[] = {
+static const float default_vertices[] = {
-1.0f, 1.0f, 0.0f, // 0 0 1
1.0f, 1.0f, 0.0f, // 1 ^
-1.0f, -1.0f, 0.0f, // 2 | 2 3
1.0f, 1.0f, // +-->
};
-int gl_flip(const void *fb, int w, int h)
+int gl_flip_v(const void *fb, int w, int h, const float *vertices)
{
+ gl_have_error("pre-flip unknown");
+
+ glBindTexture(GL_TEXTURE_2D, texture_name);
+ if (gl_have_error("glBindTexture"))
+ return -1;
+
if (fb != NULL) {
if (w != flip_old_w || h != flip_old_h) {
float f_w = (float)w / tex_w;
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
- if (gl_have_error("glTexSubImage2D"))
+ if (gl_have_error("glTexSubImage2D")) {
+ fprintf(stderr, " %dx%d t: %dx%d %p\n", w, h, tex_w, tex_h, fb);
return -1;
+ }
}
- glVertexPointer(3, GL_FLOAT, 0, vertices);
+ glVertexPointer(3, GL_FLOAT, 0, vertices ? vertices : default_vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
if (gl_have_error("glDrawArrays"))
return -1;
return 0;
}
+int gl_flip(const void *fb, int w, int h)
+{
+ return gl_flip_v(fb, w, h, NULL);
+}
+
+// to be used once after exiting menu, etc
+void gl_clear(void)
+{
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(edpy, esfc);
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(edpy, esfc);
+ glClear(GL_COLOR_BUFFER_BIT);
+ gl_have_error("glClear");
+}
+
void gl_finish(void)
{
+ // sometimes there is an error... from somewhere?
+ //gl_have_error("finish");
+ glGetError();
+
+ if (texture_name)
+ {
+ glDeleteTextures(1, &texture_name);
+ gl_have_error("glDeleteTextures");
+ texture_name = 0;
+ }
+
eglMakeCurrent(edpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(edpy, ectxt);
- ectxt = EGL_NO_CONTEXT;
- eglDestroySurface(edpy, esfc);
- esfc = EGL_NO_SURFACE;
- eglTerminate(edpy);
- edpy = EGL_NO_DISPLAY;
+ if (ectxt != EGL_NO_CONTEXT) {
+ eglDestroyContext(edpy, ectxt);
+ ectxt = EGL_NO_CONTEXT;
+ }
+ if (esfc != EGL_NO_SURFACE) {
+ eglDestroySurface(edpy, esfc);
+ esfc = EGL_NO_SURFACE;
+ }
+ if (edpy != EGL_NO_DISPLAY) {
+ eglTerminate(edpy);
+ edpy = EGL_NO_DISPLAY;
+ }
gl_es_display = (void *)edpy;
gl_es_surface = (void *)esfc;