Working with n-bit surfaces

Hallo, SDL.

   How can i create 1 (or n) bit surface. Draw on it (i can draw
   on 32 bit surface, but what happened if i'll draw pixel in
   32-bit format in 1 bit surface? How can i avoid problems with
   this (I mean, if there is some function to convert pixels?)).

   Then I need to draw 1 (n) bit surface on 32-bit surf. Should I
   use only SDL_ConverSurface() or something else?

   tnx...-- 

Best regards,
Alexei mailto:AlexeiSergeev at gmail.com

Hallo, SDL.

   How can i create 1 (or n) bit surface.

SDL_CreateRGBSurface() is the function you want. It can create just
about any type of surface. It does make some assumptions that might get
in your way. But, it does appear that you can use it to create a 1 bit
deep surface. I have not tried it, so I am not 100% certain it will
work.

Draw on it

Drawing on it is up to you. That is, you will need to do the arithmetic
and shifts to get and set the proper bits.

(i can draw
on 32 bit surface, but what happened if i’ll draw pixel in
32-bit format in 1 bit surface?

Nothing useful will happen, clearly a 32 bit value can not be stored in
a 1 bit field :slight_smile:

How can i avoid problems with
this (I mean, if there is some function to convert pixels?)).

Yes, there are several functions that can convert pixels to RGB values
and vice versa. Check out SDL_MapRGB, SDL_MapRGBA SDL_GetRGB,
SDL_GetRGBA.

In the case of a one bit pixel the only valid pixel values are 0 and 1.

   Then I need to draw 1 (n) bit surface on 32-bit surf. Should I
   use only SDL_ConverSurface() or something else?

That will work, I’m sure other people will jump in with other ways to do
the job.

	Bob PendletonOn Tue, 2005-04-19 at 21:18 +0400, Alexei Sergeev wrote:
   tnx...


±-------------------------------------+

The putpixel code on this page might be of use:

http://www.infres.enst.fr/docs/sdl/guidevideo.html

It examines the surface’s BytesPerPixel to determine whether the surface
is 8bpp, 16bpp 24bpp or 32bpp. Use SDL_MapRGB() to create the Uint32 pixel
that function wants, for example.

Good luck!

PS - I have no idea how up-to-date the rest of that guide is, so YMMV.
But the putpixel example looks fine.On Tue, Apr 19, 2005 at 09:18:47PM +0400, Alexei Sergeev wrote:

Hallo, SDL.

   How can i create 1 (or n) bit surface. Draw on it (i can draw
   on 32 bit surface, but what happened if i'll draw pixel in
   32-bit format in 1 bit surface? How can i avoid problems with
   this (I mean, if there is some function to convert pixels?)).


-bill!
bill at newbreedsoftware.com Tonight’s Forecast: Dark. Continued darkness
http://newbreedsoftware.com/ until widely scattered light in the morning.

big tnx… ill use it…On 4/21/05, Bill Kendrick wrote:

On Tue, Apr 19, 2005 at 09:18:47PM +0400, Alexei Sergeev wrote:

Hallo, SDL.

   How can i create 1 (or n) bit surface. Draw on it (i can draw
   on 32 bit surface, but what happened if i'll draw pixel in
   32-bit format in 1 bit surface? How can i avoid problems with
   this (I mean, if there is some function to convert pixels?)).

The putpixel code on this page might be of use:

http://www.infres.enst.fr/docs/sdl/guidevideo.html

It examines the surface’s BytesPerPixel to determine whether the surface
is 8bpp, 16bpp 24bpp or 32bpp. Use SDL_MapRGB() to create the Uint32 pixel
that function wants, for example.

Good luck!

PS - I have no idea how up-to-date the rest of that guide is, so YMMV.
But the putpixel example looks fine.


-bill!
bill at newbreedsoftware.com Tonight’s Forecast: Dark. Continued darkness
http://newbreedsoftware.com/ until widely scattered light in the morning.

An embedded and charset-unspecified text was scrubbed…
Name: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20050426/f1890e72/attachment.asc

Hallo, SDL.

How can i create 1 (or n) bit surface.

SDL_CreateRGBSurface() is the function you want. It can create just

about any type of surface. It does make some assumptions that might get

in your way. But, it does appear that you can use it to create a 1 bit

deep surface. I have not tried it, so I am not 100% certain it will

work.

Wouldn’t that have the general issue that a 1 bit or n bit surface isn’t very
usable for drawing?

A 1 bit surface is perfectly usable if what you need is a 1 bit surface.
Not knowing the application we can’t say what would be better.

Eventually it has to be converted into something the
graphic card handles, likely the one that is the current screen mode.

Not necessarily. We don’t know that his output is going to a screen. It
may well be part of a process that builds an image that is going to a
fax machine. Not all computer graphics is about putting images on a
screen.

Certainly it can be done since screens can be viewed as just raw memory of a
certain shape but it’d just mandate a conversion every time that was done.

Since we don’t know the application it is hard to suggest that he do
something different. He may well be working on a system with a 1 bit
display. Such things do exist. Or, perhaps he is building the planes for
a cursor or overlay plane. Or, perhaps he is working with a very large
number of pixels and needs the space to get them all in memory. Maybe he
is doing some sort of super antialiasing and will sample the 1 bit
surface by averaging 16x16 or 32x32 pixel regions into a single pixel in
his final image.

There are many reasons to use a 1 bit surface, I haven’t come close to
listing all the ones I can think of, just off the top of my head.

	Bob PendletonOn Tue, 2005-04-26 at 08:41 -0400, bloomp at rpi.edu wrote:

On Tue, 19 Apr 2005 15:10:15 -0500 Bob Pendleton wrote:

On Tue, 2005-04-19 at 21:18 +0400, Alexei Sergeev wrote:

Draw on it

Drawing on it is up to you. That is, you will need to do the arithmetic

and shifts to get and set the proper bits.

(i can draw

on 32 bit surface, but what happened if i’ll draw pixel in

32-bit format in 1 bit surface?

Nothing useful will happen, clearly a 32 bit value can not be stored in

a 1 bit field :slight_smile:

actually, it’ll write to 32 pixels together, assuming you do it memory wise.
This can be useful for faster draws where you’re calculating what the image
is displaying and the calculation step takes significantly less time than the
memory write for the pixel. As far as I’m aware, this is also optimal (4
words) for writing to memory in the first place.

How can i avoid problems with

this (I mean, if there is some function to convert pixels?)).

Yes, there are several functions that can convert pixels to RGB values

and vice versa. Check out SDL_MapRGB, SDL_MapRGBA SDL_GetRGB,

SDL_GetRGBA.

In the case of a one bit pixel the only valid pixel values are 0 and 1.

Then I need to draw 1 (n) bit surface on 32-bit surf. Should I

use only SDL_ConverSurface() or something else?

That will work, I’m sure other people will jump in with other ways to do

the job.

It’ll work, but it’d have no advantage over just drawing it in 32 bit to
begin with. If you know a conversion is happening and you know what it’s
being converted to, there’s little point not to do the math ahead of time and
convert it yourself rather than do it in program. Even if you don’t know
what it’s being converted to, why not go with something that’s as close to
your expected case as possible and check if you need to convert instead of
always converting?

Philip

A sleepy programmer


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


±-------------------------------------+

Hi,

I am currently working on a game. I’ve got a fullscreen version and a
windowed one just to ease debugging. Nothing fancy so far.

At a moment I display some surface which are located in system memory,
pixel format is the same as the display format. Each frame I copy one
reference surface to the work surface, do some modification on the work
surface and draw it on the display. The reference / work surface is
quite small and in system memory.

In windowed mode everything run perfectly smooth but in Fullscreen it is
really lagging. I’ve checked that I am not reading video memory pixel or
something like that but well no difference. So basically, do somebody
know what could be possibly wrong (I’ve done the same in DirectX in some
previous project and never had such problem).

St?phane Becker

In windowed mode everything run perfectly smooth but in Fullscreen it is
really lagging. I’ve checked that I am not reading video memory pixel or
something like that but well no difference. So basically, do somebody
know what could be possibly wrong (I’ve done the same in DirectX in some
previous project and never had such problem).

Greetings. I had this exact same problem with the code. In windowed mode
it was silky smooth and everything worked great. As soon as I switched to
fullscreen mode it was getting maybe 2-3 frames per second.

Unfortunately, I was unable to get any possible problems to check from
this list and I was unable to resolve the problem on my own. I just
wanted you to know you’re not alone out there with this problem. (But I
can’t help, I’ve moved on to using DirectX directly.)

Could you provide a mimimal example that reproduces the problem?On Tuesday 26 April 2005 09:47, St?phane Becker wrote:

Hi,
In windowed mode everything run perfectly smooth but in Fullscreen it is
really lagging. I’ve checked that I am not reading video memory pixel or
something like that but well no difference. So basically, do somebody
know what could be possibly wrong (I’ve done the same in DirectX in some
previous project and never had such problem).

Could you provide a mimimal example that reproduces the problem?

Here we go,

I did a minimal version exposing the problem, it is quite
straightforward and I stripped as much of my code as I could. What I am
doing :

  • I load a bmp file into a surface allocated in system memory, the
    surface use color keying.
  • each frame I draw 400 times this surface in a 20x20 patterns. For each
    line I lock the surface, xor all pixels, unlock the surface. This last
    point lower the framerate a lot in fullscreen mode but not in windowed.

you can grab the visual studio 2003 project here:
http://whirly.free.fr/cp/SDLTest.zip

Excuse the crude style as I rushed it a little bit.

Thanks,
St?phane Becker

I can’t understand a thing your code is doing, and all your code does on my
windows machine is instantly throw an exception. It’s difficult to see where
you’re using SDL at all, you’ve gone to great effort to abstract and/or work
around SDL’s features – using winmain instead of the plain ordinary main()
SDL provides for all platforms, using your own integer type-definitions
instead of the ones defined SDL_types.h for all platforms, defining your own
video flags instead of the SDL ones for no reason I can guess, etc, etc.
Things like that enormous 1024*768 vector involved in setting the video mode
also leave me mystified.

It’s only a guess, but if you’re passing SDL_HWSURFACE to SDL_SetVideoMode,
that’s what the difference would be – you generally can’t get a hardware
video surface in windowed mode but it’ll give you one for fullscreen, and a
hardware surface is not the same as hardware accel; you get a raw,
unvarnished video surface and blit directly to video memory. If you really
want that, you should arrange to have the picture you’re blitting in video
mem too.On Wednesday 27 April 2005 08:25, St?phane Becker wrote:

Could you provide a mimimal example that reproduces the problem?

Here we go,

I did a minimal version exposing the problem, it is quite
straightforward and I stripped as much of my code as I could.

St?phane Becker wrote:

  • each frame I draw 400 times this surface in a 20x20 patterns. For
    each line I lock the surface, xor all pixels, unlock the surface. This
    last point lower the framerate a lot in fullscreen mode but not in
    windowed.

without looking at your code i guess the following happens.

you request HWSURFACEs, you lock them, you manipulate the pixels, you
unlock them.

locking hw-surfaces means that sdl has to copy them from video
surface to system memory, so someone can access the pixel data. this is
very-very slow. if you start your application in windowed mode, sdl will
most likely not give you any hw-surfaces and SDL_LockSurface() does
nothing and your app does not suffer from this slowdown. try requesting
SWSURFACEs instead. there is one rule of thumb with sdl. use
SW-Surfaces when manipulating the pixel data directly and if you do
alpha (read per pixel alpha) blits.

hope that helps …
clemens

Clemens Kirchgatterer wrote:

St?phane Becker wrote:

without looking at your code i guess the following happens.

you request HWSURFACEs, you lock them, you manipulate the pixels, you
unlock them.

locking hw-surfaces means that sdl has to copy them from video
surface to system memory, so someone can access the pixel data. this is
very-very slow. if you start your application in windowed mode, sdl will
most likely not give you any hw-surfaces and SDL_LockSurface() does
nothing and your app does not suffer from this slowdown. try requesting
SWSURFACEs instead. there is one rule of thumb with sdl. use
SW-Surfaces when manipulating the pixel data directly and if you do
alpha (read per pixel alpha) blits.

Your guess seems correct, I’ve tested the SDLTest with and without
SDL_FULLSCREEN | SDL_DOUBLEBUF and it’s very fast without thoses flags

I change my code and now it seems to be working properly. I will just
make some statement to see if I understand things right.

In my DX realm, I can create either surface in graphic memory and in
system memory. Due to the PC architecture what I must avoid at all cost
is reading pixels from the graphic memory. I can lock a graphic memory
surface, write pixel in it and unlock and it will only be slightly
slower than if I did this on a system memory surface. Hence if you want
to do alpha blending you must use some tricks.

So with SDL my comprehension is that :

  • if you lock a surface in graphic memory, the whole content of this
    surface will be copied in system memory and then back on graphic memory
    when you unlock it.
  • if I create my application in Fullscreen with double buffering and
    with the hardware surface flag, then all surface I create will be in
    graphic memory.

Is it right ?
St?phane Becker

PS, about the code…

It is surely not so straightforward to understand as I usually
encapsulate platform specific code (and for me SDL is "platform"
specific, as I could do a port to a plaftform that does not have SDL).
That’s why it was easier to port one of my game to linux (Robin Hood,
legend of sherwood).

The vector in the code is not a stl vector, but a mathematical vector
indicating a position or size.

And last but not least, thanks for the help.

I change my code and now it seems to be working properly. I will just
make some statement to see if I understand things right.

In my DX realm, I can create either surface in graphic memory and in
system memory. Due to the PC architecture what I must avoid at all cost
is reading pixels from the graphic memory. I can lock a graphic memory
surface, write pixel in it and unlock and it will only be slightly
slower than if I did this on a system memory surface. Hence if you want
to do alpha blending you must use some tricks.

So with SDL my comprehension is that :

  • if you lock a surface in graphic memory, the whole content of this
    surface will be copied in system memory and then back on graphic memory
    when you unlock it.

That is not correct. Locking a hardware buffer does not cause it to be
copied. It just makes sure that it has a valid address so that you can
read/write from it and makes sure that the address will not change until
you unlock it. Because of multi-buffering the back buffer address can
(and usually does) change from frame to frame.

  • if I create my application in Fullscreen with double buffering and
    with the hardware surface flag, then all surface I create will be in
    graphic memory.

Again, not correct. Only surfaces that are create with the hardware
surface flag will be placed in video memory. And, even with the hardware
flag they will only be place in video memory if their is enough memory
free to allow the surface to be allocated in video memory. If you ask
for a hardware surface and it can not be allocated SDL will silently
create a software surface for you. You can check the flags in the
surface structure to find out what you actually got.

The most likely reason for a slow down in full screen mode is that you
are getting a hardware buffer in full screen mode and not in windowed
mode. Reading and writing a hardware back buffer is very slow while
reading and writing a software buffer is much faster. The result is that
building up a frame in a hardware back buffer can be very slow compared
to doing it in a software buffer and bliting it to the screen.

Personally, I try to use OpenGL whenever possible. It makes life so much
easier. :slight_smile:

	Bob PendletonOn Thu, 2005-04-28 at 11:52 +0200, St?phane Becker wrote:

Is it right ?
St?phane Becker

PS, about the code…

It is surely not so straightforward to understand as I usually
encapsulate platform specific code (and for me SDL is "platform"
specific, as I could do a port to a plaftform that does not have SDL).
That’s why it was easier to port one of my game to linux (Robin Hood,
legend of sherwood).

The vector in the code is not a stl vector, but a mathematical vector
indicating a position or size.

And last but not least, thanks for the help.


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


±-------------------------------------+