Hello,
I'm writing to explain my problem. I would like to use jpct-AE in order to create a very simple application with a 3D world inside it.
Immediately after I saw jpct-AE, I liked it, so I looked for examples but they are not as many as I expected. I tried hello world application for jpct-AE and worked fine, but after I changed some things to create something that was not just copied by the Internet, nothing worked anymore. For example, I would like to create a flat ground. I understand the logic in it, but if I apply it, it just doesn't work. Maybe it is something very easy to fix, because I didn't write so much code, just a test in order to get an idea of the way this library works. But I can't make this flat ground appear: when I launch this application, I just see a black screen and nothing in it... I also set up the ambient light, and a Sun (Light), but nothing appears anyway.
This is my source code:
MathMainActivity.java
package com.android.math_curve;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;
import com.threed.jpct.*;
import com.threed.jpct.util.BitmapHelper;
import com.threed.jpct.util.MemoryHelper;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.BitmapDrawable;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MathMainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLSurfaceView mGLView = new GLSurfaceView(getApplication());
mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
// back to Pixelflinger on some device (read: Samsung I7500)
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});
Renderer renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.math_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class MyRenderer implements Renderer
{
boolean bCalled = false;
FrameBuffer fb = null;
World world = null;
Light sun = null;
Object3D ground = null;
@Override
public void onDrawFrame(GL10 arg0) {
// TODO Auto-generated method stub
fb.clear();
world.renderScene(fb);
world.draw(fb);
fb.display();
}
public void Main3D()
{
world = new World();
world.setAmbientLight(150, 150, 150);
sun = new Light(world);
sun.setIntensity(250, 250, 250);
sun.setPosition(new SimpleVector(50, 20, 50));
ground = new Object3D(100);
TextureMgr.bitmap_as_texture_ex(getApplicationContext(), R.drawable.untitled, TextureManager.getInstance(), "mytexture", 1024, 1024);
int texture_id = TextureManager.getInstance().getTextureID("mytexture");
ground.addTriangle(
new SimpleVector(0, 0, 0),
0,
0,
new SimpleVector(100, 0, 0),
1024,
0,
new SimpleVector(0, 0, 100),
0,
1024,
texture_id);
ground.addTriangle(
new SimpleVector(100, 0, 0),
1024,
0,
new SimpleVector(100, 0, 100),
1024,
1024,
new SimpleVector(0, 0, 100),
0,
1024,
texture_id);
world.addObject(ground);
world.getCamera().setPosition(new SimpleVector(70, 35, 40));
ground.build();
ground.compile();
ground.setOrigin(new SimpleVector(0, 0, 0));
world.getCamera().lookAt(ground.getTransformedCenter());
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if( fb != null )
fb.dispose();
fb = new FrameBuffer(gl, width, height);
if( !bCalled )
{
bCalled = true;
Main3D();
}
}
@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {}
}
}
TextureMgr.java (a class I made to avoid writing multiple pieces of code)
package com.android.math_curve;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.util.BitmapHelper;
public class TextureMgr {
public static boolean is_2_pow(int n)
{
int x = n;
if( x < 0 ) return false;
while( x % 2 == 0 )
{
x /= 2;
if( x == 1 )
{
return true;
}
}
return false;
}
public static void bitmap_as_texture_ex(Context app_context, int resource_id, TextureManager tm, String texture_name, int w, int h) throws IllegalArgumentException
{
if( TextureMgr.is_2_pow(w) == false || TextureMgr.is_2_pow(h) == false )
{
throw new IllegalArgumentException("FATAL EXCEPTION: width or height of texture is not a power of 2 in TextureMgr.bitmap_as_texture_ex()");
}
Bitmap bmp = TextureMgr.get_bitmap(app_context, resource_id);
if( bmp.getHeight() != h || bmp.getWidth() != w )
{
bmp = BitmapHelper.rescale(bmp, w, h);
}
TextureMgr.add_texture(tm, texture_name, bmp);
}
public static void bitmap_as_texture(Context app_context, int resource_id, TextureManager tm, String texture_name)
{
TextureMgr.add_texture(tm, texture_name, TextureMgr.get_bitmap(app_context, resource_id));
}
@SuppressWarnings("deprecation")
public static Bitmap get_bitmap(Context app_context, int resource_id)
{
return (new BitmapDrawable(app_context.getResources().openRawResource(resource_id))).getBitmap();
}
public static void add_texture(TextureManager tm, String texture_name, Bitmap bmp)
{
tm.addTexture(texture_name, TextureMgr.new_texture(bmp));
}
public static Texture new_texture(Bitmap bmp)
{
return new Texture(bmp);
}
}
In TextureMgr.java, there are a lot of functions, but not all are used in this test, some have been made for later use.
Could you explain me why I get just a black screen?
And another big question about the U/V coordinates:
For what I understood looking for what U/V coordinates exactly are, I think U/V coordinates are x/y coordinates of the picture that the texture contains.
So when I use it with Object3D.addTriangle(), with the couples of arguments (u,v), (u2,v2), (u3,v3) I draw a triangle in the texture and that triangle will be "printed" on the triangle in the Object3D.
Is it correct or is there something that is not correct? I ask it because I think it isn't a very good idea to deal with 3D world without complete understanding of textures, maybe it is like making a radio without the knowledge of electricity, do you agree?
Please excuse me for my English, it isn't as perfect as I would like it to be, but I did my best to write this. If there is something not clear, please let me know and I'll try to make it more understandable.
I hope I will understand where the error is.
Waiting for an answer,
Richard