I made a short program to test out SDL2, though there are some things I don't understand how they work.
So I have created a window and a surface:
SDL_Window *window = nullptr;
SDL_Surface *windowSurface = nullptr;
Now I have this (the part I don't get):
window = SDL_CreateWindow("Window name", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
windowSurface = SDL_GetWindowSurface(window);
So the first line: I use the SDL_createWindow() function to create a window called window I assume. The second line, I got no idea whats going on - explanation?
Finally I have this:
SDL_BlitSurface(currentImage, NULL, windowSurface, NULL);
SDL_UpdateWindowSurface(window);
followed by some clean up code to set the pointers back to nullptr and exit the program/destroy windows etc.
The code you have pasted does the following things: Creates a SDL window called "Window name", sets its horizontal and vertical positions to center, sets the window size to 640 x 480 and marks it as shown.
The second line acquires the SDL surface bind to this window.
What this means is: Create Window , actually sets up and openGL window and a GPU texture (the Surface, althou SDL2 has seperate class for Textures), to which it is going to draw. Modifying the surface acquired with GetWindowSurface will modify the pixel on the window you have just created.
Bliting is applying a array of pixel to a target texture, in the meaning : hey i got this image/prerendered frame etc.. and I want to apply it to this surface so i can show it. Blit it.
I hope this is helpful : >
You can find more information for SDL here
Official SDL wiki
LazyFoo
LazyFoo provides a full tutorial and explanations of everything for the old SDL, but a lot of the things are the same in SDL2
Related
I am using sdl2 in c++, and want to modify the window frame in my application. Can this be achieved and implemented?
I had a look here: How to change window style/theme in c++ - but I'm not sure how it can mix in.
#include "SDL.h"
SDL_Window *window;
void main()
{
window = SDL_CreateWindow("TEST", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
SDL_Delay(3000);
}
I would like to build in a file menu and edit menu to the actual frame on the header and possibly change the color or make tabs in the frame as with google chrome.
One of SDL's main goals is to abstract window creation, so you don't have to deal with each OS's little tweaks. Said that, I don't think there is a portable, clean way to that using SDL.
What I would do is to go down the level of abstraction: Use WinAPI or MFC or one of Microsoft abstractions over the WinAPI to actually customize the window and then use DirectX or OpenGL to do all graphics. You can still use SDL for audio, input, etc. though.
I have been learning about SDL 2D programming for a while and now I wanted to create a program using SDL and OpenGL combined. I set it up like this:
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL and OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
context = SDL_GL_CreateContext(window);
The program is for now just a black window with a white line displayed using OpenGl. Here is the code for the rendering:
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2d(1, 0);
glVertex2d(-1, 0);
glEnd();
SDL_GL_SwapWindow(window);
So the thing is, I would like to render textures additionally using pure SDL and a SDL_Renderer object, as I did before without OpenGL. I tried that out but it didn't work. Is it even possible to do that and how? What I did is creating a SDL_Renderer and then after drawing OpenGL stuff doing this:
SDL_Rect fillRect;
fillRect.w = 50;
fillRect.h = 50;
fillRect.x = 0;
fillRect.y = 0;
SDL_SetRenderDrawColor(renderer, 100, 200, 100, 0);
SDL_RenderFillRect(renderer, &fillRect);
SDL_RenderPresent(renderer);
But this does not work. The rectangle is not shown, although for some milliseconds it appears slightly. I feel like the OpenGL rendering is overwriting it.
SDL uses OpenGL (or in some cases Direct3D) and OpenGL has internal state which affects the GL calls in your program. The current version of SDL does not clearly indicate which states it changes or depends upon for any call and it does not include functions to reset to a known state. That means you should not mix SDL_Renderer with OpenGL yet.
However, if you really want this functionality now, you can try SDL_gpu (note: I'm the author). It does support mixing with OpenGL calls and custom shaders. You would want to specify which version of the OpenGL API you need (e.g. with GPU_InitRenderer(GPU_RENDERER_OPENGL_1, ...)) and reset the GL state that SDL_gpu uses each frame (GPU_ResetRendererState()). Check out the 3d demo in the SDL_gpu source repository for more.
https://github.com/grimfang4/sdl-gpu/blob/master/demos/3d/main.c
You can render to an SDL_Surface with SDL, and then convert it to a texture & upload it to the GPU using OpenGL.
Example code: http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture
I have been learning about SDL 2D programming for a while and now I wanted to create a program using SDL and OpenGL combined. I set it up like this:
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow("SDL and OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
context = SDL_GL_CreateContext(window);
The program is for now just a black window with a white line displayed using OpenGl. Here is the code for the rendering:
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2d(1, 0);
glVertex2d(-1, 0);
glEnd();
SDL_GL_SwapWindow(window);
So the thing is, I would like to render textures additionally using pure SDL and a SDL_Renderer object, as I did before without OpenGL. I tried that out but it didn't work. Is it even possible to do that and how? What I did is creating a SDL_Renderer and then after drawing OpenGL stuff doing this:
SDL_Rect fillRect;
fillRect.w = 50;
fillRect.h = 50;
fillRect.x = 0;
fillRect.y = 0;
SDL_SetRenderDrawColor(renderer, 100, 200, 100, 0);
SDL_RenderFillRect(renderer, &fillRect);
SDL_RenderPresent(renderer);
But this does not work. The rectangle is not shown, although for some milliseconds it appears slightly. I feel like the OpenGL rendering is overwriting it.
SDL uses OpenGL (or in some cases Direct3D) and OpenGL has internal state which affects the GL calls in your program. The current version of SDL does not clearly indicate which states it changes or depends upon for any call and it does not include functions to reset to a known state. That means you should not mix SDL_Renderer with OpenGL yet.
However, if you really want this functionality now, you can try SDL_gpu (note: I'm the author). It does support mixing with OpenGL calls and custom shaders. You would want to specify which version of the OpenGL API you need (e.g. with GPU_InitRenderer(GPU_RENDERER_OPENGL_1, ...)) and reset the GL state that SDL_gpu uses each frame (GPU_ResetRendererState()). Check out the 3d demo in the SDL_gpu source repository for more.
https://github.com/grimfang4/sdl-gpu/blob/master/demos/3d/main.c
You can render to an SDL_Surface with SDL, and then convert it to a texture & upload it to the GPU using OpenGL.
Example code: http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture
After shrinking my applications to window size mouse coordinates won't change. Graphics work fine, just mouse coordinates are problem.
My applications native size is 1920x1080. But I wan't to shrink app to 1280x720.
Here is what I'm doing right now:
Create window with 1280x720 w/h
appWindow = SDL_CreateWindow(GAME_TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOWPOS_CENTERED);
I set glViewport to match with window
glViewport(0,0,1280,720);
I make set glOrtho with native size 1920x1080
glOrtho(0, 1920, 1080, 0, -1, 1);
Like I already said, by doing this graphics do scale on new window size but mouse coordinates don't change and i need to know how to change them.
I am not sure i understand your question, but i think here is problem: glOrtho() is opengl comand not sdl, so it affects opengl graphics only. Mouse and windowing is controlled by SDL in your case.
I dont understand what you are trying to do by saying "My applications native size is 1920x1080. But I wan't to shrink app to 1280x720." if you want to resize window use SDL_SetWindowSize. And then adjust opengl viewport and projection with glViewport and glOrtho, so your opengl view and sdl window size is in sync.
Edit 1: If you want to render as it is now, by using larger view than windows, then you need to calculate mouse position by your self. sdl gives you mouse relative to window size not opengl view and projection. Math should be quite simple if you are just scaling the view.
Edit 2: in your case glOrtho(0, 1920, 1080, 0, -1, 1) projects 1920x1080 image to glViewport(0,0, 1280 ,720) view. So it scales down if i am not mistaken. So you need to scale mouse pos down to relative to scale ratio:
untested code:
mouseX= 1920.0/1280.0 * winMouse.x
mouseY= 1080.0/720.0 * winMouse.y;
I ussually experiment alot, so just try to understand what opengl does and experiment.
My program starts with a loading window while it is compiling shaders, loading textures etc. I then want to be able to launch a fullscreen application and use these resources. My understanding is that the openGL context must be the same before and after. I tried two methods for this: first of all I tried making a second window which was fullscreen, and used the SDL_GL_makecurrent command on this window to 'transfer' the context across (couldn't find where I read about this method), and secondly tried just fullscreening the loading window. Both of these methods resulted in the loading screen being moved to the top left corner of the screen. However opengl commands no longer ran properly in fullscreen, including clearing buffers which meant that the window contained the contents of my desktop/background applications.
Is there a proper way of doing this? Or is this a strange bug in sdl/opengl drivers?
Code to fullscreen original window:
//opengl commands work fine up to here
//now to fullscreen
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL_SetWindowSize(window, 1366, 768); //tried this on either side of line above and without either line
glViewport(0, 0, 1366, 768); //update viewport
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
//window should be whited, other draw commands tried and all fail or distort
SDL_GL_SwapWindow(window);
Creating a new window and using previous context:
//Fine up to here
window2 = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1366, 768, SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_SHOWN);
SDL_GL_MakeCurrent(window2, glContext); //created with SDL_GL_CreateContext(oldwindow);
//draw commands dont work
PS: running ubuntu
Update: In the second code, reusing the context in a new window, it returns an error saying 'invalid window' when it fails, which is most of the time but not always. When it fails, the screen ends up completely corrupted(black with weird white squares and patterns), ending the program will not clear the screen of this (although screenshots are perfectly fine?), but it can be restored by ctrl+f1 to terminal then ctrl+f7 back
I dont really know if its a bug. I experienced the same issue with sdl2 and opengl.
Create an regular window
attach to opengl context.
fullscreen
BOOM. black screen and crashed window.
I only noticed that issue in ubuntu.
Trought some tests i found a quick way to fix it:
Uint32 flags = 0;
flags |= SDL_WINDOW_RESIZABLE;
//bla bla bla your tags
flags |= SDL_WINDOW_OPENGL;
m_window = SDL_CreateWindow( "hello gl", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_screen.x, m_screen.y,flags);
m_glContext = SDL_GL_CreateContext(m_window);
//Set right the way the screen to fullscrene false
SDL_SetWindowFullscreen(m_window, SDL_FALSE);
Now the fullscreen seems to work without problem.