GithubHelp home page GithubHelp logo

alnitak / flutter_opengl Goto Github PK

View Code? Open in Web Editor NEW
167.0 7.0 18.0 53.13 MB

A Flutter OpenGL ES plugin using a Texture() widget. Supports Android, Linux and Windows. Many shaders from ShaderToy.com can be copy/pasted

License: Other

CMake 1.41% C 3.04% C++ 87.53% Java 0.16% Swift 0.06% Objective-C 0.01% Dart 7.79% Kotlin 0.01% Shell 0.01%
flutter flutter-plugin opengl gles glsl shadertoy

flutter_opengl's Introduction

flutter_opengl

A Flutter OpenGL ES plugin using a Texture() widget. Supports Android, Linux and Windows. Many shaders from ShaderToy.com can be copy/pasted

Getting Started

Android Windows Linux iOS MacOS Web
x x x

gif gif gif

The main workflow of the plugin is:

  • ask to native code with a MethodChannel for a texture ID
  • use the texture ID in a Texture() widget
  • set a vertex and a fragment sources
  • start the renderer
  • change shader sources on the fly

All functionalities, but the first call to the first method channel, use FFI calls.

The starting idea developing this plugin, was not just to use GLSL, but also take advantage of the wonderful ShaderToy web site.

For now it's possible to copy/paste shaders from ShaderToy, but only those which have only one layer.

Be 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).

iResolution, iTime, iMouse, iChannel[0-3] are supported, other uniforms can be added at run-time.

  • iResolution is a vec3 uniform which represents the texture size
  • iTime is a float which represents the time since the shader was created
  • 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
  • iChannel[0-3] Sampler2D uniform textures

Simple example

SizedBox(
    width: 400,
    height: 300,
    child: FutureBuilder(
        /// The surface size identifies the real texture size and
        /// it is not related to the above SizedBox size
        future: OpenGLController().openglPlugin.createSurface(300, 200),
        builder: (_, snapshot) {
            if (snapshot.hasError || !snapshot.hasData) {
                return const SizedBox.shrink();
            }
            /// When the texture id is retrieved, it will be possible
            /// to start the renderer, set a shader and display it.

            /// Start renderer thread
            OpenGLController().openglFFI.startThread();

            /// Set the fragment shader
            OpenGLController().openglFFI.setShaderToy(fShader);

            /// build the texture widget
            return OpenGLTexture(id: snapshot.data!);
        },
    ),
)

Look at example/lib/main_in_deep.dart for a full fledged example.

Once the renderer is started all the below methods can be used via OpenGLController().openglFFI:

method description
bool rendererStatus() Returns true if the texture has been created successfully via OpenGLController().openglPlugin.createSurface()
Size getTextureSize() Get the size of the current texture. If not set it returns Size(-1, -1)
startThread() Starts the drawing thread loop.
stopThread() Delete shader, delete texture and stops the drawing thread loop.
String setShader(bool isContinuous, String vertexShader, String fragmentShader) isContinuous not used yet.
vertexShader String of the vertex shader source.
fragmentShader String of the fragment shader source

returns the compiling shader error string or an empty string if no errors.
String setShaderToy(String fragmentShader) Set the shader to be used in the current texture.
These are only fragment shaders taken from ShaderToy.com
Many of the shaders can be copy/pasted, but they must have only the "image" layer (ie no buffer).
Also many of them could be heavy for mobile devices (few FPS).

The uniforms actually available and automatically registered are:
float iTime
vec4 iMouse
vec3 iResolution
Sampler2D iChannel[0-3]
String getVertexShader() Get current vertex shader text.
String getFragmentShader() Get current fragment shader text.
addShaderToyUniforms() add these uniforms:
vec4 iMouse
vec3 iResolution
float iTime
Sampler2D iChannel[0-3]
These uniforms are automatically set when using setShaderToy()
setMousePosition(Offset startingPos, Offset pos, PointerEventType eventType, Size twSize) Set the iMouse uniform.
How to use the mouse input (only left button supported):
mouse.xy = mouse position during last button down
abs(mouse.zw) = mouse position during last button click
sign(mouze.z) = button is down
sign(mouze.w) = button is clicked

This is automatically processed by OpenGLTexture widget

For reference:
https://www.shadertoy.com/view/llySRh
https://www.shadertoy.com/view/Mss3zH
double getFps() Get current FPS (capped to 100).
bool addBoolUniform(String name, bool val)
bool addIntUniform(String name, int val)
bool addFloatUniform(String name, double val)
bool addVec2Uniform(String name, List<double> val)
bool addVec3Uniform(String name, List<double> val)
bool addVec4Uniform(String name, List<double> val)
bool addMat2Uniform(String name, List<double> val)
bool addMat3Uniform(String name, List<double> val)
bool addMat4Uniform(String name, List<double> val)
Add an uniforms.
Return true if succes or false if already added.
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.
bool replaceSampler2DUniform(String name, int width, int height, Uint8List val) Replace a Sampler2D uniform texture with another one with different size.
bool setBoolUniform(String name, bool val)
bool setIntUniform(String name, int val)
bool setFloatUniform(String name, double val)
bool setVec2Uniform(String name, List<double> val)
bool setVec3Uniform(String name, List<double> val)
bool setVec4Uniform(String name, List<double> val)
bool setMat2Uniform(String name, List<double> val)
bool setMat3Uniform(String name, List<double> val)
bool setMat4Uniform(String name, List<double> val)
Set value of an existing uniform. Return false if the uniform doesn't exist.
bool setSampler2DUniform(String name, Uint8List val) Replace a texture with another image with the same size.
Be sure the val length is the same as the previously stored image with the uniform named name.
bool startCaptureOnSampler2D(String name, String completeFilePath) Set Sampler2D uniform name with frames captured by OpenCV VideoCapture

completeFilePath can be:
- 'cam0' for webCam0
- 'cam1' for webCam1
- a complete local video file path

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.
bool stopCapture() Stop capturing thread.

Setup

Linux

Be sure you have glew, glm and OpenCV packages installed.

Windows

Go into the windows folder from the project root.

  • clone Native_SDK:

git clone https://github.com/powervr-graphics/Native_SDK.git

you can safely delete all but the lib and include directories from the cloned repo

  • clone glm

git clone https://github.com/g-truc/glm.git

  • download glew Binaries for Windows 32-bit and 64-bit from here:

https://glew.sourceforge.net (sources at https://github.com/nigels-com/glew)

extract the zip and rename its main directory to "glew"

Android

Run 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.

TODO

  • better docomentation
  • the c/c++ code is not "state of the art" written! PRs are welcomed
  • iOS, Mac and Web support
  • ES 3 on Android (now supports 2)
  • displayed FPS seems not to be correct
  • leave OpenCV into the plugin for further use?

flutter_opengl's People

Contributors

alnitak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

flutter_opengl's Issues

Any way to avoid openCV?

The ~800MB opencv library is a lot to require be default.

Is it really needed? It adds a lot of complexity to the build process.

You are amazing

This project is really great. It allows independent implementation of OpenGL in Flutter, eliminating the need to use native Java/Objective-C to handle OpenGL logic. You are amazing! But when will the iOS version be released? Looking forward to it!

Unable to run on android because of ffmpeg

Hello,
First of all, thanks for developing this package! I think it could be useful for my personal project but I can't get it to work. I tried a simple OpenGLController().initializeGL(); before the runApp call by having the package imported with :

flutter_opengl:
git:
url: https://github.com/alnitak/flutter_opengl.git
ref: master

I don't get any error when building for Linux but on android I got the following error:

Execution failed for task ':flutter_opengl:buildCMakeDebug[arm64-v8a]'.
> Build command failed.
Error while executing process /home/user/Android/Sdk/cmake/3.18.1/bin/ninja with arguments {-v -C /home/user/.pub-cache/git/flutter_opengl-c385fadea39c5174af57c0e379f866319b6a41fa/android/.cxx/Debug/47u1i66b/arm64-v8a flutter_opengl_plugin}
ninja: Entering directory '/home/user/.pub-cache/git/flutter_opengl-c385fadea39c5174af57c0e379f866319b6a41fa/android/.cxx/Debug/47u1i66b/arm64-v8a

ninja: error: '../../../../src/ffmpeg/arm64-v8a/libavcodec.so', needed by '/home/user/project/build/flutter_opengl/intermediates/cxx/Debug/47u1i66b/obj/arm64-v8a/libflutter_opengl_plugin.so', missing and no known rule to make it

So I understood that I had to build ffmpeg for android and place it in the android/src folder of the package, which I did. This time the build goes well but during the execution, there seems to be an error when executing the instruction ffi.DynamicLibrary.open("libflutter_opengl_plugin.so") (line 21 of opengl_controller.dart)

I get the following error :

ArgumentError (Invalid argument(s): Failed to load dynamic library 'libflutter_opengl_plugin.so': dlopen failed: library "libavcodec.so" not found)

It seems that it always concerns ffmpeg but I can't understand how to correct it. Could you please help me?

Seems broke

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method stopNDK on channel flutteropengl)
#0      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:319:7)

Tested on IOS and MacOs (desktop-embedding). Same error in both.

Execution failed for task ':flutter_opengl:buildCMakeDebug[arm64-v8a]'.

Having this issue while running from Debian 12 both on Emulator & Physical Device.
I have all the necessary packages installed.

  • What went wrong:
    Execution failed for task ':flutter_opengl:buildCMakeDebug[arm64-v8a]'.

com.android.ide.common.process.ProcessException: ninja: Entering directory `/home/samier/.pub-cache/hosted/pub.dev/flutter_opengl-0.9.0/android/.cxx/Debug/4g6m1p24/arm64-v8a'

C++ build system [build] failed while executing:
/home/samier/Android/Sdk/cmake/3.18.1/bin/ninja
-v
-C
/home/samier/.pub-cache/hosted/pub.dev/flutter_opengl-0.9.0/android/.cxx/Debug/4g6m1p24/arm64-v8a
flutter_opengl_plugin
from /home/samier/.pub-cache/hosted/pub.dev/flutter_opengl-0.9.0/android
ninja: error: '../../../../src/opencv/arm64-v8a/libopencv_java4.so', needed by '/home/samier/flutterP/opengl_flutter_test/build/flutter_opengl/intermediates/cxx/Debug/4g6m1p24/obj/arm64-v8a/libflutter_opengl_plugin.so', missing and no known rule to make it

Motivation for using FFI?

Really cool library! I love that it supports runtime compilation.

I was curious, why did you use FFI & FFI gen?

It seems more complicated than platform channels + Java & C, especially by requiring a ffigen build step, ndk, CMake, glw, and a c++ compiler. That's very significant complexity!

Not trying to critique, just want to understand the motivation.

Question: Does flutter_opengl support playing video from AVFrame or YUV format buffer data

Hi everyone,
I am building a Flutter application that can liveview IPCAM. Currently my application is using native lib (libc++.so) to receive data stream from IPCAM.
I used ffi and was able to get buffer data on Dart, the current buffer is in AVFrame format because I used ffmpeg_mobile decode from h265 (in libc++.so).
I want to ask if flutter_opengl has an api that supports playing video from buffer with avframe format? Or is there another plugin that supports this, hope everyone can support.
Thanks a lot

Sincerely seeking advice, How to replace the flutter default program & shaders on linux?

TextureGL *
texture_gl_new(VideoRenderer *renderer, guint32 width, guint32 height) {
    TextureGL *self = TEXTURE_GL(g_object_new(texture_gl_get_type(), NULL));
    self->renderer = renderer;
    self->width = width;
    self->height = height;

    auto vertexShader = loadShader(GL_VERTEX_SHADER, vertShaderSource);
    auto fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragShaderSource);
    self->program = linkProgram(vertexShader, fragmentShader);

    glUseProgram(self->program);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    self->attrBuffer = bindFullViewportAttrBuffer();

    self->textureId = generateEmptyTexture2D();
    self->framebufferId = generateFrameBufferTexture2D(self->textureId);

    return self;
}

This is my code, but not invalid...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.