int initialize_egl_window(screen_context_t ctx, char * window_group_name) { int usage = SCREEN_USAGE_OPENGL_ES1; int format = SCREEN_FORMAT_RGBA8888; int sensitivity = SCREEN_SENSITIVITY_ALWAYS; int rc, num_configs; // must be 2 for RGBA8888 const int num_window_buffers = 2; EGLint attrib_list[]= { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE}; // Simple egl initialization g_screen_ctx = ctx; g_egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (g_egl_disp == EGL_NO_DISPLAY) { egl_perror("eglGetDisplay"); terminate_egl_window(); return EXIT_FAILURE; } rc = eglInitialize(g_egl_disp, NULL, NULL); if (rc != EGL_TRUE) { egl_perror("eglInitialize"); terminate_egl_window(); return EXIT_FAILURE; } rc = eglBindAPI(EGL_OPENGL_ES_API); if (rc != EGL_TRUE) { egl_perror("eglBindApi"); terminate_egl_window(); return EXIT_FAILURE; } if(!eglChooseConfig(g_egl_disp, attrib_list, &g_egl_conf, 1, &num_configs)) { terminate_egl_window(); fprintf(stderr, "eglChooseConfig failed\n"); return EXIT_FAILURE; } g_egl_ctx = eglCreateContext(g_egl_disp, g_egl_conf, EGL_NO_CONTEXT, NULL); if (g_egl_ctx == EGL_NO_CONTEXT) { egl_perror("eglCreateContext"); terminate_egl_window(); return EXIT_FAILURE; } rc = screen_create_window(&g_screen_win, g_screen_ctx); if (rc) { perror("screen_create_window"); terminate_egl_window(); return EXIT_FAILURE; } /* Create the window group for our window, this is important, as we pass * the group name to MMR which uses it to 'parent' it's CHILD_WINDOW * which contains the video. */ if (screen_create_window_group(g_screen_win, window_group_name) != 0) { perror("screen_create_window_group"); return EXIT_FAILURE; } rc = screen_set_window_property_iv(g_screen_win, SCREEN_PROPERTY_FORMAT, &format); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)"); terminate_egl_window(); return EXIT_FAILURE; } rc = screen_set_window_property_iv(g_screen_win, SCREEN_PROPERTY_USAGE, &usage); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)"); terminate_egl_window(); return EXIT_FAILURE; } rc = screen_set_window_property_iv(g_screen_win, SCREEN_PROPERTY_SENSITIVITY, &sensitivity); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_SENSITIVITY)"); terminate_egl_window(); return EXIT_FAILURE; } rc = screen_get_window_property_pv(g_screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&g_screen_disp); if (rc) { perror("screen_get_window_property_pv"); terminate_egl_window(); return EXIT_FAILURE; } const char *env = getenv("WIDTH"); if (0 == env) { perror("failed getenv for WIDTH"); terminate_egl_window(); return EXIT_FAILURE; } int width = atoi(env); env = getenv("HEIGHT"); if (0 == env) { perror("failed getenv for HEIGHT"); terminate_egl_window(); return EXIT_FAILURE; } int height = atoi(env); int size[2] = { width, height }; rc = screen_set_window_property_iv(g_screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); if (rc) { perror("screen_set_window_property_iv"); terminate_egl_window(); return EXIT_FAILURE; } rc = screen_create_window_buffers(g_screen_win, num_window_buffers); if (rc) { perror("screen_create_window_buffers"); terminate_egl_window(); return EXIT_FAILURE; } g_egl_surf = eglCreateWindowSurface(g_egl_disp, g_egl_conf, g_screen_win, NULL); if (g_egl_surf == EGL_NO_SURFACE) { egl_perror("eglCreateWindowSurface"); terminate_egl_window(); return EXIT_FAILURE; } rc = eglMakeCurrent(g_egl_disp, g_egl_surf, g_egl_surf, g_egl_ctx); if (rc != EGL_TRUE) { egl_perror("eglMakeCurrent"); terminate_egl_window(); return EXIT_FAILURE; } // Set the clear color to be transparent glClearColor(0.0f, 0.0f, 0.0f, 0.0f); return EXIT_SUCCESS; }
int main(int argc, char **argv) { int pos[2] = {0, 0}; int size[2]; int vis = 1; int type; screen_create_context(&screen_ctx, SCREEN_APPLICATION_CONTEXT); int count = 0; screen_get_context_property_iv(screen_ctx, SCREEN_PROPERTY_DISPLAY_COUNT, &count); screen_display_t *screen_disps = calloc(count, sizeof(screen_display_t)); screen_get_context_property_pv(screen_ctx, SCREEN_PROPERTY_DISPLAYS, (void **)screen_disps); screen_display_t screen_disp = screen_disps[0]; free(screen_disps); int dims[2] = { 0, 0 }; screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, dims); char str[16]; snprintf(str, sizeof(str), "%d", getpid()); screen_bg_win = create_bg_window(str, dims); screen_bar_win = create_bar_window(str, bar_id_string, dims); screen_hg_win = create_hg_window(str, hg_id_string, dims); if ( create_gles_window(str, gles_id_string, dims) != EXIT_SUCCESS){ fprintf(stderr, "Could not initialize OpenGL window. Exiting...\n"); screen_destroy_context(screen_ctx); return EXIT_FAILURE; } screen_event_t screen_ev; screen_create_event(&screen_ev); // Now draw our OpenGL stuff, it does not change so we need to do it only once GLfloat vVertices[] = {0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLES, 0, 3); int rc = eglSwapBuffers(egl_disp, egl_surf); if (rc != EGL_TRUE) { egl_perror("eglSwapBuffers"); } while (1) { do { screen_get_event(screen_ctx, screen_ev, vis ? 0 : ~0); screen_get_event_property_iv(screen_ev, SCREEN_PROPERTY_TYPE, &type); if (type == SCREEN_EVENT_CLOSE) { screen_window_t screen_win; screen_get_event_property_pv(screen_ev, SCREEN_PROPERTY_WINDOW, (void **)&screen_win); if (screen_win == screen_bar_win) { screen_bar_win = NULL; } else if (screen_win == screen_hg_win) { screen_hg_win = NULL; } else if (screen_win == screen_gles_win) { screen_gles_win = NULL; } screen_destroy_window(screen_win); if (!screen_bar_win || !screen_hg_win || !screen_gles_win) { vis = 0; } } if (vis) { if (++pos[0] > dims[0] - barwidth) { pos[0] = 0; } screen_set_window_property_iv(screen_bar_win, SCREEN_PROPERTY_POSITION, pos); screen_flush_context(screen_ctx, SCREEN_WAIT_IDLE); } } while (type != SCREEN_EVENT_NONE); } screen_destroy_event(screen_ev); screen_destroy_context(screen_ctx); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { EGLConfig cfg; EGLint num_cfg; static const EGLint cfg_attrs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE }; EGLint major, minor; EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLSurface surf; static const EGLint surf_attrs[] = { EGL_WIDTH, WIDTH, EGL_HEIGHT, HEIGHT, EGL_NONE }; EGLContext ctx; static const EGLint ctx_attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; if (!eglInitialize(dpy, &major, &minor)) { fprintf(stderr, "failed to init egl\n"); exit(1); } printf("EGL version: %d.%d\n", major, minor); if (!eglChooseConfig(dpy, cfg_attrs, &cfg, 1, &num_cfg) || num_cfg != 1) { egl_perror("failed to choose config"); exit(1); } if ((surf = eglCreatePbufferSurface(dpy, cfg, surf_attrs)) == EGL_NO_SURFACE) { egl_perror("failed to create surface"); exit(1); } if ((ctx = eglCreateContext(dpy, cfg, NULL, ctx_attrs)) == EGL_NO_CONTEXT) { egl_perror("failed to create context"); exit(1); } if (!eglMakeCurrent(dpy, surf, surf, ctx)) { egl_perror("failed to make current"); exit(1); } printf("# extensions: %s\n", glGetString(GL_EXTENSIONS)); render(); eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(dpy, ctx); eglDestroySurface(dpy, surf); eglTerminate(dpy); }
int create_gles_window(const char *group, const char *id, int dims[2]) { int i, j; screen_window_t screen_win; screen_create_window_type(&screen_win, screen_ctx, SCREEN_CHILD_WINDOW); screen_join_window_group(screen_win, group); screen_set_window_property_cv(screen_win, SCREEN_PROPERTY_ID_STRING, strlen(id), id); int flag = 1; screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_STATIC, &flag); int vis = 1; screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_VISIBLE, &vis); int zorder = 3; screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ZORDER, &zorder); int format = SCREEN_FORMAT_RGBA8888; screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format); int usage = SCREEN_USAGE_OPENGL_ES2; screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage); int transparency = SCREEN_TRANSPARENCY_SOURCE_OVER; screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_TRANSPARENCY, &transparency); screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, dims); screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SIZE, dims); screen_buffer_t screen_buf; screen_create_window_buffers(screen_win, 1); screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&screen_buf); int rect[4] = { 0, 0, dims[0], dims[1] }; // OpenGL window covers all display screen_post_window(screen_win, screen_buf, 1, rect, 0); // EGL initialization stuff starts here EGLint surface_width, surface_height; GLuint rendering_program; EGLConfig egl_conf; EGLint interval = 1; int rc, num_configs; EGLint attrib_list[]= { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE}; EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; //EGL initialization egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (egl_disp == EGL_NO_DISPLAY) { egl_perror("bbutil_init_egl: eglGetDisplay"); gl_terminate(&screen_win); return EXIT_FAILURE; } rc = eglInitialize(egl_disp, NULL, NULL); if (rc != EGL_TRUE) { egl_perror("bbutil_init_egl: eglInitialize"); gl_terminate(&screen_win); return EXIT_FAILURE; } rc = eglBindAPI(EGL_OPENGL_ES_API); if (rc != EGL_TRUE) { egl_perror("bbutil_init_egl: eglBindApi"); gl_terminate(&screen_win); return EXIT_FAILURE; } if(!eglChooseConfig(egl_disp, attrib_list, &egl_conf, 1, &num_configs)) { gl_terminate(&screen_win); return EXIT_FAILURE; } egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes); if (egl_ctx == EGL_NO_CONTEXT) { egl_perror("bbutil_init_egl: eglCreateContext"); gl_terminate(&screen_win); return EXIT_FAILURE; } // Bound EGL serface to our Native Window egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); if (egl_surf == EGL_NO_SURFACE) { egl_perror("eglCreateWindowSurface"); gl_terminate(&screen_win); return 1; } rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); if (rc != EGL_TRUE) { egl_perror("eglMakeCurrent"); gl_terminate(&screen_win); return 1; } rc = eglSwapInterval(egl_disp, interval); if (rc != EGL_TRUE) { egl_perror("eglSwapInterval"); gl_terminate(&screen_win); return 1; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Last byte is 'transparency', it's important to have it 0.0f glEnable(GL_CULL_FACE); // Enable 2d eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); EGLint err = eglGetError(); if (err != 0x3000) { fprintf(stderr, "Unable to query EGL surface dimensions\n"); return EXIT_FAILURE; } glViewport(0, 0, surface_width, surface_height); // Create shaders const char *v_source = "attribute vec4 vPosition;\n" "void main()\n" "{\n" "gl_Position = vPosition;\n" "}"; const char *f_source = "precision mediump float; \n" "void main()\n" "{\n" "gl_FragColor = vec4(1.0, 0.0, 0.0, 0.7); \n" // 0.7 means we make it 'a bit' transparent "} \n"; // Compile the vertex shader GLint status; GLuint vs = glCreateShader(GL_VERTEX_SHADER); if (!vs) { fprintf(stderr, "Failed to create vertex shader: %d\n", glGetError()); return EXIT_FAILURE; } else { glShaderSource(vs, 1, &v_source, 0); glCompileShader(vs); glGetShaderiv(vs, GL_COMPILE_STATUS, &status); if (GL_FALSE == status) { GLchar log[256]; glGetShaderInfoLog(vs, 256, NULL, log); fprintf(stderr, "Failed to compile vertex shader: %s\n", log); glDeleteShader(vs); return EXIT_FAILURE; } } // Compile the fragment shader GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); if (!fs) { fprintf(stderr, "Failed to create fragment shader: %d\n", glGetError()); return EXIT_FAILURE; } else { glShaderSource(fs, 1, &f_source, 0); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &status); if (GL_FALSE == status) { GLchar log[256]; glGetShaderInfoLog(fs, 256, NULL, log); fprintf(stderr, "Failed to compile fragment shader: %s\n", log); glDeleteShader(vs); glDeleteShader(fs); return EXIT_FAILURE; } } // Create and link the program rendering_program = glCreateProgram(); if (rendering_program) { glAttachShader(rendering_program, vs); glAttachShader(rendering_program, fs); glLinkProgram(rendering_program); glGetProgramiv(rendering_program, GL_LINK_STATUS, &status); if (status == GL_FALSE){ GLchar log[256]; glGetProgramInfoLog(fs, 256, NULL, log); fprintf(stderr, "Failed to link text rendering shader program: %s\n", log); glDeleteProgram(rendering_program); rendering_program = 0; return EXIT_FAILURE; } } else { fprintf(stderr, "Failed to create a shader program\n"); glDeleteShader(vs); glDeleteShader(fs); return EXIT_FAILURE; } // We don't need the shaders anymore - the program is enough glDeleteShader(fs); glDeleteShader(vs); glUseProgram(rendering_program); // In this example we use only one rendering program, so we can call this function once screen_gles_win = screen_win; return EXIT_SUCCESS; }
SDL_Surface *PLAYBOOK_SetVideoMode_GL(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { int rc; EGLint attributes[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE }; EGLint contextAttributes[3] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; EGLConfig configs[1]; EGLint configCount; screen_window_t screenWindow; int format = SCREEN_FORMAT_RGBX8888; int sizeOfWindow[2] = {this->info.current_w, this->info.current_h}; int sizeOfBuffer[2] = {width, height}; int usage = SCREEN_USAGE_OPENGL_ES1; EGLint eglSurfaceAttributes[3] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE }; if (this->gl_config.major_version == 2) { contextAttributes[1] = 2; attributes[11] = EGL_OPENGL_ES2_BIT; usage = SCREEN_USAGE_OPENGL_ES2; } if (getenv("WIDTH") != NULL && getenv("HEIGHT") != NULL) { sizeOfWindow[0] = atoi(getenv("WIDTH")); sizeOfWindow[1] = atoi(getenv("HEIGHT")); } else { rc = screen_get_window_property_iv(_priv->mainWindow, SCREEN_PROPERTY_SIZE, sizeOfWindow); if (rc) { goto error1; } } if (_priv->screenWindow) { rc = eglMakeCurrent(_priv->eglInfo.eglDisplay, 0, 0, 0); if (rc != EGL_TRUE) { egl_perror("eglMakeNoneCurrent"); goto error1; } rc = eglDestroySurface(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface); if (rc != EGL_TRUE) { egl_perror("eglDestroySurface"); goto error1; } _priv->eglInfo.eglSurface = 0; } if (!_priv->eglInfo.eglDisplay) { _priv->eglInfo.eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (_priv->eglInfo.eglDisplay == EGL_NO_DISPLAY) { egl_perror("eglGetDisplay"); goto error1; } rc = eglInitialize(_priv->eglInfo.eglDisplay, NULL, NULL); if (rc != EGL_TRUE) { egl_perror("eglInitialize"); goto error1; } } rc = eglBindAPI(EGL_OPENGL_ES_API); if (rc != EGL_TRUE) { egl_perror("eglBindAPI"); goto error2; } rc = eglChooseConfig(_priv->eglInfo.eglDisplay, attributes, configs, 1, &configCount); if (rc != EGL_TRUE) { egl_perror("eglChooseConfig"); goto error2; } else if (configCount <= 0) { fprintf(stderr, "No matching configurations found."); goto error2; } if (!_priv->eglInfo.eglContext) { _priv->eglInfo.eglContext = eglCreateContext(_priv->eglInfo.eglDisplay, configs[0], EGL_NO_CONTEXT, contextAttributes); if (_priv->eglInfo.eglContext == EGL_NO_CONTEXT) { egl_perror("eglCreateContext"); goto error2; } } screenWindow = PLAYBOOK_CreateWindow(this, current, width, height, bpp); if (screenWindow == NULL) { goto error3; } rc = PLAYBOOK_SetupStretch(this, screenWindow, width, height); if (rc) { SDL_SetError("Failed to set window size: %s", strerror(errno)); goto error4; } rc = screen_set_window_property_iv(screenWindow, SCREEN_PROPERTY_FORMAT, &format); if (rc) { SDL_SetError("Cannot set window format: %s", strerror(errno)); goto error4; } rc = screen_set_window_property_iv(screenWindow, SCREEN_PROPERTY_USAGE, &usage); if (rc) { SDL_SetError("Cannot set window usage: %s", strerror(errno)); goto error4; } rc = screen_create_window_buffers(screenWindow, 2); if (rc) { SDL_SetError("Cannot create window buffers: %s", strerror(errno)); goto error4; } _priv->eglInfo.eglSurface = eglCreateWindowSurface(_priv->eglInfo.eglDisplay, configs[0], screenWindow, (EGLint*)&eglSurfaceAttributes); if (_priv->eglInfo.eglSurface == EGL_NO_SURFACE) { egl_perror("eglCreateWindowSurface"); goto error4; } rc = eglMakeCurrent(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface, _priv->eglInfo.eglSurface, _priv->eglInfo.eglContext); if (rc != EGL_TRUE) { egl_perror("eglMakeCurrent"); goto error5; } locateTCOControlFile(this); if (_priv->tcoControlsDir) { initializeOverlay(this, screenWindow); } _priv->screenWindow = screenWindow; current->flags &= ~SDL_RESIZABLE; current->flags |= SDL_FULLSCREEN; current->flags |= SDL_HWSURFACE; current->flags |= SDL_OPENGL; current->w = width; current->h = height; current->pixels = 0; _priv->surface = current; return current; error5: eglDestroySurface(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglSurface); _priv->eglInfo.eglSurface = 0; error4: screen_destroy_window(screenWindow); error3: eglDestroyContext(_priv->eglInfo.eglDisplay, _priv->eglInfo.eglContext); _priv->eglInfo.eglContext = 0; error2: eglTerminate(_priv->eglInfo.eglDisplay); _priv->eglInfo.eglDisplay = 0; error1: return NULL; }