Inverting draw mode?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Inverting draw mode?

joymaker
I'm porting some legacy Mac code to SDL, since Apple Computer has yanked away the C++ interfaces from beneath me.

One thing I was using was the inverting draw mode. This means that the new image is drawn onto the window or drawing surface using an exclusive-or operation at the bit level. It has the convenient property that if you draw the same object onto the same surface twice in this mode, it vanishes, restoring the surface to its previous state. This has some cool artistic uses, and is also useful for compatibility with some legacy code.

I'm not seeing it in the documentation, and I'm aware that modern graphics cards may not encourage such an operation onto the screen, but it sure would be nice to be able to do this to a Texture. Is this at all supported? If not, I would urge its adoption as an additional "Blending mode".

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inverting draw mode?

rtrussell







joymaker wrote:
Is this at all supported? If not, I would urge its adoption as an additional "Blending mode".

I rely on it. The solution I use is to force OpenGL (or GLES 1.0) when it's not the default:








Code:
SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengl") ;
window = SDL_CreateWindow(..., SDL_WINDOW_OPENGL...) ;

then you can enable the wanted drawing mode using:








Code:
   glEnable (GL_COLOR_LOGIC_OP) ;
   glLogicOp (GL_XOR) ;

Works perfectly for me on Windows, Linux, Mac OS and Android. It's unfortunate that support for glLogicOp was dropped from GLES 2.0 so on platforms which can't run full OpenGL you are forced to use the legacy GLES 1.0.

Richard.

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inverting draw mode?

Jonathan Dearborn-2
Does GLSL ES have bitwise operators?  I would think you could invert in a shader.

Jonny D

On Thu, Dec 8, 2016 at 7:12 AM, rtrussell <[hidden email]> wrote:



joymaker wrote:

Is this at all supported? If not, I would urge its adoption as an additional "Blending mode".


I rely on it. The solution I use is to force OpenGL (or GLES 1.0) when it's not the default:




Code:

SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengl") ;
window = SDL_CreateWindow(..., SDL_WINDOW_OPENGL...) ;



then you can enable the wanted drawing mode using:




Code:

   glEnable (GL_COLOR_LOGIC_OP) ;
   glLogicOp (GL_XOR) ;



Works perfectly for me on Windows, Linux, Mac OS and Android. It's unfortunate that support for glLogicOp was dropped from GLES 2.0 so on platforms which can't run full OpenGL you are forced to use the legacy GLES 1.0.

Richard.

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org



_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inverting draw mode?

EternalLands
In reply to this post by joymaker
Reading from the video memory is always a bad idea.
Why don't you make your own screen buffer, do your drawing in it, then at the end you put it in a texture and render it?

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inverting draw mode?

joymaker
In reply to this post by joymaker
EternalLands - that's what I was planning on doing anyway, I just didn't see any primitive operators with which to do it. What I don't want to do if I don't have to is reinvent the rectangle drawing primitive from scratch, just to do this.

Richard – thanks, that sounds like a good plan. So I think you're telling me that setting up the OpenGL LogicOp will modify ALL drawing done through the window, SDL primitives as well as OpenGL primitives. Right? (And is there any significant downside to specifying "opengl" as my driver, instead of the usual default?)

Thanks,
Ken

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inverting draw mode?

rtrussell
In reply to this post by joymaker







joymaker wrote:
So I think you're telling me that setting up the OpenGL LogicOp will modify ALL drawing done through the window, SDL primitives as well as OpenGL primitives. Right?

Yes, SDL drawing operations such as SDL_RenderDrawPoint, SDL_RenderDrawLine and those in SDL_gfx will be affected by the LogicOp. For safety I would recommend enabling and setting the LogicOp only around such calls rather than leaving it active for longer periods, just in case it interferes with anything else in SDL.








Quote:
(And is there any significant downside to specifying "opengl" as my driver, instead of the usual default?)

Only in Windows is OpenGL/GLES not the default, I think, and I've not noticed any significant impact from forcing its use.

Richard.

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Inverting draw mode?

rtrussell
In reply to this post by joymaker
Here's the SDL_gfx demo modified to use exclusive-or plotting:








Code:
// Demo of exclusive-or plotting by Richard Russell http://www.rtrussell.co.uk/

#include
#include "SDL2_gfxPrimitives.h"

#define WIDTH 640
#define HEIGHT 480
#define GL_COLOR_LOGIC_OP 0xBF2
#define GL_XOR 0x1506

#ifdef __WINDOWS__
    void (__stdcall *glEnable)  (int) ;
    void (__stdcall *glLogicOp) (int) ;
    void (__stdcall *glDisable) (int) ;
#else
    void (*glEnable)  (int) ;
    void (*glLogicOp) (int) ;
    void (*glDisable) (int) ;
#endif

int main(int argc, char* argv[])
{
   
    if (SDL_Init(SDL_INIT_VIDEO))
    {
        printf ("SDL_Init Error: %s", SDL_GetError());
        return 1;
    }

    SDL_SetHint (SDL_HINT_RENDER_DRIVER, "opengl") ;
   
    SDL_Window *window = SDL_CreateWindow("SDL2_gfx test", 100, 100, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
    if (window == NULL)
    {
        printf ("SDL_CreateWindow Error: %s", SDL_GetError());
        SDL_Quit();
        return 2;
    }
   
    glLogicOp = SDL_GL_GetProcAddress("glLogicOp") ;
    glEnable  = SDL_GL_GetProcAddress("glEnable") ;
    glDisable = SDL_GL_GetProcAddress("glDisable") ;

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (renderer == NULL)
    {
        SDL_DestroyWindow(window);
        printf ("SDL_CreateRenderer Error: %s", SDL_GetError());
        SDL_Quit();
        return 3;
    }
   
    SDL_Event e;
   
    int quit = 0;
    while (!quit)
    {
        if (SDL_PollEvent(&e))
        {
            if (e.type == SDL_QUIT)
                quit = 1;
        }
        SDL_SetRenderDrawColor(renderer, 0, 0, 0xFF, 0xFF);
        SDL_RenderClear(renderer);
 
        glEnable (GL_COLOR_LOGIC_OP) ;
        glLogicOp (GL_XOR) ;

        thickLineColor(renderer, 0, 0, WIDTH, HEIGHT, 20, 0xFFFFFFFF) ;
        thickLineColor(renderer, 0, HEIGHT, WIDTH, 0, 20, 0xFFFFFFFF) ;
        circleColor(renderer, WIDTH/2, HEIGHT/2, 80, 0xFF00FF00);
        filledCircleColor(renderer, WIDTH/2, HEIGHT/2, 60, 0xFF0000FF);

        glDisable (GL_COLOR_LOGIC_OP) ;

        SDL_RenderPresent(renderer);
        SDL_Delay(10);
    }
   
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Loading...