C++ image loading with SDL2 and SDL_image - c++

I have a question about image loading in SDL2 with the SDL_image libary.
Unfortunatly i dont find any information about IMG_LoadTexture in the SDL_image documentation.
So what is the difference between using IMG_LoadTexture to directly load an PNG image as texture and using IMG_Load to load a surface an then convert it to an texture with SDL_CreateTextureFromSurface? Is there any benefit in using one over the other?

When in doubt, check source (easily browsable at https://hg.libsdl.org/) - https://hg.libsdl.org/SDL_image/file/ca95d0e31aec/IMG.c#l209 :
SDL_Texture *IMG_LoadTexture(SDL_Renderer *renderer, const char *file)
{
SDL_Texture *texture = NULL;
SDL_Surface *surface = IMG_Load(file);
if (surface) {
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
}
return texture;
}

I've just finished writing a GUI in SDL. So IMG_Load is the old way to load in SDL images, from SDL 1 i believe. The way it used to work is that you'd have SDL surfaces, and then you'd merge them together and then blit them to the screen, or blit sections of the surfaces to other surfaces, using masks etc. The problem is some stuff - for example drawing lines, now requires a renderer.
Renderers pull in the new features of SDL2. It also means that you can't just blit your surfaces necessarily to a texture without converting it first.
So, in summary, if you can get away with using IMG_load and using the old SDL features, do so because it's more intuitive. If you are planning to draw any lines at all, or anything that use the SDL renderer, then you'll need to learn how to convert between surfaces and textures!
Regarding your original question, because i realise i'm not answering it very well, normally it's best to use the right function calls, such as IMG_LoadTexture directly, rather than IMG_Load and then convert it to a texture. SDL talks to the hardware directly and has a surprising amount of optimisation. Converting the surface to a texture, presumably involves blitting, which means copying a substantial amount of memory.
However, it seems that in this case at the time of writing this, there is absolutely no difference at all. The function IMG_LoadTexture does exactly the same thing.
But once again, check, you might not need textures at all, if not, you could save yourself some work ;)

Related

SDL2: How to render without clearing the screen

I'm trying to make a SDL2 adapter for a graphics library. I believe this library assumes that all the things it draws in the screens stay in the screen as long as it never draws something in top of it. (See the end of the question for details about this)
What would be the best way to do it?
I've come across multiple solutions, including:
Hardware rendering without calling SDL_RenderClear. The problem with this is that SDL uses a double buffer, so the contents can end up in either of them, and I end up seing only a subset of the render at a time.
Software rendering, in which if I'm understanding SDL correctly, it would mean having a surface that I mapped to a texture, so I can render the texture, and I would edit the pixels field of the surface in main memory. This would be very slow, and also as the library expects everything rendered instantly and has no notion of frames would mean to send the data to the gpu every time there's an update (even single pixels).
I'm probably missing something about SDL2 and definitely about the library (Adafruit-GFX-Library). What does transaction api means in this context? I've not been able to find any information about it, and I feel like it could be something important.
In my understanding of SDL2 and general rendering application programming, SDL2 is designed that you draw a complete frame every time, meaning you would clear your "current window" either by OpenGL API calls
glClearColor(0, 1.0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
which clears the current OpenGL context i.e. frame buffer, of which you would have 2 or by using the SDL2 renderer which I am not familiar with.
Then you would swap the buffers, and repeat. (Which fits perfectly with this architecture proposal I am relying on)
So either you would have to replay the draw commands from your library for the second frame somehow, or you could also disable the double frame buffering, at least for the OpenGL backend, by
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
(For the other OpenGL SDL2 setup code see this GitHub repository with a general helper class of mine

What is Renderer and Texture in SDL2, conceptually?

I was moving from SDL to SDL2, and was confused of the 'render & texture' system introduced.
Back in SDL, the most frequent operation was creating Surface's and BlitSurface them onto screen. Now there seems a trend of using renderers and textures. However, this is extremely slow (in terms of coding overhead) from my point. Why can't I just load_BMP and BlitSurface as before? What good can be introduced from this whole window-renderer-texture thing?
I have read a couple threads What is a SDL renderer? but still a little confusing.
So..
Will the old Surface way work in SDL2?
What is the point in Renderer & Texture? (could be about hardware-accelaration according to a little googling, but not sure what that means)
You might want to take a look at the migration guide for SDL2, it provides information on the new way of dealing with 2D graphics.
The point of using textures instead of surfaces is that textures works on the GPU and get loaded into video memory and surfaces works in system memory with the CPU and since GPUs are much better suited than CPU for handling graphics it will be faster. Also, the renderer hides the underlying system used (it could be D3D, OpenGL, or something else).
You can still load surfaces, but you'll have to convert them to textures before rendering them or use the SDL_UpdateWindowSurface and SDL_GetWindowSurface functions; the latter link includes an example on how to use them.
As for the SDL2 approach being slow, as you assert, I don't agree with you, you set up the window and renderer once, load your textures much like you loaded surfaces, copy them to the renderer instead of blitting and finally use SDL_RenderPresent instead of SDL_Flip. Not that different really :)
But, take a look at the migration guide, it has the information you're looking for.

LibGDX: BufferedImage into Texture

I'm trying to play videos within a LibGDX application. I've managed to load the individual video frames sequentially into a java.awt.BufferedImage using Xuggler.
Now I'm stuck trying to get that into a LibGDX Texture. Anyone know a way to do this?
I managed to find these two LibGDX files that happen to use BufferedImage's, however can't see how to use this to get my data into a Texture :(
LibGDX JoglPixmap.java
LibGDX JoglTexture.java
as soon as you transformed your bufferedImage to a pixmap just use the Texture constructor passing in a pixmap:
Texture newTexture = new Texture(myPixmap);
There are methods to construct an empty Pixmap and draw onto it. Use this pixmap then as described above
If you are using LibGDX, I have to say that I don't recommend also using BufferedImages (from Java2D), instead you could use a Pixmap, or if you really do need BufferedImages, then I guess you could use ImageIO to save the image to a file, bring the file back in as a texture, then delete the file, but that seems quite hacky and inefficient.

C++ Spin Image Resources

Does anyone know of a good resource that will show me how to load an image with C++ and spin it?
What I mean by spin is to do an actual animation of the image rotating and not physically rotating the image and saving it.
If I am not clear on what I am asking, please ask for clarification before downvoting.
Thanks
I would definitely default to OpenGL for this type of task, you can load the image into a Texture, then either redraw the image at different angles, or better yet you can just spin the 'camera' in the OpenGL engine. There are loads of OpenGL tutorials around, a quick google search will get you everything you need.
You could use SDL and the extension sdl_image and/or sdl_gfx
In Windows using GDI+ you could show rotated image in the following way:
Graphics graphics( GetSafeHwnd() ); // initialize from window handle
// You can construct Image objects from a variety of
// file types including BMP, ICON, GIF, JPEG, Exif, PNG, TIFF, WMF, and EMF.
Image image( L"someimage.bmp" );
graphics.RotateTransform( 30.0f ); // 30 - angle, in degrees.
graphics.DrawImage( &image, 0, 0 ); // draw rotated image
You could read here more detailed explanation.
Second solution is to use DirectX. You could create texture from file and later render it. It is not trivial solution, but it'll use hardware acceleration and will give you the best performance.
On Windows 7 there is available new API called Direct2D. I have not used it yet, but it looks promising.
Direct2D provides Win32 developers with the ability to perform 2-D graphics rendering tasks with superior performance and visual quality.
i agree with DeusAduro. OpenGL is a good way of doing this.
you can also do this with Qt
The "roll-your-own" solution is difficult.
I'd suggest looking into WPF - it might have some nice options in an image control.

DirectX9 Texture of arbitrary size (non 2^n)

I'm relatively new to DirectX and have to work on an existing C++ DX9 application. The app does tracking on a camera images and displays some DirectDraw (ie. 2d) content. The camera has an aspect ratio of 4:3 (always) and the screen is undefined.
I want to load a texture and use this texture as a mask, so tracking and displaying of the content only are done within the masked area of the texture. Therefore I'd like to load a texture that has exactly the same size as the camera images.
I've done all steps to load the texture, but when I call GetDesc() the fields Width and Height of the D3DSURFACE_DESC struct are of the next bigger power-of-2 size. I do not care that the actual memory used for the texture is optimized for the graphics card but I did not find any way to get the dimensions of the original image file on the harddisk.
I do (and did, but with no success) search a possibility to load the image into the computers RAM only (graphicscard is not required) without adding a new dependency to the code. Otherwise I'd have to use OpenCV (which might anyway be a good idea when it comes to tracking), but at the moment I still try to avoid including OpenCV.
thanks for your hints,
Norbert
D3DXCreateTextureFromFileEx with parameters 3 and 4 being
D3DX_DEFAULT_NONPOW2.
After that, you can use
D3DSURFACE_DESC Desc;
m_Sprite->GetLevelDesc(0, &Desc);
to fetch the height & width.
D3DXGetImageInfoFromFile may be what you are looking for.
I'm assuming you are using D3DX because I don't think Direct3D automatically resizes any textures.