Replace JavaFX with SDL2 + OpenGL ES 2.0 via JNI#1
Replace JavaFX with SDL2 + OpenGL ES 2.0 via JNI#1Copilot wants to merge 6 commits intopos2_PosBoundsfrom
Conversation
Agent-Logs-Url: https://github.com/SwuduSusuwu/SusuJava/sessions/77ade638-4784-4228-a897-83c9d8a0222a Co-authored-by: SwuduSusuwu <168943815+SwuduSusuwu@users.noreply.github.com>
@`./susuwu/FishSim.java`: @`boundsResolutionFactor`: if small resolution then factor = 2.0, if huge resolution then factor = 1.2, until invisible (unshown) `Fish` have resource use lowered
|
@copilot |
|
@copilot . Guess the packages are not the problem (Termux has |
SwuduSusuwu
left a comment
There was a problem hiding this comment.
Purpose was to include support for Termux: but can not test this on Termux due to environment problems.
No regressions on Ubuntu (performance improves), so will approve this for now.
0a59933 to
cd6c603
Compare
@`./susuwu/FishSim.java`: @`enum PhysicsMode`, @`void run(String[] args)`: document how (with `GLES2`, if `monitorRefreshMode = separateUnbound`) `SimUsages.drawNS` includes time for vertical sync, plus propose future solutions (`SDL_GL_SetSwapInterval(0);`, or subtract `GlClear()` time from `SimUsages.drawNS`.) Is followup to: commit 09d1a88 (Replace JavaFX with SDL2+GLES2 via JNI wrappers), which replaces `javafx` with `GLES2`.
@`./susuwu/SimUsages.java`: +`preSynchro()`, +`postSynchro()`. Is followup to: commit HEAD~1 (@`FishSim.java`: document SimUsages includes vsync), which suggests this solution.
@`susuwu/FishSim.java`: introduce `SimUsages.preSynchro()` before `SdlGles2.glClear()`, then `SimUsages.postSynchro()`
Is followup to: commit HEAD~1 (@`SimUsages.java`: +`{pre,post}Synchro()`).
Is followup to: commit HEAD~2 (@`FishSim.java`: document SimUsages includes vsync), whose "TODO:" lists this removes.
8ead24b to
d0ab352
Compare
JavaFX is unavailable on most smartphones; SDL2 + GLES2 is universal across desktops and Android. This replaces the ~100 lines of JavaFX usage across two files with a thin JNI bridge, preserving all physics/threading logic unchanged.
New files
susuwu/SdlGles2.java— JNI bridge:init,destroy,pollQuit,glClear*,swapWindow,setWindowTitle,drawFilledPolygonsusuwu/sdl_gles2_jni.c— C implementation via SDL2 + GLES2; includes minimal vertex/fragment shaders (pixel→clip-space with Y-flip to match JavaFX canvas orientation)FishSim.javaextends Application;main()callsnew FishSim().run(args)directlyAnimationTimer/Timelinerender loop → SDL event loop withThread.sleep(1)frame limiterTimeline/KeyFramephysics loop →ScheduledExecutorService(ms-precision) forseparateFps, background thread forseparateUnbound; synchronous/async modes unchangedFish.render(GraphicsContext)→Fish.render()viaSdlGles2.drawFilledPolygon: same pentagon vertices{0,-10},{-5,10},{-2,0},{2,0},{5,10}triangulated as fan{0,1,2},{0,2,3},{0,3,4}, rotated in Java then passed as screen-space floatsjavafx.scene.paint.Color→ nestedFishSim.Colorwithcolor(r,g,b),getRed/Green/Blue()—isSimilarTo()logic unchangedSimUsages.javaPaneparam; no display object neededPlatform.runLater(fpsTextRefresh)→ direct call (SDL2 has no UI-thread restriction)Text.setText(str)→SdlGles2.setWindowTitle("Fish Simulation (Boids) - " + str)Build scripts (
susuwu/build.sh,build.sh)PATH_TO_FX/--module-path/--add-modules javafx.*cc -shared -fPIC sdl_gles2_jni.c -o libsdl_gles2_jni.so \ -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux \ $(pkg-config --cflags --libs sdl2) -lGLESv2apt install libsdl2-dev libgles2-mesa-dev; adds-Djava.library.path=.to JVM flags.gitignoreupdated to exclude*.so/*.dll/*.dylibAll pure-Java files (
Calculus,Forces,Pos*,ImmutablePos*,PosBounds*,ClassBounds) are untouched.Original prompt
Goal
Replace all JavaFX usage with SDL2 + OpenGL ES 2.0 via JNI wrappers, so
FishSimcan execute on all desktops and smartphones (JavaFX is not available on most smartphones, but GLES2 is universal).Context
The JavaFX usage is limited to fewer than 100 lines across only 2 files:
susuwu/FishSim.java— usesjavafx.application.Application,Stage,Scene,Canvas,GraphicsContext2D,AnimationTimer,Timeline,KeyFrame,Duration,Color,Panesusuwu/SimUsages.java— usesjavafx.application.Platform.runLater(),javafx.scene.layout.Pane,javafx.scene.paint.Color,javafx.scene.text.TextAll other files (
Calculus.java,Forces.java,Pos.java,Pos2.java,ImmutablePos.java,ImmutablePos2.java,PosBounds.java,ImmutablePosBounds.java,ClassBounds.java) are pure Java with zero JavaFX dependency — these must remain unchanged.What to change
1. Create a JNI wrapper for SDL2 + GLES2
Add a new file
susuwu/SdlGles2.java(or similar name) which provides a thin JNI bridge to SDL2 and OpenGL ES 2.0. This should provide:Stage,Scene)Canvas,GraphicsContext2D)AnimationTimer,Timeline,KeyFrame)gc.save/translate/rotate/setFill/beginPath/moveTo/lineTo/closePath/fill/restore)javafx.scene.text.Text) — can be very simple/minimalAlso add the corresponding C/JNI native source file(s) (e.g.,
susuwu/sdl_gles2_jni.c) that implement thenativemethods using SDL2 and GLES2 headers.2. Modify
susuwu/FishSim.javaimport javafx.*statementsextends Applicationwith a plainpublic classwith amain()that initializes SDL2 window + GLES2 context via the JNI wrapperstart(Stage primaryStage)logic: init SDL2 window, create GLES2 context, then enter the main loopAnimationTimer/Timelineanimation loops with a simplewhile(!quit)SDL event + render loop (SDL_PollEvent / SDL_GL_SwapWindow), callingupdateFish()andrenderFish()at the configured ratesGraphicsContext gcrendering inFish::render()with GLES2 draw calls (glClear, drawing colored triangles for fish shapes using the same vertex coordinates:{0,-10}, {-5,10}, {-2,0}, {2,0}, {5,10})javafx.scene.paint.Colorwith a simple color class ordouble[]{r,g,b}/float[]{r,g,b,a}. TheFishconstructor currently takesColor.color(r,g,b)andisSimilarTo()usescolor.getRed(),color.getGreen(),color.getBlue()— these must still workCanvas.clearRect()withglClear(GL_COLOR_BUFFER_BIT)PhysicsModeenum,updateFish(),renderFish()(just the draw calls change),Fish.applyFlockingRules(),applySeparation(),applyAlignment(),applyCohesion(),applyWallAvoidance(),update(),setPos(),isSimilarTo(),getPosDiff()ReentrantLockusage,ExecutorService, and all threading logicsetResolution()logicstop()method should call SDL_Quit and executor.shutdown()3. Modify
susuwu/SimUsages.javaimport javafx.*statementsPaneconstructor parameter — replace with whatever the SDL2 JNI wrapper usesjavafx.scene.text.Textwith SDL2/GLES2 text rendering (can be very basic — e.g., render to window title viaSDL_SetWindowTitle, or use a minimal bitmap font renderer)Platform.runLater()— in SDL2 the text update can happen directly on the render threadColor.WHITEwith the equivalentstartRefresh,postRefresh,startRender,postRender,startPhysics,postPhysics,fpsTextRefresh,FpsTextModeenum) exactly4. Update
susuwu/build.shPATH_TO_FX/openjfx/--module-path/--add-modules javafx.*logicsdl_gles2_jni.cinto a shared library (.so/.dll/.dylib) usingccorgccwith-lSDL2 -lGLESv2(or appropriate flags)apt install libsdl2-dev(or equivalent) for the SDL2 dependencyjavainvocation to include-Djava.library.path=.(or wherever the.sois) so JNI can find the native libraryGITHUB_ACTIONSconditional andexit $?5. Do NOT modify these files (they have zero JavaFX dependency):
susuwu/Calculus.javasusuwu/Forces.javasusuwu/Pos.javasusuwu/Pos2.javasusuwu/ImmutablePos.javasusuwu/ImmutablePos2.javasusuwu/PosBounds.javasusuwu/ImmutablePosBounds.javasusuwu/ClassBounds.javaKey constraints
PhysicsMode...This pull request was created from Copilot chat.