Invalid conversion from int to SDL_RendererFlip - sdl

I'm trying to flip an image both horizontally and vertically. It doesn't seem to be working though:
SDL_RenderCopyEx(renderer, ResourceManager::GetInstance().getTexture("rpg_pack"), &wood_corner, &rect, 0, 0, SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL);
I'm running SDL, image, mixer, ttf and net.

Try
SDL_RendererFlip flip = (SDL_RendererFlip)(SDL_FLIP_HORIZONTAL | SDL_FLIP_VERTICAL);
SDL_RenderCopyEx(renderer, ResourceManager::GetInstance().getTexture("rpg_pack"), &wood_corner, &rect, 0, 0, flip);

Related

glfw window with no title bar

I am trying to make a way to toggle my window between windowed mode and fullscreen mode. I had done it successfully except for one problem. The title bar is not working! You can’t move the window either. Without this piece of code everything works just fine.
setFullscreen method:
void Window::setFullscreen(bool fullscreen)
{
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
if (fullscreen) {
glfwSetWindowMonitor(m_window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
glViewport(0, 0, mode->width, mode->height);
}
if (!fullscreen) {
glfwSetWindowMonitor(m_window, nullptr, 0, 0, m_width, m_height, GLFW_DONT_CARE);
glViewport(0, 0, m_width, m_height);
}
}
The result of the code:
#tomasantunes help me figure this out.
in setFullscreen I am setting the window to be at 0, 0 or the top left of the screen. The title bar didn't actually disappear is was just off screen. so if I set the window to be at 100, 100 instead I get the title bar back. This was pretty dumb of me to make a stupid mistake like this.
if (!fullscreen) {
glfwSetWindowMonitor(m_window, nullptr, 0, 0, m_width, m_height, GLFW_DONT_CARE); // I set the position to 0,0 in the 3rd and 4th parameter
glViewport(0, 0, m_width, m_height);
}
Fixed code:
if (!fullscreen) {
glfwSetWindowMonitor(m_window, nullptr, 100, 100, m_width, m_height, GLFW_DONT_CARE); // I set the position to 100, 100
glViewport(0, 0, m_width, m_height);
}
New result:
Not sure if you are still looking for an answer, however, the code I have here fixes that same problem you were initially having.
Before changing to full-screen mode, save the window position and size.
int xPos, yPos, width, height; //have somewhere stored out of function scope.
glfwGetWindowPos(windowPtr, &xPos, &yPos);
glfwGetWindowSize(windowPtr, &width, &height);
and then when changing from full-screen back to windowed mode, apply the saved positions and size properties.
glfwSetWindowMonitor(windowPtr, nullptr, xPos, yPos, width, height, 0); //Refresh rate is ignored without an active monitor.

How to show a PNG image with 25% opacity using GDI+? (MFC)

I am trying to output a PNG image by using GDI+, MFC. I want to output it with 25% opacity. Below is the way to output a PNG image on x=10, y=10:
CDC *pDC =GetDC();
Graphics graphics(pDC->m_hDC);
Image image(L"test1.png", FALSE);
graphics.DrawImage(&image, 10, 10);
But I don't know how to make it translucent. Any idea?
To draw the image with alpha blending, declare Gdiplus::ImageAttributes and Gdiplus::ColorMatrix with required alpha channel:
float alpha = 0.25f;
Gdiplus::ColorMatrix matrix =
{
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, alpha, 0,
0, 0, 0, 0, 1
};
Gdiplus::ImageAttributes attrib;
attrib.SetColorMatrix(&matrix);
graphics.DrawImage(&image,
Gdiplus::Rect(10, 10, image.GetWidth(), image.GetHeight()),
0, 0, image.GetWidth(), image.GetHeight(), Gdiplus::UnitPixel, &attrib);
See also: Using a Color Matrix to Transform a Single Color
Note that GetDC() is usually not used in MFC. If you do use it, be sure to call ReleaseDC(pDC) when pDC is no longer needed. Or simply use CClientDC dc(this) which has automatic cleanup. If painting is done in OnPaint then use CPaintDC which also has automatic cleanup:
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
Gdiplus::Graphics graphics(dc);
...
}

SDL Texture transparent background

This is probably rather simple problem, but after an hour of searching and trying I still didn't manage to solve it.
I have two png files. One is a background image and second is foreground. The foreground has an alpha channel. I want to display foreground on top of background.
I'm loading foreground using:
SDL_Surface *clip = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0xff);
SDL_Rect rect = { x, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
SDL_BlitSurface(map, &rect, clip, NULL);
*block = SDL_CreateTextureFromSurface(gRenderer, clip);
Where map is some SDL_Surface.
I'm loadin backgroun using:
SDL_Surface* loadedSurface = IMG_Load(path);
//Create texture from surface pixels
SDL_Texture* newTexture = SDL_CreateTextureFromSurface(gRenderer, loadedSurface);
SDL_FreeSurface(loadedSurface);
Then I trying to connect them:
SDL_RenderCopy(gRenderer, background, NULL, &cur);
SDL_RenderCopy(gRenderer, map, NULL, &cur);
But it results in foreground image with black background. What am i doing wrong?
You should add these 2 lines,
Uint32 colorkey = SDL_MapRGB(loadedSurface->format, 0, 0, 0);
SDL_SetColorKey(loadedSurface, SDL_TRUE, colorkey);
before this line in your code
SDL_Texture* newTexture = SDL_CreateTextureFromSurface(gRenderer, loadedSurface);

SDL2 Alpha Not Showing Up

In a game loop that I have, part of the drawing section is:
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 100);
SDL_RenderFillRect(renderer, &blur);
renderer is my renderer and blur is my rect that takes up the whole screen:
SDL_Rect blur;
blur.x = 0;
blur.y = 0;
blur.w = 640;
blur.h = 480;
My problem is that the rect isn't semi transparent. Whenever it draws it, all there is is black.
You cant even see the text that I have underneath. How do I fix this? Does my renderer not support
alpha?
The reason the alpha value isn't affecting anything is because you need to specify which colour blending method you want to use beforehand with this function:
int SDL_SetRenderDrawBlendMode(SDL_Renderer* renderer, SDL_BlendMode blendMode)
The blendMode parameter controls how colour blending works. For alpha color blending, use SDL_BLENDMODE_BLEND:
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 100);
SDL_RenderFillRect(renderer, &blur);

Slight undesired transparency from FillRectangle

I have a window created with the WS_EX_LAYERED window style. I am currently drawing onto a memory bitmap using GDI+, and using UpdateLayeredWindow to update the graphical content of my layered window.
Here's a snippet of my code:
void Redraw(HWND hWnd, int width, int height) {
static bool floppy = true;
floppy = !floppy;
HDC hScreenDC = GetDC(HWND_DESKTOP);
HDC hMemDC = CreateCompatibleDC(hScreenDC);
HBITMAP hBmp = CreateCompatibleBitmap(hScreenDC, width, height);
HGDIOBJ hObj = SelectObject(hMemDC, hBmp);
Graphics gfx(hMemDC);
SolidBrush b(Color(254, (floppy ? 255 : 0), (floppy ? 0 : 255), 0));
gfx.FillRectangle(&b, Rect(0, 0, width, height));
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = AC_SRC_ALPHA;
POINT src = { 0, 0 };
SIZE size;
size.cx = width;
size.cy = height;
Assert(UpdateLayeredWindow(
hWnd,
hScreenDC,
NULL,
&size,
hMemDC,
&src,
RGB(0, 0, 0),
&blend,
ULW_ALPHA
));
SelectObject(hMemDC, hObj);
DeleteObject(hBmp);
DeleteDC(hMemDC);
ReleaseDC(HWND_DESKTOP, hScreenDC);
}
When creating my SolidBrush, I specified the value of 254 for the alpha component. This results in a 99.6% opaque fill, which is not what I want.
When I specify 255 as the alpha component, there appears to be no fill; my window becomes completely transparent. This is an issue because I wish to draw shapes that are 100% opaque, but I also wish to draw some that aren't.
There seems to be some qwerks with FillRectangle. This becomes apparent when we observe that using FillEllipse with a SolidBrush whose alpha component is 255, results in the shape being rendered perfectly (opaque).
Here are two work-arounds that I came up with, which each solve the issue for me:
Call FillRectangle twice
SolidBrush b(Color(254, 255, 0, 0));
gfx.FillRectangle(&b, Rect(0, 0, width, height));
gfx.FillRectangle(&b, Rect(0, 0, width, height));
Since the same area is being filled twice, they will blend and create RGB(255, 0, 0) regardless of the content behind the window (it's now 100% opaque). I do not prefer this method, as it requires every rectangle to be drawn twice.
Use FillPolygon instead
Just as with FillEllipse, FillPolygon doesn't seem to have the colour issue, unless you call it like so:
SolidBrush b(Color(255, 255, 0, 0));
Point points[4];
points[0] = Point(0, 0);
points[1] = Point(width, 0);
points[2] = Point(width, height);
points[4] = Point(0, height);
gfx.FillPolygon(&b, points, 4); //don't copy and paste - this won't work
The above code will result in a 100% transparent window. I am guessing that this is either due to some form of optimisation that passes the call to FillRectangle instead. Or - most likely - there is some problem with FillPolygon, which is called by FillRectangle. However, if you add an extra Point to the array, you can get around it:
SolidBrush b(Color(255, 255, 0, 0));
Point points[5];
points[0] = Point(0, 0);
points[1] = Point(0, 0); //<-
points[2] = Point(width, 0);
points[3] = Point(width, height);
points[4] = Point(0, height);
gfx.FillPolygon(&b, points, 5);
The above code will indeed draw a 100% opaque shape, which fixes my problem.
UpdateLayeredWindow() requires a bitmap with pre-multiplied alpha:
Note that the APIs use premultiplied alpha, which means that the red,
green and blue channel values in the bitmap must be premultiplied with
the alpha channel value. For example, if the alpha channel value is x,
the red, green and blue channels must be multiplied by x and divided
by 0xff prior to the call.
You can use Bitmap::ConvertFormat() to convert a bitmap to pre-multiplied (the format is PixelFormat32bppPARGB).