Rev 4495 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4464 | Serge | 1 | #include |
2 | #include |
||
3 | #include |
||
4 | #include |
||
5 | |||
6 | #define EGL_EGLEXT_PROTOTYPES |
||
4472 | Serge | 7 | #define GL_GLEXT_PROTOTYPES |
8 | |||
4464 | Serge | 9 | #include "EGL/egl.h" |
10 | #include "EGL/eglext.h" |
||
11 | #include "GL/gl.h" |
||
12 | #include "gbm.h" |
||
4472 | Serge | 13 | #include |
4464 | Serge | 14 | #include |
15 | #include |
||
16 | |||
4498 | Serge | 17 | enum px_buffer |
18 | { |
||
19 | PX_FRONT = 0, |
||
20 | PX_BACK = 1 |
||
21 | }; |
||
22 | |||
23 | struct render |
||
24 | { |
||
25 | EGLDisplay dpy; |
||
26 | EGLContext context; |
||
27 | GLuint framebuffer; |
||
28 | EGLImageKHR front, back, screen; |
||
29 | GLuint tx_buffers[2]; |
||
30 | GLuint tx_screen; |
||
31 | int back_buffer; |
||
32 | GLuint blit_prog; |
||
33 | GLint sampler; |
||
34 | float vertices[8], texcoords[8]; |
||
35 | }; |
||
36 | |||
37 | |||
4473 | Serge | 38 | EGLImageKHR px_create_image(EGLDisplay display, EGLContext context, |
39 | int width, int height, int stride, int name); |
||
4485 | Serge | 40 | GLuint create_framebuffer(int width, int height, GLuint *tex); |
41 | GLint create_shader(GLenum type, const char *source); |
||
4498 | Serge | 42 | struct render* create_render(EGLDisplay dpy, EGLSurface surface); |
43 | void blit_texture(struct render *render, GLuint tex, int x, int y, int w, int h); |
||
44 | void render_swap_buffers(struct render *render, int x, int y, int w, int h); |
||
4472 | Serge | 45 | |
4464 | Serge | 46 | int main() |
47 | { |
||
48 | struct gbm_device *gbm; |
||
49 | struct gbm_surface *gs; |
||
4498 | Serge | 50 | struct render *render; |
4464 | Serge | 51 | |
52 | EGLDisplay dpy; |
||
53 | EGLint major, minor; |
||
54 | |||
55 | EGLContext context; |
||
56 | EGLSurface surface; |
||
4498 | Serge | 57 | |
4464 | Serge | 58 | EGLConfig config; |
59 | |||
60 | EGLint config_attribs[32]; |
||
61 | EGLint num_configs, i; |
||
62 | |||
63 | int fd; |
||
64 | |||
65 | fd = get_service("DISPLAY"); |
||
66 | gbm = gbm_create_device(fd); |
||
67 | if( gbm == NULL){ |
||
68 | printf("failed to initialize GBM device"); |
||
69 | return 1; |
||
70 | }; |
||
71 | |||
4472 | Serge | 72 | init_pixlib(HW_BIT_BLIT); |
73 | |||
4464 | Serge | 74 | dpy = eglGetDisplay((EGLNativeDisplayType)gbm); |
75 | |||
76 | if (!eglInitialize(dpy, &major, &minor)) |
||
77 | printf("failed to initialize EGL display"); |
||
78 | |||
79 | printf("EGL_VERSION = %s\n", eglQueryString(dpy, EGL_VERSION)); |
||
80 | printf("EGL_VENDOR = %s\n", eglQueryString(dpy, EGL_VENDOR)); |
||
81 | printf("EGL_EXTENSIONS = %s\n", eglQueryString(dpy, EGL_EXTENSIONS)); |
||
82 | printf("EGL_CLIENT_APIS = %s\n",eglQueryString(dpy, EGL_CLIENT_APIS)); |
||
83 | |||
84 | i = 0; |
||
85 | config_attribs[i++] = EGL_RED_SIZE; |
||
86 | config_attribs[i++] = 1; |
||
87 | config_attribs[i++] = EGL_GREEN_SIZE; |
||
88 | config_attribs[i++] = 1; |
||
89 | config_attribs[i++] = EGL_BLUE_SIZE; |
||
90 | config_attribs[i++] = 1; |
||
91 | config_attribs[i++] = EGL_DEPTH_SIZE; |
||
92 | config_attribs[i++] = 1; |
||
93 | |||
94 | config_attribs[i++] = EGL_SURFACE_TYPE; |
||
95 | config_attribs[i++] = EGL_WINDOW_BIT; |
||
96 | |||
97 | config_attribs[i++] = EGL_RENDERABLE_TYPE; |
||
98 | config_attribs[i++] = EGL_OPENGL_BIT; |
||
99 | config_attribs[i] = EGL_NONE; |
||
100 | |||
101 | if (!eglChooseConfig(dpy,config_attribs, &config, 1, &num_configs) || !num_configs) |
||
102 | printf("failed to choose a config"); |
||
103 | |||
104 | eglBindAPI(EGL_OPENGL_API); |
||
105 | context = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL); |
||
106 | if (!context) |
||
107 | printf("failed to create context"); |
||
108 | |||
4495 | Serge | 109 | gs = gbm_surface_create(gbm, 400, 300, GBM_BO_FORMAT_ARGB8888, GBM_BO_USE_RENDERING); |
4464 | Serge | 110 | |
111 | BeginDraw(); |
||
112 | DrawWindow(20, 20, 400+9, 300+24, "gl-render", 0x000000, 0x74); |
||
113 | EndDraw(); |
||
114 | |||
4495 | Serge | 115 | surface = eglCreateWindowSurface(dpy,config, (EGLNativeWindowType)gs, NULL); |
116 | if (surface == EGL_NO_SURFACE) |
||
117 | printf("failed to create surface"); |
||
4464 | Serge | 118 | |
4495 | Serge | 119 | if (!eglMakeCurrent(dpy, surface, surface, context)) |
4464 | Serge | 120 | printf("failed to make window current"); |
121 | |||
4472 | Serge | 122 | |
4495 | Serge | 123 | |
4485 | Serge | 124 | glMatrixMode(GL_PROJECTION); |
125 | glLoadIdentity(); |
||
126 | glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); |
||
127 | glMatrixMode(GL_MODELVIEW); |
||
128 | glLoadIdentity(); |
||
129 | |||
130 | glViewport(0, 0, 400, 300); |
||
131 | |||
132 | glClearColor( 0, 0, 0, 1); |
||
133 | |||
134 | glClear(GL_COLOR_BUFFER_BIT); |
||
135 | |||
136 | glBegin(GL_QUADS); |
||
137 | glColor3f(1,0,0); |
||
138 | glVertex3f( 0.9, -0.9, -30.0); |
||
139 | glColor3f(1,1,0); |
||
140 | glVertex3f( 0.9, 0.9, -30.0); |
||
141 | |||
142 | glColor3f(1,1,1); |
||
143 | glVertex3f( 0.1, 0.9, -30.0); |
||
144 | glColor3f(1,0,1); |
||
145 | glVertex3f( 0.1, -0.9, -30.0); |
||
146 | glEnd(); |
||
147 | |||
148 | glFlush(); |
||
149 | |||
4498 | Serge | 150 | asm volatile ("int3"); |
4485 | Serge | 151 | |
4498 | Serge | 152 | render = create_render(dpy, surface); |
153 | glViewport(0, 0, 1024, 768); |
||
4485 | Serge | 154 | glMatrixMode(GL_PROJECTION); |
155 | glLoadIdentity(); |
||
156 | glMatrixMode(GL_MODELVIEW); |
||
157 | glLoadIdentity(); |
||
4464 | Serge | 158 | |
4498 | Serge | 159 | render_swap_buffers(render, 20, 20, 400, 300); |
4464 | Serge | 160 | |
161 | glFinish(); |
||
162 | eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
||
4473 | Serge | 163 | // eglDestroySurface(dpy, surface); |
164 | // gbm_surface_destroy(gs); |
||
4464 | Serge | 165 | eglDestroyContext(dpy, context); |
166 | eglTerminate(dpy); |
||
167 | |||
168 | while(1) |
||
169 | { |
||
170 | delay(1); |
||
171 | } |
||
4472 | Serge | 172 | |
4464 | Serge | 173 | return 0; |
174 | } |
||
4472 | Serge | 175 | |
176 | int drmIoctl(int fd, unsigned long request, void *arg) |
||
177 | { |
||
178 | ioctl_t io; |
||
179 | |||
180 | io.handle = fd; |
||
181 | io.io_code = request; |
||
182 | io.input = arg; |
||
183 | io.inp_size = 64; |
||
184 | io.output = NULL; |
||
185 | io.out_size = 0; |
||
186 | |||
187 | return call_service(&io); |
||
188 | } |
||
189 | |||
4473 | Serge | 190 | EGLImageKHR px_create_image(EGLDisplay display, EGLContext context, |
191 | int width, int height, int stride, int name) |
||
4472 | Serge | 192 | { |
193 | EGLImageKHR image; |
||
194 | EGLint attribs[] = { |
||
195 | EGL_WIDTH, 0, |
||
196 | EGL_HEIGHT, 0, |
||
197 | EGL_DRM_BUFFER_STRIDE_MESA, 0, |
||
198 | EGL_DRM_BUFFER_FORMAT_MESA, |
||
199 | EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, |
||
200 | EGL_DRM_BUFFER_USE_MESA, |
||
201 | EGL_DRM_BUFFER_USE_SHARE_MESA | |
||
202 | EGL_DRM_BUFFER_USE_SCANOUT_MESA, |
||
203 | EGL_NONE |
||
204 | }; |
||
205 | attribs[1] = width; |
||
206 | attribs[3] = height; |
||
4485 | Serge | 207 | attribs[5] = stride/4; |
4473 | Serge | 208 | |
209 | printf("%s w:%d :%d pitch:%d handle %d\n", __FUNCTION__, |
||
210 | width, height, stride, name); |
||
211 | |||
4472 | Serge | 212 | image = eglCreateImageKHR(display, context, EGL_DRM_BUFFER_MESA, |
213 | (void *) (uintptr_t)name, attribs); |
||
214 | |||
215 | return image; |
||
216 | } |
||
4485 | Serge | 217 | |
218 | GLint create_shader(GLenum type, const char *source) |
||
219 | { |
||
220 | GLint ok; |
||
4498 | Serge | 221 | GLint shader; |
4485 | Serge | 222 | |
4498 | Serge | 223 | shader = glCreateShader(type); |
224 | if(shader == 0) |
||
225 | goto err; |
||
226 | |||
227 | glShaderSource(shader, 1, (const GLchar **) &source, NULL); |
||
228 | glCompileShader(shader); |
||
229 | glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); |
||
4485 | Serge | 230 | if (!ok) { |
231 | GLchar *info; |
||
232 | GLint size; |
||
233 | |||
4498 | Serge | 234 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &size); |
4485 | Serge | 235 | info = malloc(size); |
236 | |||
4498 | Serge | 237 | glGetShaderInfoLog(shader, size, NULL, info); |
4485 | Serge | 238 | printf("Failed to compile %s: %s\n", |
239 | type == GL_FRAGMENT_SHADER ? "FS" : "VS",info); |
||
240 | printf("Program source:\n%s", source); |
||
241 | printf("GLSL compile failure\n"); |
||
4498 | Serge | 242 | free(info); |
243 | glDeleteProgram(shader); |
||
244 | shader = 0; |
||
4485 | Serge | 245 | } |
4498 | Serge | 246 | err: |
247 | return shader; |
||
248 | } |
||
4485 | Serge | 249 | |
4498 | Serge | 250 | |
251 | struct render* create_render(EGLDisplay dpy, EGLSurface surface) |
||
252 | { |
||
253 | const char *vs_src = |
||
254 | "attribute vec4 v_position;\n" |
||
255 | "attribute vec4 v_texcoord0;\n" |
||
256 | "varying vec2 source_texture;\n" |
||
257 | "void main()\n" |
||
258 | "{\n" |
||
259 | " gl_Position = v_position;\n" |
||
260 | " source_texture = v_texcoord0.xy;\n" |
||
261 | "}\n"; |
||
262 | |||
263 | const char *fs_src = |
||
264 | // "precision mediump float;\n" |
||
265 | "varying vec2 source_texture;\n" |
||
266 | "uniform sampler2D sampler;\n" |
||
267 | "void main()\n" |
||
268 | "{\n" |
||
269 | " vec3 cg = texture2D(sampler, source_texture).rgb;\n" |
||
270 | " gl_FragColor = vec4(cg.r,cg.g,cg.b,1.0);\n" |
||
271 | "}\n"; |
||
272 | EGLint config_attribs[14]; |
||
273 | EGLConfig config; |
||
274 | EGLint num_configs; |
||
275 | |||
276 | EGLContext context; |
||
277 | |||
278 | struct drm_i915_fb_info fb; |
||
279 | GLint vs_shader, fs_shader; |
||
280 | GLenum status; |
||
281 | GLint ret; |
||
282 | int fd; |
||
283 | struct render *render; |
||
284 | |||
285 | |||
286 | |||
287 | fd = get_service("DISPLAY"); |
||
288 | |||
289 | memset(&fb, 0, sizeof(fb)); |
||
290 | ret = drmIoctl(fd, SRV_FBINFO, &fb); |
||
291 | if( ret != 0 ) |
||
292 | { printf("failed to get framebuffer info\n"); |
||
293 | goto err; |
||
294 | }; |
||
295 | |||
296 | render = (struct render*)malloc(sizeof(struct render)); |
||
297 | if(render == NULL) |
||
298 | goto err; |
||
299 | |||
300 | render->dpy = dpy; |
||
301 | |||
302 | render->front = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_FRONT); |
||
303 | if(render->front == EGL_NO_IMAGE_KHR) |
||
304 | goto err1; |
||
305 | |||
306 | render->back = eglGetBufferImage(dpy, surface, EGL_DRM_BUFFER_BACK); |
||
307 | if( render->back == EGL_NO_IMAGE_KHR) |
||
308 | goto err2; |
||
309 | |||
310 | glGenTextures(2, render->tx_buffers); |
||
311 | if(glGetError() != GL_NO_ERROR) |
||
312 | goto err3; |
||
313 | |||
314 | glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_FRONT]); |
||
315 | if(glGetError() != GL_NO_ERROR) |
||
316 | goto err4; |
||
317 | |||
318 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); |
||
319 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); |
||
320 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->front); |
||
321 | if(glGetError() != GL_NO_ERROR) |
||
322 | goto err4; |
||
323 | |||
324 | glBindTexture(GL_TEXTURE_2D, render->tx_buffers[EGL_DRM_BUFFER_BACK]); |
||
325 | if(glGetError() != GL_NO_ERROR) |
||
326 | goto err4; |
||
327 | |||
328 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); |
||
329 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); |
||
330 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->back); |
||
331 | if(glGetError() != GL_NO_ERROR) |
||
332 | goto err4; |
||
333 | |||
334 | glBindTexture(GL_TEXTURE_2D, 0); |
||
335 | |||
336 | render->back_buffer = EGL_DRM_BUFFER_BACK; |
||
337 | |||
338 | context = eglGetCurrentContext(); |
||
339 | |||
340 | config_attribs[0] = EGL_RED_SIZE; |
||
341 | config_attribs[1] = 1; |
||
342 | config_attribs[2] = EGL_GREEN_SIZE; |
||
343 | config_attribs[3] = 1; |
||
344 | config_attribs[4] = EGL_BLUE_SIZE; |
||
345 | config_attribs[5] = 1; |
||
346 | config_attribs[6] = EGL_DEPTH_SIZE; |
||
347 | config_attribs[7] = 1; |
||
348 | |||
349 | config_attribs[8] = EGL_SURFACE_TYPE; |
||
350 | config_attribs[9] = EGL_WINDOW_BIT; |
||
351 | |||
352 | config_attribs[10] = EGL_RENDERABLE_TYPE; |
||
353 | config_attribs[11] = EGL_OPENGL_BIT; |
||
354 | config_attribs[12] = EGL_NONE; |
||
355 | |||
356 | if (!eglChooseConfig(dpy,config_attribs, &config, 1, &num_configs) || !num_configs) |
||
357 | { |
||
358 | printf("failed to choose a config"); |
||
359 | goto err4; |
||
360 | } |
||
361 | |||
362 | render->context = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL); |
||
363 | if (!context) |
||
364 | { |
||
365 | printf("failed to create context"); |
||
366 | goto err4; |
||
367 | }; |
||
368 | |||
369 | if (!eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context)) |
||
370 | { |
||
371 | printf("failed to make window current"); |
||
372 | goto err5; |
||
373 | }; |
||
374 | |||
375 | render->screen = px_create_image(dpy,context,fb.width,fb.height, |
||
376 | fb.pitch,fb.name); |
||
377 | if(render->screen == EGL_NO_IMAGE_KHR) |
||
378 | goto err6; |
||
379 | |||
380 | glGenTextures(1, &render->tx_screen); |
||
381 | if(glGetError() != GL_NO_ERROR) |
||
382 | goto err6; |
||
383 | |||
384 | glBindTexture(GL_TEXTURE_2D, render->tx_screen); |
||
385 | if(glGetError() != GL_NO_ERROR) |
||
386 | goto err7; |
||
387 | |||
388 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); |
||
389 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); |
||
390 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,render->screen); |
||
391 | if(glGetError() != GL_NO_ERROR) |
||
392 | goto err7; |
||
393 | |||
394 | glBindTexture(GL_TEXTURE_2D, 0); |
||
395 | |||
396 | glGenFramebuffers(1, &render->framebuffer); |
||
397 | if(glGetError() != GL_NO_ERROR) |
||
398 | goto err8; |
||
399 | |||
400 | glBindFramebuffer(GL_FRAMEBUFFER, render->framebuffer); |
||
401 | if(glGetError() != GL_NO_ERROR) |
||
402 | goto err9; |
||
403 | |||
404 | glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0, |
||
405 | GL_TEXTURE_2D, render->tx_screen,0); |
||
406 | |||
407 | status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
||
408 | if (status != GL_FRAMEBUFFER_COMPLETE) |
||
409 | { |
||
410 | const char *str; |
||
411 | switch (status) |
||
412 | { |
||
413 | case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: |
||
414 | str = "incomplete attachment"; |
||
415 | break; |
||
416 | case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: |
||
417 | str = "incomplete/missing attachment"; |
||
418 | break; |
||
419 | case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: |
||
420 | str = "incomplete draw buffer"; |
||
421 | break; |
||
422 | case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: |
||
423 | str = "incomplete read buffer"; |
||
424 | break; |
||
425 | case GL_FRAMEBUFFER_UNSUPPORTED: |
||
426 | str = "unsupported"; |
||
427 | break; |
||
428 | case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: |
||
429 | str = "incomplete multiple"; |
||
430 | break; |
||
431 | default: |
||
432 | str = "unknown error"; |
||
433 | break; |
||
434 | } |
||
435 | printf("destination is framebuffer incomplete: %s [%#x]\n", str, status); |
||
436 | goto err9; |
||
437 | } |
||
438 | |||
439 | render->blit_prog = glCreateProgram(); |
||
440 | if(render->blit_prog == 0) |
||
441 | goto err9; |
||
442 | |||
443 | vs_shader = create_shader(GL_VERTEX_SHADER,vs_src); |
||
444 | if(vs_shader == 0) |
||
445 | goto err10; |
||
446 | |||
447 | fs_shader = create_shader(GL_FRAGMENT_SHADER, fs_src); |
||
448 | if(fs_shader == 0) |
||
449 | goto err11; |
||
450 | |||
451 | glAttachShader(render->blit_prog, vs_shader); |
||
452 | glAttachShader(render->blit_prog, fs_shader); |
||
453 | glBindAttribLocation(render->blit_prog, 0, "v_position"); |
||
454 | glBindAttribLocation(render->blit_prog, 1, "v_texcoord0"); |
||
455 | glLinkProgram(render->blit_prog); |
||
456 | |||
457 | glGetProgramiv(render->blit_prog, GL_LINK_STATUS, &ret); |
||
458 | if (!ret) |
||
459 | { |
||
460 | GLchar *info; |
||
461 | GLint size; |
||
462 | |||
463 | glGetProgramiv(render->blit_prog, GL_INFO_LOG_LENGTH, &size); |
||
464 | info = malloc(size); |
||
465 | |||
466 | glGetProgramInfoLog(render->blit_prog, size, NULL, info); |
||
467 | printf("Failed to link: %s\n", info); |
||
468 | printf("GLSL link failure\n"); |
||
469 | free(info); |
||
470 | } |
||
471 | |||
472 | render->sampler = glGetUniformLocation(render->blit_prog,"sampler"); |
||
473 | |||
474 | eglMakeCurrent(dpy, surface, surface, context); |
||
475 | |||
476 | return render; |
||
477 | |||
478 | err11: |
||
479 | glDeleteShader(vs_shader); |
||
480 | err10: |
||
481 | glDeleteProgram(render->blit_prog); |
||
482 | err9: |
||
483 | glDeleteFramebuffers(1, &render->framebuffer); |
||
484 | err8: |
||
485 | eglDestroyImageKHR(dpy, render->screen); |
||
486 | err7: |
||
487 | glDeleteTextures(1, &render->tx_screen); |
||
488 | err6: |
||
489 | eglMakeCurrent(dpy, surface, surface, context); |
||
490 | err5: |
||
491 | eglDestroyContext(dpy, render->context); |
||
492 | err4: |
||
493 | glDeleteTextures(2, render->tx_buffers); |
||
494 | err3: |
||
495 | eglDestroyImageKHR(dpy, render->back); |
||
496 | err2: |
||
497 | eglDestroyImageKHR(dpy, render->front); |
||
498 | err1: |
||
499 | free(render); |
||
500 | err: |
||
501 | return NULL; |
||
502 | }; |
||
503 | |||
504 | void render_swap_buffers(struct render *render, int x, int y, int w, int h) |
||
505 | { |
||
506 | EGLContext context; |
||
507 | EGLSurface draw, read; |
||
508 | |||
509 | float dst_xscale, dst_yscale; |
||
510 | float *vertices = render->vertices; |
||
511 | float *texcoords = render->texcoords; |
||
512 | int r, b; |
||
513 | |||
514 | if(render == NULL) |
||
515 | return; |
||
516 | |||
517 | context = eglGetCurrentContext(); |
||
518 | draw = eglGetCurrentSurface(EGL_DRAW); |
||
519 | read = eglGetCurrentSurface(EGL_READ); |
||
520 | |||
521 | eglSwapBuffers(render->dpy,draw); |
||
522 | |||
523 | if (!eglMakeCurrent(render->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, render->context)) |
||
524 | { |
||
525 | printf("failed to make window current"); |
||
526 | goto err1; |
||
527 | }; |
||
528 | |||
529 | glUseProgram(render->blit_prog); |
||
530 | glUniform1i(render->sampler, 0); |
||
531 | |||
532 | glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(float),render->vertices); |
||
533 | glEnableVertexAttribArray(0); |
||
534 | |||
535 | glActiveTexture(GL_TEXTURE0); |
||
536 | glBindTexture(GL_TEXTURE_2D, render->tx_buffers[render->back_buffer]); |
||
537 | glTexParameteri(GL_TEXTURE_2D, |
||
538 | GL_TEXTURE_MIN_FILTER, |
||
539 | GL_NEAREST); |
||
540 | glTexParameteri(GL_TEXTURE_2D, |
||
541 | GL_TEXTURE_MAG_FILTER, |
||
542 | GL_NEAREST); |
||
543 | |||
544 | glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float),render->texcoords); |
||
545 | glEnableVertexAttribArray(1); |
||
546 | |||
547 | dst_xscale = 1.0/1024; |
||
548 | dst_yscale = 1.0/768; |
||
549 | |||
550 | r = x+w-1; |
||
551 | b = y+h-1; |
||
552 | |||
553 | float t0, t1, t2, t5; |
||
554 | |||
555 | vertices[0] = t0 = 2*x*dst_xscale - 1.0; |
||
556 | vertices[1 * 2] = t2 = 2*r*dst_xscale - 1.0; |
||
557 | |||
558 | vertices[2 * 2] = t2; |
||
559 | vertices[3 * 2] = t0; |
||
560 | |||
561 | vertices[1] = t1 = 2*y*dst_yscale - 1.0; |
||
562 | vertices[2*2+1] = t5 = 2*b*dst_yscale - 1.0; |
||
563 | vertices[1*2+1] = t1; |
||
564 | vertices[3*2+1] = t5; |
||
565 | |||
566 | texcoords[0] = 0.0; |
||
567 | texcoords[1] = 0.0; |
||
568 | texcoords[1*2] = 1.0; |
||
569 | texcoords[1*2+1]= 0.0; |
||
570 | texcoords[2*2] = 1.0; |
||
571 | texcoords[2*2+1]= 1.0; |
||
572 | texcoords[3*2] = 0.0; |
||
573 | texcoords[3*2+1]= 1.0; |
||
574 | |||
575 | glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
||
576 | |||
577 | glDisableVertexAttribArray(0); |
||
578 | glDisableVertexAttribArray(1); |
||
579 | glDisable(GL_TEXTURE_2D); |
||
580 | glUseProgram(0); |
||
581 | |||
582 | render->back_buffer++; |
||
583 | render->back_buffer&=1; |
||
584 | |||
585 | err1: |
||
586 | eglMakeCurrent(render->dpy, draw, read, context); |
||
4485 | Serge | 587 | } |
588 | |||
4498 | Serge | 589 | #if 0 |
4485 | Serge | 590 | GLuint create_framebuffer(int width, int height, GLuint *tex) |
591 | { |
||
592 | GLuint buffer; |
||
593 | |||
594 | glGenTextures(1, tex); |
||
595 | glBindTexture(GL_TEXTURE_2D, *tex); |
||
596 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); |
||
597 | glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); |
||
598 | |||
599 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, |
||
600 | GL_UNSIGNED_BYTE, NULL); |
||
601 | glBindTexture(GL_TEXTURE_2D, 0); |
||
602 | |||
603 | glGenFramebuffers(1, &buffer); |
||
604 | glBindFramebuffer(GL_FRAMEBUFFER, buffer); |
||
605 | glFramebufferTexture2D(GL_FRAMEBUFFER, |
||
606 | GL_COLOR_ATTACHMENT0, |
||
607 | GL_TEXTURE_2D, *tex,0); |
||
608 | return buffer; |
||
609 | } |
||
4498 | Serge | 610 | #endif |