Drawing realtime graphics using wxDC
Drawing realtime graphics using wxDC
Hi guys,
This topic starts off more as an inquiry topic.
If it turns out that what I want is not doable using wxDC, it'll be a short topic.
If I can do what I want with wxDC, I think this will become quite a large topic.
So, for quite some time now I have been working on a map editor for a 2D game called "Command and Conquer: Tiberian Sun" or "Command and Conquer: Red Alert 2".
Now I have come to the part where I need rendering on screen.
I'm curious how far I will get using wxWidgets for blitting all graphicsto the screen.
Will I be able to get something like this on the screen using wxWidgets? I know that for voxels I will have to use OpenGL, but eventually all will be bitmaps.
This topic starts off more as an inquiry topic.
If it turns out that what I want is not doable using wxDC, it'll be a short topic.
If I can do what I want with wxDC, I think this will become quite a large topic.
So, for quite some time now I have been working on a map editor for a 2D game called "Command and Conquer: Tiberian Sun" or "Command and Conquer: Red Alert 2".
Now I have come to the part where I need rendering on screen.
I'm curious how far I will get using wxWidgets for blitting all graphicsto the screen.
Will I be able to get something like this on the screen using wxWidgets? I know that for voxels I will have to use OpenGL, but eventually all will be bitmaps.
Re: Drawing realtime graphics using wxDC
Drawing bitmaps to the screen should be pretty fast, there is not much overhead created by wxWidgets. If it will be fast enough for you is hard to tell, just write a small benchmark that draws a few thousand bitmaps on screen.
In any case, you should also try wxGraphicsContext instead of wxDC, it's possible that on some platforms wxGCDC is faster. At least under Windows using wxDirect2dGraphicsContext should be fast as it uses DirectX internally, unfortunately it's still a little unstable.
If we're lucky, we'll find a student for this GSoC idea:
http://wxwidgets.org/gsoc/projects/#ope ... cs-context
This would solve all speed-problems related to 2D drawing on all platforms.
Then again, if you only need to draw bitmaps, it should be easy to do it in OpenGL anyway.
In any case, you should also try wxGraphicsContext instead of wxDC, it's possible that on some platforms wxGCDC is faster. At least under Windows using wxDirect2dGraphicsContext should be fast as it uses DirectX internally, unfortunately it's still a little unstable.
If we're lucky, we'll find a student for this GSoC idea:
http://wxwidgets.org/gsoc/projects/#ope ... cs-context
This would solve all speed-problems related to 2D drawing on all platforms.
Then again, if you only need to draw bitmaps, it should be easy to do it in OpenGL anyway.
Use the source, Luke!
Re: Drawing realtime graphics using wxDC
In the end, everything is a bitmap that gets blitted to the screen.
In due time I will not only have to work with bitmaps, but also voxels.
Though it would be possible to map it to a bitmap as they are 8 static facings.
The reason I'm inquiring about wxWidgets drawing functionalities is because I don't want to make it overcomplex.
Weren't there rendering components in wxWidgets for OpenGL already?
In due time I will not only have to work with bitmaps, but also voxels.
Though it would be possible to map it to a bitmap as they are 8 static facings.
The reason I'm inquiring about wxWidgets drawing functionalities is because I don't want to make it overcomplex.
Weren't there rendering components in wxWidgets for OpenGL already?
Re: Drawing realtime graphics using wxDC
If that means you'll be blitting thousands of small bitmaps on screen, i have a feeling that won't be fast enough. I'd go for OpenGL right away.In due time I will not only have to work with bitmaps, but also voxels.
Use the source, Luke!
Re: Drawing realtime graphics using wxDC
For voxels I will have to use OpenGL to render them and what I intend to do then is to sort of take pictures from certain facings of the rendered voxel and create a bitmap out of those.
So lets say a tank existing of voxels will become a 2D representation. Only 8 facings are used.
Basically I convert the voxel unit to a bitmap as there is no need for 3D stuff to happen.
The map editor is a static representation.
Notice the green car in the screenshot? That's a voxel. And it has the facing to the north.
What I intend is to create some sort of a picture of when it is facing north, that will be stored as a bitmap. The entire car will become 1 bitmap.
So lets say a tank existing of voxels will become a 2D representation. Only 8 facings are used.
Basically I convert the voxel unit to a bitmap as there is no need for 3D stuff to happen.
The map editor is a static representation.
Notice the green car in the screenshot? That's a voxel. And it has the facing to the north.
What I intend is to create some sort of a picture of when it is facing north, that will be stored as a bitmap. The entire car will become 1 bitmap.
Re: Drawing realtime graphics using wxDC
I made a little benchmark with standard wxDC functions under Windows.
frame, client size 1024x768
in a paint event with static buffer bitmap i first drew a 1024x768 background bitmap and then 3072x a 16x16 bitmap with transparency.
That took around 22ms per iteration on my system (i5 3.5Ghz, GTX 1060), almost 50 fps.
That should give you a general idea about what to expect.
frame, client size 1024x768
in a paint event with static buffer bitmap i first drew a 1024x768 background bitmap and then 3072x a 16x16 bitmap with transparency.
That took around 22ms per iteration on my system (i5 3.5Ghz, GTX 1060), almost 50 fps.
That should give you a general idea about what to expect.
Use the source, Luke!
Re: Drawing realtime graphics using wxDC
That sound quite alright.
Could you share that code with me?
Could you share that code with me?
Re: Drawing realtime graphics using wxDC
Here you go. Based on the "minimal" sample. You need to replace the two hard-coded image paths with fitting images.
- Attachments
-
- minimal.cpp
- simple wxdc bitmap benchmark
- (8.52 KiB) Downloaded 330 times
Use the source, Luke!
Re: Drawing realtime graphics using wxDC
Great!
I read that I could also use a timer to let it draw on screen in intervals.
I capped it at 25fps.
Am I to assume that creating bitmaps from raw rgb(a) bytes, like a big array of 3 or 4 bytes consisting of the color data is through wxImage?
I read that I could also use a timer to let it draw on screen in intervals.
I capped it at 25fps.
Am I to assume that creating bitmaps from raw rgb(a) bytes, like a big array of 3 or 4 bytes consisting of the color data is through wxImage?
Re: Drawing realtime graphics using wxDC
Yes, you can do that if you are 100% sure that your drawing will be fast enough. Because if it isn't, timer events will stack up and your program will become unresponsive.I read that I could also use a timer to let it draw on screen in intervals. I capped it at 25fps.
That's the easiest way to do it. Another option is to use raw bitmap access:Am I to assume that creating bitmaps from raw rgb(a) bytes, like a big array of 3 or 4 bytes consisting of the color data is through wxImage?
http://docs.wxwidgets.org/trunk/classwx_pixel_data.html
Use the source, Luke!
Re: Drawing realtime graphics using wxDC
Okay, I have implemented the raw pixel access and want to use Alpha to show pixels or not.
It seems that the Alpha setting is not working as intended for me. It does not matter what Alpha value I use, the pixel never gets hidden.
This is what the tile looks like without any hiding of pixels:
All blue pixels (paletteIndices[index] == 0 has these RGB values) should not be visible on screen.
That's how the tiles connect.
I have also tested using what is in the sample (samples/image):
This also does not work as what should be gone, is rendered black.
I'll check how everything performs, I can always switch to event based rendering instead of timers.
It seems that the Alpha setting is not working as intended for me. It does not matter what Alpha value I use, the pixel never gets hidden.
Code: Select all
wxBitmap bmp(width, height, 32);
wxAlphaPixelData data(bmp, wxRect(wxSize(width, height)));
wxAlphaPixelData::Iterator p(data);
unsigned int index = 0;
p.Offset(data, 0, 0);
for (int y = 0; y < height; ++y)
{
wxAlphaPixelData::Iterator rowStart = p;
for (int x = 0; x < width; ++x, ++p)
{
auto& entry = pal->colors[paletteIndices[index]];
p.Red() = entry.red;
p.Green() = entry.green;
p.Blue() = entry.blue;
if (paletteIndices[index] == 0)
p.Alpha() = 0;
else
p.Alpha() = 255;
index++;
}
p = rowStart;
p.OffsetY(data, 1);
}
All blue pixels (paletteIndices[index] == 0 has these RGB values) should not be visible on screen.
That's how the tiles connect.
I have also tested using what is in the sample (samples/image):
Code: Select all
auto& entry = pal->colors[paletteIndices[index]];
unsigned char alpha = paletteIndices[index] == 0 ? wxALPHA_TRANSPARENT : wxALPHA_OPAQUE;
p.Red() = entry.red * alpha / 256;
p.Green() = entry.green * alpha / 256;
p.Blue() = entry.blue * alpha / 256;
p.Alpha() = alpha;
I'll check how everything performs, I can always switch to event based rendering instead of timers.
Re: Drawing realtime graphics using wxDC
The second version is the correct one, RGB values must be pre-multiplied with alpha.
BTW: Which platform and wxWidgets version are you using? Over the last few months there have been several fixes regarding the handling of bitmaps with alpha under Windows.
Can you test with the "toucan.png" from the "image" sample? That should draw correctly with alpha.
BTW: Which platform and wxWidgets version are you using? Over the last few months there have been several fixes regarding the handling of bitmaps with alpha under Windows.
Can you test with the "toucan.png" from the "image" sample? That should draw correctly with alpha.
Use the source, Luke!
Re: Drawing realtime graphics using wxDC
I am running on Windows 10 using wxWidgets 3.1.0.
It's very odd. I took the PNG from the sample you pointed me to, renamed it to sprite16.png.
When I do this, it works, but still renders the actual tile (but does work with alpha):
But when I remove the line to load the PNG, it shows full square of the tile, including what I don't want to get rendered.
It seems that some part of the PNG loading activates something inside which makes it work with alpha?
It's very odd. I took the PNG from the sample you pointed me to, renamed it to sprite16.png.
When I do this, it works, but still renders the actual tile (but does work with alpha):
Code: Select all
wxBitmap bmp(width, height, 32);
bmp.LoadFile("d:\\sprite16.png", wxBITMAP_TYPE_PNG);
bmp.SetWidth(width);
bmp.SetHeight(height);
wxAlphaPixelData data(bmp);
wxAlphaPixelData::Iterator p(data);
unsigned int index = 0;
p.Offset(data, 0, 0);
for (int y = 0; y < height; ++y)
{
wxAlphaPixelData::Iterator rowStart = p;
for (int x = 0; x < width; ++x, ++p)
{
auto& entry = pal->colors[paletteIndices[index]];
unsigned char alpha = paletteIndices[index] == 0 ? wxALPHA_TRANSPARENT : wxALPHA_OPAQUE;
p.Red() = entry.red * alpha / 256;
p.Green() = entry.green * alpha / 256;
p.Blue() = entry.blue * alpha / 256;
p.Alpha() = alpha;
index++;
}
p = rowStart;
p.OffsetY(data, 1);
}
It seems that some part of the PNG loading activates something inside which makes it work with alpha?
Re: Drawing realtime graphics using wxDC
Can you try again with the latest version from GIT?I am running on Windows 10 using wxWidgets 3.1.0
It's probably related to whether the bitmap is a DIB or DDB internally. (Device dependent/independent bitmap).It seems that some part of the PNG loading activates something inside which makes it work with alpha?
Check the value of m_bitmap->IsDIB() for both cases.
Use the source, Luke!
Re: Drawing realtime graphics using wxDC
Calling IsDIB for both the PNG and non-PNG bitmap result in true.
I have used the wxWidgets version from GitHub: results are the same as my local wxWidgets version.
I have used the wxWidgets version from GitHub: results are the same as my local wxWidgets version.