jPCT-AE - a 3d engine for Android > Support

How to draw a simple 2D line onto my jPCT Framebuffer?

(1/4) > >>

HammerNL:
Hi,

I'm developing a little 3D game in which you drive a car through a 3D world. In the upper left corner I'm displaying a fuel indicator, which is of course in simple flat 2D.

I'm using framebuffer.blit() to put the indicator itself directly on top of every frame, which is working fine.
However, inside the fuel indicator I need to draw a line, that actually indicates the level of fuel.

In the desktop version of jPCT, FrameBuffer has a getGraphics() method. But, since on Android there is no AWT, this method does not exist there. Now how do I draw my simple line?

Tnx!

Irony:
I suppose you want this to work like a real fuel indicator, where the line/indicator should rotate. I believe there is no alternative to create a bitmap showing the arrow, use it as a texture on a plane, and rotate this plane accordingly.
If rotation is not necessary, simply create a 8x8 texture out of a color, and blit it in the format 1x20 or something on the correct position.

HammerNL:
Yes, like a real fuel indicator you find in most cars. However, I do not want to draw this line in 3D space. It must somehow be possible to blit a line directly into jPCT's Framebuffer, so in real plain old 2D.

I've come up with the following:


--- Code: ---Bitmap bmp = Bitmap.createBitmap(100,100,Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmp);
Paint p = new Paint();
p.setColor(0xffffffff);

--- End code ---

then in the onDrawFrame() method:


--- Code: ---framebuffer.blit(fuelMeter,0,0,10,10,100,100,true); // blit the fuel meter without the line-indicator
// then make the line-indicator
bmp.eraseColor(0);
c.drawLine(10,10,90,90,p); // this is a static line, but of course the coordinates should move
Texture t = new Texture(bmp);
framebuffer.blit(t,0,0,10,10,100,100,true);

--- End code ---

It works OK, except after a few seconds I get an Out of Memory error:


--- Code: ---09-04 16:40:53.240: E/dalvikvm-heap(18607): Out of memory on a 65552-byte allocation.
09-04 16:40:53.240: I/dalvikvm(18607): "GLThread 6483" prio=5 tid=13 RUNNABLE
09-04 16:40:53.240: I/dalvikvm(18607):   | group="main" sCount=0 dsCount=0 obj=0x41244200 self=0x2170230
09-04 16:40:53.240: I/dalvikvm(18607):   | sysTid=18628 nice=0 sched=0/0 cgrp=default handle=34429144
09-04 16:40:53.240: I/dalvikvm(18607):   | schedstat=( 0 0 0 ) utm=874 stm=256 core=0
09-04 16:40:53.240: I/dalvikvm(18607):   at com.threed.jpct.GLRenderer.convertTexture(GLRenderer.java:~868)
09-04 16:40:53.240: I/dalvikvm(18607):   at com.threed.jpct.GLRenderer.blit(GLRenderer.java:1381)
09-04 16:40:53.240: I/dalvikvm(18607):   at com.threed.jpct.GLRenderer.blitTexture(GLRenderer.java:1747)

--- End code ---

So probably instantiating a new Texture on every frame is not a good idea, but I see no possibility to re-use an existing Texture. Or maybe I'm using an incorrect approach alltogether.

Any help would be appreciated!

EgonOlsen:
You are constantly creating new textures that way. No wonder that you'll run into an OOM that way. You could fix this by using an ITextureEffect, but i don't think that this is a good idea anyway. It will perform very badly. I can think you various solutions for this:


* Use a fuel bar instead. Much easier to implement.
* As Irony suggested: Use a texture for that. You don't have to go into 3d space for this, you can use an Overlay for that. Or you can so in 3d and use an Object3D for it. That requires a bit more coding. Have a look at my minimap here: http://www.youtube.com/watch?v=oew62wECxqY...it uses this approach.
* You can use a single Polyline. However, you are in 3d world space again with that solution, but that's actually pretty simple: You can use Interact2D to get the required 3d coordinates in world space and apply them to the Polyline.

HammerNL:
Hi Egon,

So I went for the Polyline/Interact2D solution... spend hours and hours, but I can't get it right. I must be missing something...
Here's basically what I'm doing:

init function:


--- Code: ---Polyline fuelLine = new Polyline(new SimpleVector[] { new SimpleVector(-1,0,1), new SimpleVector(1,1,1) }, RGBColor.RED);
world.addPolyline(fuelLine);
--- End code ---

Then in onDrawFrame():


--- Code: ---// determine center, radius and the line-angle of the fuel meter
int x = 100;
int y = 100;
float r = 40;
float angle = ...;

world.renderScene(framebuffer);
cam = world.getCamera();
SimpleVector[] vectors = new SimpleVector[]
{
  Interact2D.reproject2D3D(cam,framebuffer,x,y),
  Interact2D.reproject2D3D(cam,framebuffer,(int)(x+Math.sin(angle)*r+0.5),(int)(y-Math.cos(angle)*r+0.5))
};
fuelLine.update(vectors);

world.draw(framebuffer);
--- End code ---

It does produce a line, but it's nowhere near the 2D x,y coordinates that I'm using, but somewhere in the middle of the screen (size 480x800px). Also the resulting line is much too short. I expect a line of 40 pixels, but it's actually like 2 or 3 pixels.

What am I doing wrong?

Navigation

[0] Message Index

[#] Next page

Go to full version