I followed this tutorial in order to try and achieve multitexturing in LWJGL. But whenever I run my code, the second texture does not show up, or the first texture takes its place. Here is how I bind the textures:
ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB);
bindTexture(myTex);
glEnable(GL_TEXTURE_2D);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, EXTTextureEnvCombine.GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV,EXTTextureEnvCombine.GL_COMBINE_RGB_EXT, GL_REPLACE);
ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE1_ARB);
bindTexture(myTex2);
glEnable(GL_TEXTURE_2D);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, EXTTextureEnvCombine.GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, EXTTextureEnvCombine.GL_COMBINE_RGB_EXT, GL_INCR);
drawStuff();
myTex and myTex2 both Textures, drawStuff() is my function where I draw everything.
I use slick for loading the textures and such, here is my bindTexture function:
void bindTexture(Texture t) {
glBindTexture(GL_TEXTURE_2D, t.getTextureID());
}
In drawStuff() I have a custom "Face" class, and here is where I draw everything in there:
glBegin(GL_TRIANGLES);
glNormal3f(getNormal().x, getNormal().y, getNormal().z);
glNormal3f(norm1.x, norm1.y, norm1.z);
ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE0_ARB, t1.x, t1.y);
ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE1_ARB, t1.x, t1.y);
glVertex3f(p1.x, p1.y, p1.z);
glNormal3f(norm2.x, norm2.y, norm2.z);
ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE0_ARB, t2.x, t2.y);
ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE1_ARB, t2.x, t2.y);
glVertex3f(p2.x, p2.y, p2.z);
glNormal3f(norm3.x, norm3.y, norm3.z);
ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE0_ARB, t3.x, t3.y);
ARBMultitexture.glMultiTexCoord2fARB(ARBMultitexture.GL_TEXTURE1_ARB, t3.x, t3.y);
glVertex3f(p3.x, p3.y, p3.z);
glEnd();
Where t1, t2, t3, norm1, norm2, norm3, p1, p2, p3 are all instances of a 3D vector class I made (I just keep a 0 in the z component of t1, t2, and t3). The vertex and fragment shader source is exactly the same as in the aforementioned tutorial.
All the code was working just fine with plain old textures. Any ideas on how I could make this work? Or possibly a better tutorial that is easy to follow when using LWJGL?
I strongly recommend you to learn from these tutorials how to use modern OpenGL with LWJGL .?If you take a look at the examples in afore mentioned link you will find your ways.I don't know how it works in fixed pipeline but using modern one it's just a matter of plugging several textures into texture targets in fragment shaders and sample those blending texels as you wish.
Related
i want to render model via JPCT-AE and use the ARToolkit to realizing AR Application.
so , i inject the code as below into the ARToolkit Project:
Matrix projMatrix = new Matrix();
projMatrix.setDump(ARNativeActivity.getProjectM());
projMatrix.transformToGL();
SimpleVector translation = projMatrix.getTranslation();
SimpleVector dir = projMatrix.getZAxis();
SimpleVector up = projMatrix.getYAxis();
cameraController.setPosition(translation);
cameraController.setOrientation(dir, up);
Matrix transformM = new Matrix();
transformM .setDump(ARNativeActivity.getTransformationM());
transformM .transformToGL();
model.clearTranslation();
model.translate(transformM .getTranslation());
dump.setRow(3,0.0f,0.0f,0.0f,1.0f);
model.clearRotation();
model.setRotationMatrix(transformM );
And then , the model can be render on the screen but always lie on the mark in the screen, ever i using model.rotateX/Y/Z( (float)Math.PI/2 );
Actually, the matrix output from the ARToolkit::ARNativeActivity.getTransformationMatrix() is correct, and then i split this 4*4Matrix into translation Matrix and Rotation Matrix and set into the model like this:
model.translate(transformM .getTranslation());
model.setRotationMatrix(transformM );
But still no work.
I would suggest to organize better your code, and work with matrices to separate the transformations to make to your model and the transformations to place the model in the marker.
What I suggest is:
First, use an additional matrix. It may be called modelMatrix, as it will store the transformation done to the model (scale, rotation and translation).
Then, declare all matrices outside this method (it is for performance reasons only, but is recommended), and on each frame simply setIdentity to them:
projMatrix.setIdentity();
transformM.setIdentity();
modelM.setIdentity();
later, make the model transformations on the modelM matrix. This transformations will apply to the model, after placed on the marker.
modelM.rotateZ((float) Math.toRadians(-angle+180));
modelM.translate(movementX, movementY, 0);
then, multiply the modelM matrix by the trasnformM (this means you get all the transformations done, and move and rotate them as the transformM describes, which in our case means that all the transformations done to the model are moved on top of the marker).
//now multiply trasnformationMat * modelMat
modelM.matMul(trasnformM);
And finally, apply the rotation and translation to your model:
model.setRotationMatrix(modelM);
model.setTranslationMatrix(modelM);
so the whole code would look as:
projMatrix.setIdentity();
projMatrix.setDump(ARNativeActivity.getProjectM());
projMatrix.transformToGL();
SimpleVector translation = projMatrix.getTranslation();
SimpleVector dir = projMatrix.getZAxis();
SimpleVector up = projMatrix.getYAxis();
cameraController.setPosition(translation);
cameraController.setOrientation(dir, up);
model.clearTranslation();
model.clearRotation();
transformM.setIdentity();
transformM .setDump(ARNativeActivity.getTransformationM());
transformM .transformToGL();
modelM.setIdentity()
//do whatever you want to your model
modelM.rotateZ((float)Math.toRadians(180));
modelM.matMul(transformM);
model.setRotationMatrix(modelM );
model.setTranslationMatrix(modelM);
I strongly reccomend to look at this tutorial about matrices and OpenGL, it is not about JPCT, but all concepts may apply also to there, and it is what I've used to place correctly models in markers with the ARSimple example as you may see in this blog entry I made.
Hope this helps!
I am using Leap Motion with processing utilising the Leap Motion for Processing library. (Leap Motion for Processing Lib)
I am however struggling to find a way to use scaleFactor as seen in Java Leap Motion documentation. (Java Api Docs)
I want to access this functionality in order to create a zoom function in my application when moving hands away from each other.
Any help would be much appreciated!
I took a quick glance through the processing library that you are using and it didn't look like it exposes the scale factor or other motion attributes from the Leap Motion Frame class (which is where you would get the scale factor for two-handed motion). That's not a library created or maintained by Leap Motion. I suspect your options are to use the Leap Motion Java library directly or to get the feature added to the processing library you are using.
It looks like you would add the feature you are trying to use in LeapMotion.java -- but you should discuss this with the developer who created the library.
I found a solution to this issue in the form of an alternative library. It means I will have to recode the gestures I have already created due to the libraries working differently but I do now have access to the Frame class which I was missing before.
This is the library I am now using... https://github.com/heuermh/leap-motion-processing
Below is a simple snippet of code which shows the scaleFactor working...
import com.leapmotion.leap.Controller;
import com.leapmotion.leap.Frame;
import com.leapmotion.leap.processing.LeapMotion;
LeapMotion leapMotion;
float zoomFactor = 0;
void setup()
{
size(16 * 50, 9 * 50);
background(20);
frameRate(30);
leapMotion = new LeapMotion(this);
}
void draw()
{
fill(20);
rect(0, 0, width, height);
fill(200);
rect(0, 0, (zoomFactor * 100), (zoomFactor * 100));
}
void onFrame(final Controller controller)
{
Frame frame = controller.frame();
Frame sinceFrame = controller.frame(25);
zoomFactor = frame.scaleFactor(sinceFrame);
println(zoomFactor);
}
I'm getting this when I load any .obj file with ObjLoader:
How it looks like in real:
How I'm loading it:
ModelInstance instance = new ModelInstance(model);
instance.transform.setToTranslation(-4, 0, 0);
instance.transform.mul(transform.setToRotation(Axis.X,(float)(Math.random()*360)));
Then in onCreate():
Gdx.gl.glClearDepthf(1.0f);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthFunc(GL20.GL_LESS);
Gdx.gl.glDepthRangef(0f, 1f);
Gdx.gl.glEnable(GL20.GL_TEXTURE_2D);
And in render():
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClearColor(.1f, .1f, .1f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
shader.begin(camera, instances.get(i).transform);
modelBatch.begin(camera);
if (environment !=null) modelBatch.render(instances.get(i), environment, shader);
else modelBatch.render(instances.get(i), shader);
modelBatch.end();
shader.end();
Clean source code here:
source code
SOLUTION:
1, probleme was with the .mtl file, copy pasted from the ship.mtl and rewrite
2, probleme was with the camera near, and far plane (0.1 and 1000 is the good)
3, probleme was with the obj file texture, because it flipped on the obj file, solution was to convert g3db with -f
When using the libgdx 3D api (ModelBatch and/or Shader), you should not change the opengl state outside the Shader class. So, enabling/disabling depth test etc. is useless and might result in unpredicted behavior.
You should not use obj files. Instead use fbx-conv and use the g3db or g3dj file format. Also, your model is missing the mtl file, causing the material not to be applied.
You are using your own shader, you should not have to call shader.end(), modelbatch does this for you.
I tried your model (without material obviously) and it renders correctly using the default shader.
Looks more like you've some problems with your normals here. I don't think it's a problem of wrong depth. Depending on your modelling program e.g. blender3D, you could try to recalculate your facenormals and export it again!
You may follow these steps on 3D Studio Max:
Select all your design with CTRL+A (If you use Windows)
Press ALT+G to select Group category near Edit and Tools selection
Make your all work as a group
Try again on your Android application.
It should be done.
I'm getting mixed results trying to render a basic alien that was done in Blender:
I export in to Ogre 3D and load it in Eclipse:
Then when I load it in my code and try to render it the material won't render:
Could you tell me what I must do to achieve the full alien in my scene? The code I use in Jmonkeyengine is
Spatial model3 = assetManager
.loadModel("objects/creatures/alien/alien.mesh.xml");
model3.scale(0.3f, 0.3f, 0.3f);
model3.setLocalTranslation(-40.0f, 3.5f, -20.0f);
rootNode.attachChild(model3);
Update
I've got material files like these from the export:
dev#dev-OptiPlex-745:~$ ls workspace/DungeonWorld2/assets/objects/creatures/alien/
alien.mesh Material.002.material Material.005.material
alien.mesh.xml Material.003.material
alien.skeleton.xml Material.004.material
dev#dev-OptiPlex-745:~$
This material code actually produces a material in the scene but it's not the one from blender:
model3.setMaterial( new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md") );
Result:
However, loading a 3D model of an alephant without defining the material does work:
Spatial elephant = (Spatial) assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
float scale = 0.05f;
elephant.scale(scale,scale,scale);
elephant.setLocalTranslation(-50.0f, 3.5f, -20.0f);
control = elephant.getControl(AnimControl.class);
control.addListener(this);
channel = control.createChannel();
for (String anim : control.getAnimationNames())
System.out.println("elephant can:"+anim);
The above code correctly renders the elephant so why can't I export a mesh like that for the alien? I tried to explcitly load the material but it's not working for me:
Spatial model3 = assetManager
.loadModel("objects/creatures/alien/alien.mesh.xml");
model3.scale(0.3f, 0.3f, 0.3f);
model3.setLocalTranslation(-40.0f, 3.5f, -20.0f);
model3.setMaterial( new Material(assetManager,
"objects/creatures/alien/alien.material") );
rootNode.attachChild(model3);
The above generates an exception and I don't really know what material file it is that I'm loading and what do to with the two or three other material files that the export generated:
java.lang.ClassCastException: com.jme3.material.MaterialList cannot be cast to com.jme3.material.MaterialDef
at com.jme3.material.Material.<init>(Material.java:116)
at adventure.Main.simpleInitApp(Main.java:309)
at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:225)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)
at java.lang.Thread.run(Thread.java:679)
Update
Loading other models this way is working:
BlenderKey blenderKey = new BlenderKey(
"objects/creatures/troll/troll.mesh.xml");
Spatial troll = (Spatial) assetManager.loadModel(blenderKey);
troll.setLocalTranslation(new Vector3f(-145, 15, -10));
rootNode.attachChild(troll);
BlenderKey blenderKey2 = new BlenderKey(
"objects/creatures/spaceman/man.mesh.xml");
Spatial man = (Spatial) assetManager.loadModel(blenderKey2);
man.setLocalTranslation(new Vector3f(-140, 15, -10));
rootNode.attachChild(man);
I get the models inside my game and they look alreight, both the troll and the spaceman that both originally were .blend files.
Now it's much better when I did it over and it is loading the material. The only problem with the alien left now is the holes in the head that was also answered here.
BlenderKey blenderKey = new BlenderKey(
"objects/creatures/alien/alien.mesh.xml");
Spatial alien = (Spatial) assetManager.loadModel(blenderKey);
alien.setLocalTranslation(new Vector3f(-145, 15, -10));
rootNode.attachChild(alien);
You didn't write anything about your material - did you write one and used it correctly? The problem you get seems to be the lack of material to me.
In general you'll need some *.material file and probably some textures (if you used them in Blender). For the beginning you can use one of the materials that come with Ogre, you'll just need to add:
model3.setMaterialName( "Examples/Rockwall" );
Then look if it changes anything. If you still get the problem you can look into 'Ogre.log' file - it's always worth checking because all the errors goes there.
I also see the second problem here - you render the object as 'one sided' while blender probably render is as two-sided mesh, so you get the holes on the head. You can select in the material to be two sided, but it's better (and faster during rendering) to just create your models without the holes :).
I have created some applications for image and movies using android.view package. Now I want to create the same for the Android tablets.
I see that I can use android.animation packages for Android 3.0, but I cannot find any documentation to apply fade, zoom effects using this package. I am trying to convert all my source code in this package.
How do I use the ValueAnimator and ObjectAnimator? In the Api Demo, I found this code piece for fading. But how do I assign the Alpha value? In view.animation, I had fromAlpha, toAlpha...
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
balls.remove(((ObjectAnimator)animation).getTarget());
}
});
Again I have this code piece:
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(500);
anim.start();
When do I use ValuAnimator and when do I use ObjectAnimator?
there are two blogposts on this subject on the android developer blog, http://android-developers.blogspot.com/2011/02/animation-in-honeycomb.html and http://android-developers.blogspot.com/2011/05/introducing-viewpropertyanimator.html
I strongly recomend both articles as I got a very good understanding of the new animation APIs after reading them.