// Platform messages are asynchronous, so we initialize in an async method.
Future initPlatformState() async {
width = screenSize!.width;
height = width;
if (!initShaders(_gl, vs, fs)) {
print('Failed to intialize shaders.');
return;
}
// Write the positions of vertices to a vertex shader
n = initVertexBuffers(_gl);
if (n < 0) {
print('Failed to set the positions of the vertices');
return;
}
initShaders(gl, vs_source, fs_source) {
// Compile shaders
var vertexShader = makeShader(gl, vs_source, gl.VERTEX_SHADER);
var fragmentShader = makeShader(gl, fs_source, gl.FRAGMENT_SHADER);
// Create program
glProgram = gl.createProgram();
// Attach and link shaders to the program
gl.attachShader(glProgram, vertexShader);
gl.attachShader(glProgram, fragmentShader);
gl.linkProgram(glProgram);
var _res = gl.getProgramParameter(glProgram, gl.LINK_STATUS);
print(" initShaders LINK_STATUS _res: ${_res} ");
if (_res == false || _res == 0) {
print("Unable to initialize the shader program");
return false;
}
// Use program
gl.useProgram(glProgram);
return true;
Future loadImage(String imgPath) async{
final ByteData imageData = await rootBundle.load(imgPath);
final Uint8List bytes = imageData.buffer.asUint8List();
// Decode the image
final ui.Codec codec = await ui.instantiateImageCodec(bytes);
final ui.Image image = (await codec.getNextFrame()).image;
// Flip the image vertically
final Uint8List pixelData = await _flipImageVertically(image);
return pixelData;
}
Future _flipImageVertically(ui.Image image) async {
final int width = image.width;
final int height = image.height;
final ByteData? byteData = await image.toByteData();
final Uint8List pixels = Uint8List.fromList(byteData?.buffer.asUint8List() ?? []);
for (int y = 0; y < height ~/ 2; y++) {
final int topOffset = y * width * 4;
final int bottomOffset = (height - y - 1) * width * 4;
for (int x = 0; x < width; x++) {
final int topIndex = topOffset + x * 4;
final int bottomIndex = bottomOffset + x * 4;
final int r = pixels[topIndex];
final int g = pixels[topIndex + 1];
final int b = pixels[topIndex + 2];
final int a = pixels[topIndex + 3];
pixels[topIndex] = pixels[bottomIndex];
pixels[topIndex + 1] = pixels[bottomIndex + 1];
pixels[topIndex + 2] = pixels[bottomIndex + 2];
pixels[topIndex + 3] = pixels[bottomIndex + 3];
pixels[bottomIndex] = r;
pixels[bottomIndex + 1] = g;
pixels[bottomIndex + 2] = b;
pixels[bottomIndex + 3] = a;
}
}
return pixels;
}
}
`
When I render on Android mobile. It's not showing as a 3D cube, but as a 2D square.
My image
My Code ` import 'dart:async'; import 'dart:io'; import 'dart:typed_data';
import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart';
import 'package:flutter_gl/flutter_gl.dart'; import 'package:flutter_gl/openGL/opengl/opengl_es_bindings/opengl_es_bindings.dart'; import 'package:vector_math/vector_math.dart' as math;
class ExampleCube extends StatefulWidget { _MyAppState createState() => _MyAppState(); }
class _MyAppState extends State {
late FlutterGlPlugin flutterGlPlugin;
int? fboId; num dpr = 1.0; late double width; late double height;
ui.Size? screenSize;
dynamic glProgram; dynamic _vao; dynamic _ebo; dynamic _texture1; dynamic _texture2;
dynamic sourceTexture;
dynamic defaultFramebuffer; dynamic defaultFramebufferTexture;
int n = 0;
int t = DateTime.now().millisecondsSinceEpoch;
@override void initState() { super.initState();
}
// Platform messages are asynchronous, so we initialize in an async method. Future initPlatformState() async {
width = screenSize!.width;
height = width;
}
setup() async { // web no need use fbo if (!kIsWeb) { await flutterGlPlugin.prepareContext();
}
initSize(BuildContext context) { if (screenSize != null) { return; }
}
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Example app'), ), body: Builder( builder: (BuildContext context) { initSize(context); return SingleChildScrollView(child: _build(context)); }, ), floatingActionButton: FloatingActionButton( onPressed: () { clickRender(); }, child: Text("Render"), ), ), ); }
Widget _build(BuildContext context) { return Column( children: [ Container( width: width, height: width, color: Colors.black, child: Builder(builder: (BuildContext context) { if (kIsWeb) { return flutterGlPlugin.isInitialized ? HtmlElementView( viewType: flutterGlPlugin.textureId!.toString()) : Container(); } else { return flutterGlPlugin.isInitialized ? Texture(textureId: flutterGlPlugin.textureId!) : Container(); } })), ], ); }
setupDefaultFBO() { final _gl = flutterGlPlugin.gl; int glWidth = (width dpr).toInt(); int glHeight = (height dpr).toInt();
}
clickRender() { print(" click render ... "); render(); }
render() { final _gl = flutterGlPlugin.gl;
}
prepare() { final _gl = flutterGlPlugin.gl;
precision mediump float; // add a precision qualifier
layout (location = 0) in vec3 a_Position; layout (location = 1) in vec2 a_TexCoord;
out vec2 TexCoord;
uniform mat4 mvp;
void main() { gl_Position = mvp * vec4(a_Position, 1.0); TexCoord = vec2(a_TexCoord.x,a_TexCoord.y); } """;
precision mediump float;
out vec4 pc_fragColor;
define gl_FragColor pc_fragColor
in vec2 TexCoord;
uniform sampler2D texture1; uniform sampler2D texture2;
void main() { gl_FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2); } """;
}
initVertexBuffers(gl) { // Vertices var dim = 3;
}
initShaders(gl, vs_source, fs_source) { // Compile shaders var vertexShader = makeShader(gl, vs_source, gl.VERTEX_SHADER); var fragmentShader = makeShader(gl, fs_source, gl.FRAGMENT_SHADER);
}
makeShader(gl, src, type) { var shader = gl.createShader(type); gl.shaderSource(shader, src); gl.compileShader(shader); var _res = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (_res == 0 || _res == false) { print("Error compiling shader: ${gl.getShaderInfoLog(shader)}"); return; } return shader; }
Future loadImage(String imgPath) async{
final ByteData imageData = await rootBundle.load(imgPath);
final Uint8List bytes = imageData.buffer.asUint8List();
}
Future _flipImageVertically(ui.Image image) async {
final int width = image.width;
final int height = image.height;
} } ` When I render on Android mobile. It's not showing as a 3D cube, but as a 2D square.
My image
![flutter540](https://user-images.githubusercontent.com/3026024/228766764-9dcff1d6-5c28-44bd-85a6-6b8a36ab1a59.jpg)