GDI+ equivalent of GDI Rectangle - winapi

What is the GDI+ equivalent of the GDI Rectangle function?
| Library | Outline | Fill interior | Both |
|---------|---------------|---------------|-------------|
| GDI | FrameRect | FillRect | Rectangle |
| GDI+ | DrawRectangle | FillRectangle | ? |

GDI+ version of Rectangle
Delphi:
class procedure TGDIPlusHelper.Rectangle(g: TGPGraphics; OutlinePen: TGPPen; InteriorFillBrush: TGPBrush; x, y, width, height: Single);
begin
//GDI has Rectangle.
//GDI+ we simulate it with FillRectangle followed by DrawRectangle
g.FillRectangle(InteriorFillBrush, x, y, width, height);
g.DrawRectangle(OutlinePen, x, y, width, height);
end;
C#:
void Rectangle(Graphics g, Pen outlinePen; Brush interiorFillBrush, Single x, Single y, Single width, Single height)
{
//GDI has Rectangle.
//GDI+ we simulate it with FillRectangle followed by DrawRectangle
g.FillRectangle(InteriorFillBrush, x, y, width, height);
g.DrawRectangle(OutlinePen, x, y, width, height);
}

Related

MFC: strange behavior of CDC and DrawText with DT_CALCRECT?

In BeginPrinting, I calculate the printing rect like below. I rely on this to count the number of pages.
CRect rect(30, -50, 200, -60);
int height = pDC->DrawText(cstr, &rect, DT_EDITCONTROL | DT_WORDBREAK | DT_LEFT | DT_CALCRECT);
Then in OnPrint, I do the same calculation again. However, the height result is different. I don't know what could be wrong with it.

LibGDX Rotating a sprite at each iteration

I'm using the function
SpriteBatch.draw(region, x, y, originX, originY, width, height, scaleX, scaleY, rotation);
And I call it as, being screen a SpriteBatch and img as Sprite, the variable dir is in radians:
screen.draw(img, x, y, 0, 0, img.getWidth(), img.getHeight(), 0.8f, 0.8f, dir*180/((float) Math.PI));
What I'm getting is a rotation around a pivot and not the center of the image nor the coordinates x,y which holds that said center.
I have already tried to use the sprite functions, centerOrigin and setCenter and neither of them changes to what I Want.
Set all the scaling and position and rotation on the sprite img and then call img.draw(spriteBatch); instead of spriteBatch.draw(...). The spriteBatch.draw(...) method that you are calling is not aware of any parameters that you set on the sprite, such as calling setCenter on it, so you have to draw it from the sprite.
The X and Y co-ordinates which represent the centre of the object should be given as originX and originY if you want the image to rotate around its centre.
screen.draw(img, x, y, img.getWidth() / 2, img.getHeight() / 2, img.getWidth(), img.getHeight(), 0.8f, 0.8f, dir*180/((float) Math.PI));

Button region Win32Api

I create a PUSHBUTTON with this code:
hWndBtn = CreateWindow(L"Button", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, x, y, width, height, hWndParent, (HMENU)IDC_MYBUTTON, hInst, NULL);
Then, I create a Ellipse region:
HRGN hRgn = CreateEllipticRgn(x1, y1, x2, y2);
Finally I set button region:
SetWindowRgn(hWndBtn, hRgn, true);
But my button is still rectangle. How can I make it an ellipse?
SetWindowRgn only works on top-level windows, not child windows.

openGL image quality (blured)

i use openGL to create an slideshow app. Unfortunatly the images rendered with openGL look blured compared to the gnome image viewer.
Here are the 2 Screenshots
(opengl) http://tinyurl.com/dxmnzpc
(image viewer) http://tinyurl.com/8hshv2a
and this is the base image:
http://tinyurl.com/97ho4rp
the image has the native size of my screen. (2560x1440)
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/freeglut.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <unistd.h>
GLuint text = 0;
GLuint load_texture(const char* file) {
SDL_Surface* surface = IMG_Load(file);
GLuint texture;
glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
SDL_PixelFormat *format = surface->format;
printf("%d %d \n",surface->w,surface->h);
if (format->Amask) {
gluBuild2DMipmaps(GL_TEXTURE_2D, 4,surface->w, surface->h, GL_RGBA,GL_UNSIGNED_BYTE, surface->pixels);
} else {
gluBuild2DMipmaps(GL_TEXTURE_2D, 3,surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
}
SDL_FreeSurface(surface);
return texture;
}
void display(void) {
GLdouble offset_x = -1;
GLdouble offset_y = -1;
int p_viewport[4];
glGetIntegerv(GL_VIEWPORT, p_viewport);
GLfloat gl_width = p_viewport[2];//width(); // GL context size
GLfloat gl_height = p_viewport[3];//height();
glClearColor (0.0,2.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glEnable( GL_TEXTURE_2D );
glTranslatef(0,0,0);
glBindTexture( GL_TEXTURE_2D, text);
gl_width=2; gl_height=2;
glBegin(GL_QUADS);
glTexCoord2f(0, 1); //4
glVertex2f(offset_x, offset_y);
glTexCoord2f(1, 1); //3
glVertex2f(offset_x + gl_width, offset_y);
glTexCoord2f(1, 0); // 2
glVertex2f(offset_x + gl_width, offset_y + gl_height);
glTexCoord2f(0, 0); // 1
glVertex2f(offset_x, offset_y + gl_height);
glEnd();
glutSwapBuffers();
}
int main(int argc, char **argv) {
glutInit(&argc,argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutGameModeString("2560x1440:24");
glutEnterGameMode();
text = load_texture("/tmp/raspberry/out.jpg");
glutDisplayFunc(display);
glutMainLoop();
}
UPDATED TRY
void display(void)
{
GLdouble texture_x = 0;
GLdouble texture_y = 0;
GLdouble texture_width = 0;
GLdouble texture_height = 0;
glViewport(0,0,width,height);
glClearColor (0.0,2.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, -1, 1);
//Do pixel calculatons
texture_x = ((2.0*1-1) / (2*width));
texture_y = ((2.0*1-1) / (2*height));
texture_width=((2.0*width-1)/(2*width));
texture_height=((2.0*height-1)/(2*height));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,0);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, text);
glBegin(GL_QUADS);
glTexCoord2f(texture_x, texture_height); //4
glVertex2f(0, 0);
glTexCoord2f(texture_width, texture_height); //3
glVertex2f(width, 0);
glTexCoord2f(texture_width, texture_y); // 2
glVertex2f(width,height);
glTexCoord2f(texture_y, texture_y); // 1
glVertex2f(0,height);
glEnd();
glutSwapBuffers();
}
What you run into is a variation of the fencepost problem, that arises from how OpenGL deals with texture coordinates. OpenGL does not address a texture's pixels (texels), but uses the image data as support for a interpolation, that in fact covers a wider range than the images pixels. So the texture coordinates 0 and 1 don't hit the left-/bottom most and right-/top most pixels, but go a little further, in fact.
Let's say the texture is 8 pixels wide:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
^ ^ ^ ^ ^ ^ ^ ^ ^
0.0 | | | | | | | 1.0
| | | | | | | | |
0/8 1/8 2/8 3/8 4/8 5/8 6/8 7/8 8/8
The digits denote the texture's pixels, the bars the edges of the texture and in case of nearest filtering the border between pixels. You however want to hit the pixels' centers. So you're interested in the texture coordinates
(0/8 + 1/8)/2 = 1 / (2 * 8)
(1/8 + 2/8)/2 = 3 / (2 * 8)
...
(7/8 + 8/8)/2 = 15 / (2 * 8)
Or more generally for pixel i in a N wide texture the proper texture coordinate is
(2i + 1)/(2N)
However if you want to perfectly align your texture with the screen pixels, remember that what you specify as coordinates are not a quad's pixels, but edges, which, depending on projection may align with screen pixel edges, not centers, thus may require other texture coordinates.
Note that if you follow this, irregardless of your filtering mode and mipmaps your image will always look clear and crisp, because the interpolation hits exactly your sampling support, which is your input image. Switching to another filtering mode, like GL_NEAREST may look right at first look, but it's actually not correct, because it will alias your samples. So don't do it.
There are few other issues with your code as well, but they're not as a huge problem. First and foremost, you're choosing a rather arcane way to viewport dimensions. You're (probably without further thought) explout the fact that the default OpenGL viewport is the size of the window the context has been created with. You're using SDL, which has the side effect, that this approach won't bite you, as long as you stick with SDL-1. But switch to any other framework, that may create the context via a proxy drawable, and you're running into a problem.
The canonical way is usually to retrieve the window size from the windowing system (SDL in your case) and then setting the viewport at one of the first actions in the display function.
Another issue is your use of gluBuildMipmaps, because a) you don't want to use mipmaps and b) since OpenGL-2 you can upload texture images of arbitrary size (i.e. you're not limited to powers of 2 for the dimensions), which completely eliminates the need for gluBuildMipmaps. So don't use it. Just use glTexImage2D directly and switch to a non-mipmapping filtering mode.
Update due to question update
The way you calculate the texture coordinates still doesn't look right. It seems like you're starting to count at 1. Texture pixels are 0 base indexed, so…
This is how I'd do it:
Assuming the projection maps the viewport
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, win_width, 0, win_height, -1, 1);
glViewport(0, 0, win_width, win_height);
we calculate the texture coordinates as
//Do pixel calculatons
glBindTexture( GL_TEXTURE_2D, text);
GLint tex_width, tex_height;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex_width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex_height);
texture_s1 = 1. / (2*width); // (2*0-1
texture_t1 = 1. / (2*height);
texture_s2 = (2.*(tex_width -1) + 1) / (2*width);
texture_t2 = (2.*(tex_height-1) + 1) / (2*height);
Note that tex_width and tex_height give the number of pixels in each direction, but the coordinates are 0 based, so you've to subtract 1 from them for the texture coordinate mapping. Hence we also use a constant 1 in the numerator for the s1, t1 coordinates.
The rest looks okay, given the projection you choose
glEnable( GL_TEXTURE_2D );
glBegin(GL_QUADS);
glTexCoord2f(s1, t1); //4
glVertex2f(0, 0);
glTexCoord2f(s2, t1); //3
glVertex2f(tex_width, 0);
glTexCoord2f(s2, t2); // 2
glVertex2f(tex_width,tex_height);
glTexCoord2f(s1, t2); // 1
glVertex2f(0,tex_height);
glEnd();
I'm not sure if this is really the problem, but I think you don't need/want mipmaps here. Have you tried using glTexImage2D instead of gluBuild2DMipmaps in combination with nearest neighbor filtering (glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN/MAG_FILTER, GL_NEAREST);)?

Minimum and maximum of a box?

Given the, width, height and depth of a box and its center point, how could I find the minimum, x, y, and z coordinate and the maximum x, y and z coordinate without bruteforcing through each vertex? its an AABB box.
Thanks
from a top view
---------------
| |
| |
| c |
| |
|--------------|
This should do it:
(xmin, ymin, zmin) = (xcentre, ycentre, zcentre) - (width, height, depth) / 2
(xmax, ymax, zmax) = (xcentre, ycentre, zcentre) + (width, height, depth) / 2
or in full:
xmin = xcentre - width / 2
xmax = xcentre + width / 2
ymin = ycentre - height / 2
...

Resources