{"id":15519455,"url":"https://github.com/alnitak/flutter_opengl","last_synced_at":"2025-05-12T14:53:44.162Z","repository":{"id":56829838,"uuid":"191439046","full_name":"alnitak/flutter_opengl","owner":"alnitak","description":"A Flutter OpenGL ES plugin using a Texture() widget. Supports Android, Linux and Windows. Many shaders from ShaderToy.com can be copy/pasted","archived":false,"fork":false,"pushed_at":"2023-03-18T16:59:56.000Z","size":54404,"stargazers_count":187,"open_issues_count":7,"forks_count":21,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-31T23:29:27.547Z","etag":null,"topics":["flutter","flutter-plugin","gles","glsl","opengl","shadertoy"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alnitak.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-11T19:46:05.000Z","updated_at":"2025-03-20T02:57:41.000Z","dependencies_parsed_at":"2023-02-12T15:45:49.476Z","dependency_job_id":null,"html_url":"https://github.com/alnitak/flutter_opengl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnitak%2Fflutter_opengl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnitak%2Fflutter_opengl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnitak%2Fflutter_opengl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnitak%2Fflutter_opengl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alnitak","download_url":"https://codeload.github.com/alnitak/flutter_opengl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253759278,"owners_count":21959732,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flutter","flutter-plugin","gles","glsl","opengl","shadertoy"],"created_at":"2024-10-02T10:21:35.585Z","updated_at":"2025-05-12T14:53:44.103Z","avatar_url":"https://github.com/alnitak.png","language":"C++","readme":"# flutter_opengl\n\nA Flutter OpenGL ES plugin using a Texture() widget. Supports Android, Linux and Windows. Many shaders from ShaderToy.com can be copy/pasted \n\n## Getting Started\n\n| Android | Windows | Linux | iOS | MacOS | Web|\n| ---- | ---- | ---- | ---- | ---- | ---- |\n| ✅  | ✅ | ✅ | x | x | x|\n\n![gif](https://github.com/alnitak/flutter_opengl/blob/master/images/flutter_opengl.gif?raw=true \"Flutter OpenGL Demo\")\n![gif](https://github.com/alnitak/flutter_opengl/blob/master/images/flutter_OpenGL-video.gif?raw=true \"Flutter OpenGL Demo\")\n![gif](https://github.com/alnitak/flutter_opengl/blob/master/images/flutter_OpenGL-textures.gif?raw=true \"Flutter OpenGL Demo\")\n\nThe main workflow of the plugin is:\n\n- ask to native code with a MethodChannel for a texture ID\n- use the texture ID in a Texture() widget\n- set a vertex and a fragment sources\n- start the renderer\n- change shader sources on the fly\n\nAll functionalities, but the first call to the first method channel, use FFI calls.\n\nThe starting idea developing this plugin, was not just to use GLSL, but also take advantage of the wonderful [ShaderToy](https://www.shadertoy.com/) web site.\n\nFor now it's possible to copy/paste shaders from ShaderToy, but only those which have only one layer.\n\nBe aware that on a real device, many shaders could be very slow because they are hungry of power and some others needs ES 3 and for now is not supported on Android (ie latest 3 shaders in the *lib/main_in_deep.dart* example).\n\n***iResolution***, ***iTime***, ***iMouse***, ***iChannel[0-3]*** are supported, other uniforms can be added at run-time.\n\n- ***iResolution*** is a vec3 uniform which represents the texture size\n- ***iTime*** is a float which represents the time since the shader was created\n- ***iMouse*** is a vec4 which the x and y values represent the coordinates where the mouse or the touch is grabbed hover the *Texture()* widget\n- ***iChannel[0-3]*** Sampler2D uniform textures\n\n### Simple example\n\n```dart\nSizedBox(\n    width: 400,\n    height: 300,\n    child: FutureBuilder(\n        /// The surface size identifies the real texture size and\n        /// it is not related to the above SizedBox size\n        future: OpenGLController().openglPlugin.createSurface(300, 200),\n        builder: (_, snapshot) {\n            if (snapshot.hasError || !snapshot.hasData) {\n                return const SizedBox.shrink();\n            }\n            /// When the texture id is retrieved, it will be possible\n            /// to start the renderer, set a shader and display it.\n\n            /// Start renderer thread\n            OpenGLController().openglFFI.startThread();\n\n            /// Set the fragment shader\n            OpenGLController().openglFFI.setShaderToy(fShader);\n\n            /// build the texture widget\n            return OpenGLTexture(id: snapshot.data!);\n        },\n    ),\n)\n```\nLook at ***example/lib/main_in_deep.dart*** for a full fledged example.\n\nOnce the renderer is started all the below methods can be used via *OpenGLController().openglFFI*:\n\n| method | description |\n| ---- | ---- |\n| bool **rendererStatus**() | Returns true if the texture has been created successfully via *OpenGLController().openglPlugin.createSurface()* |\n| Size **getTextureSize**() | Get the size of the current texture. If not set it returns Size(-1, -1)|\n| **startThread**() | Starts the drawing thread loop. |\n| **stopThread**() | Delete shader, delete texture and stops the drawing thread loop. |\n|String **setShader**(bool isContinuous, String vertexShader, String fragmentShader)|**isContinuous** not used yet.\u003cbr\u003e**vertexShader** String of the vertex shader source. \u003cbr\u003e **fragmentShader** String of the fragment shader source\u003cbr\u003e\u003cbr\u003ereturns the compiling shader error string or an empty string if no errors.|\n| String **setShaderToy**(String fragmentShader) |Set the shader to be used in the current texture.\u003cbr\u003eThese are only fragment shaders taken from ShaderToy.com\u003cbr\u003eMany of the shaders can be copy/pasted, but they must have only the \"image\" layer (ie no buffer).\u003cbr\u003eAlso many of them could be heavy for mobile devices (few FPS).\u003cbr\u003e\u003cbr\u003eThe uniforms actually available and automatically registered are:\u003cbr\u003efloat **iTime**\u003cbr\u003evec4 **iMouse**\u003cbr\u003evec3 **iResolution**\u003cbr\u003eSampler2D **iChannel[0-3]**|\n| String **getVertexShader**() |Get current vertex shader text.|\n| String **getFragmentShader**() |Get current fragment shader text.|\n| **addShaderToyUniforms**() |add these uniforms:\u003cbr\u003evec4 **iMouse**\u003cbr\u003evec3 **iResolution**\u003cbr\u003efloat **iTime**\u003cbr\u003eSampler2D **iChannel[0-3]**\u003cbr\u003eThese uniforms are automatically set when using **setShaderToy()**|\n|**setMousePosition**(Offset startingPos, Offset pos, PointerEventType eventType, Size twSize)|Set the **iMouse** uniform.\u003cbr\u003eHow to use the mouse input (only left button supported):\u003cbr\u003emouse.xy  = mouse position during last button down\u003cbr\u003eabs(mouse.zw) = mouse position during last button click\u003cbr\u003esign(mouze.z)  = button is down\u003cbr\u003esign(mouze.w)  = button is clicked\u003cbr\u003e\u003cbr\u003eThis is automatically processed by **OpenGLTexture** widget\u003cbr\u003e\u003cbr\u003eFor reference:\u003cbr\u003ehttps://www.shadertoy.com/view/llySRh\u003cbr\u003ehttps://www.shadertoy.com/view/Mss3zH|\n| double **getFps**() |Get current FPS (capped to 100).|\n|bool **addBoolUniform**(String name, bool val)\u003cbr\u003ebool **addIntUniform**(String name, int val)\u003cbr\u003ebool **addFloatUniform**(String name, double val)\u003cbr\u003ebool **addVec2Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **addVec3Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **addVec4Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **addMat2Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **addMat3Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **addMat4Uniform**(String name, List`\u003cdouble\u003e` val)| Add an uniforms.\u003cbr\u003eReturn true if succes or false if already added.|\n|bool **addSampler2DUniform**(String name, int width, int height, Uint8List val)| Add a Sampler2D uniform. The raw image stored in *val* must be in RGBA32 format.|\n|bool **replaceSampler2DUniform**(String name, int width, int height, Uint8List val)|Replace a Sampler2D uniform texture with another one with different size.|\n|bool **setBoolUniform**(String name, bool val)\u003cbr\u003ebool **setIntUniform**(String name, int val)\u003cbr\u003ebool **setFloatUniform**(String name, double val)\u003cbr\u003ebool **setVec2Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **setVec3Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **setVec4Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **setMat2Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **setMat3Uniform**(String name, List`\u003cdouble\u003e` val)\u003cbr\u003ebool **setMat4Uniform**(String name, List`\u003cdouble\u003e` val)| Set value of an existing uniform. Return false if the uniform doesn't exist.|\n|bool **setSampler2DUniform**(String name, Uint8List val)|Replace a texture with another image with the same size.\u003cbr\u003eBe sure the *val* length is the same as the previously stored image with the uniform named *name*.|\n|bool **startCaptureOnSampler2D**(String name, String completeFilePath)|Set Sampler2D uniform *name* with frames captured by OpenCV VideoCapture\u003cbr\u003e\u003cbr\u003e*completeFilePath* can be:\u003cbr\u003e- 'cam0' for webCam0\u003cbr\u003e- 'cam1' for webCam1\u003cbr\u003e- a complete local video file path\u003cbr\u003e\u003cbr\u003e**Note**: this video capture is just for reference on how textures work in real time. Videos FPS are not precise and the camera on Android doesn't work.|\n| bool **stopCapture**() | Stop capturing thread.|\n\n\n# Setup\n\n## Linux\nBe sure you have **glew**, **glm** and **OpenCV** packages installed.\n\n\n## Windows\nGo into the windows folder from the project root.\n-  clone **Native_SDK**:\n\n```git clone https://github.com/powervr-graphics/Native_SDK.git```\n\nyou can safely delete all but the *lib* and *include* directories from the cloned repo\n\n- clone **glm**\n\n```git clone https://github.com/g-truc/glm.git```\n\n- download **glew** *Binaries for Windows 32-bit and 64-bit* from here:\n\n[https://glew.sourceforge.net](https://glew.sourceforge.net/) (sources at https://github.com/nigels-com/glew)\n\nextract the zip and rename its main directory to \"glew\"\n\n- run \"SCRIPTS\\setupOpenCV-windows.bat\" or manually download OpenCV and extract it into SCRIPT dir:\nhttps://github.com/opencv/opencv/releases/download/4.7.0/opencv-4.7.0-windows.exe\n\n## Android\nRun the script *SCRIPT/setupOpenCV-android.sh* or manually download OpenCV from here https://github.com/opencv/opencv/releases/download/4.7.0/opencv-4.7.0-android-sdk.zip locate libs and include folders and copy them into android/src/opencv. \n\n# TODO\n- better docomentation\n- the c/c++ code is not \"state of the art\" written! PRs are welcomed\n- iOS, Mac and Web support\n- ES 3 on Android (now supports 2)\n- displayed FPS seems not to be correct\n- leave OpenCV into the plugin for further use?\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falnitak%2Fflutter_opengl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falnitak%2Fflutter_opengl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falnitak%2Fflutter_opengl/lists"}