2360a0c34b4a815d992e883856ed9e0c1695134e
[libpicofe.git] / gl.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include <EGL/egl.h>
5 #include <GLES/gl.h>
6 #include "gl.h"
7
8 static EGLDisplay edpy;
9 static EGLSurface esfc;
10 static EGLContext ectxt;
11
12 static int gl_have_error(const char *name)
13 {
14         GLenum e = glGetError();
15         if (e != GL_NO_ERROR) {
16                 fprintf(stderr, "GL error: %s %x\n", name, e);
17                 return 1;
18         }
19         return 0;
20 }
21
22 static int gles_have_error(const char *name)
23 {
24         EGLint e = eglGetError();
25         if (e != EGL_SUCCESS) {
26                 fprintf(stderr, "%s %x\n", name, e);
27                 return 1;
28         }
29         return 0;
30 }
31
32 int gl_init(void *display, void *window)
33 {
34         EGLConfig ecfg = NULL;
35         GLuint texture_name = 0;
36         void *tmp_texture_mem = NULL;
37         EGLint num_config;
38         int retval = -1;
39         int ret;
40         EGLint attr[] =
41         {
42                 EGL_NONE
43         };
44
45         tmp_texture_mem = calloc(1, 1024 * 512 * 2);
46         if (tmp_texture_mem == NULL) {
47                 fprintf(stderr, "OOM\n");
48                 goto out;
49         }
50
51         edpy = eglGetDisplay((EGLNativeDisplayType)display);
52         if (edpy == EGL_NO_DISPLAY) {
53                 fprintf(stderr, "Failed to get EGL display\n");
54                 goto out;
55         }
56
57         if (!eglInitialize(edpy, NULL, NULL)) {
58                 fprintf(stderr, "Failed to initialize EGL\n");
59                 goto out;
60         }
61
62         if (!eglChooseConfig(edpy, attr, &ecfg, 1, &num_config)) {
63                 fprintf(stderr, "Failed to choose config (%x)\n", eglGetError());
64                 goto out;
65         }
66
67         if (ecfg == NULL || num_config == 0) {
68                 fprintf(stderr, "No EGL configs available\n");
69                 goto out;
70         }
71
72         esfc = eglCreateWindowSurface(edpy, ecfg,
73                 (EGLNativeWindowType)window, NULL);
74         if (esfc == EGL_NO_SURFACE) {
75                 fprintf(stderr, "Unable to create EGL surface (%x)\n",
76                         eglGetError());
77                 goto out;
78         }
79
80         ectxt = eglCreateContext(edpy, ecfg, EGL_NO_CONTEXT, NULL);
81         if (ectxt == EGL_NO_CONTEXT) {
82                 fprintf(stderr, "Unable to create EGL context (%x)\n",
83                         eglGetError());
84                 goto out;
85         }
86
87         eglMakeCurrent(edpy, esfc, esfc, ectxt);
88
89         glEnable(GL_TEXTURE_2D);
90
91         glGenTextures(1, &texture_name);
92
93         glBindTexture(GL_TEXTURE_2D, texture_name);
94
95         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB,
96                 GL_UNSIGNED_SHORT_5_6_5, tmp_texture_mem);
97         if (gl_have_error("glTexImage2D"))
98                 goto out;
99
100         // no mipmaps
101         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
102         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
103
104         //glViewport(0, 0, 512, 512);
105         glLoadIdentity();
106         glFrontFace(GL_CW);
107         glEnable(GL_CULL_FACE);
108
109         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
110         glEnableClientState(GL_VERTEX_ARRAY);
111
112         if (gl_have_error("init"))
113                 goto out;
114
115         retval = 0;
116 out:
117         free(tmp_texture_mem);
118         return retval;
119 }
120
121 static float vertices[] = {
122         -1.0f,  1.0f,  0.0f, // 0    0  1
123          1.0f,  1.0f,  0.0f, // 1  ^
124         -1.0f, -1.0f,  0.0f, // 2  | 2  3
125          1.0f, -1.0f,  0.0f, // 3  +-->
126 };
127
128 static float texture[] = {
129         0.0f, 0.0f, // we flip this:
130         1.0f, 0.0f, // v^
131         0.0f, 1.0f, //  |  u
132         1.0f, 1.0f, //  +-->
133 };
134
135 int gl_flip(const void *fb, int w, int h)
136 {
137         static int old_w, old_h;
138
139         if (w != old_w || h != old_h) {
140                 float f_w = (float)w / 1024.0f;
141                 float f_h = (float)h / 512.0f;
142                 texture[1*2 + 0] = f_w;
143                 texture[2*2 + 1] = f_h;
144                 texture[3*2 + 0] = f_w;
145                 texture[3*2 + 1] = f_h;
146                 old_w = w;
147                 old_h = h;
148         }
149
150         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
151                 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
152         if (gl_have_error("glTexSubImage2D"))
153                 return -1;
154
155         glVertexPointer(3, GL_FLOAT, 0, vertices);
156         glTexCoordPointer(2, GL_FLOAT, 0, texture);
157         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
158
159         if (gl_have_error("glDrawArrays"))
160                 return -1;
161
162         eglSwapBuffers(edpy, esfc);
163         if (gles_have_error("eglSwapBuffers"))
164                 return -1;
165
166         return 0;
167 }
168
169 void gl_finish(void)
170 {
171         eglMakeCurrent(edpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
172         eglDestroyContext(edpy, ectxt);
173         ectxt = EGL_NO_CONTEXT;
174         eglDestroySurface(edpy, esfc);
175         esfc = EGL_NO_SURFACE;
176         eglTerminate(edpy);
177         edpy = EGL_NO_DISPLAY;
178 }