My game crashes with this message:
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000066bcbd0d, pid=13948, tid=12700
# [...]
#
# Problematic frame:
# C [gdx-box2d64.dll+0xbd0d]
From log file:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j com.badlogic.gdx.physics.box2d.World.jniCreateBody(JIFFFFFFFFZZZZZF)J+0
j com.badlogic.gdx.physics.box2d.World.createBody(Lcom/badlogic/gdx/physics/box2d/BodyDef;)Lcom/badlogic/gdx/physics/box2d/Body;+80
j de.tennoxlab.cellolution.Food.<init>(Lde/tennoxlab/cellolution/CellWorld;FFZZ)V+115
j de.tennoxlab.cellolution.CellWorld.generateFood(IFFFFZ)V+54
J 89 C2 de.tennoxlab.cellolution.CellWorld.update()V (159 bytes) # 0x00000000024623b4 [0x0000000002461c60+0x754]
j de.tennoxlab.cellolution.Cellolution.render()V+40
j com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop()V+698
j com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run()V+27
v ~StubRoutines::call_stub
Full log: http://pastebin.com/QjY3msYS
From all the other posts with similar crashes it is probably some world modification when it shouldn't happen.
The crash occurs during the creation of new Food objects:
// generateFood() - called during World.update
for (int i = 0; i < count; i++) {
float x = minX + (float) Math.random() * (maxX - minX);
float y = minY + (float) Math.random() * (maxY - minY);
Gdx.app.debug("World", "Generating food piece "+i);
this.foods.add(new Food(this, x, y, animateGrowth, this.renderable));
}
in the Food constructor:
// in Food(...) constructor
BodyDef bodyDef = new BodyDef(); //TODO: set to sleep on init?
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(x, y);
bodyDef.linearDamping = 0.5f;
bodyDef.angularDamping = 1f;
Gdx.app.debug("Food", "Init body with " + bodyDef + " at " + x + "," + y);
foodBody = world.box2dWorld.createBody(bodyDef); // <== HERE IS WHERE THE CRASH HAPPENS
CircleShape shape = new CircleShape();
shape.setRadius(getSizeFromEnergy());
fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.5f;
fixtureDef.friction = 0.4f;
fixtureDef.restitution = 0.2f;
fixture = foodBody.createFixture(fixtureDef);
fixture.setUserData(this);
shape.dispose();
But it only happens occassionally, sometimes after minutes of gameplay (when the generateFood code was executed successfully hundreds of times). So I thought, the crash must have something to do with what happens with the world BEFORE the Food generation. So I started enabling and disabling code, until I found out, that the crash only happens, when after the destruction of box2d bodies of my Cell objects:
public void update() { // Cell.update - called during World.update
if (this.energy <= 0) {
world.cells.remove(this);
Vector2 pos = cellBody.getPosition();
Gdx.app.debug("Cell", "Destroying " + cellBody+" at "+pos.x+","+pos.y);
world.box2dWorld.destroyBody(cellBody); // -> Without this line, the crashes don't happen!
return;
}
}
Here's the log:
World: Generating food piece 99
Food: Init body with com.badlogic.gdx.physics.box2d.BodyDef#72aff016 at -28.201607,-56.101532
World: Removing cell: de.tennoxlab.cellolution.Cell#7cbb6f2c
Cell: Destroying com.badlogic.gdx.physics.box2d.Body#757ff1ad at -51.92446,-56.464954
World: Removing cell: de.tennoxlab.cellolution.Cell#7cbb6f2c
Cell: Destroying com.badlogic.gdx.physics.box2d.Body#757ff1ad at -51.92446,-56.464954
World: Generating 100 new food pieces
World: Generating food piece 0
Food: Init body with com.badlogic.gdx.physics.box2d.BodyDef#3828ef8f at 14.653984,96.249084
[...]
World: Generating food piece 21
Food: Init body with com.badlogic.gdx.physics.box2d.BodyDef#2b91d887 at -15.35305,13.934067
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000066bcbd0d, pid=9792, tid=13288
#
I solved it myself. It was a nasty little bug like in probably all the other problems like that.
As you can see in the log file, the same Cell is deleted twice:
World: Removing cell: de.tennoxlab.cellolution.Cell#7cbb6f2c
Cell: Destroying com.badlogic.gdx.physics.box2d.Body#757ff1ad at -51.92446,-56.464954
World: Removing cell: de.tennoxlab.cellolution.Cell#7cbb6f2c
Cell: Destroying com.badlogic.gdx.physics.box2d.Body#757ff1ad at -51.92446,-56.464954
When I realised that I quickly found the issue: I have been adding the Player cell to the list twice, thus updating it twice, destroying it twice - which box2d obviously didn't like.
As these 'solutions' to crashes like these don't really help if you got this crash yourself (because your bug will be something else), I can only suggest trying to figure out the problem by rigorious debugging. (I added tons of debug log lines everywhere and examined the output - for many hours...) Because mistakes like these happen. For some more frequently, for some less frequently, but they happen.
Something else I want to add: box2d crash messages are really unhelpful. It is really hard to find out, what **really* caused the crash. That sucks. I wish there would be more debugging information, more safety checks and stuff like that in the library itself (or libgdx, maybe).
I'm really looking forward to more of those (seemingly) unsolvable bugs/crashes during the ongoing developement of the game :Z
You already solved your problem but if someone stubles upon this thread: In my case the issue was, that a Box2D world was disposed twice.
Related
I'm trying to copy the NV12 NVDEC decoded buffer directly into an NV12 d3d11 texture. No luck so far. What I've managed to do is a double shot copy using 2 d3d11 textures (luma + chroma), 2 cuGraphicsMapResources, 2 cuGraphicsSubResourceGetMappedArray, 2 CUDA_MEMCPY2D and a pixel shader to merge all....no way to perform a single shot copy, and no response from NVidia forum so far.
I've found this old question facing a very similar problem, no solution there either.
Perhaps you need something like this. This code snipped taken from FFmpeg Project (opensource), libavutil/hwcontext_cude.c file:
for (i = 0; i < FF_ARRAY_ELEMS(src->data) && src->data[i]; i++) {
CUDA_MEMCPY2D cpy = {
.srcMemoryType = CU_MEMORYTYPE_HOST,
.dstMemoryType = CU_MEMORYTYPE_DEVICE,
.srcHost = src->data[i],
.dstDevice = (CUdeviceptr)dst->data[i],
.srcPitch = src->linesize[i],
.dstPitch = dst->linesize[i],
.WidthInBytes = FFMIN(src->linesize[i], dst->linesize[i]),
.Height = src->height >> (i ? priv->shift_height : 0),
};
ret = CHECK_CU(cu->cuMemcpy2DAsync(&cpy, hwctx->stream));
if (ret < 0)
goto exit;
}
Not sure how this can be done with NVidia/Cuda as I'm not familiar with. But this is how I managed to do it with Direct3D (D3D11va) that might help you to translate it to your situation:-
(NV12 NDEC Device).CopySubresourceRegion(src NV12 NVDEC texture, srcSubresourceArrayIndex, dst NV12 shared texture)
(Get Shared Handle for the newly created NV12 shared texture)
(Your Device).OpenSharedResource(NV12 shared handle)
(Prepare VideoProcessorInputView, VideoProcessorOutputView and Streams)
(Your Device).VideoProcessorBlt(src NV12 shared handle, dst Your RGBA/BGRA Render Texture)
This process is Video Acceleration and it happens only in your GPU (no CPU/RAM involved). You should also ensure that the GPU adapter supports that.
I try to record PCM sound from flash (using Microphone class). I use org.bytearray.micrecorder.MicRecorder helper class.
In Microphone class I cannot find property like bitDepth or bitsPerSample.
I always get 32 bits.
Is it possible to do?
UPDATE: The asker John812 was able to solve this by using..
bit16_bytes.writeShort( data.readFloat() * 32767 ); see comments below for context
METHOD #2: Based on my experience with using the LoadPCMfromByteArray method
I have something you could try but I've only used it with an actual 32bit WAVE file and played via the LoadPCMFromByteArray command.
The AS3 Microphone Class records 32 bits. You have to write the conversion of samples to a different bit-depth by yourself. I have no idea how many samples you are processing but the general code below shows you how to convert. Note: * 512 means use your actual samples amount (example: * 4096? or * 8192?) If you get the numbers wrong there'll be hiss/distortion so either experiment from small or provide the full details in your question for a more helpful edit/answer.
CONVERT: Assuming your recorded byteArray is called data
public var bit16_bytes : ByteArray; //will hold the 16bit version
public function convert_to16Bit () : void
{
bit16_bytes = new ByteArray(); data.position = 0;
while (bit16_bytes.position < data.length - 4)
//if you get noise/distortion try either: 256, 512, 1024, 2048, 4096 or 8192
{ bit16_bytes.writeShort( data.readInt() * 512 ); } //multiply by samples amount
data = new ByteArray(); //recycle for re-use
bit16_bytes.position = 0; //reset or else E-O-File error
bit16_bytes.readBytes( data ); //copy 16bit back into Data byte-array
}
To run the above function whenever you're ready just add the line convert_to16Bit(); inside whatever function deals with your "recording complete" situation.
I have been spending several days trying to solve this problem and I am about to go mad. Your help would be very much appreciated.
I am using a 2D stage in libgdx. I want to move actors (or sprite) to this stage with a "gravity" display effect: for example for actor1, his initial coordinates are (0, 0), destination coordinates would be (100, 50), and I want to move this actor to this destination with a gravity trajectory effect. Then I want to use the same gravity for actor2 moving from (0, 0) to (25, 75), then actor3 from (0, 0) to (200, 75) etc.
I managed to apply a gravity trajectory to any actor based on this well known loop:
setX(getX() + velocity.x);
setY(getY() + velocity.y);
velocity.y += getGravity().y * delta;
So tweaking the gravity value would modify the trajectory. It works fine.
Now, as I said earlier I want to give every actors a unique trajectory given their predetermined destination.
So I have tried to find a formula to determine the x and y for each actor at every frame of their trajectory
I am using the following static parameters:
gravity.y : same for all actors
delay : the amount of frames during which each actor moves between his initial coordinates and his destination coordinates. Same value for all actors too
First I calculate the velocity with this SUPER UGLY formula that I am absolutely not proud of:
velocity = new Vector2 ( (destinationx - b.getX() )/time, initdisty/time + ( Math.sqrt(delta*1000)*time / ( 500/Math.abs(gravity) ) ));
where delta = Gdx.graphics.getDeltaTime();
Then I apply this velocity each frame to calculate the x and y of each actor:
public void act(float delta){
for (int i=0; i<delay; i++) {
setX(getX() + velocity.x);
setY(getY() + velocity.y);
velocity.y += gravity.y * delta;
}
}
It KIND OF work, but of course, this can not be a long term solid solution. Calculating the x and y for each frame for each actor (there can be 5-6 actors moving at the same time) doesn't look good at all.
The main problem is that the trajectories are good on computer with consistent 60FPS, they are okay on a tablet, but on a phone with limited memory and 30 < fps < 60, the trajectories become terribly wrong.
After reading several blog posts, it seems like I could avoid the multi device memory fps problems by removing the delta parameter from my formulas, but I haven't found how. And it still doesn't give me a strong long term solution to calculate the trajectory with predetermined destination coordinates.
Thanks for reading and for your time, please let me know if this is unclear I'll do my best to explain better.
Cause of the problem
Maintaining both position and velocity leads to discretization of the system resulting in quantization error. So you will experience inconsistent behavior by your current method when fps fluctuates.
Solution
All you need is to reduce your number of state variables to only two i.e. don't store current velocity. It is causing the errors in final position.
In stead use parametric form of the trajectory.
v = u + at
and
s = ut + ½at²
Implementation
Suppose you want to go from (sourceX, sourceY) to (targetX, targetY) in time 'totalTime'.
Calculate initial velocity.
Vector2 initialVelocity = new Vector2((targetX - sourceX) / totalTime,
(targetY - sourceY) / totalTime - gravity * totalTime / 2);
float currentTime = 0;
In each iteration, calculate position directly and keep track of currentTime.
public void act(float delta){
if (currentTime < totalTime) {
currentTime += delta;
setX((initialVelocity.x + gravity.x * currentTime / 2) * currentTime);
setY((initialVelocity.y + gravity.y * currentTime / 2) * currentTime);
} else {
setX(targetX);
setY(targetY);
}
}
I'm beginner for coding, I've questions :
First I'd like know why that code is not moving :
local speed = 5
function cube ()
for i = 1,20,2 do
local rect = display.newRect(50,50,50,50)
rect.x = screenleft-300 + (50*i)
rect.y = _y
rect.x = rect.x - speed
if (rect.x < -450 )then
rect.x = 1200
end
end
end
timer.performWithDelay(1, cube, -1)
Secondly : What's the difference between
Runtime:addEventListener( "enterFrame", cube )
and
timer.performWithDelay(1, cube, -1)
Because I get the same result with both of them
And to be done, Why when I use the function "for" to duplicate something like the square i've done upside, this one put the image behind eachother and not like the square beside eachother ( the image i'm trying to duplicate has more than 4 side )
Thanks for all your reply !
thks a lot dude , I know what you mean by here but my question is little bit weird maybe lol and maybe we can't do it
I try to explain again :
for i=1,10,1 do
local Circle = display.newCircle(50, 20, 20)
Circle.x = _x + (50*i)
Circle.y = _y
end
So here I've a Circle line like that 00000 (imagine 0 are circle ^^)
and I want to make that line moving from the left to the right screen, but when i try to make it move with :
Circle.x = Circle.x - speed
Corona don't recognize the " circle.x " so I can't, maybe because is insert into the"FOR"
SO my question is : "How to move this Circle line if that's possible with the "FOR" ?
I hope I've Been clearer
Anyway, Thanks for all
I'll answer your second question first:
Runtime:addEventListener( "enterFrame", cube )
The function addEventListener adds a listener to the object’s list of listeners. When the named event occurs (in this case "enterFrame"), the listener will be invoked and be supplied with a table representing the event. In your code, the listener will call cube() on every frame (normaly, games run at 60 frames per second).
timer.performWithDelay(delay, listener [, iterations])
performWithDelay does what it says it does: Call a specified function after a delay. The timer function returns an object that can be used with other timer.* functions. In your code timer.performWithDelay(1, cube, -1) the function is calling cube() every 1ms and it is going to do so forever. This is not a good thing to do. There's nothing catching the return of the timer function and it is going to be running forever.
Now, to answer your main question. I believe what you are trying to do is create a square an move it in the screen. If that's correct, here's how you should do it:
local square = display.newRect(100,100,50,50)
local speed = 2
-- called every frame
local function moveSquare()
square.x = square.x + speed
end
Runtime:addEventListener("enterFrame", moveSquare)
The reason your code doesn't do what you want it to do is because you misunderstood a some basic CoronaSDK things.
Hope this little code helps you to understand more about how CoronaSDK works. Don't forget to check the documentation of Corona in http://docs.coronalabs.com/
You're creating an object locally in a loop and trying to move it outside of the loop. This doesn't work due to the way lua uses local variables. See http://www.lua.org/pil/4.2.html for more info about this.
Also, you'll need to place the objects into a single display group in order to move them easily. If you're using Box2D physics at all, I recommend reading up on it more at http://docs.coronalabs.com/api/library/physics/index.html.
Your code:
for i=1,10,1 do
local Circle = display.newCircle(50, 20, 20)
Circle.x = _x + (50*i)
Circle.y = _y
end
Should Be Changed to:
local Circle = display.newGroup(); --Forward declaration of Variable. Place this before any calls for it.
local speed = 2;
for i=1,10,1 do
local object = display.newCircle(50,20,20);
object.x = _x + (50*i);
object.y = _y;
Circle:insert(object); --Insert this local object into the display group
end
function moveCircle()
Circle.x = Circle.x + speed;
end
Runtime:addEventListener( "enterFrame", moveCircle);
This will move the Circle line every frame, on the X-axis, by the speed variable's value.
If you're trying to move it with a for-loop, then we'd need to see more of you code in context.
I have been working on creating an assets class that can generate dynamic TextureAtlas objects whenever I need them. The specific method is Assets.generateTextureAtlas() and I am trying to optimise it as much as possible as I quite frequently need to regenerate texture atlas's and was hoping to get a better time than my 53ms average.
53ms is currently costing me about 3 frames which can add up quickly the more items I need to pack inside my texture atlas and the frequency I need to generate them. So an answer to all the pitfalls within my code would be great.
The entire class code is available here in a github gist.
The RectanglePacker class is simply used to pack rectangles as close together as possible (similar to Texture Packer) and can be found here.
For reference, here is the method:
public static function generateTextureAtlas(folder:String):void
{
if (!_initialised) throw new Error("Assets class not initialised.");
if (_renderTextureAtlases[folder] != null)
{
(_renderTextureAtlases[folder] as TextureAtlas).dispose();
}
var i:int;
var image:Image = new Image(_blankTexture);
var itemName:String;
var itemNames:Vector.<String> = Assets.getNames(folder + "/");
var itemsTexture:RenderTexture;
var itemTexture:Texture;
var itemTextures:Vector.<Texture> = Assets.getTextures(folder + "/");
var noOfRectangles:int;
var rect:Rectangle;
var rectanglePacker:RectanglePacker = new RectanglePacker();
var texture:Texture;
noOfRectangles = itemTextures.length;
if (noOfRectangles == 0)
{
return;
}
for (i = 0; i < noOfRectangles; i++)
{
rectanglePacker.insertRectangle(Math.round(itemTextures[i].width), Math.round(itemTextures[i].height), i);
}
rectanglePacker.packRectangles();
if (rectanglePacker.rectangleCount != noOfRectangles)
{
throw new Error("Only " + rectanglePacker.rectangleCount + " out of " + noOfRectangles + " rectangles packed for folder: " + folder);
}
itemsTexture = new RenderTexture(rectanglePacker.width, rectanglePacker.height);
itemsTexture.drawBundled(function():void
{
for (i = 0; i < noOfRectangles; i++)
{
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i, rect);
image.texture = itemTexture;
image.readjustSize();
image.x = rect.x + itemTexture.frame.x;
image.y = rect.y + itemTexture.frame.y;
itemsTexture.draw(image);
}
});
_renderTextureAtlases[folder] = new TextureAtlas(itemsTexture);
for (i = 0; i < noOfRectangles; i++)
{
itemName = itemNames[rectanglePacker.getRectangleId(i)];
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i);
(_renderTextureAtlases[folder] as TextureAtlas).addRegion(itemName, rect, itemTexture.frame);
}
}
Well reading the project & finding what all can be optimized would sure take time.
Start by removing multiple calls to rectanglePacker.getRectangle(i) inside loops.
For example :
itemName = itemNames[rectanglePacker.getRectangleId(i)];
itemTexture = itemTextures[rectanglePacker.getRectangleId(i)];
rect = rectanglePacker.getRectangle(i);
perhaps, could have been:
rect = rectanglePacker.getRectangle(i);
itemName = itemNames[rect];
itemTexture = itemTextures[rect];
If getRectangle does indeed just 'get a rectangle' & not set anything.
I think the bigger issue at hand is this, why oh why do you HAVE to do this during run-time, in a situation when this can't take more time? This IS an expansive operation, no matter how much you optimize this you will probably end up with it taking about 40ms or similar when done in AS3.
This is why these kind of operations should be done during compile time or during "loading screens" or other "transitions" when frame-rate is not critical and when you can afford it.
Alternatively create another system in c++ or some other language which can actually handle the number-crunching that gives you the finished result.
Also, when it comes to checking performance, yes the entire function takes 53ms, BUT, where are those milliseconds used? 53ms says nothing and is only the "overhead profiling thing" where you found the culprit, you need to break it down into smaller chunks to gather some reliable information about what it is that ACTUALLY takes time, inside that function.
I mean, inside that function, you have 3 for loops, several calls to other classes, casts, deletes, creations. It's not like you are doing one thing, that function probably results in ~500 lines of code and a bazillion cpu operations. And, you have no idea where it is used. I would guess that it is the rectanglePacker.packRectangles(); that takes 60% of that time, but without profiling, you and we don't know on what to optimize, we simply don't have sufficient data.
If you HAVE to do this during run-time in AS3, I would recommend doing this spread out during several frames and distributing workload evenly during 10 frames or so. You could also doing it with help of another thread and workers. But most of all, this seems like a design error since this could probably be done at another time. And if not, then in another language which is better at these kind of operations.
The easiest way to profile this is to add a couple of timestamps similar to:
var timestamps:Array = [];
And then push getTimer() at different places in code, and then print them out when function is done
As others said, it's unlikely that the reason of bad performance is non-optimized AS code. Output from the profiler (Scout, for example) wold be very helpful. However, if your purpose is just adding new textures, I can suggest several optimizations:
Why would you need to re-generate the whole atlas every time (calling Assets.getTextures() and creating new render texture)? Why don't you just add new items to the existing atlas? Creation of a new RenderTexture (and, thus, a new texture in GPU memory) is very costly operation, because it requires sync between CPU and GPU. On the other hand, drawing into RenderTexture is carried out entirely inside GPU, so it takes much less time.
If you place every item on a grid, then you can avoid using RectanglePacker as all of your rectangles can have the same dimensions matching the dimensions of a grid.
Edit:
To clarify, some time ago I had a similar problem: I had to add new items to the existing atlas on a regular basis. And the performance of this operation was quite acceptable (about 8ms on iPad3 using 1024x1024 dynamic texture). But I used the same RenderTexture and the same Sprite object that contained my dynamic atlas items. When I need to add a new item, I just create new Image with desired texture (stand-alone or from another static atlas), then place it inside the Sprite container, and then redraw this container to the RenderTexture. Similarly with deletion/modification of an item.