Dark Bit Factory & Gravity
PROGRAMMING => Coding tutorials => Topic started 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:
- Fullscreen option
- Key_Test example
- Mouse x,y position and left,right button support, see "Mouse_Test.bas" example
- Disable screensaver while ptc is running
-
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.
-
@Rbraz:
Sounds interesting. Do you have any speed tests about the OpenGL glDrawPixels command
compared to e.g. DirectX or direct memory accessing ?
-
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
-
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.
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:
-
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 :)
-
@SW: added mouse support as you wish.
About "screendim command", I don't know exactly what do you mean, maybe Jim can help.
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)
while(GetAsyncKeyState(VK_ESCAPE)<>-32767)
...
...
wend
Maybe access Opengl's lines,polygons and gourad triangles?
I'm afraid that this is not possible for now...
-
Works like a charm :)
-
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
-
@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.
-
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
-
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.
-
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
-
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
#include "gl/gl.bi"Then, before ptc_update() do this
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
-
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.....
-
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:
-
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?
-
sounds good shockwave!
me personally i dont mind where ever the speed is im there :)
-
I think that 2 versions are needed. ......
Yeah, I agree with Shockwave :)
-
Couldnt you do something similar to how you'd make FB use windowed mode. And have something for example: DEFINE LIBRARY_MODE1
-
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.
-
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 ;)
-
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.
-
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 :)
-
Mmmm. Both have their merits :) Thanks Rbraz.
-
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:
-
No problem, have some Karma for it anyway :)
-
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 :( )
-
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
#include "gl/gl.bi"Then, before ptc_update() do this
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...
-
->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
-
@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.
-
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
-
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.
-
Possibly something like:
int* buffer = (int*)malloc(RES_X*RES_Y*sizeof(int));
memset(buffer, 0, RES_X*RES_Y*sizeof(int));
ptc_update(buffer);
-
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
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
unsigned int *buffer = new unsigned int [RES_X*RES_Y];
Jim
-
Thanks Jim, that works great :)
-
Great to hear! Are you making a demo?
Jim
-
I don't know what I'm making actually :P I'm just trying out the library. Perhaps it will become a demo :)
-
I tried to write a function that converts RGB to a single value, but with no luck:
// 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.
-
It should be easy enough to define something to convert 3 values to rgb.
Use this sort of maths to do it;
PIXEL=(((RED SHL 8)+GREEN) SHL 8)+BLUE
-
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.
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):
return (alpha<<24)|(red<<16)|(green<<8)|blue;
-
I solved it :) This is how it's done:
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
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.
-
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.
-
You're right :) It can be shortened to:
return 0xFF+(((red<<8)+green)<<8)+blue;
-
IF you want to set the alpha bits, it should be
0xff000000
-
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
delete [] buffer;
Jim
-
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 ;
-
The last line should just be
delete myentity;
It's not an array so you don't need the []
Jim
-
ah cool so it can be used in exactly the same way as malloc and free cheers!
-
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!
-
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.
-
@Stormbringer:
Thanks for pointing that out!
-
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...
-
How is this going?
-
Status = Closed.
:) We stopped working on it after having incompatibilities (slow down) on some PC config, and then tinyptc_ext born.
-
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.