I have this code to draw a rectangle on a 256z256 picturebox, however, I don't see the whole rectangle, I only see half of it.. what it might be?
e.Graphics.DrawRectangle(mypen,0,0,256,256);
Maybe it draws it from the center? Try
Rectangle m_rectangle = new Rectangle(0, 0, 512, 512);
e.Graphics.DrawRectangle(mypen,m_rectangle);
Just a stab in the dark.
Related
In my TextureAtlas the Sprite's for my Animation are rotated 90 degrees.
When I draw my Animation it's still rotaed by 90 degrees. How can I fix that?
My code looks like that:
TextureAtlas spritesheet = new TextureAtlas(Gdx.files.internal("images/spritesheet/spritesheet.atlas"));
Array<AtlasRegion> CLOUD_ANIMATION_REGIONS = spritesheet.findRegions("cloud_animation");
Animation animation = new Animation(0.1f,ImageProvider.CLOUD_ANIMATION_REGIONS);
In the render method:
batch.draw(animation.getKeyFrame(elapsedTime, true), x, y);
The animation works perfectly fien but it's rotated by 90 degree like in the spritesheet.
I realize that if I have a Sprite I can call Sprite.draw(batch) and it will fix the rotation but I don't seem to be able to use that mechanism for Animation's?
EDIT:
Like Alexander said, this will do the trick:
batch.draw(textureRegion, x, y, 0, 0,textureRegion.getRegionWidth(), textureRegion.getRegionHeight(), 1, 1, 90);
Ok, here is untested code:
TextureRegion textureRegion = animation.getKeyFrame(elapsedTime, true);
if (textureRegion instanceof TextureAtlas.AtlasRegion && ((TextureAtlas.AtlasRegion) textureRegion).rotate)
{
batch.draw(textureRegion, x, y, 0, 0, textureRegion.getRegionWidth(), textureRegion.getRegionHeight(), 1, 1, 90, true);
}
else
{
batch.draw(textureRegion, x, y);
}
What I'm doing here: I check if atlas packer marked the region as rotated and then draw it rotated 90 angle clockwise to compensate original 90 angle counter-clockwise rotation. See AtlasRegion's javadoc and special version of draw method that can rotate TextureRegion.
EDITED: fix arguments based on Markus comment
Somehow you should be using AtlasSprite I think. That carries out the unrotate in its constructor. You dont want to be rotating every frame - thats some overhead. Also the AtlasSprite should take care of trimmed regions in the atlas : something thats very important to maximise a single atlas texture. Alas it doesnt seem very easy to use as it seems one needs a seperate sprite for each frame which seems massive overhead.
Let's say we have the following code:
void setup() {
background(0);
size(200, 200);
fill(255);
rect(75, 75, 50, 50);
}
void draw() {
fill(0, 2);
rect(0, 0, width, height);
}
Even after waiting 'forever,' the white 50x50 rectangle is still visible, albeit faded. Why doesn't the fill(0, 2) eventually cover this up?
I suppose this question is twofold:
Why doesn't it eventually fade to black, as in why does drawing another dark rectangle on top of the white one not erase it eventually (I'm thinking along the lines of putting tinted windows over each other; eventually even the brightest light won't shine through), and
Why doesn't it eventually fade to black, as in why is this the behavior intended by the Processing community?
Here's a post explaining what's going on: http://processing.org/discourse/beta/num_1138703939.html
Basically, the problem is that Processing stores colors as ints, but takes float arguments. When combining colors, Processing rounds the floats to ints. In your case, your color is getting stuck at a value of 63, 63, 63 because at that point the blending is too slight to make a difference that is detectable after rounding.
The solution is to do the fading from the source, not by overlaying an alpha color over top.
I had the same issue with fill(0, 0, 0, 5);.
Interestingly, changing the alpha value to 20 helped (and I'm sure many other values work too).
void draw() {
fill(0, 0, 0, 20); // Note the value 20 for the alpha channel.
rect(0, 0, width, height);
}
The default background color is darker than the color you assigned to the first rectangle, thus it gets black sooner.
Why doesn't it eventually fade to black, as in why does drawing another dark rectangle on top of the white one not erase it eventually
(I'm thinking along the lines of putting tinted windows over each
other; eventually even the brightest light won't shine through), and
Why doesn't it eventually fade to black, as in why is this the behavior intended by the Processing community?
Also, in your original code (not the above sample) you're probably drawing the white rectangle continuously, so it will never fade.
I've noticed some strange behaviour with glDrawPixels() when using a 0.375 translation. This is my GL initialization:
width = 640; height = 480;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity( );
glOrtho(0, width, height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity( );
glTranslatef(0.375, 0.375, 0.0);
Now I want to draw a 640x30 pixel buffer to the very last 30 rows of my GL window. Hence, I do the following:
glRasterPos2i(0, 480);
glDrawPixels(640, 30, GL_RGBA, GL_UNSIGNED_BYTE, pixelbuffer);
Unfortunately, nothing gets drawn using this code. glGetError() also returns 0. The interesting thing is that as soon as I remove the call to glTranslatef(0.375, 0.375, 0.0) everything works fine!
So could somebody explain to me why this 0.375 translation on both axes confuses glDrawPixels()? Is this somehow rounded to 1.0 internally making my call to glDrawPixels() suddenly want to draw beyond the context's boundaries and thus it gets clipped by OpenGL? This is the only explanation I can think of but I don't understand why OpenGL should round a 0.375 translation to 1.0... it should be rounded down to 0.0 instead, shouldn't it?
The point (0,480) actually straddles one of your clipping planes given your projection matrix. Your sub-pixel shift hack pushes the point beyond the breaking point and the raster position is clipped. In GL, glRasterPos (...) will invalidate all following raster operations as long as the initial position is clipped (which in this case, it is).
You could try glRasterPos2i (0, 479). This is altogether more meaningful given the dimensions of your window anyway. You could also drop the whole charade and use glWindowPos2i (...) instead of relying on your projection and modelview matrices to position the raster coordinate in window-space.
I can't answer your question on why glTranslatef stops glDrawPixels from working, but I can tell you that isn't the way to select where to draw. Check the man page for glDrawPixels for a bit more info. It will tell you about glRasterPos and glWindowPos
Please check this neat piece of code I found:
glEnable(GL_LINE_SMOOTH);
glColor4ub(0, 0, 0, 150);
mmDrawCircle( ccp(100, 100), 20, 0, 50, NO);
glLineWidth(40);
ccDrawLine(ccp(100, 100), ccp(100 + 100, 100));
mmDrawCircle( ccp(100+100, 100), 20, 0, 50, NO);
where mmDrawCircle and ccDrawLine just draws these shapes [FILLED] somehow... (ccp means a point with the given x, y coordinates respectively).
My problem .... Yes, you guessed it, The line overlaps with the circle, and both are translucent (semi transparent). So, the final shape is there, but the overlapping part becomes darker and the overall shape looks ugly.. i.e, I would be fine if I was drawing with 255 alpha.
Is there a way to tell OpenGL to render one of the shapes in the overlapping parts??
(The shape is obviously a rectangle with rounded edges .. half-circles..)
You could turn on GL_DEPTH_TEST and render the line first and a little closer to the camera. When you then render the circle below, the fragments of the line won't be touched.
(You can also use the stencil buffer for an effect like this).
Note that this might still look ugly. If you want to use anti-aliasing you should think quite hard on which blending modes you apply and in what order you render the primitives.
I have a sprite I'm animating on an html canvas using normal sprite sheet blitting. On certain key events I'd like to change the direction of the sprite (ie, flip it, or rotate it 180 degrees) without changing anything (the other sprites) on the canvas.
Does anyone know how to do this?
So I was having this issue with my game; I had cells for up, down, and left animations, but no right cells. So I needed to flip the left cells to draw the right cells.
For each sprite I keep track of it's current top and left in the canvas, as well as each cell's top and left in the sprite sheet.
I've seen previous answers showing a simple horizontal flip as just translating the origin and flipping (inverse scale) of the axes, BUT this does not take into account that with sprites, flipping the origin will mess up the sprite's registration point (its top and left on the canvas).
This issue manifested in the sprite being mirrored correctly, but it's position being off by the width of the sprite. I solved it by taking into account the width of the sprite. Notice how I'm using CanvasRenderingContext2D.prototype.drawImage with 9 arguments since I'm slicing a sprite out of a sprite sheet:
// check if we need to flip image (special case for right movement)
if(sprite.translated){
context.save();
context.translate(context.canvas.width, 0);
context.scale(-1, 1);
context.drawImage(sprite.sheet,
cell.left,
cell.top,
sprite.width,
sprite.height,
// secret sauce: change the destination's X registration point
context.canvas.width - sprite.left - sprite.width,
sprite.top,
sprite.width, sprite.height);
context.restore();
} else {
// Assumes cells are all the same width and height, set in sprite
context.drawImage(sprite.sheet, cell.left, cell.top, sprite.width,
sprite.height, sprite.left, sprite.top, sprite.width, sprite.height);
}
Note: I also could have done the math in the translate, since it's meant to simplify calculations elsewhere.
Simply redraw the sprite, with a rotate transformation. Transformations in HTML Canvas 2D Context
The canvas is just an off-screen buffer. It won't be cleared unless you tell it to, and nothing else will be changed unless you tell it to.
There's a bunch of different situations in which you may have to redraw the area of or around the sprite. Otherwise, you'll get a ghosting effect where part of the old sprite is still visible below the new drawing, or other drawings become obscured. Some reasons are:
Your sprite is partially transparent,
Your sprite is partially translucent,
Other drawings are made on top of your sprite,
Your sprite is non-rectangular,
You're doing flips that are not multiples of 90 degrees.
So that might be a bit more work, and there are several different approaches to doing that. You could simply redraw the entire scene, or just the specific objects at the location, perhaps using the clip method.
A completely different direction might be to use other HTML elements, img or div, with absolute positioning and CSS3 transformations. That's basically a bit of trickery to delegate the rendering of your scene to the browser.
While I appreciate Shtééf's answer, after a bit of research, I have found that rotating the canvas you are actually using to display doesn't seem to be ideal. The saving, rotating and restoring while trying to create complex animations (aka think Street Fighter 2 not astroids) causes the canvas to flicker in even Chrome.
I have found however a usable strategy. The idea here is that you actually create two canvases, one will be for your game and the other will be a backbuffer of sorts and it will be used to rotate or scale your sprites. You essentially transform the backbuffer canvas, draw the image in question, then transfer it to your main canvas and restore (or not) the backbuffer. In this manner, you only rotate the hidden canvas and only effect the sprite in question not the entire game board.
The code looks something like this (work in progress):
mainContext.clearRect(lastXpos, lastYpos, lastWidth, lastHeight);
backContext.clearRect(0, 0, lastWidth, lastHeight);
lastXpos = xpos;
lastYpos = ypos;
lastWidth = width;
lastHeight = height;
backContext.save();
//check the direction of the sprite
//turn the backContext to this direction
//SPRITE_INVERTED==-1
if (spriteXDirection == SPRITE_INVERTED || spriteYDirection == SPRITE_INVERTED)
{
var horScale = 0;
var verScale = 0;
if (spriteXDirection == SPRITE_INVERTED)
{
horScale = width;
}
if (spriteYDirection == SPRITE_INVERTED)
{
verScale = height;
}
backContext.translate(horScale, verScale);
backContext.scale(spriteXDirection, spriteYDirection);
}
//draw the sprite not we always use 0,0 for top/left
backContext.drawImage(animations[currentPlay].sheet,
animationX,
animationY,
width,
height, 0, 0, width, height);
//Get the image data from the back context
var image = backContext.getImageData(0, 0, width, height);
//flip the back context back to center - or not, I haven't decided how to optimize this yet.
backContext.restore();
//transfer the image to your main context
mainContext.putImageData(image, xpos, ypos);
This has saved me a lot of headaches in understanding how to translate my sprites without having everything on my gameboard move all over the place. It also seems to perform better then modifying the main context.
Why don't you use save() and restore
ctx.save(); // save current state
ctx.rotate(Math.PI); // rotate
ctx.drawImage(link,x,y,20,20); // draws a chain link or dagger
ctx.restore(); // restore original states (no rotation etc)
How to rotate one image in a canvas?