Videomem

Started by
7 comments, last by fettodingo 22 years, 2 months ago
How do I get a pointer to the videobuffer in OpenGL, so that I can paint directly to the screen before flipping? (Like directdraw)
;-)
Advertisement
I don''t think you can.

The generally preferred way to draw 2D stuff to OpenGL is to draw textured quads in glOrtho / gluOrtho2D mode. Suppose your screen is width x height, then this code should allow for pixel perfect "blitting" in OpenGL:

/* Set 2D matrices */
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, width, 0, height, -1, 1);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

/* Example of some 2D rendering
* Draws a fullscreen textured quad
*/
glBindTexture(GL_TEXTURE_2D, hudTextureID);
glBegin(GL_QUADS);
glTexCoord2f(0,1)
glVertex2i(0,height);
glTexCoord2f(0,0)
glVertex2i(0,0);
glTexCoord2f(1,0)
glVertex2i(width,0);
glTexCoord2f(1,1)
glVertex2i(width,height);

glEnd();

/* Restore 3D matrices */
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();

And an additional tip: Those width and height variables don''t actually have to match your OpenGL window''s resolution. That''s a handy thing to support multiple resolutions. For instance you could set glOrtho to 640x480 even though the window is 800x600. All the rendering will get enlarged automatically by OpenGL.
Dirk =[Scarab]= Gerrits
Yeah thats handy.. but I need direct access to the surface, mainly for special-effects and stuff.
;-)
The closest you''ll get is glDrawPixels. It''s going to be slow for two reasons: (a) you only have so much bandwidth to your video card and (b) it isn''t optimized in most consumer level graphics cards. Direct access can''t be hardware accelerated. Having direct access is against OpenGL''s primary goal: to be completely hardware accelerated.

That doesnt leave much to the experimenting programmer now does it? To bad. Annyway.. thanks for the answers.
;-)
Maybe you should explain what effect you are trying to accomplish. Surely there must be an alternative way to implement it. And if there isn''t you can resort to glRead/DrawPixels as Null and Void suggests (SLOOOW).
Dirk =[Scarab]= Gerrits
In the strictest sense, it''s effectively impossible to get a pointer to video memory on any modern operating system. The problem is that not all video cards handle frame buffers the same way (this is really not that true anymore, but since you can''t assume that everything is the same, assume that they''re all different).

On modern systems, the best you can get is some abstraction of video memory. DirectDraw does exactly that, and the pointer it gives you is only valid between Lock/Unlock calls for the surface in question, and the addresses are virtual ones, not physical ones.

OpenGL happens to abstract things even further, which is what glReadPixels and glDrawPixels are for. Most hardware vendors don''t bother to optimize these functions in their drivers—NVIDIA is essentially the one exception. Of course, you cannot mix DirectDraw and OpenGL (for no good technical reason, either), so don''t bother to try that.

Unfortunately, there is really no good answer to this, except to tell you to move to Direct3D since you''ll also get DirectDraw with that. But then you''re locked into Direct3D''s particular set of limitations (and, of course, all APIs have limitations), though that may not be a problem for you.

These days, direct framebuffer access is pretty much useless. If you''re using OpenGL, you want 3D stuff, and there''s simply no need to tamper with the framebuffer. I''d suggest either find some other way to implement or approximate the effect you want (perhaps pixel shaders might do the trick), or forget it altogether since it''s probably not portable anyway. Or, use glDrawPixels, but make the feature togglable for machines where that function is slow.
Ok. And it is impossible to get direct access to the z-buffer to then?
;-)
The depth buffer is normally stored on the video card, if possible, as well. Even if you could get read/write access to it it''d be slow. Why would you want access to the depth buffer? I''m pretty sure there''s a better method to do what you want.

This topic is closed to new replies.

Advertisement