1.. _opengl_es_driver:
2
3===============================
4OpenGL ES Display/Inputs Driver
5===============================
6
7Overview
8--------
9
10| The **OpenGL ES** display/input `driver <https://github.com/lvgl/lvgl/src/drivers/opengles>`__ offers support for simulating the LVGL display and keyboard/mouse inputs in an desktop window created via GLFW.
11| It is an alternative to **Wayland**, **XCB**, **SDL** or **Qt**.
12
13The main purpose for this driver is for testing/debugging the LVGL application in an **OpenGL** simulation window.
14
15Prerequisites
16-------------
17
18The OpenGL driver uses GLEW GLFW to access the OpenGL window manager.
19
201. Install GLEW and GLFW: ``sudo apt-get install libglew-dev libglfw3-dev``
21
22Configure OpenGL Driver
23-----------------------
24
251. Required linked libraries: -lGL -lGLEW -lglfw
262. Enable the OpenGL driver support in lv_conf.h, by cmake compiler define or by KConfig
27    .. code-block:: c
28
29        #define LV_USE_OPENGLES  1
30
31Basic Usage
32-----------
33
34.. code-block:: c
35
36    #include "lvgl/lvgl.h"
37    #include "lvgl/examples/lv_examples.h"
38    #include "lvgl/demos/lv_demos.h"
39
40    #define WIDTH 640
41    #define HEIGHT 480
42
43    int main()
44    {
45        /* initialize lvgl */
46        lv_init();
47
48        /* create a window and initialize OpenGL */
49        lv_glfw_window_t * window = lv_glfw_window_create(WIDTH, HEIGHT, true);
50
51        /* create a display that flushes to a texture */
52        lv_display_t * texture = lv_opengles_texture_create(WIDTH, HEIGHT);
53        lv_display_set_default(texture);
54
55        /* add the texture to the window */
56        unsigned int texture_id = lv_opengles_texture_get_texture_id(texture);
57        lv_glfw_texture_t * window_texture = lv_glfw_window_add_texture(window, texture_id, WIDTH, HEIGHT);
58
59        /* get the mouse indev of the window texture */
60        lv_indev_t * mouse = lv_glfw_texture_get_mouse_indev(window_texture);
61
62        /* add a cursor to the mouse indev */
63        LV_IMAGE_DECLARE(mouse_cursor_icon);
64        lv_obj_t * cursor_obj = lv_image_create(lv_screen_active());
65        lv_image_set_src(cursor_obj, &mouse_cursor_icon);
66        lv_indev_set_cursor(mouse, cursor_obj);
67
68        /* create Widgets on the screen */
69        lv_demo_widgets();
70
71        while (1)
72        {
73            uint32_t time_until_next = lv_timer_handler();
74            lv_delay_ms(time_until_next);
75        }
76
77        return 0;
78    }
79
80Advanced Usage
81--------------
82
83The OpenGL driver can draw textures from the user. A third-party library could be
84used to add content to a texture and the driver will draw the texture in the window.
85
86.. code-block:: c
87
88    #include "lvgl/lvgl.h"
89    #include <GL/glew.h>
90    #include <GLFW/glfw3.h>
91
92    #define WIDTH 640
93    #define HEIGHT 480
94
95    void custom_texture_example(void)
96    {
97        /*****************
98        *  MAIN WINDOW
99        *****************/
100
101        /* create a window and initialize OpenGL */
102        /* multiple windows can be created */
103        lv_glfw_window_t * window = lv_glfw_window_create(WIDTH, HEIGHT, true);
104
105        /****************************
106        *   OPTIONAL MAIN TEXTURE
107        ****************************/
108
109        /* create a main display that flushes to a texture */
110        lv_display_t * main_texture = lv_opengles_texture_create(WIDTH, HEIGHT);
111        lv_display_set_default(main_texture);
112
113        /* add the main texture to the window */
114        unsigned int main_texture_id = lv_opengles_texture_get_texture_id(main_texture);
115        lv_glfw_texture_t * window_main_texture = lv_glfw_window_add_texture(window, main_texture_id, WIDTH, HEIGHT);
116
117        /* get the mouse indev of this main texture */
118        lv_indev_t * main_texture_mouse = lv_glfw_texture_get_mouse_indev(window_main_texture);
119
120        /* add a cursor to the mouse indev */
121        LV_IMAGE_DECLARE(mouse_cursor_icon);
122        lv_obj_t * cursor_obj = lv_image_create(lv_screen_active());
123        lv_image_set_src(cursor_obj, &mouse_cursor_icon);
124        lv_indev_set_cursor(main_texture_mouse, cursor_obj);
125
126        /* create Widgets on the screen of the main texture */
127        lv_demo_widgets();
128
129        /**********************
130        *   ANOTHER TEXTURE
131        **********************/
132
133        /* create a sub display that flushes to a texture */
134        const int32_t sub_texture_w = 300;
135        const int32_t sub_texture_h = 300;
136        lv_display_t * sub_texture = lv_opengles_texture_create(sub_texture_w, sub_texture_h);
137
138        /* add the sub texture to the window */
139        unsigned int sub_texture_id = lv_opengles_texture_get_texture_id(sub_texture);
140        lv_glfw_texture_t * window_sub_texture = lv_glfw_window_add_texture(window, sub_texture_id, sub_texture_w, sub_texture_h);
141
142        /* create Widgets on the screen of the sub texture */
143        lv_display_set_default(sub_texture);
144        lv_example_keyboard_2();
145        lv_display_set_default(main_texture);
146
147        /* position the sub texture within the window */
148        lv_glfw_texture_set_x(window_sub_texture, 250);
149        lv_glfw_texture_set_y(window_sub_texture, 150);
150
151        /* optionally change the opacity of the sub texture */
152        lv_glfw_texture_set_opa(window_sub_texture, LV_OPA_80);
153
154        /*********************************************
155        *   USE AN EXTERNAL OPENGL TEXTURE IN LVGL
156        *********************************************/
157
158        unsigned int external_texture_id;
159        glGenTextures(1, &external_texture_id);
160        glBindTexture(GL_TEXTURE_2D, external_texture_id);
161        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
162        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
163        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
164        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
165        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
166        LV_IMAGE_DECLARE(img_cogwheel_argb);
167    #if LV_COLOR_DEPTH == 8
168        const int texture_format = GL_R8;
169    #elif LV_COLOR_DEPTH == 16
170        const int texture_format = GL_RGB565;
171    #elif LV_COLOR_DEPTH == 24
172        const int texture_format = GL_RGB;
173    #elif LV_COLOR_DEPTH == 32
174        const int texture_format = GL_RGBA;
175    #else
176    #error("Unsupported color format")
177    #endif
178        glTexImage2D(GL_TEXTURE_2D, 0, texture_format, img_cogwheel_argb.header.w, img_cogwheel_argb.header.h, 0, GL_BGRA, GL_UNSIGNED_BYTE, img_cogwheel_argb.data);
179        glGenerateMipmap(GL_TEXTURE_2D);
180        glBindTexture(GL_TEXTURE_2D, 0);
181
182        /* add the external texture to the window */
183        lv_glfw_texture_t * window_external_texture = lv_glfw_window_add_texture(window, external_texture_id, img_cogwheel_argb.header.w, img_cogwheel_argb.header.h);
184
185        /* set the position and opacity of the external texture within the window */
186        lv_glfw_texture_set_x(window_external_texture, 20);
187        lv_glfw_texture_set_y(window_external_texture, 20);
188        lv_glfw_texture_set_opa(window_external_texture, LV_OPA_70);
189
190        /*********************************************
191        *   USE AN LVGL TEXTURE IN ANOTHER LIBRARY
192        *********************************************/
193
194        lv_refr_now(sub_texture);
195
196        /* the texture is drawn on by LVGL and can be used by anything that uses OpenGL textures */
197        third_party_lib_use_texture(sub_texture_id);
198    }
199
200OpenGL Texture Caching Renderer
201-------------------------------
202
203There is a renderer in LVGL which caches software-rendered areas as OpenGL textures.
204The textures are retrieved from the cache and reused when there is a match.
205The performance will be drastically improved in most cases.
206
207.. code-block:: c
208
209    #define LV_USE_DRAW_OPENGLES 1
210
211Known Limitations
212~~~~~~~~~~~~~~~~~
213
214- Performance will be the same or slightly worse if the drawn areas are never found in the cache
215  due to Widgets with continuously varying colors or shapes. One example is a label whose color
216  is set to a random value every frame, as in the "Multiple labels" scene of the benchmark demo.
217- Layers with transparent pixels and an overall layer transparency will not blend correctly.
218  The effect can be observed in the "Containers with opa_layer" scene of the benchmark demo
219  in the border corners.
220- Layers with rotation are not currently supported. Images with rotation are fine.
221
222
223.. Comment:  The above blank line is necessary for Sphinx to not complain,
224    since it looks for the blank line after a bullet list.
225