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