Im created GLX window, that contains CWOverrideRedirect attribute, and destroyed input shape, so it looks like OpenGL overlay. Now I am wanted to draw a 2d text or use ImGUI. A lot of examples use GLFW library. So, the main problem is to make GLFWwindow transparency and without input shape.
int attr_mask =
CWOverrideRedirect| //borderless, always on top
CWColormap|
CWBorderPixel|
CWEventMask;
window_handle = XCreateWindow( Xdisplay,
Xroot,
x, y, width, height,
0,
visual->depth,
InputOutput,
visual->visual,
attr_mask, &attr);
..............
// Destroy input shape
XRectangle rect;
XserverRegion region = XFixesCreateRegion(Xdisplay, &rect, 1);
XFixesSetWindowShapeRegion(Xdisplay, window_handle, ShapeInput, 0, 0, region);
XFixesDestroyRegion(Xdisplay, region);
if ((del_atom = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", 0)) != None) {
XSetWMProtocols(Xdisplay, window_handle, &del_atom, 1);
}
From ImGUI opengl3 example
GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL3 example", NULL, NULL);
glfwMakeContextCurrent(window);
gl3wInit();
Related
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.
I have the following working code, which attaches the OpenGL handle to an existing WinAPI window. It works fine and I can properly get the properties (height and width for example) of the WinAPI dialog through calling openGL glfwGetWindowSize(glfwWnd, &windowWidth, &windowHeight); function.
LPCTSTR WindowName = "Untitled - Notepad";
HWND hwnd = FindWindow("Notepad", WindowName);
if (!glfwInit()) {
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", NULL, NULL);
GLFWwindow* glfwWnd = glfwAttachWin32Window(hwnd, window);
GLint windowWidth, windowHeight;
glfwGetWindowSize(glfwWnd, &windowWidth, &windowHeight);
But what I actually want is for window "My Title" to be embedded inside the Notepad window frame. Which is not happening as they are still two separate windows. Any way of achieving this?
I'm making a retro pixel game so I want to make my window a very low resolution (256x256). However when I try to make it fullscreen, the whole window was just rendered top left, while leaving all other areas black.
I want to know a way of globally setting the size of each pixel in a window, in order to let it fit the fullscreen, or, a way of stretching the whole window (or a renderer?) to a specified size(and full screen) while having the (w, h) unchanged in parameter 2 and 3 in SDL_CreateWindow, and also whilst having the sizes proportional (so, if it was a square window, it should be a square window after stretched, not a rect after stretched into a rect displayer).
First, render your game to a 256x256 texture. This gist has an example, I will inline it below.
Next, figure out the correct size and position of your game texture on your actual window, and render the texture there. That will require modifications to the SDL_RenderCopyEx call, as the gist simply renders it stretched to the screen.
#include <iostream>
#ifdef __linux__
#include <SDL2/SDL.h>
#elif defined(_WIN32)
#include <SDL.h>
#endif
const int WIN_WIDTH = 640;
const int WIN_HEIGHT = 480;
int main(int argc, char **argv){
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
std::cerr << "SDL_Init failed: " << SDL_GetError() << "\n";
return 1;
}
SDL_Window *win = SDL_CreateWindow("Rendering to a texture!", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, WIN_WIDTH, WIN_HEIGHT, 0);
SDL_Renderer *renderer = SDL_CreateRenderer(win, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
//Put your own bmp image here
SDL_Surface *bmpSurf = SDL_LoadBMP("../res/image.bmp");
SDL_Texture *bmpTex = SDL_CreateTextureFromSurface(renderer, bmpSurf);
SDL_FreeSurface(bmpSurf);
//Make a target texture to render too
SDL_Texture *texTarget = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_TARGET, WIN_WIDTH, WIN_HEIGHT);
//Now render to the texture
SDL_SetRenderTarget(renderer, texTarget);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, bmpTex, NULL, NULL);
//Detach the texture
SDL_SetRenderTarget(renderer, NULL);
//Now render the texture target to our screen, but upside down
SDL_RenderClear(renderer);
SDL_RenderCopyEx(renderer, texTarget, NULL, NULL, 0, NULL, SDL_FLIP_VERTICAL);
SDL_RenderPresent(renderer);
SDL_Delay(1000);
SDL_DestroyTexture(texTarget);
SDL_DestroyTexture(bmpTex);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
I would like help with building a layered rendering system in SDL2.
I have a first layer containing a map of Paris with its roads.
I need to draw a line between two points on this map - the problem occurs when the before state of this line does not disappear.
I need to draw this line over the map and keep this.
How do I make s a system to save the map state whithout any overlaid lines drawn, and such that frame by frame I can show the map with the new state of the line overlaid on top of this?
Solved, below an example !! Thank you all
SDL_Window *window;
SDL_Renderer *render;
SDL_Texture *map; //map texture (my layer)
window = SDL_CreateWindow("Test window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
map = SDL_CreateTexture(render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 640, 480); //Creating a texture
/*Map is a red background stored in map texture*/
SDL_SetRenderDrawColor(render, 255, 0, 0, 255);
SDL_SetRenderTarget(render, map);
SDL_RenderClear(render);
SDL_SetRenderTarget(render, NULL);
/*Seting the line color*/
SDL_SetRenderDrawColor(render, 0, 255, 0, 255);
/*Coping the map texture to the render and drawing a green line on top of this*/
SDL_RenderCopy(render, map, NULL, NULL);
SDL_RenderDrawLine(render, 0, 0, 640, 480);
SDL_RenderPresent(render);
SDL_Delay(2000);
/*Another line*/
SDL_RenderCopy(render, map, NULL, NULL);
SDL_RenderDrawLine(render, 0, 480, 640, 0);
SDL_RenderPresent(render);
SDL_Delay(2000);
SDL_DestroyWindow(window);
SDL_DestroyRenderer(render);
SDL_Quit();
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);