Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
I'm attempting to integrate AGG into a project. I tried to use SDL_LockTexture to pass my surface->pixels but it doesn't work, all I get is black.
Do I have the concept backwards? Why does SDL_LockTexture have argument void**pixels? Here is my code snippet: /*     SDL_Texture* tex = SDL_CreateTexture             (ren,             SDL_PIXELFORMAT_RGBA8888,             SDL_TEXTUREACCESS_STREAMING,             frame_width,             frame_height);                 SDL_LockTexture     (         tex,         NULL,         &surf->pixels,         &surf->pitch     );     SDL_UnlockTexture(tex);         SDL_RenderCopy     (         ren,         tex,         NULL,         NULL     );     SDL_RenderPresent(ren); */ The whole program on pastebin (it is only 165 lines) - http://pastebin.com/XNsvHQnn |
|||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
Thanks for the feedback Naith, however I don't think that is my issue. To quote the wiki;
https://wiki.libsdl.org/SDL_UpdateTexture "This is a fairly slow function, intended for use with /static textures/ that do not change often. If the texture is intended to be updated often, it is preferred to create the texture as streaming and use the locking functions referenced below. While this function will work with streaming textures, for optimization reasons you may not get the pixels back if you lock the texture afterward" I figured out my issue, mostly. SDL_LockTexture has argument void** pixels, and I assumed that meant I pass it a reference to my pixel buffer, with pixels already drawn and set how I want them. Instead, SDL_LockTexture zeros the buffer and /then/ accepts new changes to it. My code now looks (pseudo) like this;SDL_Surface* surf = SDL_CreateRGBSurface ... SDL_LockSurface(surf); ... SDL_Texture* tex = SDL_CreateTexture ... SDL_LockTexture ... //draw stuff to surf->pixels //---------------------------------- ... SDL_UnlockSurface(surf); ... SDL_UnlockTexture(tex); ... SDL_RenderCopy ... SDL_RenderPresent(ren); It works, accept that the pixel format is switching from RGBA32 to ABGR32 and my colors are all wonky. http://pastebin.com/ydABzEj6 On 17 May 2015 at 04:53, Naith wrote:
|
|||||||||||||
|
Naith
|
I understand.
I think it's best if you tell me/us what you're planning to do and me- or someone else on this forum might have a solution for it. |
|||||||||||
|
Naith
|
Sorry. I missed to read some of the text in your earliest answer.
|
|||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
The plan overall is to use AGG and SDL for realtime graphics.
The current program just draws a test pattern. What is the best, cross platform way, to ensure my pixels are in the correct byte order? Some research indicates that ABGR is the most common order, is that so? I may want to represent everything like that internally, to reduce conversion expense. I just discovered SDL_GetWindowSurface. Would this offer better performance than SDL_LockTexture, in respect to drawing a pixel buffer to the screen? On 17 May 2015 at 06:56, Naith wrote:
|
|||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
Is there any difference between SDL_ConvertSurface and SDL_ConvertSurfaceFormat?
My initial intuition for assuring correct byte order is to check the texture's pixel format with SDL_Query_Texture, but that won't work, will it? It appears that the *actual* pixel format is dependent on the hardware driver, so I need to instead use SDL_GetRendererInfo... Code should look something like; SDL_Surface* surf = SDL_CreateRGBSurface ... SDL_LockSurface(surf); ... //draw stuff to surf->pixels //---------------------------------- ... SDL_UnlockSurface(surf); ... SDL_RendererInfo* info = NULL; ... SDL_GetRendererInfo(ren, info); ... SDL_Surface* conv_surf = SDL_ConvertSurface(surf, info->format); ... SDL_Surface* surf_to_tex = SDL_CreateRGBSurface ... SDL_Texture* tex = SDL_CreateTexture ... SDL_LockTexture ... SDL_UnlockTexture(tex); ... SDL_RenderCopy ... SDL_RenderPresent(ren); Okay, so I'm going to try implementing this... On 17 May 2015 at 07:48, Travis McKinney wrote:
|
|||||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
So here's what I came up with
http://pastebin.com/tkV9L62r -- it doesn't work; (the window should show a green bow-tie on a blue background) (it only shows black now) (to recap, the current goal is to efficiently convert the pixel format every frame) (this is a test, so there's only one frame, presently)    //convert pixel format and display image       SDL_PixelFormat* sdl_pixfmt = new SDL_PixelFormat;    sdl_pixfmt->format = SDL_GetWindowPixelFormat(win);          SDL_Surface* conv_surf = SDL_ConvertSurface    (       surf,       sdl_pixfmt,       0    );       SDL_Surface* surf_to_tex = SDL_CreateRGBSurface    (       0,       frame_width,       frame_height,       32,       rmask,       gmask,       bmask,       amask    );       SDL_Texture* tex = SDL_CreateTexture    (       ren,       SDL_PIXELFORMAT_RGBA8888,       SDL_TEXTUREACCESS_STREAMING,       frame_width,       frame_height    );       SDL_LockTexture    (       tex,       NULL,       &surf_to_tex->pixels,       &surf_to_tex->pitch    );       SDL_BlitSurface    (       conv_surf,       NULL,       surf_to_tex,       NULL    );       SDL_UnlockTexture(tex);    SDL_RenderCopy    (       ren,       tex,       NULL,       NULL    );    SDL_RenderPresent(ren); On 17 May 2015 at 09:22, Travis McKinney wrote:
|
|||||||||||||||||
|
Naith
|
I'm afraid I don't have much knowledge when it comes to pixel formats and various topics so the only thing I can help you with is this:
Whenever I'm gonna do any SDL_Surface -> SDL_Texture pixel manipulations, I always make sure that my SDL_Surface and SDL_texture has the same pixel format as my window and since I usually don't have a clue about what pixel format my window has I use some SDL functions that can tell me that information and my code then usually looks like this:
Then, each frame, if the texture needs to be updated every frame, I manipulate the pixels in the surface, upload the pixels to the texture with the SDL_UpdateTexture function and then finally render the texture. I don't know if this will help you at all but hopefully it will. |
|||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
I think I was getting overly fixated on converting pixel formats real time.
A preprocessor macro is quite an elegant fix for this, as one binary won't run on every device anyway...    #if SDL_BYTEORDER == SDL_BIG_ENDIAN    #define AGG_RGBA32_BYTE_ORDER agg::pixfmt_rgba32    rmask = 0xff000000;    gmask = 0x00ff0000;    bmask = 0x0000ff00;    amask = 0x000000ff;    #else    #define AGG_RGBA32_BYTE_ORDER agg::pixfmt_abgr32    rmask = 0x000000ff;    gmask = 0x0000ff00;    bmask = 0x00ff0000;    amask = 0xff000000;    #endif On 17 May 2015 at 12:27, Naith wrote:
|
|||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
I broke it again. Added code into the event loop to check for mouse motion & button press then draw a line. Works great using SDL_RenderDrawLine but hangs up using SDL_Lock/Unlock texture approach.
The behavior is odd. It's slow but does draw a line, so it seems mousemotion events are being processed but it doesn't stop drawing a line or allow exiting the program -- not even with sigterm. AGG functions are commented out to highlight that this is a problem with how I'm using SDL, more than AGG. http://pastebin.com/M9QPTWXx             case SDL_MOUSEBUTTONDOWN:                if (e.button.button == SDL_BUTTON_LEFT)                {                   SDL_GetMouseState(&a.x, &a.y);                   SDL_RenderDrawPoint(ren, a.x, a.y); //                  path.move_to(a.x, a.y);                }                break;                            case SDL_MOUSEMOTION:                if(e.motion.state & SDL_BUTTON_LMASK)                {                   SDL_GetMouseState(&b.x, &b.y);                   SDL_RenderDrawLine                   (                      ren,                      a.x,                      a.y,                      b.x,                      b.y                   );                                     SDL_LockSurface(surf);                   SDL_LockTexture                   (                        tex,                      NULL,                      &surf->pixels,                      &surf->pitch                   ); /*                  path.line_to(b.x, b.y);                   ras.add_path(stroke);                     rscan.color(agg::rgba8(200, 150, 50, 255));                   agg::render_scanlines(ras, scanline, rscan);    */                                 SDL_UnlockSurface(surf);                   SDL_UnlockTexture(tex);                   SDL_RenderCopy                   (                      ren,                      tex,                      NULL,                      NULL                   );                   SDL_RenderPresent(ren);                   a=b;                }                break; On 17 May 2015 at 14:14, Travis McKinney wrote:
|
|||||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Jonny D
|
I get the feeling that bad memory things are happening here. That's the first thing you should be thinking when the program causes weird problems or fails to respond to signals.
You should not be mixing the memory locations of the surface and the texture, which is what I see. SDL_LockSurface() says that you want to modify the surf->pixels by hand. SDL_LockTexture() says that you want a new pointer to the texture pixels. It looks like you overwrite the surface's pixel pointer with a pointer to the texture's temporary pixels (not to mention the surface's pitch). Once you start unlocking those objects, you're in weird territory. For example, the surface and texture pitches might not match, so when the surface is accessed (now with a different pitch than it was created with), you're liable to run right off the end of the allocated pixels. Also, the surface's pixels have been leaked and are no longer accessible. You'll be trying to access the texture's temporary pixel data, which might have been deallocated already. If you're on Linux, try running it through valgrind and you'll probably get some verification of this. I think what you should be doing is either using SDL_UpdateTexture() or copying the data (e.g. with memcpy) instead of replacing the pointers to the memory. If you're getting along alright without SDL_GetWindowSurface(), then I suggest you don't bother using it. Going from direct texture updates to shadow surfaces is a step backward. Jonny D On Sun, May 17, 2015 at 11:26 PM, Travis McKinney wrote:
|
|||||||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
That makes sense. I got rid of the SDL_Surface and replaced it with void *tex_pixels and int tex_pitch. Unfortunately I'm getting the same performance as before.
Downloading valgrind now. Interested to see what it comes up with, because I'm completely out of ideas. On 17 May 2015 at 21:00, Jonathan Dearborn wrote:
|
|||||||||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
http://pastebin.com/K8vfbdQB
                  //SDL_LockSurface(surf);                   SDL_LockTexture                   (                        tex,                      NULL,                      &tex_pixels,                      &tex_pitch                   ); /*                  path.line_to(b.x, b.y);                   ras.add_path(stroke);                     rscan.color(agg::rgba8(200, 150, 50, 255));                   agg::render_scanlines(ras, scanline, rscan);    */               //                  SDL_UnlockSurface(surf);                   SDL_UnlockTexture(tex);                   tex_pixels = NULL;                   tex_pitch = -1;                   SDL_RenderCopy                   (                      ren,                      tex,                      NULL,                      NULL                   );                   SDL_RenderPresent(ren);                   a=b; On 17 May 2015 at 21:41, Travis McKinney wrote:
|
|||||||||||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
Rewritten to use SDL_UpdateTexture, same issues.
http://pastebin.com/zQaKPvzP On 17 May 2015 at 22:36, Travis McKinney wrote:
|
|||||||||||||||||||||||||
|
Trouble with LockTexture & TextureStreaming |
Travis McKinney
Guest
|
changed
if(SDL_PollEvent(&e)) ... to while(SDL_PollEvent(&e)) ... works as expected now, using SDL_UpdateTexture but will try again with SDL_LockTexture On 17 May 2015 at 23:19, Travis McKinney wrote:
|
|||||||||||||||||||||||||||
|
found a bug in SDL_TTF |
jeroen.clarysse
|
when using TTF_SetFontStyle() with the style set to TTF_STYLE_UNDERLINE the resulting texture after using TTF_RenderUTF8_Blended_Wrapped() does NOT underline.
Using TTF_RenderText_Blended() will work fine. it is the wrapping that somehow disables the underlining _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||
|
found a bug in SDL_TTF |
slvn
|
In "TTF_RenderUTF8_Blended", there is this block that handles the
"underline" style : 1826 /* Handle the underline style */ 1827 if ( TTF_HANDLE_STYLE_UNDERLINE(font) ) { 1828 row = TTF_underline_top_row(font); 1829 TTF_drawLine_Blended(font, textbuf, row, pixel); 1830 } 1831 1832 /* Handle the strikethrough style */ 1833 if ( TTF_HANDLE_STYLE_STRIKETHROUGH(font) ) { 1834 row = TTF_strikethrough_top_row(font); 1835 TTF_drawLine_Blended(font, textbuf, row, pixel); 1836 } But, in "TTF_RenderUTF8_Blended_Wrapped", those blocks are commented out. This is the reason for this bug. Also, same bug probably applies with "strike-through" style. You need to uncomment it, but you also need to debug it : currently, it would very likely underline N times the first line. Whereas, you want to underline each line. So "row" needs to be replaced by something like "row + line * rowSize". On 20 May 2015 at 11:51, jeroen clarysse wrote:
-- Sylvain Becker _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
SDL_dynapi_procs.h: No such file or directory. |
Sergi Pasoev
Guest
|
Hi
I found suspicious errors while debugging the program which uses SDL to display images as SDL_Texture-s as I was trying to make the valgrind output clean. Namely, SDL_dynapi_procs.h: No such file or directory. And SDL_render.c: No such file or directory. A fuller view on error as I got while running the program on gdb:
I am using SDL 2.0.2 on Debian Gnu/Linux. Thanks |
|||||||||||||
|
SDL_dynapi_procs.h: No such file or directory. |
Eirik Byrkjeflot Anonsen
Guest
|
Sergi Pasoev writes:
I assume you only get those errors when you stop the program in gdb? These error messages means that gdb can't find the mentioned file, so it can not show the line from the source code. These errors do not affect the program itself in any way whatsoever. eirik _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
SDL_dynapi_procs.h: No such file or directory. |
Sergi Pasoev
Guest
|
Thanks very much, that absolutely answers my problem, I seem to have
confused the errors coming from gdb not finding files and errors (or warnings) from SDL itself. On 02/06/15 19:19, Eirik Byrkjeflot Anonsen wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|