My allegro 5 game needs to draw a region of a tilesheet then i used al_draw_bitmap_region, but now i added the function to change the screen resolution, so now i also need to scale that bitmap but allegro 5 do not have something like al_draw_scaled_bitmap_region, it have al_draw_bitmap_region andal_draw_scaled_bitmap` but not both.
somebody can help me how use both?
There is no al_draw_scaled_bitmap_region, but there is
al_draw_tinted_scaled_rotated_bitmap_region. You can just pass 'default'
values to the parameters you don't need.
al_draw_tinted_scaled_rotated_bitmap_region(
bitmap,
sx, sy, sw, sh, // source bitmap region
al_map_rgb(1, 1, 1), // color, just use white if you don't want a tint
cx, cy, // center of rotation/scaling
float dx, float dy, // destination
xscale, yscale, // scale
0, 0)); // angle and flags
You could also use transforms to scale your bitmap:
ALLEGRO_TRANSFORM trans, prevTrans;
// back up the current transform
al_copy_transform(&prevTrans, al_get_current_transform());
// scale using the new transform
al_identity_transform(&trans);
al_scale_transform(&trans, xscale, yscale);
al_use_transform(&trans);
al_draw_bitmap_region(*bitmap, sx, sy, sw, sh, dx, dy, 0));
// restore the old transform
al_use_transform(&prevTrans);
Related
I was wondering if it possible to give a shape to a Texture in LibGDX.
In particular, I have a Texture and I want to make a button out of it. To do so, I wanted to give it a rounded corners shape.
In a nutshell, I have this :
and I want this :
I've already read some similar questions with any clear answer. Does anyone have experience this problem and found a smart solution ?
Create rounded texture image using bellow method and then add text to it.
public static Texture createPixmapRoundCornerRect(Color color, int width,
int height, int radius) {
Pixmap pixmap = new Pixmap(width, height, Format.RGBA8888);
pixmap.setColor(color);
pixmap.fillCircle(radius, radius, radius);
pixmap.fillCircle(width - radius, radius, radius);
pixmap.fillCircle(width - radius, height - radius, radius);
pixmap.fillCircle(radius, height - radius, radius);
pixmap.fillRectangle(0, radius, width, height - (radius * 2));
pixmap.fillRectangle(radius, 0, width - (radius * 2), height);
Texture pixmaptex = new Texture(pixmap);
pixmap.dispose();
return pixmaptex;
}
This has been already answered here. You have to implement your own Texture which uses polygons to achieve what you are trying to do.
After calibrating my camera using some sample data in OpenCV, my camera matrix becomes an identity matrix.
Here is my code:
std::vector<cv::Point3f> t_3d;
t_3d.push_back(cv::Point3f(50, 100, 0));
t_3d.push_back(cv::Point3f(375, 100, 0));
t_3d.push_back(cv::Point3f(50, 1600, 0));
t_3d.push_back(cv::Point3f(750, 1600, 0));
object_points.push_back(t_3d);
std::vector<cv::Point2f> t_2d;
t_2d.push_back(cv::Point2f(2.27556, 98.9867));
t_2d.push_back(cv::Point2f(631.467, 58.0267));
t_2d.push_back(cv::Point2f(207.076, 1020.59));
t_2d.push_back(cv::Point2f(1061.55, 969.387));
image_points.push_back(t_2d);
cv::calibrateCamera(object_points, image_points, cv::Size(1440, 900), cam_mat,
dist_coeffs, rvecs, tvecs, CV_CALIB_USE_INTRINSIC_GUESS);
Is this behaviour normal?
According to the docs, you need to initialize your camera matrix at least partially beforehand.
From the docs:
If CV_CALIB_USE_INTRINSIC_GUESS and/or CV_CALIB_FIX_ASPECT_RATIO are specified, some or all of fx, fy, cx, cy must be initialized before calling the function.
and
CV_CALIB_USE_INTRINSIC_GUESS cameraMatrix contains valid initial values of fx, fy, cx, cy that are optimized further. Otherwise, (cx, cy) is initially set to the image center ( imageSize is used), and focal distances are computed in a least-squares fashion.
In your case, since you haven't set cam_mat to any value, I believe c_x and c_y are being set to the image center (presumably (0,0)) and the focal distances f_x and f_y are 1 because of your use of CV_CALIB_USE_INTRINSIC_GUESS.
Try passing in 0 instead of that flag.
I just use FTGL to use it in my app. I want to use the version FTBufferFont to render font but it renders in the wrong way. The font(texture?buffer?) is flipped in the wrong axis.
I want to use this kind of orthographic settings:
void enable2D(int w, int h)
{
winWidth = w;
winHeight = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//I don't even want to swap the 3rd and 4th param
//because I like to retain the top-left as the origin
glOrtho(0, w, h, 0, 0, +1);
glMatrixMode(GL_MODELVIEW);
}
And I want the window origin to be top-left
I render the font like this:
//No pushing and popping of matrices
//No translation
font.Render("Hello World!", -1, position, spacing, FTGL::RenderMode::RENDER_FRONT);
On the other forums, they said, just scaled it down to -1, but it wont work in mine
I can't see relevant problem like in mine in google so I decide to ask this here again.
Update:
How can I flip its axis in a proper way. I can think of like editing the source code and flip the texture coordinates but its not good.
I really need a quick fix..
When I do this:
SpriteBatch spriteBatch = new SpriteBatch();
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho(0, 320, 0, 240, -1, 1));
spriteBatch.begin();
spriteBatch.draw(textureRegion, 0, 0);
spriteBatch.end();
SpriteBatch will draw the textureRegion onto the coordinate system 320-240 that I have specified to the whole screen. Say I want to draw with the same coordinate system 320 240 but only on the left half of the screen (which means everything will be scaled down horizontally in the left side, leaving the right half of the screen black), how can I do?
You're going to want to use the ScissorStack. Effectively, you define a rectangle that you want to draw in. All drawing will be in the rectangle that you defined.
Rectangle scissors = new Rectangle();
Rectangle clipBounds = new Rectangle(x,y,w,h);
ScissorStack.calculateScissors(camera, spriteBatch.getTransformMatrix(), clipBounds, scissors);
ScissorStack.pushScissors(scissors);
spriteBatch.draw(...);
spriteBatch.flush();
ScissorStack.popScissors();
This will limit rendering to within the bounds of the rectangle "clipBounds".
It is also possible push multiple rectangles. Only the pixels of the sprites that are within all of the rectangles will be rendered.
From http://code.google.com/p/libgdx/wiki/GraphicsScissors
Before rendering the batch, you can set the viewport to draw on a specific screen area. The important line is:
Gdx.gl.glViewport(x, y, w, h);
The viewport usually starts at x = 0 and y = 0 and extends to the full width and height of the screen. If we want to see only a part of that original viewport, we need to change both the size and the starting position. To draw only on the left half of the screen, use:
x = 0;
y = 0;
w = Gdx.graphics.getWidth()/2;
h = Gdx.graphics.getWidth();
I found the solution here and originally answered this question to a slightly more complicated problem, but the technique is the same.
To focus on any different portion of the viewport, simply choose x, y, w, and h accordingly. If you're going to do any more rendering in the normal fashion, make sure to reset the viewport with the original x, y, w, and h values.
Perhaps I am misunderstanding the question, but could you not just double the viewport width, setting it to 640 instead of 320?
SpriteBatch spriteBatch = new SpriteBatch;
spriteBatch.setProjectionMatrix(new Matrix4().setToOrtho(0, 640, 0, 240, -1, 1));
spriteBatch.begin();
spriteBatch.draw(textureRegion, 0, 0);
spriteBatch.end();
You could either
double the viewport width of the SpriteBatch
use a Sprite and set its width scale to 0.5f (be careful about the origin) and use its draw(SpriteBatch) method to draw it.
I have some questions about the screen set up. Originally when I would draw a triangle the x vector 1 would be all the way to the right and -1 would be all the way to the left. Now I have adjusted it to account for the different aspect ratio of the window. My new question how do I make the numbers which are used to render a 2d tri go along with the pixel values. If my window is 480 pixels wide and 320 tall I want to have to enter this to span the screen with a tri
glBegin(GL_TRIANGLES);
glVertex2f(240, 320);
glVertex2f(480, 0);
glVertex2f(0, 0);
glEnd();
but instead it currently looks like this
glBegin(GL_TRIANGLES);
glVertex2f(0, 1);
glVertex2f(1, -1);
glVertex2f(-1, -1);
glEnd();
Any ideas?
You need to use functions glViewport and glOrtho with correct values. Basically glViewport sets the part of your window capable of rendering 3D-Graphics using OpenGL. glOrtho establishes coordinate system within that part of a window using OpenGL's coordinates.
So for your task you need to know exact width and height of your window. If you are saying they are 480 and 320 respectively then you need to call
glViewport(0, 0, 480, 320)
// or: glViewport ( 0,0,w,h)
somewhere, maybe in your SizeChanging-handler(if you are using WINAPI it is WM_SIZE message)
Next, when establishing OpenGL's scene you need to specify OpenGL's coordinates. For orthographic projection they will be the same as dimensions of a window so
glOrtho(-240, 240, -160, 160, -100, 100)
// or: glOrtho ( -w/2, w/2, -h/2, h/2, -100, 100 );
is siutable for your purppose. Not that here I'm using depth of 200 (z goes from -100 to 100).
Next on your rendering routine you may draw your triangle
Since the second piece of code is working for you, I assume your transformation matrices are all identity or you have a shader that bypasses them. Also your viewport is spanning the whole window.
In general if your viewport starts at (x0,y0) and has WxH size, the normalized coordinates (x,y) you feed to glVertex2f will be transformed to (vx,vy) as follows:
vx = x0 + (x * .5f + .5f) * W
vy = y0 + (y * .5f + .5f) * H
If you want to use pixel coordinates you can use the function
void vertex2(int x, int y)
{
float vx = (float(x) + .5f) / 480.f;
float vy = (float(y) + .5f) / 320.f;
glVertex3f(vx, vy, -1.f);
}
The -1 z value is the closest depth to the viewer. It's negative because the z is assumed to be reflected after the transformation (which is identity in your case).
The addition of .5f is because the rasterizer considers a pixel as a 1x1 quad and evaluates the coverage of your triangle in the middle of this quad.