PDA

View Full Version : FBOs and OpenGL Extensions



code_glitch
18-07-2012, 04:46 PM
Well, long time no see PGD! Looks like I found some trouble though and after a few days of googling in the dark nothing seems to have solved my problem(s) while implementing some FBO goodness in OpenGl.

Issue number 1:
On my desktop (ATI 5750 w/ fglrx and mint 11 64 bit) fpc spits out things that look like this:


FrameBuffer.pas(38,37) Error: Identifier not found "GL_FRAMEBUFFER"

which is unnafected by whether I do


glBindFramebufferEXT(GL_FRAMEBUFFER, 0);

or


glBindFramebuffer(GL_FRAMEBUFFER, 0);

which doest happen on my laptop (Intel GMA 4500MHD) which is weird. I tried downgrading FPC from 2.6.0 to 2.4.4 with an "apt-get --purge fpc fp-*" but no luck, apparently fpc denies all existence of GL_FrameBuffer O.o As to why, I have no clue since I put gl, glu and glext under the uses section...

Issue number 2:
Once I compield it on my laptop with the intel card there were no issues, until I ran it in GDB which is convinced that


glGenFrameBuffersEXT(1, @FrameBufferID);

as well as


glGenFrameBuffers(1, @FrameBufferID);

crashes the program and doesnt identify a cause other than:


[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Cannot find new threads: generic error


Anyone have any ideas as to what I should hit up next? I'm totally lost on this one.... ???
Thanks.

User137
19-07-2012, 12:11 AM
FrameBuffer.pas(38,37) Error: Identifier not found "GL_FRAMEBUFFER"
This is simple compiler error. You are using something that's not found in the namespace. Check that you have right OpenGL header unit in the uses list, and that GL_FRAMEBUFFER is defined there at interface section. Check that header version is same on both computers.

The above might solve your second problem, but if it doesn't, make sure that header has initialized those functions (glGenFrameBuffers...).
(Also you need to have a render context ready.)

paul_nicholls
19-07-2012, 02:09 AM
Issue number 2:
Once I compield it on my laptop with the intel card there were no issues, until I ran it in GDB which is convinced that


glGenFrameBuffersEXT(1, @FrameBufferID);

as well as


glGenFrameBuffers(1, @FrameBufferID);

crashes the program and doesnt identify a cause other than:


[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Cannot find new threads: generic error


Anyone have any ideas as to what I should hit up next? I'm totally lost on this one.... ???
Thanks.

I'm guessing that you have something like this in your main FP program code?



{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}

If not, this might help...

Just a thought :)

code_glitch
20-07-2012, 02:51 PM
Thanks for all the fast replies and sorry for this late one, I just got off the phone from BT whom now admit the line fault was their doing efter an hour of 'your extension wiring is faulty and is not done by BT...' when I've got the modem hooked into their test socket.... Anyway, I digress.

User137: Thats what baffled me: the opengl headers come from the same package and are thus identical on both machines - why they differ is beyond me O.o

Paul: Yes, the glGenFrameBuffers() is in the main program code and you're right in including cthreads as it is a common unit often ommited form some code that causes issues later. However, in this case its inclusion seems to have no effect and the behaviour GDB reported earlier continues to occur.

After now 5 days of tweaking this and searching high and low I've found that in C/C++ and other such languages, glGenFrameBuffers is a pointer and must be set to the actual procedure. Is this the case with the header files in fpc? And if so does anyone have any ideas where I might find some example code/documentation?

Thanks :)

User137
20-07-2012, 06:16 PM
I use dglOpenGL headers. Some say fpc headers are outdated. Additional bonus is that dglOpenGL works for Delphi and fpc.

WILL
21-07-2012, 06:00 AM
Speaking of "outdated," aren't FBOs supposed to be obsolete with the newest version of OpenGL? At least that's what I've been told not too long ago.

code_glitch
21-07-2012, 12:01 PM
I must admit to having heard something similar to you WILL though my issue with a lot of the new OpenGl stuff is that a lot of computers I use are knocking on 3 years of age and although all but one are intel GMA chips the standard of the new OpenGl implementations seems to vary greatly (*cough*ATI*cough*). Oh, and I still havent come accross much in the way of tutorials and native FPC support (I'm lazy when it comes to unit hunting ::)) :D

Of course if anyone has any pointers in these departments all suggestions are welcome :) Especially since I'm not getting any luck on this front...

User137
21-07-2012, 03:00 PM
Thats what baffled me: the opengl headers come from the same package and are thus identical on both machines - why they differ is beyond me O.o
Did you actually verify that they differ? It should propably be mentioned in the beginning of header. Do you have same FPC and Lazarus versions on both computers?

code_glitch
21-07-2012, 05:15 PM
Its the fact they DONT differ across platforms (their md5sums are the same - to be expected if you install from the same tarball ;) ) and yet throw up different errors which baffles me. I also happen to have no lazaruses and the fpc version is exactly the same - 2.6.0 - (probably due to them being installed from the same tarball ;) )

And to be on the same side I did do a


sudo du -ah / | grep -i /gl.ppu

Just to make sure there were any other gl.ppu headers anywhere ;) There werent...

My issue with OpenGl 3 is the the GMA4500MHD chips in one of my laptops is OpenGl 2.1 only which happens to be overly popular in england at the moment since we've now had about 3 years of intel fever where every ad break would have at least one advert from currys and pc world advertising the fact that a 'intel graphics' are better -_-

code_glitch
24-07-2012, 04:20 PM
Well I managed to sort out the weird FPC error... Seems when I upgraded from 2.4.whatever to 2.6.0 the installer didnt change the path for fpc to look for some PPU files and kept using the 2.4.4 files... Nothing a reinstall couldn't fix :)

On the other hand, although this now compiles fine, I still cant get it to run - the dglOpenGl headers seem to make no difference (aside from making things run a little faster ;) ). Next stop: porting a C/C++ demo and seeing if that runs. Fun -_-.

Edit/Update:
So I wondered if it was the way I was creating my OpenGl context since I do it from the ground up with XLib and GlX, so I headed over to the wiki pages for lazarus and fpc and found their demo program for GLUT which compiles and runs fine out of the box, thus I included the FBO code so it all looks like this:


program firstprogram;

{$mode objfpc}{$H+}

uses
gl, glu, glut,
glext;

const
AppWidth = 640;
AppHeight = 480;

procedure InitializeGL;
begin
glClearColor(0.18, 0.20, 0.66, 0);
end;

var
Tex1, FBO, Ren: GLUint;
Status: GLEnum;

procedure DrawGLScene; cdecl;
begin
glGenTextures(1, @Tex1);
glBindTexture(GL_TEXTURE_2D, Tex1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
writeln('Tex OK');
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, Nil);

write('Gen FBO... ');
glGenFramebuffersEXT(1, @FBO);
write(' OK! ');
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
writeln('FBO Bound OK!');

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, Tex1, 0);

glGenRenderbuffersEXT(1, @Ren);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, Ren);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 256, 256);

glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, Ren);

status := glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glutSwapBuffers;
end;

procedure ReSizeGLScene(Width, Height: Integer); cdecl;
begin
if Height = 0 then
Height := 1;

glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, Width / Height, 0.1, 1000);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;

procedure GLKeyboard(Key: Byte; X, Y: Longint); cdecl;
begin
if Key = 27 then
Halt(0);
end;

procedure glutInitPascal(ParseCmdLine: Boolean);
var
Cmd: array of PChar;
CmdCount, I: Integer;
begin
if ParseCmdLine then
CmdCount := ParamCount + 1
else
CmdCount := 1;
SetLength(Cmd, CmdCount);
for I := 0 to CmdCount - 1 do
Cmd[I] := PChar(ParamStr(I));
glutInit(@CmdCount, @Cmd);
end;

var
ScreenWidth, ScreenHeight: Integer;
begin
glutInitPascal(True);
glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);
glutInitWindowSize(AppWidth, AppHeight);
ScreenWidth := glutGet(GLUT_SCREEN_WIDTH);
ScreenHeight := glutGet(GLUT_SCREEN_HEIGHT);
glutInitWindowPosition((ScreenWidth - AppWidth) div 2, (ScreenHeight - AppHeight) div 2);
glutCreateWindow('OpenGL Tutorial :: First Program');

InitializeGL;

glutDisplayFunc(@DrawGLScene);
glutReshapeFunc(@ReSizeGLScene);
glutKeyboardFunc(@GLKeyboard);

glutMainLoop;
end.


And I know this would only work on the first loop but it crashes before then - on glGenFrameBuffersEXT() again which means I must clearly be missing something when I initialize OpenGl or doing something so idiotic I'm overlooking it each time...

LP
24-07-2012, 08:07 PM
And I know this would only work on the first loop but it crashes before then - on glGenFrameBuffersEXT() again which means I must clearly be missing something when I initialize OpenGl or doing something so idiotic I'm overlooking it each time...
This extension might not be supported by your driver or not loaded properly in the headers. Make sure to call ReadExtensions or something similar.

P.S. FBOs are not deprecated; in fact, they are adopted into core. See here (http://www.opengl.org/wiki/Framebuffer_Object).

code_glitch
24-07-2012, 08:29 PM
I'm pretty sure that FBOs and most extensions are supported by my driver (latest catalyst 12.6 for my 5750), or at least that's the case for my desktop. Just to check I also hunted down an FBO demo to run which itself runs fine. That should narrow it down to something going pear shaped on the pascal side right?

Also, out of curiosity, if an extension is adopted into core in say, OpenGl 3; would that automatically mean all cards that support OpenGl 3 support these extensions unlike OpenGl 2 where its vendor specific?

Thanks :)

phibermon
25-07-2012, 12:09 PM
Also, out of curiosity, if an extension is adopted into core in say, OpenGl 3; would that automatically mean all cards that support OpenGl 3 support these extensions unlike OpenGl 2 where its vendor specific?

Well I can't confidently claim that any OpenGL card/driver set that supports OpenGL 3.0 will *always* support equivalent extensions when working on GL2.

ARB – Extensions officially approved by the OpenGL Architecture Review Board
EXT – Extensions agreed upon by multiple OpenGL vendors

in a GL2 style framework, it's always advisable to check the GL extensions string stuff first to see if it's available.

(-tip for anybody studying this topic-
If you've got the time to write alternative fallback rendering code, one way to manage it could be :
Create a list of record structures that hold callbacks to render functions, a prefered priority, a list of required extensions.
Then when the engine/framework starts up, you simply go thru the list in priority order and attach that given render callback function (or set a var etc) somewhere for the first technique that matches the extension requirments. This is a good way to handle card/driver specific quirks and different GL versions as well)

code_glitch
25-07-2012, 02:09 PM
Well I checked the compatibility of all my cards and its all fine there, I also tested some demos and they have no issues which means its only my code thats crashing. Are there any specific calls I should be making to initialize OpenGl extensions before calling them which could cause this? All the errors occur at $0000000000000000 which should narrow the cause to a null pointer somewhere which after doing some reading about glew in C/C++ seems to be normal as apparently glGenFrameBuffersEXT is a pointer itself and must be set O.o. Or at least thats my understanding of the C/C++ side of things. If this is correct, how would one get the correct pointer to the function and assign it?

LP
25-07-2012, 07:16 PM
Before initializing OpenGL you need to create its window context first. During this context creation it is typical to request specific Core functionality; if you don't, GL2 and lower is used by default. Note that some features may not be enabled until you request 3.0 core functionality explicitly, which may also disable some older deprecated functionality.

Therefore, unless you are explicitly using Core 3 functionality, you *should* check for extension support before use.

Although it may not be your case, on some video cards (mostly by Intel) there are bugs in OpenGL implementation that may lead to crashes. For instance, on Intel X3100 and latest drivers, creating and releasing textures frequently causes AV.

By the way, if you are using DGL headers, where do you call InitOpenGL(), ReadExtensions() and ReadImplementationProperties()?

code_glitch
25-07-2012, 08:39 PM
Hmm.... OpenGl 2 and lower is the default? Sounds like there lies my issue. At the moment, I'm not using the dglOpenGl headers because I didn't find any noticeable difference when I played with them earlier on. The graphics cards I'm using are an ATI 5750 with the latest amd ccc drivers, the generic intel drivers shipped with linux for the GMA4500MHD from intel and an nvidia 8200M with the latest nvidia drivers for linux and at the moment all exhibit the same behaviour.

Which calls should I make to request OpenGl 3 and such functionality?

User137
26-07-2012, 12:26 AM
By the way, if you are using DGL headers, where do you call InitOpenGL(), ReadExtensions() and ReadImplementationProperties()?
- (Optional, create window here. You can use ready TForm, or with Lazarus you should use TOpenGLContext.)
- InitOpenGL()
- Create window (if wasn't already)
- Initialize rendering context (don't need to do much with TOpenGLContext, at least MakeCurrent())
- ReadExtensions()
- ReadImplementationProperties()
- Now you can initialize the projection matrix, load textures etc.

LP
26-07-2012, 04:59 PM
- (Optional, create window here. You can use ready TForm, or with Lazarus you should use TOpenGLContext.)
- InitOpenGL()
- Create window (if wasn't already)
- Initialize rendering context (don't need to do much with TOpenGLContext, at least MakeCurrent())
- ReadExtensions()
- ReadImplementationProperties()
- Now you can initialize the projection matrix, load textures etc.
My question was addressed to code_glitch (so I don't understand why are you quoting me?) as the issue may be in context creation and/or when reading extensions, but the order of the calls that you described should work.

User137
28-07-2012, 08:34 AM
Misread topic flow when skimmed quickly. Your message body seems actually guiding, not asking how it's done sort...

paul_nicholls
29-07-2012, 12:57 AM
At the moment, I'm not using the dglOpenGl headers because I didn't find any noticeable difference when I played with them earlier on.

Even if you didn't notice any difference with the dglOpenGL headers, the best thing is that they work on Windows, Linux, and OSX :)

Ingemar
05-08-2012, 06:53 AM
Speaking of "outdated," aren't FBOs supposed to be obsolete with the newest version of OpenGL? At least that's what I've been told not too long ago.

Why on earth would FBOs be outdated? I mean, replaced by what? I know that so much OpenGL is gone in 3.2 and up, but not FBOs.

And as mentioned in other parts of the thread, FBOs are not deprecated but core functionality, at least last time I looked.

LP
05-08-2012, 05:49 PM
As I've mentioned earlier in my post, FBOs are in no way outdated nor deprecated. They were adopted into Core and therefore are considered standard and official.

Perhaps Jason meant to say that pixel transfer and operations are deprecated? While working with OpenGL it is common to accidentally keep using deprecated functionality since in all its mess it is difficult to know what's still current and what's outdated. One way to stay out of trouble is to explicitly request Core 3 functionality, therefore disabling deprecated stuff and forcing you to use only the current features.

The bad news is that Intel IGPs are so popular these days yet they are quite troublesome with OpenGL: while Intel HD 3000 (and HD 4000) supposedly support OpenGL 3, they are quite problematic even with OpenGL 2.1; on the other hand, Intel Atom's IGPs such as GMA 950 and 3150 can barely run OpenGL 1.5 apps with sluggish performance. Therefore, to maintain compatibility, an engine will most likely need to be an hybrid of all OpenGL incarnations.

code_glitch
18-08-2012, 12:50 PM
Well, I dont want to revive an old thread so late on but I did indeed find a solution in the end while on holiday and flicking through some PDFs and now I have internet I figured I'd post up just how 'idiotic' I had been...



glext_LoadExtension('GL_EXT_framebuffer_object');


Yes people... That line helps. A lot... :D

User137
18-08-2012, 04:48 PM
glext_LoadExtension('GL_EXT_framebuffer_object');

In dglOpenGL this is automatically included in the call to ReadExtensions; :)