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