Drawrectangle border missing in GDIPlus - drawing

CPaintDC dc(this); // device context for painting
Graphics graphics(dc.m_hDC);
float x = 10
float y= 10
float width = 400;
float height = 400;
RectF rectfloat(x,y,width,height);//rectangle
RectF clipRect(rectfloat);
graphics.SetClip(clipRect,CombineModeReplace);
graphics.FillRectangle(&SolidBrush(Color(255, 255, 0, 0)), rectfloat);
float lineWidth =1;
Pen pen(Color(255,0,0,0),lineWidth);
graphics.DrawRectangle(&pen,rectfloat);
Why the right and bottom lines are missing from DrawRectangle?
If I change the pixeloffsetMode of graphics to PixelOffsetModeHalf the top and bottom line are missing.I don't want to remove the clipping.I want to know why the border is missing if I use the same dimension as clipped graphics.

Related

End cap in gdiplus with transformation is broken

I am using gdiplus inside my mfc application. I want to draw an arc ended with a cap. When I use a TranslateTransform (in this example I want to swap the positive angle direction), the end cap is crossed by a line.
I used only this simple code inside the OnPaint method:
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);
Gdiplus::Graphics gdip(dc.GetSafeHdc());
gdip.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
Gdiplus::SolidBrush brush(Gdiplus::Color(255, 255, 255));
gdip.FillRectangle(&brush, rect.left, rect.top, rect.Width(), rect.Height());
Gdiplus::Pen pen(Gdiplus::Color(0, 0, 0), 1.0f);
Gdiplus::AdjustableArrowCap endArrow(10.0f, 10.0f);
pen.SetCustomEndCap(&endArrow);
int radius = 100;
gdip.TranslateTransform(rect.CenterPoint().x, rect.CenterPoint().y);
gdip.ScaleTransform(1.0f, -1.0f);
gdip.DrawArc(&pen, -radius, -radius, 2 * radius, 2 * radius, 0.0f, 90.0f);
If I remove the "gdip.TranslateTransform..." line the direction is opposite but the end cap is ok. Is this a known issue? Does anybody know how to set the angle orientation correctly so as the end caps stay ok?

Windows API CRect Inverting so works like graph paper

I guess i am old school when it comes to doing graphics (graphs) etc.
My Brain = Bottom/Left is 0,0, Top is Size y, Right is Size x
DC Rect = Top/Left is 0,0, Bottom is Size y, Right is Size x
Hence I find drawing in Windows DC Rect a pain as Y is inverted and I have to flip my brain for each drawing function.
Is there a way to draw in Rect or DC in graph mode and/or flip/mirror it into the Windows dc rect?
You can move the viewport origin anywhere you like. This is done using either SetViewportOrgEx (GDI) or CDC::SetViewportOrg in MFC.
The fundamentals are explained in Microsoft's documentation under Coordinate Spaces and Transformations.
While this moves the viewport origin to an arbitrary position, it doesn't flip the orientation along the y-axis. There are several ways to accomplish that, though the easiest is probably to take advantage of adjustable viewport scaling (ScaleViewportExtEx, or CDC::ScaleViewportExt). The following OnPaint implementation draws a line from (0, 0) to (height, width). With the viewport adjustments in place, this line goes from the bottom left to the top right.
void CSampleDlg::OnPaint()
{
CPaintDC dc{ this };
CRect rc{};
GetClientRect(&rc);
auto const width{ rc.right - rc.left };
auto const height{ rc.bottom - rc.top };
dc.SetMapMode(MM_ANISOTROPIC);
dc.SetViewportOrg(0, height);
dc.ScaleViewportExt(1, 1, -1, 1);
dc.MoveTo(0, 0);
dc.LineTo(width, height);
}

C++ Winapi - How to draw a fill shape rectangle and set the border thickness?

I'm trying to draw a rectangle with a border.
RECT rect;
GetClientRect(hwnd, &rect);
FillRect((HDC)wParam, &rect, CreateSolidBrush(RGB(0,0,0))); //black fill
FrameRect((HDC)wParam, &rect, CreateSolidBrush(RGB(255,0,0))); //red border
The above code works, though I'm not actually sure if that's the proper way to do it.
Anyway, I would like to set the thickness of the border. But I'm having a hard time figuring how. Can anyone can point me in the right direction or much better give a working example?
If GDI+ is allowed then this is how I'll do it
int width = 100; //set the width.
int height = 100; //set the height.
int borderSize = 5; //set border size.
HDC hdc = GetDC(hwnd); //don't forget to release later when done.
Graphics g(hdc);
SolidBrush brush((Color(255, 241, 103, 210))); //Set the fill color.
Pen pen(Color(255,255, 0, 0), borderSize); //Set the border color and border size.
width = width-borderSize; //deduct the border size to width to get the same point we wanted, for border only.
height = height-borderSize; //deduct the border size to height to get the same point we wanted, for border only
g.DrawRectangle(&pen, (borderSize / 2), (borderSize / 2), width, height); //draw the border
g.FillRectangle(&brush, borderSize, borderSize, width-borderSize, height - borderSize); //draw the fill shape, and again deduct the border size to the width and height to get the same point we wanted.
DeleteObject(&brush); //always delete object
DeleteObject(&pen); //always delete object
ReleaseDC(hwnd, hdc); //always release hdc
It's a little tricky, refer to the comments for the explanation.
FrameRect documentation says
The width and height of the border are always one logical unit.
So, one option is to change the mapping between logical units and physical units. If you don't want to mess up subsequent drawing operations, you'll have to save the old mapping and restore it after drawing your rectangle and frame. And the rectangle dimensions will need to change when the mapping changes. What a mess!
A better and simpler option is to stop using FrameRect. Simply use FillRect and the border brush, then DeflateRect to obtain a rectangle representing the interior, and FillRect that rectangle with your fill brush. The parameters to DeflateRect will determine the border thickness.
This doesn't work for creating hollow borders the way that FrameRect does, but for a border on a filled rectangle it is an elegant solution.

How glm::ortho works

I am fairly new to OpenGL and I am trying to handle a window resizing event using glm::ortho. I am displaying a simple triangle on screen and I am trying to make it so it keeps the same width/height ratio upon window resizing. However, when I resize the window, the triangle just disappears.
Here is my window resizing handling function:
int width = 800, height = 800;
void windowResized(GLFWwindow* window, int width2, int height2) {
width = width2;
height = height2;
glViewport(0, 0, width, height);
proj_matrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f);
}
Cheers!

How to center fullscreen window

I have a 16:9 display where I'd like to show fullscreen SDL window which is in 4:3 mode.SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN) sets the window to the left side of the screen and leaves a big black bar to the right.
I'd like to center the window and have black bars on the left and the right side.
It seems that SDL_SetWindowPosition(window, x, y) has no effect on window when it is in fullscreen mode. Can I center the fullscreen window in SDL2?
There are two situation:
(1) display with renderer and texture base on window size.
(2) display with screen and surface base on pixel.
For (1) here is a simple solution base on setting view port for renderer.(no testing but a guideline)
void SDL_SetRendererViewportRatio_4_3(SDL_Window *window,
SDL_Renderer *renderer
SDL_Rect *viewport) {
Uint8 r, g, b, a;
SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_SetRenderDrawColor(renderer, r, g, b, a);
int w, h;
SDL_GetWindowSize(window, &w, &h);
if (w * 3 > h * 4) {
viewport->w = h * 4 / 3;
viewport->h = h;
} else {
viewport->w = w;
viewport->h = w * 3 / 4;
}
viewport->x = (w - viewport->w) / 2;
viewport->y = (h - viewport->h) / 2;
SDL_RenderSetViewport(renderer, viewport);
}
Note that you should call this function whenever window changed size.
For (2) I guess you should calculate the coordinate of surface and draw big black bars by yourself. It is more difficult that I cannot prove simple solution.