🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

"Virtual" window for programmer practice

Started by
7 comments, last by SyncViews 3 years, 10 months ago

I want to try myself on programming a simple 2D-engine in c++. However native c++ is quite complicated if you want to use a window application or the console as “screen”.

Is there anything that handles all the window stuff (in windows) and just gives you direct access to the pixels and maybe (screen width and height)? It doesn't have to be resizable or swithcable from fullscreen to window mode ore anything complicated. For now I don't really want to have to bother with windows (windows 10 as well as the window within windows 10)itself.

I know there is the olcPixelGameEngine and similar but these already have too much “implemented” for me.

Thanks in advance ?

Advertisement

@Byter Might want to take a look at the first 4 days of Handmade Hero.

🙂🙂🙂🙂🙂<←The tone posse, ready for action.

Usually there is a basic widget in a window system named canvas or so (canvas is the name I see often, but I am not on Windows), which allows direct drawing on it (lines or images usually).

Such widgets are also interesting to window programming tutorials, as they provide nice graphics and don't need much code. You could try to dig up a window widget tutorial like that, and copy/paste the code as a starting point.

Byter said:
I know there is the olcPixelGameEngine and similar but these already have too much “implemented” for me.

What do you mean by “too much implemented”? To go back to something like hardware access, you are looking at old devices or emulators, modern systems have a ton of stuff at the OS level between you and the display.

Direct access to pixels is generally not how most things are done. Pixel access tends to be very inefficient, so libraries will deal with higher level things, a 2D library might have for example rectangles, gradients, lines, images/sprites, text, etc.

That said basically any library will let you do something like it, just not directly like with old hardware. Even with straight Win32 that part is not particularly complicated, but will need to look up a bunch of steps (create a blank Window, how to display a HBITMAP (say an image file) in it, then how to use say `CreateDIBSection` to make a HBITMAP you can easily update as a pixel array).

With say SDL 2 you might write your pixel buffer to a texture with SDL_UpdateTexture, then display that.

SyncViews said:
Direct access to pixels is generally not how most things are done.

on a programming level. But in the end the PC/GPU does it. It's the lowest level of graphical interaction I can think of (and that is what I want).

That's what I actually want. Access to a framebuffer which then is directly drawn onto screen. (Thanks for mentioning “pixel array”)

In order to then programm rectangles lines, spritedrawing, etc myself. That's why I asked for something like a “virtual window” (/screen).

At the moment I am researching if I can create such a “virtual screen” (/framebuffer) with, what Alberth said, a window.

That brought me to this page:

https://docs.microsoft.com/en-us/windows/win32/learnwin32/painting-the-window

And that connects to SyncViews suggestion to use Win32.

However it would still be easier for me if there was a programm/library that would directly grant me framebuffer access

EDIT: I am looking into SDL2 at the moment and it sounds quite like what I am looking for

It's curious how you mention “virtual” and “framebuffer” but still claim that you want the lowest level of graphical interaction…

Yeah just whip up something in SDL2 - or HTML Canvas (I enjoy that for quickly doing pixel manipulation stuff)

@supervga Why is it curious? I'm aware that with a usual Computer you won't get uncomplicated hardware access (As I am not too experienced with that). That's why I ask for a “virtual” screen (and of course because I couldn't find anything on the internet).

Ok technically it isn't the lowest level of graphical interaction anymore. You are right there.

It's not about the low-level graphical interactions but about direct access to the pixels drawn on screen (≙ framebuffer) I need

Byter said:
on a programming level. But in the end the PC/GPU does it. It's the lowest level of graphical interaction I can think of (and that is what I want).

This has not happened on any recent PC. There is no user code on Windows that can do a “byte *pixels = GetScreenBuffer()” and directly manipulate the display.

You can find emulators if want to do that sort of thing (or I suppose you could boot some much older OS maybe). In some cases the display is literally a block of bytes at a certain fixed memory address, and you can write that memory as the display chip scans through it.

Byter said:
That's why I ask for a “virtual” screen (and of course because I couldn't find anything on the internet).

Creating a HBITMAP that you “treat like the display”, or a buffer you copy to OpenGL or Direct3D, or equivalent through some other library (SDL_Updatetexture etc.) is how to get a “virtual” screen.

Consider that any time you can take say a .png file from disk and display that you are providing pixels, so instead of taking the image, you can just write whatever you want.

unsigned width = 800;
unsigned height = 640;
auto pixels = std::make_unique<unsigned char[]>(width * height * 3);
memset(pixels.get(), 0x00, width * height * 3); // black
for (unsigned x = 0; x < width; ++x)
  pixels[300 * width * 3 + x * 3 + 0] = 0xFF; // horizontal line

glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels.get());

There is also like `glDrawPixels` which is perhaps a little more direct, you need to go back to an older OpenGL version (before 3?) to get it, but I believe the drivers/implementation will still have it for software compatibility. That can then write a pixel array to the current frame buffer (render target).

EDIT:

If you want to know how GPUs do it then Direct3D11 or OpenGL is probably where to look. It's not direct pixel access because the hardware just doesn't work like that these days. Instead you will generally draw triangles defined by 3 points (and 2 triangles can make a rectangle), then you have a “pixel shader" (or fragment shader in OpenGL terms) which is a small program you write that will process one pixel at a time as it scans through that triangle (the “output merger” actually puts the output into the result, you can control the configuration of this, e.g. tell it to overwrite or do alpha blending or additive blending etc., but it is not a software component you can code).

This topic is closed to new replies.

Advertisement