Sign in to follow this  
Phynix

OpenGL Accessing video memory in c++

Recommended Posts

Hey...I would like to make my own 3d graphics library (just a hobby project, so please don't tell me to use direct3d or opengl or any of those stuff). So, how would I access video memory directly in Windows, or can I only draw inside a frame? If so, how can I use the WinAPI to do this? Thanks in advice!

Share this post


Link to post
Share on other sites
You can't access video memory directly. Usually the closest thing is to create a Direct3D surface/backbuffer, lock it, and write manually. Then you can flip that to screen. You could use a GDI construct like an HBITMAP instead, but it will be slower for no advantage.

Share this post


Link to post
Share on other sites
ok,thanks, but is it possible to draw individual pixels in the WinAPI, without having to get the DirectX sdk, wasting a bunch of RAM, etc? I'm trying to not use an existing 3d engine to make this.

Share this post


Link to post
Share on other sites
Quote:
Original post by Phynix
ok,thanks, but is it possible to draw individual pixels in the WinAPI, without having to get the DirectX sdk, wasting a bunch of RAM, etc? I'm trying to not use an existing 3d engine to make this.
PixelToaster might be more what you are looking for - a simple framework providing pixel-access to a framebuffer.

Share this post


Link to post
Share on other sites
Isn't that just a wrapper around Direct3D? Maybe that's fine for the OP's purposes, although he sounded like he didn't even want to have any sort of dependency on D3D. In which case, I'm not sure it's possible without a kernel driver and a ton of work.

Share this post


Link to post
Share on other sites
yeah, it would be preferable if there was no Direct3D dependancy, but if there is nothing else...which i really doubt...then, i would just have to settle with d3d. what im sort of asking is if you can draw directly to a winapi window.

Share this post


Link to post
Share on other sites
Quote:
Original post by Phynix
ok,thanks, but is it possible to draw individual pixels in the WinAPI, without having to get the DirectX sdk, wasting a bunch of RAM, etc? I'm trying to not use an existing 3d engine to make this.
No, you can't directly access the hardware in any modern operating system. Physical access to hardware is controlled via the kernel (to understand why, just think: what would happen if two programs wanted to access the hardware at the same time?)

You can draw bitmaps to the screen with plain old GDI/GDI+ of course (e.g. with BitBlt in GDI), but you won't be "access[ing] video memory directly". Libraries such as SDL also provide a simple API for drawing 2D images in a cross-platform way, perhaps you can start there?

In particular, if you're wanting to write your own software rasterizer, you don't actually need "direct" access to video memory, and I would say that the interface provided by SDL would be more than sufficient for your scenario.

Share this post


Link to post
Share on other sites
You don't access to the hardware directly. Leave that to the driver.
Besides even if you could, each video card model is different, and you would need to code for each and every one.
Instead, there IS already an interface to the driver: it's called Direct3D.

Direct3D is a low-level API that allows you to access the video card in a generic way. It's NOT an engine.
Over time Direct3D grew and now it's bigger and contains a lot of stuff usefull for game developers, but it doesn't make it an engine. It's still a low level API.

Furthermore, everything that is not truly necessary is in the D3DX library, stay away from D3DX and it will be fine.

You can try GDI instead, which is another, older, interface.
But I don't understand why you want to stay away from D3D.

Cheers
Dark Sylinc

Share this post


Link to post
Share on other sites
In the old days, you could access the actual video memory directly (mode 13h FTW), but these days you can't. More importantly, you probably don't want to, because you have to play nice with your windowing environment.

What you most probably mean is that you want a single, contiguous block of memory that can be used as a suitable linear framebuffer for software rendering/rasterization.

The Win32 APIs give you enough to do just this -- in fact, its exactly the way that WinG, which was the precursor to DirectX, worked in order to entice game developers to move away from DOS. The Previously mentioned PixelToaster does exactly what you want and supports multiple platforms, IIRC.


My own software rendering system works completely independently of any OS API up until I need to get my back-buffer onto the screen, and the sum total of Windows API code, aside from window creation, involved in getting my results to the screen is about 12 lines. It supports both windowed and fullscreen rendering.

Share this post


Link to post
Share on other sites
Quote:
Original post by Matias Goldberg
You can try GDI instead, which is another, older, interface.
But I don't understand why you want to stay away from D3D.


OK, I will try GDI, thanks. I also found a great tutorail on the web by googling (http://www.functionx.com/win32/index.htm), and is pretty close to what I originally wanted: a method of manipulating pixels using the Win32 API.

And the reason I wanted to stay away from D3D is because it would be redundant. I don't find any point in creating D3D from D3D (creating a graphics library that has the same or less functionality than the thing it was based upon). Direct3D is already a 3D library, and it doesn't make sense to make a 3D library out of a 3D library.

So, my question is pretty much answered. Thanks Matias Goldberg and Codeka, and everyone else. (Wow, I love these forums)

Share this post


Link to post
Share on other sites
Quote:
Original post by Phynix
And the reason I wanted to stay away from D3D is because it would be redundant. I don't find any point in creating D3D from D3D (creating a graphics library that has the same or less functionality than the thing it was based upon). Direct3D is already a 3D library, and it doesn't make sense to make a 3D library out of a 3D library.
Thus why you should use PixelToaster, rather than mucking about with GDI. PixelToaster will abstract away all the little details that don't matter to your 3D engine, and probably perform better than GDI into the bargain [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by EngineCoder
Why not simply use SDL?


If you don't know any of them, and are only looking out to stuffing some surface with pixels, then pixel-toaster might be the easier and more appropriate choice.

Share this post


Link to post
Share on other sites
So you're going to use D3D, via pixeltoaster, to write a D3D-like API/library? Why?

Quote:
is it possible to draw individual pixels in the WinAPI, without having to get the DirectX sdk, wasting a bunch of RAM, etc?


Your plan is hardly going to improve your memory usage. I don't think anyone really understands why you want to do this. If it's for your own understanding, then why are you so averse to using D3D? If it's to try to create a usable 3D API then it's hardly worth bothering, as you're not going to be able to better D3D or OpenGL, which have access to the graphics hardware through the graphics drivers.

Basically you are going to have to use D3D or OpenGL at some level to get your graphics data to the graphics card's display memory, even if you do all the rendering with the CPU.

EDIT: If you really want to write your own software renderer, then use D3D with a lockable backbuffer, and just change the backbuffer pixels in memory (perhaps using a simple #define macro). It's not a very good way to draw 3D graphics, but then ignoring the graphics card's capabilities isn't a very good way to draw 3D graphics either. That way, you'll be only be using D3D to get a pointer to the video memory. You can't really get any further from using it than that.

Share this post


Link to post
Share on other sites
Quote:
Original post by EngineCoder
Why not simply use SDL?
Because PixelToaster is optimised for software rasterisers/ray-tracers, while SDL is designed for sprite blitting. The performance difference may be negligible, but PixelToaster is a lot simpler to use (don't have to worry about surface formats, etc.).

Share this post


Link to post
Share on other sites
Quote:
Original post by stonemetal
Or better yet look at the code in SDL and pixeltoaster(if it is open) and aim for as low a level as possible.


Why would that be better?

Share this post


Link to post
Share on other sites
Quote:
Original post by stonemetal
Or better yet look at the code in SDL and pixeltoaster(if it is open) and aim for as low a level as possible.
Not sure why you'd want to do that. If the goal is a software rasterizer (which is what it seems to be) then doing all the "low-level" stuff would just be a waste of time. You're much better off using something like PixelToaster to handle that for you and just work with the flat buffer it gives you. Then you can concentrate on all the "interesting" stuff!

Share this post


Link to post
Share on other sites
One downside to PixelToaster is that it only supports 32bit ARGB and 128bit (4xfloat) ARGB color formats. Granted 32bit is pretty standard, even for software renderers, but going to 16bit color can essentially double your fill-rate for free.

If you want to support 16bit (or even 8bit CLUT) color formats, you'll need to go through GDI/Win32.

Share this post


Link to post
Share on other sites
I like to do char *myScreen = new char[height*width*3], and draw to that. Then you can copy that to your window however you like, it can easily be implemented separate from the rest of your game in all the mentioned APIs. The easiest probably being StretchDIBits in Win32, which with a single function call puts those pixels in the window.

Share this post


Link to post
Share on other sites
I hate to sound asinine, but maybe you would have better luck accessing video memory directly if you used a hacked-up version of the Linux kernel. I think the linear frame buffer is still there on x86 machines at 0x0000a0000. It's also easier to write a device driver under Linux than Windows.

Short of that the only way your going to access the video memory directly is if you write your own operating system and/or your own video driver. Like one of the poster's above mentioned if you *DID* write your own video driver, the API to it would be your replacement to D3D (except for the fact that it would only work with one specific type of hardware, whereas D3D is generic enough to interface with 99.9% of existing video cards).

Or you could just roll your own mini-os that has no purpose except to access video memory. Another alternative would be to create a Windows program that was compiled using the Boot Environment Application subsystem, that gives pretty raw access to the video buffer (through Bg/Bl APIs) but is largely undocumented. So you could write your whole program there and the machine would hit the BIOS then the POST, then your Boot program and as long as you keep it from exiting back to bootmgfw then your program would be the one and only!

Share this post


Link to post
Share on other sites
Quote:
Original post by Steve_Segreto
I hate to sound asinine, but maybe you would have better luck accessing video memory directly if you used a hacked-up version of the Linux kernel. I think the linear frame buffer is still there on x86 machines at 0x0000a0000. It's also easier to write a device driver under Linux than Windows.

Short of that the only way your going to access the video memory directly is if you write your own operating system and/or your own video driver. Like one of the poster's above mentioned if you *DID* write your own video driver, the API to it would be your replacement to D3D (except for the fact that it would only work with one specific type of hardware, whereas D3D is generic enough to interface with 99.9% of existing video cards).

Or you could just roll your own mini-os that has no purpose except to access video memory. Another alternative would be to create a Windows program that was compiled using the Boot Environment Application subsystem, that gives pretty raw access to the video buffer (through Bg/Bl APIs) but is largely undocumented. So you could write your whole program there and the machine would hit the BIOS then the POST, then your Boot program and as long as you keep it from exiting back to bootmgfw then your program would be the one and only!


That sounds a bit complicated, and i don't really want to make a new OS. PixelToaster is fine for my needs, and is pretty fast (is it? I'm just making 3D lines right now :) )

And while in the topic of PixelToaster, it is created using Direct3D, right? And Direct3D is hardware accelerated on most windows machines, right? So, if this is true, then that means that anything i create with PixelToaster is hardware accelerated, right?

Share this post


Link to post
Share on other sites
Quote:
Original post by Phynix
And while in the topic of PixelToaster, it is created using Direct3D, right? And Direct3D is hardware accelerated on most windows machines, right? So, if this is true, then that means that anything i create with PixelToaster is hardware accelerated, right?
The presence or not of hardware acceleration in PixelToaster is really pretty meaningless when you are performing software rasterisation/ray-tracing [wink]

That said, PixelToaster is using D3D to present your surface under Windows, but even were it not, I highly doubt the blit operation could over-shadow your software rendering.

Share this post


Link to post
Share on other sites
Quote:
Original post by PhynixAnd while in the topic of PixelToaster, it is created using Direct3D, right? And Direct3D is hardware accelerated on most windows machines, right? So, if this is true, then that means that anything i create with PixelToaster is hardware accelerated, right?


As pointed out, hardware acceleration these days isnt about setting single pixels or blitting, it's about transforming geometry, rasterizing, texture lookups, shader execution and parallelizing the heck out of it. What's accelerated is pretty much everything you insist on doing yourself, so basically you're walking on your hands saying "but I'm wearing running shoes, so I _should_ be pretty fast".

As a hobby project this can be fun and teaching you a lot, but don't expect your hand-rasterized triangle to be even remotely as fast as one done with D3D or OpenGL.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this