I'm still having problems getting the Charm Down PicturesService to work.
(I already posted a question regarding the issue).
Now I created a very simple test application and updated the build.gradle file with the latest library versions.
However, the PicturesService is still working very unreliable. Selecting a picture sometimes works, sometimes it doesn't. Taking a picture seems to be working even more unreliable.
buildscript {
repositories {
jcenter()
}
dependencies { classpath 'org.javafxports:jfxmobile-plugin:1.3.5'}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
maven {
url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
}
}
mainClassName = 'com.gluonapplication.GluonApplication'
dependencies {
compile 'com.gluonhq:charm:4.3.4'
compile 'org.javafxports:jfxdvk:8.60.9'
compileNoRetrolambda 'com.airhacks:afterburner.mfx:1.6.2'
}
jfxmobile {
downConfig {
version = '3.3.0'
plugins 'display', 'lifecycle', 'statusbar', 'storage', 'pictures'
}
android {
manifest = 'src/android/AndroidManifest.xml'
compileSdkVersion = '23'
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'license/LICENSE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
}
}
}
The necessary permissions are added to the AndroidManifest:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
MobileApplication:
public class GluonApplication extends MobileApplication {
#Override
public void init() {
addViewFactory(HOME_VIEW, () ->
{
PicturesService pictureService = Services.get(PicturesService.class)
.orElseThrow(() -> new IllegalStateException("Failed to get PictureService"));
Button btnLoadImage = new Button("load image");
btnLoadImage.setOnAction(e -> pictureService.loadImageFromGallery().ifPresent(i -> imv.setImage(i)));
CheckBox chkSavePicture = new CheckBox("save picture");
Button btnTakePhoto = new Button("take photo");
btnTakePhoto.setOnAction(e -> pictureService.takePhoto(chkSavePicture.isSelected()).ifPresent(i -> imv.setImage(i)));
ImageView imv= new ImageView();
imv.setFitHeight(300);
imv.setFitWidth(300);
VBox content = new VBox(16, btnLoadImage, btnTakePhoto, chkSavePicture, imv);
content.setAlignment(Pos.CENTER);
return new View(content);
});
}
}
Tested on a Huawei P9 lite, Android 6.0
Logcat take photo succeeded:
05-13 16:08:49.200: V/FXActivity(18796): onActivityResult with requestCode 2 and resultCode = -1 and intent = null
05-13 16:08:50.180: V/FXActivity(18796): onRestart
05-13 16:08:50.187: V/FXActivity(18796): onStart
05-13 16:08:50.187: V/FXActivity(18796): onResume
05-13 16:08:50.196: V/FXEntity(18796): Surface created.
05-13 16:08:50.198: V/FXActivity native(18796): [JVDBG] SURFACE created native android window at 0xe7c9b208, surface = 0xffac4e60
05-13 16:08:50.202: D/mali_winsys(18796): new_window_surface returns 0x3000
05-13 16:08:50.202: I/GLASS(18796): Native code is notified that surface has changed (repaintall)!
05-13 16:08:50.203: V/FXEntity(18796): Called Surface changed [1080, 1740], format 4
05-13 16:08:50.203: V/FXActivity native(18796): [JVDBG] SURFACE created native android window at 0xe7c9b208, surface = 0xffac4e40
05-13 16:08:50.204: I/GLASS(18796): Native code is notified that surface has changed with size provided (repaintall)!
05-13 16:08:50.204: V/FXEntity(18796): Called Surface redraw needed
05-13 16:08:50.205: V/FXEntity(18796): Redraw...
05-13 16:08:50.205: I/GLASS(18796): Call surfaceRedrawNeeded
05-13 16:08:50.205: I/GLASS(18796): Native code is notified that surface needs to be redrawn (repaintall)!
05-13 16:08:50.205: V/FXEntity(18796): Wait a while before doing this again...
05-13 16:08:50.230: I/System.out(18796): PPSRenderer: scenario.effect - createShader: LinearConvolveShadow_20
05-13 16:08:50.310: I/System.out(18796): PPSRenderer: scenario.effect - createShader: LinearConvolveShadow_28
05-13 16:08:50.408: V/FXEntity(18796): Redraw again...
05-13 16:08:50.408: I/GLASS(18796): Call surfaceRedrawNeeded
05-13 16:08:50.408: I/GLASS(18796): Native code is notified that surface needs to be redrawn (repaintall)!
05-13 16:08:50.416: I/OpenGLRenderer(18796): Initialized EGL, version 1.4
05-13 16:08:50.419: D/mali_winsys(18796): new_window_surface returns 0x3000
Logcat take photo failed:
05-13 22:18:38.264: I/art(9381): Late-enabling -Xcheck:jni
05-13 22:18:38.299: D/ActivityThread(9381): ActivityThread,attachApplication
05-13 16:07:13.229: D/HwCust(18033): Create obj success use class android.content.res.HwCustHwResourcesImpl
05-13 16:07:13.393: I/MultiDex(18033): VM with version 2.1.0 has multidex support
05-13 16:07:13.393: I/MultiDex(18033): install
05-13 16:07:13.393: I/MultiDex(18033): VM has multidex support, MultiDex support library is disabled.
05-13 16:07:13.429: V/FXActivity(18033): Initializing JavaFX Platform, using 8.60.9-SNAPSHOT
05-13 16:07:13.438: V/FXActivity native(18033): Loading JavaFXDalvik library
05-13 16:07:13.452: V/HwPolicyFactory(18033): : success to get AllImpl object and return....
05-13 16:07:13.474: I/HwCust(18033): Constructor found for class android.app.HwCustHwWallpaperManagerImpl
05-13 16:07:13.474: D/HwCust(18033): Create obj success use class android.app.HwCustHwWallpaperManagerImpl
05-13 16:07:13.475: V/ActivityThread(18033): ActivityThread,callActivityOnCreate
05-13 16:07:13.482: I/System.out(18033): usetextureview = false, useswipekeyboard = false
05-13 16:07:13.484: I/HwSecImmHelper(18033): mSecurityInputMethodService is null
05-13 16:07:13.485: V/FXActivity(18033): onCreate called, using 8.60.9-SNAPSHOT
05-13 16:07:13.486: V/FXActivity native(18033): Notification queue instance created.
05-13 16:07:13.486: V/FXActivity native(18033): Notification queue started
05-13 16:07:13.498: V/HwWidgetFactory(18033): : successes to get AllImpl object and return....
05-13 16:07:13.542: V/FXActivity native(18033): appDataDir: /data/user/0/com.gluonapplication
05-13 16:07:13.543: V/FXActivity(18033): onStart
05-13 16:07:13.544: D/ActivityThread(18033): add activity client record, r= ActivityRecord{a0b6377 token=android.os.BinderProxy#a432176 {com.gluonapplication/javafxports.android.FXActivity}} token= android.os.BinderProxy#a432176
05-13 16:07:13.544: V/FXActivity(18033): onActivityResult with requestCode 2 and resultCode = -1 and intent = null
05-13 16:07:13.544: V/FXActivity(18033): onResume
05-13 16:07:13.566: D/OpenGLRenderer(18033): Use EGL_SWAP_BEHAVIOR_PRESERVED: false
05-13 16:07:13.638: I/OpenGLRenderer(18033): Initialized EGL, version 1.4
05-13 16:07:13.655: D/mali_winsys(18033): new_window_surface returns 0x3000
05-13 16:07:13.665: V/FXEntity(18033): Surface created.
05-13 16:07:13.666: V/FXActivity native(18033): [JVDBG] SURFACE created native android window at 0xe7c99d08, surface = 0xffac4f30
05-13 16:07:13.816: I/System.out(18033): user.locale=de-DE
05-13 16:07:13.816: I/System.out(18033): javax.xml.stream.XMLEventFactory=com.sun.xml.stream.events.ZephyrEvent...
05-13 16:07:13.816: I/System.out(18033): prism.text=native
05-13 16:07:13.816: I/System.out(18033): java.vendor.url=http://www.android.com/
05-13 16:07:13.816: I/System.out(18033): java.ext.dirs=
05-13 16:07:13.816: I/System.out(18033): line.separator=
05-13 16:07:13.816: I/System.out(18033): file.encoding=UTF-8
05-13 16:07:13.816: I/System.out(18033): java.runtime.version=0.9
05-13 16:07:13.816: I/System.out(18033): prism.dirtyopts=true
05-13 16:07:13.816: I/System.out(18033): user.name=root
05-13 16:07:13.816: I/System.out(18033): java.compiler=
05-13 16:07:13.816: I/System.out(18033): android.icu.unicode.version=7.0
05-13 16:07:13.816: I/System.out(18033): javax.xml.stream.XMLOutputFactory=com.sun.xml.stream.ZephyrWriterFactory
05-13 16:07:13.816: I/System.out(18033): prism.debugfonts=true
05-13 16:07:13.816: I/System.out(18033): com.sun.javafx.gestures.rotate=true
05-13 16:07:13.816: I/System.out(18033): java.version=0
05-13 16:07:13.816: I/System.out(18033): android.icu.library.version=55.1
05-13 16:07:13.816: I/System.out(18033): use.egl=true
05-13 16:07:13.816: I/System.out(18033): embedded=monocle
05-13 16:07:13.816: I/System.out(18033): com.sun.javafx.gestures.scroll=true
05-13 16:07:13.816: I/System.out(18033): prism.lcdtext=false
05-13 16:07:13.816: I/System.out(18033): os.arch=armv7l
05-13 16:07:13.816: I/System.out(18033): java.io.tmpdir=/data/user/0/com.gluonapplication/cache
05-13 16:07:13.816: I/System.out(18033): glass.platform=Monocle
05-13 16:07:13.816: I/System.out(18033): android.zlib.version=1.2.8
05-13 16:07:13.816: I/System.out(18033): user.language=de
05-13 16:07:13.816: I/System.out(18033): java.vm.version=2.1.0
05-13 16:07:13.816: I/System.out(18033): com.sun.javafx.isEmbedded=true
05-13 16:07:13.816: I/System.out(18033): javax.xml.stream.XMLInputFactory=com.sun.xml.stream.ZephyrParserFactory
05-13 16:07:13.816: I/System.out(18033): prism.glDepthSize=16
05-13 16:07:13.816: I/System.out(18033): path.separator=:
05-13 16:07:13.816: I/System.out(18033): java.runtime.name=Android Runtime
05-13 16:07:13.816: I/System.out(18033): java.specification.version=0.9
05-13 16:07:13.816: I/System.out(18033): user.dir=/
05-13 16:07:13.816: I/System.out(18033): prism.maxTextureSize=2048
05-13 16:07:13.816: I/System.out(18033): java.vm.specification.vendor=The Android Project
05-13 16:07:13.816: I/System.out(18033): com.sun.javafx.gestures.zoom=true
05-13 16:07:13.816: I/System.out(18033): java.vm.name=Dalvik
05-13 16:07:13.816: I/System.out(18033): monocle.platform=Android
05-13 16:07:13.816: I/System.out(18033): log.lens=FINEST
05-13 16:07:13.816: I/System.out(18033): java.vm.specification.version=0.9
05-13 16:07:13.816: I/System.out(18033): user.home=
05-13 16:07:13.816: I/System.out(18033): java.specification.name=Dalvik Core Library
05-13 16:07:13.816: I/System.out(18033): file.separator=/
05-13 16:07:13.816: I/System.out(18033): java.library.path=/vendor/lib:/system/lib
05-13 16:07:13.816: I/System.out(18033): user.variant=
05-13 16:07:13.816: I/System.out(18033): os.version=3.10.90-g033208c
05-13 16:07:13.816: I/System.out(18033): java.boot.class.path=/system/framework/core-libart.jar:/sy...
05-13 16:07:13.816: I/System.out(18033): DALVIK.prism.verbose=true
05-13 16:07:13.816: I/System.out(18033): java.vm.specification.name=Dalvik Virtual Machine Specification
05-13 16:07:13.816: I/System.out(18033): javafx.platform=android
05-13 16:07:13.816: I/System.out(18033): glass.lens=eglfb
05-13 16:07:13.816: I/System.out(18033): os.name=Linux
05-13 16:07:13.816: I/System.out(18033): user.region=DE
05-13 16:07:13.816: I/System.out(18033): java.class.path=.
05-13 16:07:13.816: I/System.out(18033): android.icu.impl.ICUBinary.dataPath=/data/misc/zoneinfo/current/icu:/syst...
05-13 16:07:13.816: I/System.out(18033): prism.verbose=true
05-13 16:07:13.816: I/System.out(18033): prism.vsync=false
05-13 16:07:13.816: I/System.out(18033): java.specification.vendor=The Android Project
05-13 16:07:13.816: I/System.out(18033): java.vm.vendor=The Android Project
05-13 16:07:13.816: I/System.out(18033): prism.allowhidpi=true
05-13 16:07:13.816: I/System.out(18033): java.vendor=The Android Project
05-13 16:07:13.816: I/System.out(18033): http.agent=Dalvik/2.1.0 (Linux; U; Android 6.0; ...
05-13 16:07:13.816: I/System.out(18033): android.icu.cldr.version=27.0.1
05-13 16:07:13.816: I/System.out(18033): android.openssl.version=BoringSSL
05-13 16:07:13.817: I/System.out(18033): java.home=/system
05-13 16:07:13.817: I/System.out(18033): java.vm.vendor.url=http://www.android.com/
05-13 16:07:13.817: I/System.out(18033): java.class.version=50.0
05-13 16:07:13.817: V/DalvikLauncher(18033): Launch JavaFX application on DALVIK vm.
05-13 16:07:13.848: V/DalvikLauncher(18033): We have JavaFX on our current (base) classpath, registered exit listener
05-13 16:07:13.854: V/DalvikLauncher(18033): application class: [class com.gluonapplication.GluonApplication]
05-13 16:07:13.854: V/DalvikLauncher(18033): preloader class: [null]
05-13 16:07:13.854: V/DalvikLauncher(18033): javafx application class: [class javafx.application.Application]
05-13 16:07:13.854: V/DalvikLauncher(18033): javafx launcher class: [class com.sun.javafx.application.LauncherImpl]
05-13 16:07:13.854: V/DalvikLauncher(18033): launch application method: [public static void com.sun.javafx.application.LauncherImpl.launchApplication(java.lang.Class,java.lang.Class,java.lang.String[])]
05-13 16:07:13.871: V/FXEntity(18033): Called Surface changed [1080, 1740], format 4
05-13 16:07:13.871: V/FXActivity native(18033): [JVDBG] SURFACE created native android window at 0xe7c99d08, surface = 0xffac4f10
05-13 16:07:13.871: V/FXEntity(18033): Called Surface redraw needed
05-13 16:07:13.878: V/FXEntity(18033): Called Surface redraw needed
05-13 16:07:13.993: I/System.out(18033): Prism pipeline init order: es2
05-13 16:07:13.993: I/System.out(18033): Using native-based Pisces rasterizer
05-13 16:07:13.993: I/System.out(18033): Using dirty region optimizations
05-13 16:07:13.993: I/System.out(18033): Using system sized mask for primitives
05-13 16:07:13.993: I/System.out(18033): Not forcing power of 2 sizes for textures
05-13 16:07:13.993: I/System.out(18033): Using hardware CLAMP_TO_ZERO mode
05-13 16:07:13.993: I/System.out(18033): Opting in for HiDPI pixel scaling
05-13 16:07:14.000: I/System.out(18033): Prism pipeline name = com.sun.prism.es2.ES2Pipeline
05-13 16:07:14.010: I/System.out(18033): Loading ES2 native library ... prism_es2_monocle
05-13 16:07:14.023: I/System.out(18033): succeeded.
05-13 16:07:14.023: I/System.out(18033): GLFactory using com.sun.prism.es2.MonocleGLFactory
05-13 16:07:14.054: I/GLASS(18033): I have to Call dlopen libGLESv2.so
05-13 16:07:14.055: I/GLASS(18033): handle = 0xf76fcd04
05-13 16:07:14.055: I/GLASS(18033): I have to Call dlopen libEGL.so
05-13 16:07:14.056: I/GLASS(18033): handle = 0xf76fc9c4
05-13 16:07:14.057: I/GLASS(18033): Binding to libactivity.so
05-13 16:07:14.058: I/GLASS(18033): GetNativeWindow = 0xf3762da1, getDensitiy = 0xf3762dad
05-13 16:07:14.058: V/FXEntity(18033): notify_glassHasStarted called in FXActivity. register device now.
05-13 16:07:14.079: D/mali_winsys(18033): new_window_surface returns 0x3000
05-13 16:07:14.089: I/System.out(18033): (X) Got class = class com.sun.prism.es2.ES2Pipeline
05-13 16:07:14.104: I/System.out(18033): Initialized prism pipeline: com.sun.prism.es2.ES2Pipeline
05-13 16:07:14.127: I/DENSITY(18033): GETDENSITY, answer = 3.000000
05-13 16:07:14.185: I/System.out(18033): Maximum supported texture size: 8192
05-13 16:07:14.186: I/System.out(18033): Maximum texture size clamped to 2048
05-13 16:07:14.186: I/System.out(18033): Non power of two texture support = true
05-13 16:07:14.186: I/System.out(18033): Maximum number of vertex attributes = 16
05-13 16:07:14.186: I/System.out(18033): Maximum number of uniform vertex components = 4096
05-13 16:07:14.186: I/System.out(18033): Maximum number of uniform fragment components = 4096
05-13 16:07:14.186: I/System.out(18033): Maximum number of varying components = 60
05-13 16:07:14.186: I/System.out(18033): Maximum number of texture units usable in a vertex shader = 16
05-13 16:07:14.186: I/System.out(18033): Maximum number of texture units usable in a fragment shader = 16
05-13 16:07:14.190: I/System.out(18033): Graphics Vendor: ARM
05-13 16:07:14.191: I/System.out(18033): Renderer: Mali-T830
05-13 16:07:14.192: I/System.out(18033): Version: OpenGL ES 3.1 v1.r8p0-01dev0.bbfc5a14ef62ccdf784a9fff6af72acd
05-13 16:07:14.216: I/System.out(18033): register device done
05-13 16:07:14.227: W/System.err(18033): vsync: false vpipe: true
05-13 16:07:14.227: I/System.out(18033): [MON] Create device
05-13 16:07:14.230: I/System.out(18033): [MON] Create device done, add done
05-13 16:07:14.414: W/System.err(18033): Loading FontFactory com.sun.javafx.font.freetype.FTFactory
05-13 16:07:14.414: W/System.err(18033): Subpixel: enabled
05-13 16:07:14.434: W/System.err(18033): Freetype2 Loaded (version 2.5.0)
05-13 16:07:14.434: W/System.err(18033): LCD support Enabled
05-13 16:07:14.444: W/art(18033): Before Android 4.1, method void com.sun.javafx.scene.transform.TransformUtils$ImmutableTransform.ensureCanTransform2DPoint() would have incorrectly overridden the package-private method in javafx.scene.transform.Transform
05-13 16:07:14.630: W/System.err(18033): Temp file created: /data/user/0/com.gluonapplication/cache/+JXF415078203.tmp
05-13 16:07:14.643: W/System.err(18033): Temp file created: /data/user/0/com.gluonapplication/cache/+JXF1552782793.tmp
05-13 16:07:14.650: W/System.err(18033): Temp file created: /data/user/0/com.gluonapplication/cache/+JXF-728135178.tmp
05-13 16:07:14.657: W/System.err(18033): Temp file created: /data/user/0/com.gluonapplication/cache/+JXF-646868817.tmp
05-13 16:07:14.828: W/art(18033): Before Android 4.1, method double javafx.scene.text.TextFlow.computeChildPrefAreaHeight(javafx.scene.Node, javafx.geometry.Insets) would have incorrectly overridden the package-private method in javafx.scene.layout.Region
05-13 16:07:14.828: W/art(18033): Before Android 4.1, method double javafx.scene.text.TextFlow.computeChildPrefAreaWidth(javafx.scene.Node, javafx.geometry.Insets) would have incorrectly overridden the package-private method in javafx.scene.layout.Region
05-13 16:07:15.067: I/System.out(18033): max rectangle texture cell size = 62
05-13 16:07:15.084: I/System.out(18033): wrap rectangle texture = 2 x 2
05-13 16:07:15.087: I/System.out(18033): ES2ResourceFactory: Prism - createStockShader: AlphaTexture_Color.frag
05-13 16:07:15.106: I/System.out(18033): ES2ResourceFactory: Prism - createStockShader: Texture_Color.frag
05-13 16:07:15.122: I/System.out(18033): PPSRenderer: scenario.effect - createShader: LinearConvolveShadow_20
05-13 16:07:15.133: I/System.out(18033): ES2ResourceFactory: Prism - createStockShader: Solid_TextureRGB.frag
05-13 16:07:15.150: I/System.out(18033): ES2ResourceFactory: Prism - createStockShader: FillRoundRect_Color.frag
05-13 16:07:15.154: I/System.out(18033): Loading Prism common native library ...
05-13 16:07:15.163: I/System.out(18033): succeeded.
05-13 16:07:15.177: I/System.out(18033): PPSRenderer: scenario.effect - createShader: LinearConvolveShadow_28
Related
I have a working GLTF animation that automatically starts playing when the page loads, however whenever I try to add a material to it, the animation no longer plays but the material appears. How do I fix this or if there is an easier way just to add a block colour to a gltf model please let me know, thanks.
var loader = new THREE.GLTFLoader();
loader.setDRACOLoader( new THREE.DRACOLoader() );
// Load a glTF resource
loader.load(
// resource URL
'../models/fox3.gltf',
// called when the resource is loaded
function ( gltf ) {
gltf.animations; // Array<THREE.AnimationClip>
gltf.scene; // THREE.Scene
gltf.scenes; // Array<THREE.Scene>
gltf.cameras; // Array<THREE.Camera>
gltf.asset; // Object
//Loading in and positioning model
var object = gltf.scene;
object.scale.set(10,10,10);
object.position.set (-300, 20,-400);
object.rotation.y = 0.5;
//Playing Animation
mixer = new THREE.AnimationMixer(gltf.scene);
console.log(gltf.animations)
mixer.clipAction( gltf.animations[0] ).play();
//Adding texture/colour to model (causes animation to stop playing)
// materialObj = new THREE.MeshBasicMaterial( { color: "#9E4300"} );
// object.traverse(function(child){
// if (child instanceof THREE.Mesh){
// //child.material = materialObj;
// }
// });
console.log(object);
scene.add( object )
});
or if there is an easier way just to add a block colour to a gltf model please let me know, thanks.
I'll address this last part of your question. The MeshBasicMaterial has the lighting calculations turned off, and in glTF this is supported with an extension called KHR_materials_unlit.
Here's a sample model called BoxUnlit.gltf that shows this extension in action. Two key places to note are ExtensionsUsed at the top, and the material near the bottom.
One major gotcha here is that the material's BaseColorFactor is specified in linear colorspace, while textures are provided in sRGB colorspace. So you have to take your chosen color and convert it to linear, typically by mathematically raising each component to the power of 2.2.
For example, your question contains color value #9E4300, which in 0..255 scale is equal to (158, 67, 0). Divide each number by 255, then raise by 2.2:
Red == (158 / 255.0) ** 2.2 == 0.348864834
Green == ( 67 / 255.0) ** 2.2 == 0.052841625
Blue == ( 0 / 255.0) ** 2.2 == 0.0
Use those values as the RGB values of the glTF model's BaseColorFactor, along with an alpha value of 1.0, like so:
"materials": [
{
"pbrMetallicRoughness": {
"baseColorFactor": [
0.348864834,
0.052841625,
0.0,
1.0
]
},
"extensions": {
"KHR_materials_unlit": {}
}
}
],
With that, ThreeJS should automatically select the MeshBasicMaterial for the model.
Try changing the skinning to true on the material of gltb and it should work. I had the same problem earlier.
While testing code in three.js, animation is not needed. I can see the first rendered frame. This would use less power, and stop the fan on the laptop from kicking in as the graphics card heats up.
The examples in three.js have the following structure:
function init() {
animate()
}
function animate() {
requestAnimationFrame( animate );
render();
targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
}
function render() {
group.rotation.y += ( targetRotation - group.rotation.y ) * 0.05;
renderer.render( scene, camera );
}
I do not see how to turn off the repeated calls to animate.
Is there any easy way to turn off animation?
You do not have to have an animation loop in three.js -- say, if you have a static scene. Just call
renderer.render( scene, camera );
You will need to re-render whenever the camera moves or when loaders finish loading models or loading textures.
If you are using OrbitControls with a static scene, you can instantiate OrbitControls like so:
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render ); // use if there is no animation loop
where render() calls renderer.render( scene, camera ).
If you are loading models or textures, the three.js loaders have a callback function you can specify. For example,
var loader = new THREE.TextureLoader();
var texture = loader.load( 'myTexture.jpg', render );
Also
var manager = new THREE.LoadingManager();
var loader = new THREE.OBJLoader( manager );
loader.load( 'myModel.obj', function( object ) {
// your code...
render();
}
three.js r.75
I need to blur the frame buffer and I don't know how to get the frame buffer using THREE.js.
I want to blur the whole frame buffer rather than blur each textures in the scene. So I guess I should read the frame buffer and then blur, rather than doing this in shaders.
Here's what I have tried:
Call when init:
var renderTarget = new THREE.WebGLRenderTarget(512, 512, {
wrapS: THREE.RepeatWrapping,
wrapT: THREE.RepeatWrapping,
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter,
format: THREE.RGBAFormat,
type: THREE.FloatType,
stencilBuffer: false,
depthBuffer: true
});
renderTarget.generateMipmaps = false;
Call in each frame:
var gl = renderer.getContext();
// render to target
renderer.render(scene, camera, renderTarget, false);
framebuffer = renderTarget.__webglFramebuffer;
console.log(framebuffer);
gl.flush();
if (framebuffer != null)
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
var width = height = 512;
var rdData = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, rdData);
console.log(rdData);
// render to screen
renderer.render(scene, camera);
But framebuffer is WebFramebuffer {} and rdData is full of 0. Am I doing this in the right way?
Any blur should use shaders to be efficient, but in this case not as materials.
If you want to blur the entire frame buffer and render that to the screen use the effect composer. It's located in three.js/examples/js./postprocessing/EffectComposer.js
Set up the scene camera and renderer as normal but in addition add an instance of the effect composer. With the scene as a render pass.
composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass( scene, camera ) );
Then blur the whole buffer with two passes using the included blur shaders located in three.js/examples/shaders/
hblur = new THREE.ShaderPass( THREE.HorizontalBlurShader );
composer.addPass( hblur );
vblur = new THREE.ShaderPass( THREE.VerticalBlurShader );
// set this shader pass to render to screen so we can see the effects
vblur.renderToScreen = true;
composer.addPass( vblur );
finally in your method called in each frame render using the composer instead of the renderer
composer.render();
Here is a link to a working example of full screen blur
Try using the MeshDepthMaterial and render this into your shader.
I suggest rendering the blur pass with a dedicated camera using the same settings as the scene's diffuse camera. Then by adjusting the camera's frustrum you can do both screen and depth of blur effects. For a screen setup move the near frustrum towards the camera and move the far frustrum in increments away from the camera.
http://threejs.org/docs/#Reference/Materials/MeshDepthMaterial
I have an OpenGL 3.2 CORE context on OSX 10.7.5 set up and trying to render to a 3D texture,
using a layered rendering approach. The geometry shader feature "gl_layer" is supported, but I cannot bind a GL_TEXTURE_3D to my framebuffer attachment. It returns GL_FRAMEBUFFER_UNSUPPORTED.
This is the card and driver version in my MBP:
AMD Radeon HD 6770M 1024 MB - OpenGL 3.2 CORE (ATI-7.32.12)
This feature does not directly relate to a specific extension AFAIK.
Does anybody know how to figure out whether this is unsupported by the driver or hardware?
Thanks so much.
Below the code to reconstruct. I use glfw to set up the context:
// Initialize GLFW
if (!glfwInit())
throw "Failed to initialize GLFW";
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Open a window and create its OpenGL context
if (!glfwOpenWindow(720, 480, 8, 8, 8, 8, 24, 8, GLFW_WINDOW))
throw "Failed to open GLFW window";
//
// ...
//
GLuint framebuffer, texture;
GLenum status;
glGenFramebuffers(1, &framebuffer);
// Set up the FBO with one texture attachment
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, texture);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 256, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
throw status;
//
// status is GL_FRAMEBUFFER_UNSUPPORTED here !!!
//
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &framebuffer);
exit(1);
Does anybody know how to figure out whether this is unsupported by the driver or hardware?
It just told you. That's what GL_FRAMEBUFFER_UNSUPPORTED means: it's the driver exercising veto-power over any framebuffer attachments it doesn't like for any reason whatsoever.
There's not much you can do when this happens except to try other things. Perhaps rendering to a 2D array texture.
i have some problems in a project i want to support for ios5. I have code of an app that contains 3d rendering using opengl-es and antialiasing using multisample frame buffers. The code works great on ios4.3. Since ios5 the 3d models won't get rendered. On the simulator i just get a pink screen.
After some tests i found out, that the function
glResolveMultisampleFramebufferAPPLE()
is the problem. This function raises an error. 0x502
NSLog(#"0x%x", glGetError()); // "0x502"
I have no idea what's going on and why this function won't work on ios5. Can please anyone help me with this?? Here is some code that creates the frame buffers.
//first destroy frame buffers
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer)
{
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
// Generate IDs for a framebuffer object and a color renderbuffer
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
// This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer)
// allowing us to draw into a buffer that will later be rendered to screen whereever the layer is (which corresponds with our view).
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
//Width and height der viewBoundingBox in Pixeln
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
//Generate our MSAA Frame and Render buffers
glGenFramebuffersOES(1, &msaaFramebuffer);
glGenRenderbuffersOES(1, &msaaRenderBuffer);
//Bind our MSAA buffers
glBindFramebufferOES(GL_FRAMEBUFFER_OES, msaaFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, msaaRenderBuffer);
// Generate the msaaDepthBuffer.
// 4 will be the number of pixels that the MSAA buffer will use in order to make one pixel on the render buffer.
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4,GL_RGB565_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, msaaRenderBuffer);
glGenRenderbuffersOES(1, &msaaDepthBuffer);
//Bind the msaa depth buffer.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, msaaDepthBuffer);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT16_OES, backingWidth , backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, msaaDepthBuffer);
// Make sure that you are drawing to the current context
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, msaaFramebuffer);
[controller drawView:self];
//Bind both MSAA and View FrameBuffers
glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer);
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, viewFramebuffer);
if((err = glGetError())) NSLog(#"%x error in line %u in method %s", err, __LINE__, __FUNCTION__);
// Call a resolve to combine both buffers
glResolveMultisampleFramebufferAPPLE();
if((err = glGetError())) NSLog(#"%x error in line %u in method %s", err, __LINE__, __FUNCTION__);
// Use discard to improve fill rate and overall performance!
GLenum attachments[] = {GL_DEPTH_ATTACHMENT_OES, GL_COLOR_ATTACHMENT0_OES, GL_STENCIL_ATTACHMENT_OES};
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 3, attachments);
// Present final image to screen
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
For me, this problem was cause by the format passed to glRenderbufferStorageMultisampleAPPLE.
Try using GL_RGBA8_OES or GL_RGB5_A1_OES instead.