Dark Bit Factory & Gravity

PROGRAMMING => Coding tutorials => Topic started by: Rbz on September 23, 2006

Title: OpenGL framebuffer library
Post by: Rbz on September 23, 2006
I started this new topic to post the development status of opengl ptc and stop hijacking Clyde topics :)

I'm using this section since it's coded in C/C++, anyway you will able to use this library with Freebasic,C/C++ and others programing language capable to link with static library.  Â Btw the main idea was to code it for Freebasic and there is a example for it in the ptc.rar file.

Jim coded the main part of the library and I'm trying to help finish it  ;)

Added:




Title: Re: OpenGL framebuffer library
Post by: Shockwave on September 24, 2006
Looking forward to seeing a final version of this.
By the way Rbraz, are you taking requests for this library? I'd love to add a wish list.
Title: Re: OpenGL framebuffer library
Post by: benny! on September 24, 2006
@Rbraz:

Sounds interesting. Do you have any speed tests about the OpenGL glDrawPixels command
compared to e.g. DirectX or direct memory accessing ?
Title: Re: OpenGL framebuffer library
Post by: Jim on September 24, 2006
Whatever the DirectX speed is, OpenGl will come out pretty much the same.  Somehow you have to hammer 640x480x4x60 bytes per second up to the gfx card.  That's around 80Mb/s, which is a lot.

Jim

Title: Re: OpenGL framebuffer library
Post by: Rbz on September 24, 2006
Quote
Do you have any speed tests about the OpenGL glDrawPixels command
compared to e.g. DirectX or direct memory accessing ?
Not yet, but as Jim said it should be fast like DirectDraw framebuffer.

Quote
By the way Rbraz, are you taking requests for this library? I'd love to add a wish list.
If there's anything that I can help, just ask. Btw this version is the most tiny and functional possible, and capable to replace the original tinyptc.


Check out the new version, I've added a fullscreen option and an example to how to use keyboard check in to your programs.
 :cheers:
Title: Re: OpenGL framebuffer library
Post by: Shockwave on September 24, 2006
It works really well Rbraz. I love it, it's great that you have included some functions that will help to get people started and that they behave like Blitz.

I'm not sure if I would find these functions useful myself as I'd prefer to resource my media into the program to get it one filed but I am glad that you have included them as it gives a great example for people who are making the step from Blitz to FB.

The PTC_SETFLIP command is wicked. Love it, it works brilliantly.

I see

while(1)
...
wend

I have to check this. how is this relating to the keyboard? Is that check a part of the lib?
So if I want to have a demo that exits on escape, that's all I have to do? :)

Great that it runs without any modifications to the original install of FB.

Now, to make this really kickass, here are a few things that I would do.

1: a screendim command.
as this is using opengl now, how about using a blank sprite as a means of dimming the screen?
The dim command could be;

dim (&HFFFFFF , 255) Where the colour is the colour of the sprite and the following number is the opacity of it. The sprite could just be drawn over the top of the screen. That would really rock.

Maybe access Opengl's lines,polygons and gourad triangles?

I don't know how practical these suggestions would be to get them to work in conjunction with a screen buffer.

GETMOUSEX
GETMOUSEY
GETLEFTBUTTON
GETRIGHTBUTTON

Commands for reasing the mouse.

As far as it is at the moment though, it is something to be proud of. I'll definately be using it :)

Title: Re: OpenGL framebuffer library
Post by: Rbz on September 24, 2006
@SW: added mouse support as you wish.

About "screendim command", I don't know exactly what do you mean, maybe Jim can help.

Quote
I have to check this. how is this relating to the keyboard? Is that check a part of the lib?
The library check for Escape key and exit if it was pressed.
Btw, for the main loop, I take a look at it, and it's more safe if you do it like this:
(Include windows.bi)

Code: [Select]
while(GetAsyncKeyState(VK_ESCAPE)<>-32767)
...
...
wend



Quote
Maybe access Opengl's lines,polygons and gourad triangles?
I'm afraid that this is not possible for now...
Title: Re: OpenGL framebuffer library
Post by: Shockwave on September 24, 2006
Works like a charm :)
Title: Re: OpenGL framebuffer library
Post by: Jim on September 25, 2006
added:
Alt-Enter can now toggle full screen mode.
ptc_openex(title,width, height, fullscreen, refreshrate)
ptc_fullscreen(onoff)

fixed:
Took out the SPI_SETSCREENSAVERACTIVE. This isn't the recommended way of disabling screensavers. Correct way is to handle WM_SYSCOMMAND and WM_POWERBROADCAST messages.
Coming out of fullscreen mode wouldn't reset the display correctly.
vc project file now builds to libptc.a directly.
vc project file now excludes default libraries.

I can't see any reason why you can't use OpenGL commands in your freebasic programs now...just include gl/gl.bi.  If you mess up the view matrices, expect the screen to go funny.  Don't mix ptc_update, just draw things with OpenGL and call ptc_flip().

Would love some requests for features :D

Jim
Title: Re: OpenGL framebuffer library
Post by: Rbz on September 25, 2006
@Jim: the alt+enter doesn't work for me...

Anyway nice additions, didn't noticed that SPI_SETSCREENSAVERACTIVE isn't the recommended way to disable screensavers, nice one.
Title: Re: OpenGL framebuffer library
Post by: Jim on September 25, 2006
Rats.  Any idea why/where it's failing?

As this gets more complicated, we need to add a C program that tests it so you can actually debug it in VC.

Jim
Title: Re: OpenGL framebuffer library
Post by: relsoft on September 25, 2006
Code: [Select]
int __cdecl ptc_update(const unsigned int *pixels)
{
// process messages
MSG msg;
while (PeekMessage(&msg,gameWindow,0,0,PM_REMOVE))
{
// translate and dispatch
TranslateMessage(&msg);
DispatchMessage(&msg);
}

glDrawPixels(g_w,g_h,GL_BGRA_EXT,GL_UNSIGNED_BYTE,pixels);
ogl_flip();
return PTC_OK;
}


Hi guys, why glDrawPixels?  Can't glTexSubImage2D be used for this?  Oreven gltexImage2d.  Just my thoughts.



Title: Re: OpenGL framebuffer library
Post by: Jim on September 25, 2006
You could use glTexSubImage2D to load the screen data into a next-power-of-2 sized texture you'd previously created.  So you could make a 1024x512 texture for a 640x480 screen.  Then after that you'd have to render a single GL_QUAD to draw the texture to the screen.  That would definitely work.  glDrawPixels moves the image directly to the screen, so you'd think it would be quicker since it involves one less copy of the data.  Lots of glDrawPixels calls are very, very slow on my PC, but doing just one is fast.  I will definitely check this option later on but tbh, it's blazingly quick anyway.  It would certainly make it possible to do all kinds of feedback/motion blur tricks if you could use the last screen output as a texture in a new scene, which would be very cool.

That leads me to another question.  I know dbf is strongly focussed on doing everything in software.  I like that :).  Depending on how much gets added to this lib all kinds of things could be accelerated by OpenGL.  Is that what is wanted from this lib, or just a few special fx?  Perhaps that will require two versions.  A tiny <10Kb lib that does the basic stuff, and a bigger one with all the bells and whistles.  Any comments?

Jim
Title: Re: OpenGL framebuffer library
Post by: Jim on September 25, 2006
Quote
1: a screendim command.
as this is using opengl now, how about using a blank sprite as a means of dimming the screen?

Here's an example of what I mean.  OpenGL allows an offset and a scale to the colours that are uploaded by glDrawPixels or glTex.
At the top of your program add
Code: [Select]
#include "gl/gl.bi"Then, before ptc_update() do this
Code: [Select]
glPixelTransferf(GL_RED_SCALE, 0.9)
glPixelTransferf(GL_GREEN_SCALE, 0.5)
glPixelTransferf(GL_BLUE_SCALE, 0.1)

The number is the scale amount for red, green and blue, ranging from 0.0 to 1.0.  Numbers over 1.0 clamp to 1.0 for some other odd fx.  Lots more info here (http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0530&db=man&fname=/usr/share/catman/g_man/cat3/OpenGL/glpixeltransfer.z)

Jim
Title: Re: OpenGL framebuffer library
Post by: MrP on September 25, 2006
This really is starting to to look like a very cool lib. However I'm going to have to chastise you all for not coming up with it sooner. Maybe before I'd nearly finished writing most of my own stuff that uses GFXLib.... lol... Only kidding guys keep it up going to d/load and give this a whirl tonight when I get in from work.....
Title: Re: OpenGL framebuffer library
Post by: ninogenio on September 25, 2006
i think a tiny version and a delux version might be the way to go!

i had no idea you could alpha pixels like that.hows about using a bit of mmx for 64 bit transfers im guessing you would have to use glteximage2d for mmx though?

i like the idea of using opengl renderd lines and polys. great work guys  :cheers:
Title: Re: OpenGL framebuffer library
Post by: Shockwave on September 25, 2006
I think that 2 versions are needed.
Basically I think that for me, I am going to have to carry on doing softrendered stuff, but not everyone here wants that. This could be a really cool and unique tool that will help a lot of people get into demo programming. Maybe we could start a topic for each with the features that each lib should include?
Title: Re: OpenGL framebuffer library
Post by: ninogenio on September 25, 2006
sounds good shockwave!

me personally i dont mind where ever the speed is im there :)
Title: Re: OpenGL framebuffer library
Post by: Rbz on September 26, 2006
I think that 2 versions are needed. ......
Yeah, I agree with Shockwave  :)
Title: Re: OpenGL framebuffer library
Post by: Clyde on September 26, 2006
Couldnt you do something similar to how you'd make FB use windowed mode. And have something for example: DEFINE LIBRARY_MODE1
Title: Re: OpenGL framebuffer library
Post by: relsoft on September 26, 2006
I have a similar approach done to my game render. You might wanna check this out.

Using FBGFX to draw to a buffer and blit to screen using GL or sofware.




Title: Re: OpenGL framebuffer library
Post by: TinDragon on September 27, 2006
After seeing this I have a feeling I might be able to setup this kind of framebuffer system in bmax since I have full access to the opengl commands. If it's as simple as it appears from looking at the C code then it will enable some of us bmax users to convert alot of tinyptc code over, if I get stuck I will come asking for help  ;)
Title: Re: OpenGL framebuffer library
Post by: Shockwave on October 15, 2006
Ok. Heres a question about this for Rbraz and Jim.. I am one of the people who love this lib. What version is the most up to date and stable please?
I want to make sure I use the latest version in my next demo.
Also I'd like to put together some tutorials at some stage in the near future :)
Thanks.
Title: Re: OpenGL framebuffer library
Post by: Rbz on October 15, 2006
You can use that one attached to my first post, you can call it by tiny version, or you can use that last one that Jim have been attached, and you can call it by an extra version.

I hope Jim agree with me  :)





Title: Re: OpenGL framebuffer library
Post by: Shockwave on October 16, 2006
Mmmm. Both have their merits :) Thanks Rbraz.
Title: Re: OpenGL framebuffer library
Post by: Dr_D on December 17, 2006
Here's something that might help. I wrote it as an extension for YAGL. It's relies on extensions, so it might not be suitable for this project. I just thought I'd post it anyway because it might be of use. ;)


EDIT: Errr... sorry. I didn't realize I was posting in the C/C++ forum. :whack:
Title: Re: OpenGL framebuffer library
Post by: Shockwave on December 18, 2006
No problem, have some Karma for it anyway :)
Title: Re: OpenGL framebuffer library
Post by: stormbringer on September 03, 2007
You could use glTexSubImage2D to load the screen data into a next-power-of-2 sized texture you'd previously created.  So you could make a 1024x512 texture for a 640x480 screen.  Then after that you'd have to render a single GL_QUAD to draw the texture to the screen.  That would definitely work.  glDrawPixels moves the image directly to the screen, so you'd think it would be quicker since it involves one less copy of the data.  Lots of glDrawPixels calls are very, very slow on my PC, but doing just one is fast.  I will definitely check this option later on but tbh, it's blazingly quick anyway.  It would certainly make it possible to do all kinds of feedback/motion blur tricks if you could use the last screen output as a texture in a new scene, which would be very cool.

That leads me to another question.  I know dbf is strongly focussed on doing everything in software.  I like that :).  Depending on how much gets added to this lib all kinds of things could be accelerated by OpenGL.  Is that what is wanted from this lib, or just a few special fx?  Perhaps that will require two versions.  A tiny <10Kb lib that does the basic stuff, and a bigger one with all the bells and whistles.  Any comments?

Jim


what Jim said is completly true => avoid glDrawPixels() as much as you can => use glTexSubImage2D() instead with either the next power of 2 sized texture or a rectangular texture (if you use NVidia or ATI extensions)

also make sure the internal format of the texture is the same as your buffer in memory (i.e. same color mode, same bitdepth and avoid RGB to RGBA buffers or vice-versa or similar as it goes through conversions usually done at the driver level, most of the time in software :( )
Title: Re: OpenGL framebuffer library
Post by: stormbringer on September 03, 2007
Quote
1: a screendim command.
as this is using opengl now, how about using a blank sprite as a means of dimming the screen?

Here's an example of what I mean.  OpenGL allows an offset and a scale to the colours that are uploaded by glDrawPixels or glTex.
At the top of your program add
Code: [Select]
#include "gl/gl.bi"Then, before ptc_update() do this
Code: [Select]
glPixelTransferf(GL_RED_SCALE, 0.9)
glPixelTransferf(GL_GREEN_SCALE, 0.5)
glPixelTransferf(GL_BLUE_SCALE, 0.1)

The number is the scale amount for red, green and blue, ranging from 0.0 to 1.0.  Numbers over 1.0 clamp to 1.0 for some other odd fx.  Lots more info here (http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0530&db=man&fname=/usr/share/catman/g_man/cat3/OpenGL/glpixeltransfer.z)

Jim


I would not recommend this technique... it's very slow on some drivers.... render to textures and set the texture mode to modulate, set the color and then render quads or triangles (fastest) => much much faster!

glPixelTransferXXX() functions are legacy! new drivers are optimized for shaders that replace this much more efficiently. In some cases, shaders are not necessary and most effects can be achieved through other tricks...
Title: Re: OpenGL framebuffer library
Post by: Jim on September 04, 2007
->Stormbringer.  I agree with everything you say.  My only argument against using shaders or other advanced features directly in this lib is that it is meant to run on everything from the oldest card to the latest $1000 monsters from ATI and nVidia.  If people want more fx, then the best thing is they break away from this lib and learn, with our help, to code their own startup and render routines.

Jim
Title: Re: OpenGL framebuffer library
Post by: stormbringer on September 04, 2007
@Jim: you do not need shaders for everything.... glPixelTransfer can be less efficient than in memory lookup tables sometimes... and for the screen dimming, a texture with modulated color is much faster, as long as you draw into a texture. You do not need extensions for that, just draw in the opengl buffer and copy to the texture (sort of virtual screen), then draw a textured quad, etc.
Title: Re: OpenGL framebuffer library
Post by: Jim on September 04, 2007
I know, that was just an example of something that might have been added to a deluxe version of DBF PTC.  We never actually did anything with it ;D
Jim
Title: Re: OpenGL framebuffer library
Post by: Phoenix on October 14, 2007
Code: [Select]
int* buffer = malloc(RES_X*RES_Y);
memset(buffer, 0, RES_X*RES_Y);

ptc_update(buffer);

Isn't that how it's supposed to be done? I get an unhandled exception when I try to run it.
Title: Re: OpenGL framebuffer library
Post by: Stonemonkey on October 14, 2007
Possibly something like:
Code: [Select]
int* buffer = (int*)malloc(RES_X*RES_Y*sizeof(int));
memset(buffer, 0, RES_X*RES_Y*sizeof(int));

ptc_update(buffer);
Title: Re: OpenGL framebuffer library
Post by: Jim on October 14, 2007
Right, the problem was that you need to allocate an 'int' for each pixel.  The crash is in PTC trying to read too much data from your array.

If you're coding in C, you're much better off leaving off the type casts.
So I'd write it
Code: [Select]
unsigned int *buffer = malloc(RES_X*RES_Y* sizeof *buffer);
memset(buffer, 0, RES_X*RES_Y*sizeof *buffer);
ptc_update(buffer);
Many reasons for that
1) unsigned int is the correct type for pixels (shifting is ill-defined for signed values - who knew that eh?)
2) the type cast can hide errors
3) by using sizeof *buffer instead of sizeof(int) you remove one more place that you might need to change the code.

In C++, you need to write it like Stonemonkey says, the type casts are essential, but then in C++, you'd probably want to use
Code: [Select]
unsigned int *buffer = new unsigned int [RES_X*RES_Y];

Jim
Title: Re: OpenGL framebuffer library
Post by: Phoenix on October 15, 2007
Thanks Jim, that works great :)
Title: Re: OpenGL framebuffer library
Post by: Jim on October 15, 2007
Great to hear!  Are you making a demo?

Jim
Title: Re: OpenGL framebuffer library
Post by: Phoenix on October 15, 2007
I don't know what I'm making actually :P I'm just trying out the library. Perhaps it will become a demo :)
Title: Re: OpenGL framebuffer library
Post by: Phoenix on October 15, 2007
I tried to write a function that converts RGB to a single value, but with no luck:
Code: [Select]
// BGRA
return (blue<<24)|(green<<16)|(red<<8)|0xFF;
What's wrong here? I think there should be a torgb() function included in the lib.
Title: Re: OpenGL framebuffer library
Post by: Shockwave on October 15, 2007
It should be easy enough to define something to convert 3 values to rgb.

Use this sort of maths to do it;

Code: [Select]
PIXEL=(((RED SHL 8)+GREEN)  SHL 8)+BLUE
Title: Re: OpenGL framebuffer library
Post by: Stonemonkey on October 15, 2007
1) unsigned int is the correct type for pixels (shifting is ill-defined for signed values - who knew that eh?)
oops, I should've.

2) the type cast can hide errors
cheers Jim, hadn't thought of it that way.

3) by using sizeof *buffer instead of sizeof(int) you remove one more place that you might need to change the code.
Hadn't thought of that either.


Code: [Select]
unsigned int *buffer = new unsigned int [RES_X*RES_Y];
Looks better but is there any difference in how it allocates the memory?


There's sometimes different formats used but tinyptc uses this (although I'm not sure if some different graphics cards need it in a different format):
Code: [Select]

return (alpha<<24)|(red<<16)|(green<<8)|blue;

Title: Re: OpenGL framebuffer library
Post by: Phoenix on October 15, 2007
I solved it :) This is how it's done:
Code: [Select]
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
int __cdecl ptc_torgb(unsigned char red, unsigned char green, unsigned char blue)
{
return 0xFFFFFFFFFF000000|(((red<<8)+green)<<8)+blue;
}

However, I have no idea how it works :P I was testing in the windows calculator converting various ARGB values into hex, and lots of F:s appeared in front of the colors.
Title: Re: OpenGL framebuffer library
Post by: Stonemonkey on October 15, 2007
If your ints are 32 bit then the first 8 Fs shouldn't make any difference, as for the rest of it, in this case using + (add) is the same as using | (or) because each of the 8 bit colour values don't overlap and both ways have the effect of writing the 8 bit value into the appropriate 8 bits of the result, and the red bits are shifted by 8 bits twice which is the same as shifting by 16 bits.

It used to be the case that OR was faster than ADD but I don't think it makes any difference any more.
Title: Re: OpenGL framebuffer library
Post by: Phoenix on October 15, 2007
You're right :) It can be shortened to:
Code: [Select]
return 0xFF+(((red<<8)+green)<<8)+blue;
Title: Re: OpenGL framebuffer library
Post by: Stonemonkey on October 15, 2007
IF you want to set the alpha bits, it should be

0xff000000

Title: Re: OpenGL framebuffer library
Post by: Jim on October 16, 2007
Quote
Code: [Select]
unsigned int *buffer = new unsigned int [RES_X*RES_Y];
Looks better but is there any difference in how it allocates the memory?
Yes, you can overload the 'new' and 'new []' operators in C++ so it calls something else.  It can also throw exceptions on failure.
The actual memory still comes form the same place though, but you mustn't mix malloc/free with new/delete.
In this case you'd want
Code: [Select]
delete [] buffer;

Jim
Title: Re: OpenGL framebuffer library
Post by: ninogenio on October 19, 2007
jim can the above be done in these conditions in cpp.

typedef struct {
       
          float x;
          float y;
          float z;
}vertex;

typedef struct {
           
           vertex * myvertex;
           blah ..
           blah ..
} entity

entity * myentity;

myentity = new entity;
myentity->myvertex = new vertex[10] ;

delete [] myenetity->myvertex ;
delete [] myentity ;
Title: Re: OpenGL framebuffer library
Post by: Jim on October 19, 2007
The last line should just be
Code: [Select]
delete myentity;
It's not an array so you don't need the []

Jim
Title: Re: OpenGL framebuffer library
Post by: ninogenio on October 19, 2007
ah cool so it can be used in exactly the same way as malloc and free cheers!
Title: Re: OpenGL framebuffer library
Post by: Allosentient on November 11, 2008
Whatever the DirectX speed is, OpenGl will come out pretty much the same.  Somehow you have to hammer 640x480x4x60 bytes per second up to the gfx card.  That's around 80Mb/s, which is a lot.

Jim



I know this is an old post, but wanted to contribute.  I noticed that DrawPixels was mentioned right before this post.  The goal of using the graphics card is to have the graphics card procedurally create the pixels you are talking about here.  You are not sending 80 mb/sec to the graphics card, you are sending a set of instructions for the graphics card to process on the side.  This is why the use of DrawPixels isn't really recommended for the entire screen.

I am not an expert here by any means so please correct me if I am wrong!
Title: Re: OpenGL framebuffer library
Post by: stormbringer on July 03, 2009
I also noticed that a lot of OpenGL framebuffer libs here use DrawPixels. This has been marked as deprecated in OpenGL 3.0 (and potentially removed in a few years). It's a very old method of updating stuff in the OpenGL frame buffer and has been left out of hardware acceleration by most drivers (especially on laptops and small systems). For future proof, hardware accelerated bitmap transfers, you should always create textures with glTexImage1D/2D/3D and update the texture buffer with glTexSubImage1D/2D/3D.

Textures can then be used in shaders, can be used for texturing primitives and benefit from the latest OpenGL extensions and of course hardware acceleration.
Title: Re: OpenGL framebuffer library
Post by: benny! on July 05, 2009
@Stormbringer:
Thanks for pointing that out!
Title: Re: OpenGL framebuffer library
Post by: hellfire on July 07, 2009
Quote
you should always create textures with glTexImage1D/2D/3D and update the texture buffer with glTexSubImage1D/2D/3D.
That's essentially what I was doing here (http://www.dbfinteractive.com/forum/index.php/topic,4102.0.html), but unluckily support for non-power-of-two textures isn't quite were I expected it to be.
So for a 640x480 image you upload 1024x512 which leads the concept ad absurdum...
Title: Re: OpenGL framebuffer library
Post by: Clyde on September 07, 2009
How is this going?
Title: Re: OpenGL framebuffer library
Post by: Rbz on September 08, 2009
Status = Closed.

:) We stopped working on it after having incompatibilities (slow down) on some PC config, and then tinyptc_ext born.
Title: Re: OpenGL framebuffer library
Post by: hellfire on September 08, 2009
Another option is to use Direct3D instead as most modern chipsets aim to be compatible with Windows Vista (requiring to support per-pixel floating-point processing) but still fail to read a texel from an arbitrary sized texture using OpenGL.