Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - AeroShark333

Pages: [1] 2 3 ... 21
1
Support / Re: How to add more texture maps to obj
« on: June 10, 2022, 04:31:03 pm »
In Blender, try to import the model.
Then in top-left of your screen, change from Object Mode to Edit Mode.
Press CTRL+T (Triangulate mesh).
And then export this new Mesh as .Obj

(source: https://blender.stackexchange.com/questions/19253/how-to-make-all-polygons-into-triangles)

2
Support / Re: How to add more texture maps to obj
« on: June 04, 2022, 04:36:14 pm »
I believe the general logic should be:
- Load textures with full names
- Load model file
- Load MTL file
- Load 3D object using model and MTL files

If used properly then Object3D#setTexture(...) is not necessary
The model loader will find the texture names that are specified in the MTL file. But these names should be properly set in the texture manager.

Instead of this:
tm.addTexture("_Vegetation_Blur7_1",_Vegetation_Blur7_1);

Try one of these:
tm.addTexture("changjing2/_Vegetation_Blur7_1.jpg",_Vegetation_Blur7_1);

Or:
tm.addTexture("changjing2/_Vegetation_Blur7_1",_Vegetation_Blur7_1);

3
Support / Re: is it possible to make JPCT work with Cesium?
« on: April 08, 2022, 11:07:23 pm »
https://www.cesium.com/why-cesium/3d-tiles/ seems like they use .glTF 3D Objects.
I have used these in the past and converted them to .obj extension using Blender.
I suppose there might be some Java library that can do read-out/convert these .glTF files as well.

Seems like a difficult thing to implement, but doable ;)

4
Projects / Re: my project - Vehicle Simulation
« on: March 30, 2022, 07:33:53 pm »
Hi everyone,
i released a demo of this on moddb, here is the link.
https://www.moddb.com/games/vehicle-simulation
it is not a fun and fast game, there are a lot of texts to read if you want to fly in it. but you can quickly make something move and see the effects - you need keyboard for that.
the moddb page is new, i haven't spent much time on it. just uploaded the file and share with you guys.
I have tried it (Google didn't seem to trust the app but I ignored the warnings and installed it anyway).
I haven't been able to try it a lot because of limited time.
I used a bluetooth keyboard on my phone for the controls.
I'm not really used to these controls yet, so I'll test more later; it would be nice to have an option for different or custom control sets.
(Maybe copy controls from popular games (GTA V) or flight simulators (MS-FS 2020, XPlane, YSFlight, etc.)
It would be nice to have on screen controls too (as it's an Android app)
I liked the visuals, HUDs, GUIs and the menu system.

5
Support / Re: jPCT-AE vs. jPCT (and the future of jPCT-AE)
« on: March 30, 2022, 05:54:47 pm »
Thanks for the replies... (I haven't been actively programming lately due to broken PC so excuse me for the late reply)

Quote
Is https://www.jpct.net/jpct-ae/doc/com/threed/jpct/World.html#setDefaultThread-java.lang.Thread- useful in some scenarios?

Not very likely. jPCT-AE sets is automatically to the main thread (i.e. the thread that created the world instance). If it's set to the wrong thread, all that happens is that more garbage objects will be created. There's no performance benefit in setting it to some other thread except if that thread is the actual thread that does the calculations.
Okay, I guess it is best then to leave it untouched...

Hi

About multithreading; I am using threading in this manner..

Thread 1: Calculating half of everything that is not graphics, but only the parts of graphics for flagging if objects should be visible or not.
Thread 2: Calculating the other half of everything that is not graphics, but only the parts of graphics for flagging if objects should be visible or not.
Thread 3: Checking what 3D objects that are flagged to be loaded and do that with the Loader.
JPCT-AE: The jpct´s graphics thread, displaying all the objects that should be visible, if flagged that they should not be visible it removes them.
Firebase: The Firebase real time database thread, storing and loading from the database.

I am creating a big multiplayer space game with over 200 planets that you can dock at and walk around, build stuff, dimensions that brings the players to mazes where they can find things they´ll need and hide things by building blocks around them. This method was the only way to use several threads, and it even runs on crappy phones too because of the way things are loaded, unloaded and removed from visible depending on where the player is in the world.

More multithreading than this is not needed, it will only complex things for you and might even slow things down.
That is my point of view.
Hmmm okay, interesting... so far I have only used multi-threading for texture loading (as it can be very blocking process on the GL-thread from my experience).
I believe it would be good to try using multi-threading more to offload processing but I'm afraid to break something, to have dead-locks, and to get other synchronization issues so that has made me hold back a little.

Thanks both for the replies still

6
Support / Re: About jpct-ae loading Problems with FBX format files
« on: March 30, 2022, 05:46:45 pm »
You can import an FBX file in Blender and export it to OBJ ;)

7
Support / Re: jPCT-AE vs. jPCT (and the future of jPCT-AE)
« on: January 22, 2022, 03:52:58 pm »
That's quite a lot to answer... ;) I'll do my very best...
Hehe... Thanks for answering, and so extensively too!

On a general note: The basic "design" of jPCT is almost 23 years old now. That alone explains a lot and I'll refer to this as an excuse explaination in the latter. This will become more clear once I manage to reply to the "jPCT origins thread"...
I never knew jPCT was that old... That's nearly my age :o
Getting more curious about the ' jPCT origins thread' now

Quote
1. Why can a Light object only be assigned to one World? As far as I know you can only add a Light to the World using the constructor of Light.
That's because I was stupid/lazy when doing the light implemention in the early days of jPCT. I simply coded the lights to be part of the world in a way that they are bound to it, because of...reasons...I guess. I didn't change that, when I released jPCT to the public after doing some cleanup work. However, I then added the Light class to hide this to a degree. See the documention of the Light class for desktop jPCT, which also tries to explain this. When converting jPCT to jPCT-AE, I kept this behaviour for compatibility reasons, but I tried to hide the actual implementation completely by solely relying on the Light class and removing all light related methods from World...except for removeAllLights(). I kept this, because I had to give the user at least some way to remove the lights from a World instance that he actually never attached to it directly. Yes, this all sucks...but that's the way it is now and it will stay this way.
Hmmm, okay... Is there a possibility to still add some more control for lighting?
I believe there's variables/attributes passed to the shader that are more or less unused or unchangable?
At least, I haven't found a way to change the specularColor for instance.

Quote
2. Is there any beneficial multi-threading capabilities jPCT-AE has or could have?
No, there isn't. OpenGL is a state machine. It can't handle multiple threads. You could do the processing in multiple threads, of course. But in almost all cases, it's not worth it for what you do with such an engine like jPCT. The desktop version supports multiple threads for the software renderer (which really helps a lot) and for the processing (via the WorldProcessor), which isn't worth it expect in some rare and almost artifical cases. Also, jPCT isn't thread-safe and jPCT-AE is even less thread-safe. The reason for the latter is, again, history. When I started jPCT-AE in 2008, Android used the Dalvik-VM on single core processors running at around 800Mhz. The VM had no JIT, a maximum ram size of 24mb and only a stop-the-world-garbage collector. Which was very slow as well. That meant that garbage collection took somewhere between 80 and 500ms once triggered. And that meant, that the usual game loop when using jPCT-AE wasn't allowed to produce any garbage at all, or the application would have suffered greatly from stuttering. To achieve that, I added some static "caches" if you will call them that. Variables and instance pools, that could be reused instead of created/destroyed each time you called the method. But this, of course, limits the ability to multi-thread even more.
If you abstract your game logic/entities from jPCT's objects and couple jPCT loosly to render your entities, then you have more options to multi-thread things on your own. I did this for the grass rendering in Naroth...turns out, it wasn't worth it, so I disabled it ;)
Hmmm, okay... fair enough.
Is https://www.jpct.net/jpct-ae/doc/com/threed/jpct/World.html#setDefaultThread-java.lang.Thread- useful in some scenarios?

Quote
3. Will ReflectionHelper be ported to jPCT-AE?
Not very likely. OpenGL ES doesn't support some functions (clipping plane related IIRC) that this implementation is using in desktop jPCT. You would have to do in a shader yourself but that would make the default shaders overly complicated, so I didn't do that. It's just a helper class anyway. It's not part of the core.
Hmmm, okay... I thought because the ShadowHelper was ported, maybe it was possible with the ReflectionHelper as well...
I might try something myself if I find the time for it...

Quote
4. Will BloomGLProcessor be ported to jPCT-AE?
Again, no. This thing is more of a hack anyway. It requires huge amounts of fillrate, which still isn't there on mobile.
Okay, I guess there's other ways to create a bloom shader/post-processor.
I was thinking to render the scene (with lightsources only/or filtering the bright areas afterwards) to a lower-resolution RenderTexture.
Then blitting it additively to the scene with linear filtering (for some blur effect)... I'm not entirely sure if it's all possible like this but yeah...
Otherwise I'd need a one-pass/two-pass Gaussian filter or something...

Quote
5. Why can a VertexController only be assigned to a single mesh?
Because the GenericVertexController implementation stores some mesh related data on initialization.
Okay, I guess that makes sense.

Quote
6. Why does jPCT-AE use a static TextureManager instance?
Again, it's a design decision that I made over 20 years ago. However, I think it's still fine (unlike the lights...). I see it as a pool for textures that each class can easily access without the need to pass instances around. I fail to see the benefit of having multiple texture pools in an app.
Hmmm, I usually add textures with a renderer-ID as suffix in the texture-name to the texturemanager to seperature textures per renderer (so they don't get overriden).
I have only found it a bit more troublesome with imported Object3D's from model files with predefined texturenames (these might conflict/override with different renderers instances).
At the moment, I read the mat-files and change the file-names of the textures so they stay 'unique'...

Quote
7. Why does jPCT-AE still attempt to draw non-visible polygons?
Because it has to. It culls away objects on all six planes, but you can't cull single polygons that are part of a single mesh. OpenGL is most efficient when rendering large batches of polygons, not single ones. The per-polygon culling happens later on the GPU. That said, desktop jPCT culls single polygons when using the software renderer or the hybrid hardware rendering mode (i.e. the one without compiled objects), but both aren't feasible on mobile. I didn't port Portals, because it requires some preconditions that usually aren't met in most scenes and it greatly simplified the port to leave them out. Nobody ever used them anyway except me in one single demo application. Portals were all the rage when I started with jPCT, but given their limitations and the fact that we went from software to hardware rendering, their significance faded.
Hmmm, okay I guess portals aren't so necessary then...
What about meshes that are well outside of the fogging parameters (too far away), these are still 'visible' it seems...
Would it be better to clip the farPlane then or to manually set these 'out of range' Object3D's visibility to false?

Quote
8. Is there any other plans for the future of jPCT-AE?
I'll continue to support it, fix problems and maybe add some things if people need them, but I haven't got a big plan for it apart from that. The default lighting model will stay like it is. If you need more complex lighting, then write your own shaders. Naroth for example uses a lot of custom shaders for texture splatting, foilage, phong shading, dynamic recoloring of textures, parallax mapping in dungeons etc. I can't possibly cover all these things in a way that they will still work with the given lighting model.
I once looked into Vulkan, laughed and never looked at it again. It's completely low level. Don't get me wrong, I like my low level stuff as much as the next guy. After all, I'm still coding in assembly language for old 8-bit computers. But to support Vulkan, one would have to implement a new library of functions that would map what jPCT-AE needs to Vulkan calls. And I really don't see the point of this. Draw call performance isn't an issue for an app running in a VM on Android.
Regarding open source: I usually open source all of my stuff (https://github.com/EgonOlsen71/), but jPCT. Mainly because I don't feel comfortable without some major rewrite of some parts (like the lights... ;) ) on the one hand but I can't be bothered to do this on the other hand.
Okay, that seems fine. I guess I will write some default Phong shading shader or something at some point...
I took a look, it seems you're a lot into retro devices/development (such as for C64 or something); an OpenGL graphics library seems something completely different, however..? I mean compared to your other work which is open sourced...

Quote
9. Any idea what causes these crashes..?
No. I see similar crashes every now and then in my own developer console as well but I don't know what causes them. I've never experienced anything like this in all my testings on all of my devices...not once. I checked some code paths in the engine at least a dozen times without finding any issue, so I doubt that it's that. Might be driver problems or problems when an app returns from sleep or when a context change goes wrong...I really don't know, I'm just guessing widely here.
Hmmm, okay... I guess, I feel pretty clueless about these SIGSEGV errors... I don't know what causes it, nor when it happens nor what could possibly fix it.
What about the last stacktrace? That one is from Java (non-native), but it's out of my scope kinda I guess...

8
Support / jPCT-AE vs. jPCT (and the future of jPCT-AE)
« on: January 17, 2022, 06:14:21 pm »
Hello,

I'm back with some questions I had wondered about for quite some time but never really bothered to ask.
Maybe a few things could be suggestions for the future of jPCT-AE as well...
It's a long list (and I'm not necessarily in a rush/hurry for answers so please take your time...) but anyway, here goes:

1. Why can a Light object only be assigned to one World? As far as I know you can only add a Light to the World using the constructor of Light.
When you look further, World does have the option to remove all lights with World.removeAll() or World.removeAllLights().
But there is no World.addLight(Light light) or World.addLights(Light[] lights) option... ???
In one of my projects, I remember having had 2 Worlds with diffent fogging parameters but same Lights, where I had to declare the 'same' Lights twice.

2. Is there any beneficial multi-threading capabilities jPCT-AE has or could have?
I have tried World.setDefaultThread(...) for instance but I never really understood its purpose entirely in jPCT-AE...
I tried to set it to a "new Thread()" but the application only became slower I believe...
I am not entirely sure if jPCT-AE has any other beneficial multi-threading capabilities (I haven't really found so far)...
I believe OpenGL doesn't entirely allow it anyway. But maybe some non-OpenGL things that jPCT does before rendering could still be done using multi-threading..? Pre-processing or anything like that
I figured that since devices become much better at multi-threading, maybe it would be nice to have some multi-threading options.
I found something interesting in the jPCT documentation: https://www.jpct.net/doc/com/threed/jpct/threading/package-summary.html and https://www.jpct.net/doc/com/threed/jpct/WorldProcessor.html but I haven't found something similar for jPCT-AE.

3. Will ReflectionHelper be ported to jPCT-AE?
I am referring to: https://www.jpct.net/doc/com/threed/jpct/util/ReflectionHelper.html
I believe ShadowHelper has been ported to jPCT-AE at a later stage too but I thought ReflectionHelper would be interesting too.
For mirror-like surfaces I believe it would be nice to have.

4. Will BloomGLProcessor be ported to jPCT-AE?
Here, I am referring to: https://www.jpct.net/doc/com/threed/jpct/procs/BloomGLProcessor.html
I am not sure if it is heavy or something but I thought it would be interesting to have.

5. Why can a VertexController only be assigned to a single mesh?
When you try to apply the same VertexController to another mesh you will get an error like:
"java.lang.RuntimeException: [ 1639357199784 ] - ERROR: This instance has already been assigned to another Mesh!"
I thought that maybe it would work too if the same VertexController was applied to multiple meshes, but I guess not...

6. Why does jPCT-AE use a static TextureManager instance?
I thought it would have made more sense to make a TextureManager per renderer or something
I believe it would be possible to have both too (so even Textures loaded from other renderers are accessible for whatever reason you have...)
With having both I mean that you have a 'TextureManager' per renderer but also still the global static one.

7. Why does jPCT-AE still attempt to draw non-visible polygons?
I believe polygons that are not visible in the scene are still sent to the GPU to 'draw' while they won't really be drawn.
Examples:
- polygons out of the FOV of the camera (or it seems jPCT still processes these unless they have been manually set to Object3D.setVisibility(false).
- polygons out of max fogging distance range.
- also this is not available in jPCT-AE: https://www.jpct.net/doc/com/threed/jpct/Portals.html

8. Is there any other plans for the future of jPCT-AE?
Further development? (implement new techniques and such; better lighting (Phong), more control for lighting (specularity))
Optimizing? (speeding up/improving existing implementations, multi-threading, etc.)
New features? (support for OpenGL3+ (compute shaders or something) or Vulkan or something)
More future-proofing? (I believe some things in jPCT-AE have been made for when Android 2.2/2.3 was more popular; so maybe they need to be reconsidered; think of memory limitations, max. texture size, max. texture stages, Phong shading, loading newer 3D models (other/newer file types), etc.)
Open-sourcing? (on GitHub or something so people can contribute)
Porting from other graphics libraries or jPCT? (some features that are present in other graphics libraries or jPCT but missing in jPCT-AE)

9. Any idea what causes these crashes..?
Most of these are native crashes but they might still point to some clue in the stacktrace (as some refer to the Java code)
Code: [Select]
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.aeroshark333.artofearthify <<<

backtrace:
  #00  pc 000000000001706c  /vendor/lib64/libsrv_um.so
  #00  pc 00000000000cc808  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 000000000002dcc4  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 0000000000031fb0  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 000000000002c4c8  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 000000000002bf24  /vendor/lib64/egl/libGLESv2_mtk.so (glDrawElements+120)
  #00  pc 00000000000e7e1c  /system/lib64/libandroid_runtime.so (android_glDrawElements__IIILjava_nio_Buffer_2(_JNIEnv*, _jobject*, int, int, int, _jobject*)+276)
  #00  pc 00000000002d3504  /system/framework/arm64/boot-framework.oat (art_jni_trampoline+196)
  #00  pc 00000000020072fc  /memfd:/jit-cache (com.threed.jpct.GL20.glDrawElements+60)
  #00  pc 0000000002020fc0  /memfd:/jit-cache (com.threed.jpct.CompiledInstance.render+11664)
  #00  pc 000000000203cc88  /memfd:/jit-cache (com.threed.jpct.GLRenderer.drawVertexArray+2088)
  #00  pc 0000000002047390  /memfd:/jit-cache (com.threed.jpct.World.draw+704)
  #00  pc 000000000204a11c  /memfd:/jit-cache (com.threed.jpct.World.draw+60)
  #00  pc 0000000002018c28  /memfd:/jit-cache (com.aeroshark333.artofearthify.lw.ArtOfEarthify.onDrawFrame+9096)
  #00  pc 0000000000137334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
  #00  pc 00000000001460ac  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
  #00  pc 00000000002e3758  /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384)
  #00  pc 00000000002de7e4  /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+900)
  #00  pc 00000000005a8a8c  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtualQuick+596)
  #00  pc 0000000000135594  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual_quick+20)
  #00  pc 000000000022cd84  /data/app/com.aeroshark333.artofearthify-yaNv3ycyylpEX_4FbNxKmA==/oat/arm64/base.vdex (com.aeroshark333.artofearthify.lw.LiveWallpaperRenderer.onDrawFrame+4)
  #00  pc 00000000005a4364  /apex/com.android.runtime/lib64/libart.so (MterpInvokeInterface+1740)
  #00  pc 0000000000131a14  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_interface+20)
  #00  pc 00000000002f475c  /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.guardedRun+2068)
  #00  pc 00000000005a4f00  /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+1168)
  #00  pc 0000000000131914  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20)
  #00  pc 00000000002f5152  /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.run+114)
  #00  pc 00000000002b4088  /apex/com.android.runtime/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.13310094408155829753)+240)
  #00  pc 0000000000593d00  /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1024)
  #00  pc 0000000000140468  /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88)
  #00  pc 0000000000137334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
  #00  pc 00000000001460ac  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
  #00  pc 00000000004b2da0  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104)
  #00  pc 00000000004b3e50  /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416)
  #00  pc 00000000004f43a8  /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176)
  #00  pc 00000000000e5614  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
  #00  pc 0000000000085458  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

Code: [Select]
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.aeroshark333.artofearthify <<<

backtrace:
  #00  pc 000000000001706c  /vendor/lib64/libsrv_um.so
  #00  pc 00000000000ce0d8  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 000000000002e2cc  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 000000000003264c  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 000000000002ca84  /vendor/lib64/egl/libGLESv2_mtk.so
  #00  pc 000000000002c4dc  /vendor/lib64/egl/libGLESv2_mtk.so (glDrawElements+120)
  #00  pc 0000000000079d38  /vendor/lib64/egl/libGLES_meow.so
  #00  pc 00000000000e6cac  /system/lib64/libandroid_runtime.so (android_glDrawElements__IIILjava_nio_Buffer_2(_JNIEnv*, _jobject*, int, int, int, _jobject*)+276)
  #00  pc 00000000002ca994  /system/framework/arm64/boot-framework.oat (art_jni_trampoline+196)
  #00  pc 0000000000088d88  /data/app/com.aeroshark333.artofearthify-qsfIgfJfssMx7-jwHqMHFA==/oat/arm64/base.odex (com.threed.jpct.GL20.glDrawElements+72)
  #00  pc 0000000000064158  /data/app/com.aeroshark333.artofearthify-qsfIgfJfssMx7-jwHqMHFA==/oat/arm64/base.odex (com.threed.jpct.CompiledInstance.render+12008)
  #00  pc 000000000006cf88  /data/app/com.aeroshark333.artofearthify-qsfIgfJfssMx7-jwHqMHFA==/oat/arm64/base.odex (com.threed.jpct.GLRenderer.drawVertexArray+2264)
  #00  pc 000000000007f18c  /data/app/com.aeroshark333.artofearthify-qsfIgfJfssMx7-jwHqMHFA==/oat/arm64/base.odex (com.threed.jpct.World.draw+844)
  #00  pc 000000000007fc10  /data/app/com.aeroshark333.artofearthify-qsfIgfJfssMx7-jwHqMHFA==/oat/arm64/base.odex (com.threed.jpct.World.draw+64)
  #00  pc 0000000000051178  /data/app/com.aeroshark333.artofearthify-qsfIgfJfssMx7-jwHqMHFA==/oat/arm64/base.odex (com.aeroshark333.artofearthify.lw.ArtOfEarthify.onDrawFrame+9240)
  #00  pc 0000000000056930  /data/app/com.aeroshark333.artofearthify-qsfIgfJfssMx7-jwHqMHFA==/oat/arm64/base.odex (com.aeroshark333.artofearthify.lw.LiveWallpaperRenderer.onDrawFrame+64)
  #00  pc 0000000002006824  /memfd:/jit-cache (android.opengl.GLSurfaceView$GLThread.guardedRun+6852)
  #00  pc 0000000000137334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
  #00  pc 00000000001460ac  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
  #00  pc 00000000002e3c38  /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384)
  #00  pc 00000000002decc4  /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+900)
  #00  pc 00000000005a4a40  /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+400)
  #00  pc 0000000000131914  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20)
  #00  pc 00000000002d79b6  /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.run+114)
  #00  pc 00000000002b4568  /apex/com.android.runtime/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.14186875840613789731)+240)
  #00  pc 0000000000593b40  /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1024)
  #00  pc 0000000000140468  /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88)
  #00  pc 0000000000137334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
  #00  pc 00000000001460ac  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
  #00  pc 00000000004b2898  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104)
  #00  pc 00000000004b3948  /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416)
  #00  pc 00000000004f3e98  /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176)
  #00  pc 00000000000e2364  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
  #00  pc 0000000000083d98  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

Code: [Select]
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.aeroshark333.artofearthify <<<

backtrace:
  #00  pc 0000000000019164  /system/lib/libc.so (memcpy+96)
  #00  pc 00000000000b37db  /vendor/lib/libgsl.so (ioctl_kgsl_sharedmem_write+114)
  #00  pc 00000000000f99b3  /vendor/lib/egl/libRBGLESv2_adreno.so (rb_vbo_cache_vertex_attrib+278)
  #00  pc 000000000006a97d  /vendor/lib/egl/libRBGLESv2_adreno.so (cache_vertex_array+1396)
  #00  pc 000000000006b643  /vendor/lib/egl/libRBGLESv2_adreno.so (cache_vertex_elements+3162)
  #00  pc 0000000000074bfd  /vendor/lib/egl/libRBGLESv2_adreno.so (core_glDrawElementsInstancedXXX+984)
  #00  pc 00000000000752bd  /vendor/lib/egl/libRBGLESv2_adreno.so (core_glDrawElements+20)
  #00  pc 0000000000052a51  /vendor/lib/egl/libRBGLESv2_adreno.so (glDrawElements+72)
  #00  pc 0000000000d6352b  /system/framework/arm/boot-framework.oat (offset 0x637000) (android.opengl.GLES10.glClearColorx [DEDUPED]+122)
  #00  pc 0000000000012c37  /dev/ashmem/dalvik-jit-code-cache_12126_12126 (deleted)

Code: [Select]
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.aeroshark333.artofearthify <<<

backtrace:
  #00  pc 0000000000018da0  /system/lib/libc.so (memcpy+100)
  #00  pc 0000000000093e03  /vendor/lib/egl/libGLESv2_mtk.so
  #00  pc 000000000001c137  /vendor/lib/egl/libGLESv2_mtk.so
  #00  pc 000000000001f1c7  /vendor/lib/egl/libGLESv2_mtk.so
  #00  pc 000000000001af75  /vendor/lib/egl/libGLESv2_mtk.so
  #00  pc 000000000001aabf  /vendor/lib/egl/libGLESv2_mtk.so (glDrawElements+54)
  #00  pc 000000000008441d  /system/lib/libandroid_runtime.so (android_glDrawElements__IIILjava_nio_Buffer_2(_JNIEnv*, _jobject*, int, int, int, _jobject*)+116)
  #00  pc 0000000000a09d75  /system/framework/arm/boot-framework.oat (offset 0x5ea000) (android.graphics.Color.nativeRGBToHSV [DEDUPED]+140)
  #00  pc 00000000000102f7  /dev/ashmem/dalvik-jit-code-cache (deleted)

Code: [Select]
java.lang.RuntimeException:
  at com.threed.jpct.Logger.log (Logger.java:206)
  at com.threed.jpct.GL20.checkFrameBufferObject (GL20.java:2100)
  at com.threed.jpct.GL20.setRenderTarget (GL20.java:2060)
  at com.threed.jpct.GLRenderer.setRenderTarget (GLRenderer.java:2179)
  at com.threed.jpct.FrameBuffer.setRenderTarget (FrameBuffer.java:287)
  at com.threed.jpct.FrameBuffer.setRenderTarget (FrameBuffer.java:249)
  at com.aeroshark333.blackhole3d.BlackHole3D.onDrawFrame (BlackHole3D.java:415)
  at com.aeroshark333.blackhole3d.livewallpaper.LiveWallpaperRenderer.onDrawFrame (LiveWallpaperRenderer.java:83)
  at android.opengl.GLSurfaceView$GLThread.guardedRun (GLSurfaceView.java:1591)
  at android.opengl.GLSurfaceView$GLThread.run (GLSurfaceView.java:1286)

I guess this is all I have to ask for now. Looking forward to your reply!

Cheers,
Abiram

9
Support / Re: Lighting on merged Object3Ds
« on: January 09, 2022, 01:57:47 pm »
Happy new year to you as well.

I had a look and I think that I've identified the issue. Can you please give this jar a try: https://jpct.de/download/beta/jpct_ae.jar ?
Works like a charm! :D

It fixed both the test case and the original rendering bug.
Thanks for the support (as always) :)

10
Support / Re: Lighting on merged Object3Ds
« on: January 06, 2022, 10:28:16 am »
Thanks for looking into it.

I believe compiler might be smart enough in some cases for the pow(x,y) function:
If you manually set y = 0.0, then the compiler probably gets rid of the pow(x,y) altogether and replaces it with a constant value.
If you set y = shininess, then the compiler cannot get rid of the pow(x,y) evaluation as it's dependent on a non-constant value (which could potentially change during runtime).
I believe the compiler-level pow() evaluation goes well or something, but the runtime-level pow() does not..?
I don't know, I'm not an expert on this but this is what I'm guessing :p
Maybe interesting: https://www.shadertoy.com/view/slKSWc

Little late but best wishes for the New Year! :)

11
Support / Re: Lighting on merged Object3Ds
« on: January 06, 2022, 04:02:58 am »
To be sure: Which device are you using that has this issue? As said, I tried it on a S7 and it works fine. It also works fine in the emulator. I fails on the LG G4.
The videos I sent before are made from an emulator; but I get the same results on my phone (Samsung Galaxy Note 9)

Ok, it's cleary some kind of shader bug. Not in the shader code itself but in the shader compiler of some devices. Or in the GPU...I don't know...
I went through some debugging myself...
I believe it might not be a shader bug after all (or maybe a solvable one still..?)
It appears as if the shininess value(s) is/are not transferred properly to the merged Object3D for some reason..?  ???

According to my IDE (Android Studio in debugging mode) the shininess value sometimes is 0.0 instead of 1.0
I want to stress the "sometimes" above here... it seems that for the merged Object3D, it is sometimes 0.0 and sometimes 1.0..?
I assume it is for different parts of the merged Object3D that it is sometimes 0.0 and sometimes 1.0

I'm tracking the shininess value from here:
GLES20.java [line 282~284 according to IDE's decompiler]
Code: [Select]
if (newShader.shininessHandle != 0) {
            GLES20.glUniform1f(newShader.shininessHandle, this.shininess);
        }

Expectation:
Expected shininess: 1.0
Expected spec_color: vec3(0.0)
Expected result: 0.0*x^1.0 = 0.0*x = 0.0

Experiment:
Measured shininess: 0.0
(Expected) spec_color: vec3(0.0)
Expected result: 0.0*x^0.0 = 0.0*1.0 = 0.0

A zero vector multiplied by some value (in this case the result of the pow()-calculation) should be...a zero vector. Because, as we all know, 0 times something is still 0. Turns out, that some devices beg to differ.
I would have expected this too even with the shininess that seems to fluctuate...

Clearly, specPart has to be a zero vector as well in all cases. But it's not. shininess on the other hand is set to 1. However, it too seems to fluctuate in value as well while the shader is executing, which is actually impossible. It's supposed to stay fixed once the shader is executed for a given mesh, hence the name "uniform". Or maybe it doesn't fluctuate but evaluating it in the shader goes wrong for the same reasons that 0 times something is something else rather than 0.
specPart should always be a zero vector... There seems to be some kind of shader bug there as I agree with the previous statement (0 times x is 0).
To me, it seems that the GPU/driver/OpenGL does not handle "pow(..., x) with x an uniform/non-constant equal to 0" in a shader well.
Though, it seems that this value of 0 is sort of unintented as shininess should be 1?
Therefore, the bug can be avoided by making sure the Java code doesn't supply a zero value I guess..? Or something...

From the OpenGL ES Shading Language sheet:
https://www.khronos.org/files/opengles_shading_language.pdf
[section 8.2, page 65]
Quote
genType pow (genType x, genType y)
Returns x raised to the y power, i.e., x^y
Results are undefined if x < 0.
Results are undefined if x = 0 and y <= 0.
I believe it might not be a shader bug after all since the shader might deal with "Results are undefined if x = 0 and y <= 0"
Though mathematically 0^0 should exist still...
And when you try pow(0.0, 0.0), it still does the multiplication correctly later and zeroes it out...  :o
But when you try pow(0.0, shininess), it breaks again...
What I think is that pow(0.0, 0.0) evaluates to 1.0 and pow(0.0, shininess) evaluates to 'undefined', although they are basically the same...
I guess the shader becomes unpredictable when dealing with 'undefined' values.
And I guess some devices are able to handle the 0.0 values in pow() well still and don't cause any visual bugs...

Are you by any chance already using your own shaders? I that case, we could just cut the specular part (if not used, that is) and call it a day. If not, it might be worth considering to do so.
I'm not using my own shaders (yet) but I might go that way (probably will be based of default shaders)...

I'm not sure what to do here.
I suggest the following solutions:
1. Make sure that a merged Object3D does not have 0 shininess values
2. Make sure that when the shininess value is altered, the Java code will only allow to pass shininess > 0 values. (excluding 0).
3. Make sure that the GLSL shader code can handle 0 shininess values by setting a minimal value. Replace "shininess" with "max(shininess, 0.00001)"
4. Make sure that the GLSL shader code can handle 0 shininess values by adding an offset. Replace "shininess" with "shininess+0.00001"
5. Make sure that the GLSL shader code can handle the first pow term properly. Replace "max(0.0" with "max(0.00001,"
I believe all these solutions would work but I currently ranked them from best to worse...
Personally, I'd only do both 1 and 2... I guess it is best to 'sanitize' the input variables; rather than to fix it in a later stage...

12
Support / Re: Lighting on merged Object3Ds
« on: January 04, 2022, 04:01:04 am »
I'm not sure if what's going on then, but then again, I'm not sure what the actual issue really is. The videos don't really make it clear to me. Can you create something that is more, well, obvious?
I'm not sure if this is any helpful but I enlarged the shapes..? Well... here goes:

Explanation:
If the sphere on the right is visible, then it will only render the merged Object3D.
If the sphere on the right is NOT visible, then it will only render the unmerged Object3Ds.
The merged Object3D consists of the unmerged Object3Ds.

Expectation:
Similar visuals for both scenarios

Result:
Not similar visuals; there seem to be lighting differences (bugs?)
Only when all of the unmerged Object3Ds use 1 texture (instead of 2 or 3 different textures), the bug seems to disappear.

Video proof:
https://imgur.com/a/Ox51NRL
https://imgur.com/a/Ag76Sml (different texture variations)

Test code (for reproducing):
Code: [Select]
final GLSurfaceView.Renderer testRenderer = new GLSurfaceView.Renderer() {
                private FrameBuffer frameBuffer;
                private World world;
                private Object3D master;
                private Object3D plane1;
                private Object3D plane2;
                private Object3D plane3;
                private Camera camera;
                private boolean offset = false;
                private Object3D mergeObj;

                @Override
                public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {

                }

                @Override
                public void onSurfaceChanged(GL10 gl10, int w, int h) {
                    Config.nearPlane = 1f;
                    Config.glIgnoreNearPlane = false;

                    frameBuffer = new FrameBuffer(w, h);
                    world = new World();
                    world.setAmbientLight(0, 0, 0);
                    Light l1 = new Light(world);
                    l1.setPosition(new SimpleVector(0f, 6f, 0f));
                    camera = world.getCamera();

                    final Texture sphereTexture = new Texture(2, 2, new RGBColor(75, 0, 0));
                    final Texture overlayTexture = new Texture(2, 2, new RGBColor(0, 0, 75));
                    final Texture planeTexture = new Texture(2, 2, new RGBColor(0, 75, 0));
                    final Texture whiteTexture = new Texture(2,2, new RGBColor(255,255,255));

                    final TextureManager textureManager = TextureManager.getInstance();
                    textureManager.addTexture("tex0", sphereTexture);
                    textureManager.addTexture("tex1", overlayTexture);
                    textureManager.addTexture("tex2", planeTexture);
                    textureManager.addTexture("tex3", whiteTexture);

                    //master = Object3D.createDummyObj();

                    plane1 = new Object3D(4);
                    plane2 = new Object3D(8);
                    plane3 = new Object3D(8);

                    master = ExtendedPrimitives.createSphere(3.0f,60);
                    master.setTexture("tex3");

                    plane1.addTriangle(new SimpleVector(-5.55, -0.941941941, -4.5), 0.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 4.5), 0.0f, 4.5f, new SimpleVector(5.55, -0.941941941, -4.5), 4.5f, 0.0f);
                    plane1.addTriangle(new SimpleVector(5.55, -0.941941941, 4.5), 4.5f, 4.5f, new SimpleVector(5.55, -0.941941941, -4.5), 4.5f, 0.0f, new SimpleVector(-5.55, -0.941941941, 4.5), 0.0f, 4.5f);
                    //roadMaster.setAdditionalColor(100, 100, 100);

                    //plane1.setAdditionalColor(100, 100, 100);
                    //plane1.compile(false, true);
                    //plane1.strip();
                    //plane1.build();
                    plane1.setTexture("tex0");

                    plane2.addTriangle(new SimpleVector(-6.6, -0.9, -4.52), 0.5f, 0.0f, new SimpleVector(-6.6, -0.9, 4.52), 0.5f, 4.5f, new SimpleVector(-5.55, -0.9, -4.52), 4.5f, 0.0f);
                    plane2.addTriangle(new SimpleVector(-5.55, -0.9, 4.52), 4.5f, 4.5f, new SimpleVector(-5.55, -0.9, -4.52), 4.5f, 0.0f, new SimpleVector(-6.6, -0.9, 4.52), 0.5f, 4.5f);
                    plane2.addTriangle(new SimpleVector(5.55, -0.9, -4.52), 0.0f, 0.0f, new SimpleVector(5.55, -0.9, 4.52), 0.0f, 4.5f, new SimpleVector(6.6, -0.9, -4.52), 0.5f, 0.0f);
                    plane2.addTriangle(new SimpleVector(6.6, -0.9, 4.52), 0.5f, 4.5f, new SimpleVector(6.6, -0.9, -4.52), 0.5f, 0.0f, new SimpleVector(5.55, -0.9, 4.52), 0.0f, 4.5f);

                    //plane2.setAdditionalColor(100, 100, 100);
                    //plane2.compile(false, true);
                    //plane2.strip();
                    //plane2.build();
                    plane2.setTexture("tex1");

                    float heightMultiplier = 333f;
                    float lastHeightLeft = 0.03f;
                    float newHeightLeft = 0.024f;
                    float newHeightRight = 0.012f;
                    float lastHeightRight = 0.01f;

                    // base

                    //plane3.setAdditionalColor(100, 100, 100);
                    plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -4.52), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 4.52), 0.5f, 4.5f, new SimpleVector(-6.6f, -0.941941941, -4.52), 4.5f, 0.0f);
                    plane3.addTriangle(new SimpleVector(-6.6f, -0.941941941, 4.52), 4.5f, 4.5f, new SimpleVector(-6.6f, -0.941941941, -4.52), 4.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 4.52), 0.5f, 4.5f);
                    plane3.addTriangle(new SimpleVector(6.6f, -0.941941941, -4.52), 0.0f, 0.0f, new SimpleVector(6.6f, -0.941941941, 4.52), 0.0f, 4.5f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -4.52), 0.5f, 0.0f);
                    plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 4.52), 0.5f, 4.5f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -4.52), 0.5f, 0.0f, new SimpleVector(6.6f, -0.941941941, 4.52), 0.0f, 4.5f);
                    plane3.setTexture("tex2");
                    //plane3.build();

                    boolean merge = false;

                    if (merge) {
                        mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        //mergeObj.setAdditionalColor(100, 100, 100);
                        mergeObj.build();
                        mergeObj.compile(false, true);
                        mergeObj.strip();
                        world.addObject(mergeObj);
                    } else {
                        world.addObject(plane1);
                        world.addObject(plane2);
                        world.addObject(plane3);

                        mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        world.addObject(mergeObj);
                        //mergeObj.setAdditionalColor(100, 100, 100);
                        if(offset) {
                            mergeObj.translate(0, 0, 6f);
                            plane1.translate(0, 0, -6f);
                            plane2.translate(0, 0, -6f);
                            plane3.translate(0, 0, -6f);
                        }else{
                            mergeObj.translate(0, 0, 6f);
                            plane1.translate(0, 0, 6f);
                            plane2.translate(0, 0, 6f);
                            plane3.translate(0, 0, 6f);
                            world.addObject(master);
                            master.translate(0,6f,-6f);
                        }
                        mergeObj.build();
                    }
                }

                @Override
                public void onDrawFrame(GL10 gl10) {
                    frameBuffer.clear();
                    final float maxDistance = 105f;
                    if(!offset){
                        if(Math.cos(world.getFrameCounter() * 0.03f)<0.0f){
                            plane3.setVisibility(false);
                            plane2.setVisibility(false);
                            plane1.setVisibility(false);
                            mergeObj.setVisibility(true);
                            master.setVisibility(true);
                        }else{
                            plane3.setVisibility(true);
                            plane2.setVisibility(true);
                            plane1.setVisibility(true);
                            mergeObj.setVisibility(false);
                            master.setVisibility(false);
                        }
                    }
                    camera.setPosition(-(0.5f * ((float) Math.abs(Math.cos(world.getFrameCounter() * 0.03f))) + 0.25f) * maxDistance, 30f, 0f);
                    camera.lookAt(new SimpleVector(0, 6f, 0f));
                    world.renderScene(frameBuffer);
                    world.draw(frameBuffer);
                    frameBuffer.display();
                }
            };

            // Attach to some GLSurfaceView...
            viewer.setRenderer(testRenderer);

13
Support / Re: Lighting on merged Object3Ds
« on: December 28, 2021, 01:33:08 am »
Have you tried to create larger textures? Maybe it's a rendering glitch caused by the small size and mip-mapping somehow?
I tried:
Code: [Select]
final Texture sphereTexture = new Texture(2048, 2048, new RGBColor(75, 0, 0));
                    final Texture overlayTexture = new Texture(2048, 2048, new RGBColor(0, 0, 75));
                    final Texture planeTexture = new Texture(2048, 2048, new RGBColor(0, 75, 0));

                    sphereTexture.setMipmap(false);
                    overlayTexture.setMipmap(false);
                    planeTexture.setMipmap(false);
Both true and false for mip-mapping. Seems to behave as before.

14
Support / Re: Lighting on merged Object3Ds
« on: December 14, 2021, 08:38:00 pm »
I changed the code to your suggestions (see below):

Here are the animations:
https://imgur.com/a/Jk8zt2g
https://imgur.com/a/Zwxem7I

Code:
Code: [Select]
final GLSurfaceView.Renderer testRenderer = new GLSurfaceView.Renderer() {
                private FrameBuffer frameBuffer;
                private World world;
                private Object3D master;
                private Object3D plane1;
                private Object3D plane2;
                private Object3D plane3;
                private Camera camera;

                @Override
                public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {

                }

                @Override
                public void onSurfaceChanged(GL10 gl10, int w, int h) {
                    Config.nearPlane = 1f;
                    Config.glIgnoreNearPlane = false;

                    frameBuffer = new FrameBuffer(w, h);
                    world = new World();
                    world.setAmbientLight(0, 0, 0);
                    Light l1 = new Light(world);
                    l1.setPosition(new SimpleVector(0f, 6f, 0f));
                    camera = world.getCamera();

                    final Texture sphereTexture = new Texture(2, 2, new RGBColor(75, 0, 0));
                    final Texture overlayTexture = new Texture(2, 2, new RGBColor(0, 0, 75));
                    final Texture planeTexture = new Texture(2, 2, new RGBColor(0, 75, 0));

                    final TextureManager textureManager = TextureManager.getInstance();
                    textureManager.addTexture("tex0", sphereTexture);
                    textureManager.addTexture("tex1", overlayTexture);
                    textureManager.addTexture("tex2", planeTexture);

                    master = Object3D.createDummyObj();

                    plane1 = new Object3D(4);
                    plane2 = new Object3D(8);
                    plane3 = new Object3D(8);

                    plane1.addTriangle(new SimpleVector(-5.55, -0.941941941, -1.0), 0.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f);
                    plane1.addTriangle(new SimpleVector(5.55, -0.941941941, 1.0), 1.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f);
                    //roadMaster.setAdditionalColor(100, 100, 100);

                    //plane1.setAdditionalColor(100, 100, 100);
                    //plane1.compile(false, true);
                    //plane1.strip();
                    //plane1.build();
                    plane1.setTexture("tex0");

                    plane2.addTriangle(new SimpleVector(-6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f);
                    plane2.addTriangle(new SimpleVector(-5.55, - 0.9, 1.02), 1.0f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f);
                    plane2.addTriangle(new SimpleVector(5.55, - 0.9, -1.02), 0.0f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f);
                    plane2.addTriangle(new SimpleVector(6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f);

                    //plane2.setAdditionalColor(100, 100, 100);
                    //plane2.compile(false, true);
                    //plane2.strip();
                    //plane2.build();
                    plane2.setTexture("tex1");

                    float heightMultiplier = 333f;
                    float lastHeightLeft = 0.03f;
                    float newHeightLeft = 0.024f;
                    float newHeightRight = 0.012f;
                    float lastHeightRight = 0.01f;

                    // base

                    //plane3.setAdditionalColor(100, 100, 100);
                    plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f);
                    plane3.addTriangle(new SimpleVector(-6.6f, -0.941941941, 1.02), 1.0f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f);
                    plane3.addTriangle(new SimpleVector(6.6f, -0.941941941, -1.02), 0.0f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f);
                    plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f);
                    plane3.setTexture("tex2");
                    //plane3.build();

                    boolean merge = false;

                    if(merge){
                        Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        //mergeObj.setAdditionalColor(100, 100, 100);
                        mergeObj.build();
                        mergeObj.compile(false, true);
                        mergeObj.strip();
                        world.addObject( mergeObj);
                    }else {
                        world.addObject(plane1);
                        world.addObject(plane2);
                        world.addObject(plane3);

                        Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        world.addObject( mergeObj);
                        //mergeObj.setAdditionalColor(100, 100, 100);
                        mergeObj.translate(0,0,3f);
                        plane1.translate(0,0,-3f);
                        plane2.translate(0,0,-3f);
                        plane3.translate(0,0,-3f);
                    }
                }

                @Override
                public void onDrawFrame(GL10 gl10) {
                    frameBuffer.clear();
                    final float maxDistance = 150f;
                    camera.setPosition(-(0.5f * ((float) Math.abs(Math.cos(world.getFrameCounter() * 0.03f))) + 0.25f) * maxDistance, 30f, 0f);
                    camera.lookAt(new SimpleVector(0,4.5f,0));
                    world.renderScene(frameBuffer);
                    world.draw(frameBuffer);
                    frameBuffer.display();
                }
            };

            // Attach to some GLSurfaceView...
            viewer.setRenderer(testRenderer);

If I do:
Code: [Select]
plane2.setTexture("tex2");the problem disappears..?  ???

15
Support / Re: Lighting on merged Object3Ds
« on: December 12, 2021, 04:32:09 am »
Actually, if the normals have been calculated (or loaded from file with Config.useNormalsFromOBJ=true) already before merging, they won't be recalculated after the merge when you call build on the merged object. I'm not sure if your issue is related to merging at all, though. I rather think it's caused by normal vectors that aren't calculated in a why that fits your scene. Does the file from which these objects come includes normals? In that case, you could try the config switch mentioned above.
I'm not using models from files, but I create them using Object3D#addTriangle (as they are simple planes sort of...)
I don't think the Config switch would do anything for this...

I was able to create a test case, however... (it doesn't look amazing but it shows the problem I guess...)
Code: [Select]
final GLSurfaceView.Renderer testRenderer = new GLSurfaceView.Renderer() {
                private FrameBuffer frameBuffer;
                private World world;
                private Object3D master;
                private Object3D plane1;
                private Object3D plane2;
                private Object3D plane3;
                private Camera camera;

                @Override
                public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {

                }

                @Override
                public void onSurfaceChanged(GL10 gl10, int w, int h) {
                    Config.nearPlane = 1f;
                    Config.glIgnoreNearPlane = false;

                    frameBuffer = new FrameBuffer(w, h);
                    world = new World();
                    world.setAmbientLight(0, 0, 0);
                    Light l1 = new Light(world);
                    l1.setPosition(new SimpleVector(0f, 6f, 0f));
                    camera = world.getCamera();

                    final Texture sphereTexture = new Texture(2, 2, new RGBColor(75, 0, 0));
                    final Texture overlayTexture = new Texture(2, 2, new RGBColor(0, 0, 75));
                    final Texture planeTexture = new Texture(2, 2, new RGBColor(0, 75, 0));

                    final TextureManager textureManager = TextureManager.getInstance();
                    textureManager.addTexture("tex0", sphereTexture);
                    textureManager.addTexture("tex1", overlayTexture);
                    textureManager.addTexture("tex2", planeTexture);

                    master = Object3D.createDummyObj();

                    plane1 = new Object3D(4);
                    plane2 = new Object3D(8);
                    plane3 = new Object3D(8);

                    plane1.addTriangle(new SimpleVector(-5.55, -0.941941941, -1.0), 0.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f);
                    plane1.addTriangle(new SimpleVector(5.55, -0.941941941, 1.0), 1.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f);
                    //roadMaster.setAdditionalColor(100, 100, 100);

                    plane1.setAdditionalColor(100, 100, 100);
                    plane1.compile(false, true);
                    plane1.strip();
                    plane1.build();
                    plane1.setTexture("tex0");

                    plane2.addTriangle(new SimpleVector(-6.6, -0.939, -1.02), 0.5f, 0.0f, new SimpleVector(-6.6, -0.939, 1.02), 0.5f, 1.0f, new SimpleVector(-5.55, -0.941941941, -1.02), 1.0f, 0.0f);
                    plane2.addTriangle(new SimpleVector(-5.55, -0.941941941, 1.02), 1.0f, 1.0f, new SimpleVector(-5.55, -0.941941941, -1.02), 1.0f, 0.0f, new SimpleVector(-6.6, -0.939, 1.02), 0.5f, 1.0f);
                    plane2.addTriangle(new SimpleVector(5.55, -0.941941941, -1.02), 0.0f, 0.0f, new SimpleVector(5.55, -0.941941941, 1.02), 0.0f, 1.0f, new SimpleVector(6.6, -0.939, -1.02), 0.5f, 0.0f);
                    plane2.addTriangle(new SimpleVector(6.6, -0.939, 1.02), 0.5f, 1.0f, new SimpleVector(6.6, -0.939, -1.02), 0.5f, 0.0f, new SimpleVector(5.55, -0.941941941, 1.02), 0.0f, 1.0f);

                    plane2.setAdditionalColor(100, 100, 100);
                    plane2.compile(false, true);
                    plane2.strip();
                    plane2.build();
                    plane2.setTexture("tex1");

                    float heightMultiplier = 333f;
                    float lastHeightLeft = 0.03f;
                    float newHeightLeft = 0.024f;
                    float newHeightRight = 0.012f;
                    float lastHeightRight = 0.01f;

                    // base

                    plane3.setAdditionalColor(100, 100, 100);
                    plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(-6.6f, -0.939, -1.02), 1.0f, 0.0f);
                    plane3.addTriangle(new SimpleVector(-6.6f, -0.939, 1.02), 1.0f, 1.0f, new SimpleVector(-6.6f, -0.939, -1.02), 1.0f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f);
                    plane3.addTriangle(new SimpleVector(6.6f, -0.939, -1.02), 0.0f, 0.0f, new SimpleVector(6.6f, -0.939, 1.02), 0.0f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f);
                    plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(6.6f, -0.939, 1.02), 0.0f, 1.0f);
                    plane3.setTexture("tex2");
                    plane3.build();

                    boolean merge = false;

                    if(merge){
                        Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        world.addObject( mergeObj);
                    }else {
                        world.addObject(plane1);
                        world.addObject(plane2);
                        world.addObject(plane3);

                        Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        world.addObject( mergeObj);
                        mergeObj.setSpecularLighting(false);
                        mergeObj.translate(0,0,3f);
                    }
                }

                @Override
                public void onDrawFrame(GL10 gl10) {
                    frameBuffer.clear();
                    final float maxDistance = 150f;
                    camera.setPosition(-(0.5f * ((float) Math.abs(Math.cos(world.getFrameCounter() * 0.03f))) + 0.25f) * maxDistance, 30f, 0f);
                    camera.lookAt(new SimpleVector(0,0,0));
                    world.renderScene(frameBuffer);
                    world.draw(frameBuffer);
                    frameBuffer.display();
                }
            };

            // Attach to some GLSurfaceView...
            viewer.setRenderer(testRenderer);

Results: https://imgur.com/a/KffOw9m (left = merged object, right = not merged objects)
The first two images show the same but at a slightly different camera distance/angle, and you can see that the green tile on the left object is slightly darker than the in the second image.
In the last image, you can see some shading pattern on the red and green on the left object.

These do share coordinates however... maybe that nullifies the build() effect...

EDIT:
Okay... apparently it still happens when the coordinates are NOT shared...
So now I don't understand why build() didn't work...

Code snippet for non-sharing coordinates (replace these lines in the test case...):
Code: [Select]
plane2.addTriangle(new SimpleVector(-6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f);
                    plane2.addTriangle(new SimpleVector(-5.55, - 0.9, 1.02), 1.0f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f);
                    plane2.addTriangle(new SimpleVector(5.55, - 0.9, -1.02), 0.0f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f);
                    plane2.addTriangle(new SimpleVector(6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f);

                    plane2.setAdditionalColor(100, 100, 100);
                    plane2.compile(false, true);
                    plane2.strip();
                    plane2.build();
                    plane2.setTexture("tex1");

                    float heightMultiplier = 333f;
                    float lastHeightLeft = 0.03f;
                    float newHeightLeft = 0.024f;
                    float newHeightRight = 0.012f;
                    float lastHeightRight = 0.01f;

                    // base

                    plane3.setAdditionalColor(100, 100, 100);
                    plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f);
                    plane3.addTriangle(new SimpleVector(-6.6f, -0.941941941, 1.02), 1.0f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f);
                    plane3.addTriangle(new SimpleVector(6.6f, -0.941941941, -1.02), 0.0f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f);
                    plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f);
                    plane3.setTexture("tex2");
                    plane3.build();

EDIT2: I forgot to set the additionalColor on the merged object... Just forget everything above...
Here is a test case without any additionalColor:
Code: [Select]
final GLSurfaceView.Renderer testRenderer = new GLSurfaceView.Renderer() {
                private FrameBuffer frameBuffer;
                private World world;
                private Object3D master;
                private Object3D plane1;
                private Object3D plane2;
                private Object3D plane3;
                private Camera camera;

                @Override
                public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {

                }

                @Override
                public void onSurfaceChanged(GL10 gl10, int w, int h) {
                    Config.nearPlane = 1f;
                    Config.glIgnoreNearPlane = false;

                    frameBuffer = new FrameBuffer(w, h);
                    world = new World();
                    world.setAmbientLight(0, 0, 0);
                    Light l1 = new Light(world);
                    l1.setPosition(new SimpleVector(0f, 6f, 0f));
                    camera = world.getCamera();

                    final Texture sphereTexture = new Texture(2, 2, new RGBColor(75, 0, 0));
                    final Texture overlayTexture = new Texture(2, 2, new RGBColor(0, 0, 75));
                    final Texture planeTexture = new Texture(2, 2, new RGBColor(0, 75, 0));

                    final TextureManager textureManager = TextureManager.getInstance();
                    textureManager.addTexture("tex0", sphereTexture);
                    textureManager.addTexture("tex1", overlayTexture);
                    textureManager.addTexture("tex2", planeTexture);

                    master = Object3D.createDummyObj();

                    plane1 = new Object3D(4);
                    plane2 = new Object3D(8);
                    plane3 = new Object3D(8);

                    plane1.addTriangle(new SimpleVector(-5.55, -0.941941941, -1.0), 0.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f);
                    plane1.addTriangle(new SimpleVector(5.55, -0.941941941, 1.0), 1.0f, 1.0f, new SimpleVector(5.55, -0.941941941, -1.0), 1.0f, 0.0f, new SimpleVector(-5.55, -0.941941941, 1.0), 0.0f, 1.0f);
                    //roadMaster.setAdditionalColor(100, 100, 100);

                    //plane1.setAdditionalColor(100, 100, 100);
                    plane1.compile(false, true);
                    plane1.strip();
                    plane1.build();
                    plane1.setTexture("tex0");

                    plane2.addTriangle(new SimpleVector(-6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f);
                    plane2.addTriangle(new SimpleVector(-5.55, - 0.9, 1.02), 1.0f, 1.0f, new SimpleVector(-5.55, - 0.9, -1.02), 1.0f, 0.0f, new SimpleVector(-6.6, - 0.9, 1.02), 0.5f, 1.0f);
                    plane2.addTriangle(new SimpleVector(5.55, - 0.9, -1.02), 0.0f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f);
                    plane2.addTriangle(new SimpleVector(6.6, - 0.9, 1.02), 0.5f, 1.0f, new SimpleVector(6.6, - 0.9, -1.02), 0.5f, 0.0f, new SimpleVector(5.55, - 0.9, 1.02), 0.0f, 1.0f);

                    //plane2.setAdditionalColor(100, 100, 100);
                    plane2.compile(false, true);
                    plane2.strip();
                    plane2.build();
                    plane2.setTexture("tex1");

                    float heightMultiplier = 333f;
                    float lastHeightLeft = 0.03f;
                    float newHeightLeft = 0.024f;
                    float newHeightRight = 0.012f;
                    float lastHeightRight = 0.01f;

                    // base

                    //plane3.setAdditionalColor(100, 100, 100);
                    plane3.addTriangle(new SimpleVector(-11.4f, lastHeightLeft * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f);
                    plane3.addTriangle(new SimpleVector(-6.6f, -0.941941941, 1.02), 1.0f, 1.0f, new SimpleVector(-6.6f, -0.941941941, -1.02), 1.0f, 0.0f, new SimpleVector(-11.4f, newHeightLeft * heightMultiplier / 3f, 1.02), 0.5f, 1.0f);
                    plane3.addTriangle(new SimpleVector(6.6f, -0.941941941, -1.02), 0.0f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f);
                    plane3.addTriangle(new SimpleVector(11.4f, newHeightRight * heightMultiplier / 3f, 1.02), 0.5f, 1.0f, new SimpleVector(11.4f, lastHeightRight * heightMultiplier / 3f, -1.02), 0.5f, 0.0f, new SimpleVector(6.6f, -0.941941941, 1.02), 0.0f, 1.0f);
                    plane3.setTexture("tex2");
                    plane3.build();

                    boolean merge = false;

                    if(merge){
                        Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        //mergeObj.setAdditionalColor(100, 100, 100);
                        world.addObject( mergeObj);
                    }else {
                        world.addObject(plane1);
                        world.addObject(plane2);
                        world.addObject(plane3);

                        Object3D mergeObj = Object3D.mergeObjects(plane1, plane2);
                        mergeObj = Object3D.mergeObjects(plane3, mergeObj);
                        world.addObject( mergeObj);
                        //mergeObj.setAdditionalColor(100, 100, 100);
                        mergeObj.translate(0,0,3f);
                        plane1.translate(0,0,-3f);
                        plane2.translate(0,0,-3f);
                        plane3.translate(0,0,-3f);
                    }
                }

                @Override
                public void onDrawFrame(GL10 gl10) {
                    frameBuffer.clear();
                    final float maxDistance = 150f;
                    camera.setPosition(-(0.5f * ((float) Math.abs(Math.cos(world.getFrameCounter() * 0.03f))) + 0.25f) * maxDistance, 30f, 0f);
                    camera.lookAt(new SimpleVector(0,0,0));
                    world.renderScene(frameBuffer);
                    world.draw(frameBuffer);
                    frameBuffer.display();
                }
            };

            // Attach to some GLSurfaceView...
            viewer.setRenderer(testRenderer);

EDIT3: An animated image for the last test case: https://imgur.com/a/wR8MqgG
I believe I get similar-ish results but it gets brighter for me randomly but I guess it's a similar idea

EDIT4: I have a slight feeling this issue is there because the merged Object3D is multi-textured..? I'm not entirely sure...
The issue seems to disappear if it has 1 or 2 different textures only (but when you add the third, the lighting seems to behave differently)

Pages: [1] 2 3 ... 21