Recent

Author Topic: [Solved]Can't render textures and display lists don't work for me.  (Read 1939 times)

Commando950

  • Newbie
  • Posts: 4
Relevant Details(Maybe)
OS: Windows 7 64 bit.
Graphics Card: NVidia GT 610

Hey there guys! As you can no doubt probably tell I'm new here. I think I put this in the right place as its related to OpenGL.

I'm relatively out of the loop when it comes to using Lazarus and even more so with OpenGL. So forgive me if I do something really dumb. While http://wiki.freepascal.org/OpenGL_Tutorial does cover much of the information I seem to need to know it does leave some stuff out for someone of my skill level and familiarity.

There are two problems I am having working with OpenGL currently and would like somebody who knows what they are doing to explain to me what stupid stuff I'm doing wrong.

Note: Please forgive the awful spacing and such as when I set custom settings in Lazarus for tabbing and such it gives really really weird results when I paste it places.

Problem A: Textures simply don't work. I added pl_vampyreimaging to the project inspector but then its missing the ImagingOpenGL file so I either added it in manually or added it in through project inspector.(I feel this is a mistake somehow but I have no other idea of how to actually use/install it)

Overall it seemed to work with no errors but no textures appear and instead I get a white square in the middle of the screen. I intended the square to be in the middle of the screen taking up only a little bit of space but at the same time I did not intend for it to be blank.

The code for it is here...

Code: Pascal  [Select]
  1. unit PGLSampleCode;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.         Classes, SysUtils, FileUtil, OpenGLContext, gl, Forms, Controls, Graphics,
  9.         Dialogs, ExtCtrls, ImagingOpenGL;
  10.  
  11. type
  12.          { TForm1 }
  13.         TForm1 = class(TForm)
  14.                 procedure FormCreate(Sender: TObject);
  15.           procedure GLPaint(Sender: TObject);
  16.         private
  17.  
  18.         public
  19.           GLBox: TOpenGLControl;
  20.         end;
  21.  
  22. var
  23.         Form1: TForm1;
  24.         MyImage: GLuint;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. { TForm1 }
  31.  
  32. procedure TForm1.FormCreate(Sender: TObject);
  33. begin
  34.         GLBox := TOpenGLControl.Create(Form1);
  35.         GLBox.AutoResizeViewport := true;
  36.         GLBox.Parent             := Form1;
  37.         GLBox.MultiSampling      := 4;
  38.         GLBox.Align              := alClient;
  39.         GLBox.OnPaint            := @Form1.GLPaint;
  40.         GLBox.invalidate;
  41.      MyImage := LoadGLTextureFromFile('test2.bmp');
  42.      glEnable(GL_TEXTURE_2D);
  43. end;
  44.  
  45. procedure TForm1.GLPaint(Sender: TObject);
  46. begin
  47.      glClearColor(0,0.2,1, 1);
  48.      glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  49.      glLoadIdentity;
  50.      glBindTexture(GL_TEXTURE_2D, MyImage);
  51.      glBegin(GL_QUADS);
  52.      glTexCoord2f(1, 0);
  53.      glVertex3f( 0.5, 0.5, 0);
  54.      glTexCoord2f(0, 0);
  55.      glVertex3f(-0.5, 0.5, 0);
  56.      glTexCoord2f(0, 1);
  57.      glVertex3f(-0.5,-0.5, 0);
  58.      glTexCoord2f(1, 1);
  59.      glVertex3f( 0.5,-0.5, 0);
  60.         glEnd;
  61.      GLBox.SwapBuffers;
  62. end;
  63.  
  64. end.
  65.  

Problem B: Display lists never work for me.. like ever...

I'm sure its something to do with the way I'm reading it or maybe something else, however, I also read that they are deprecated. Thats quite awkward for me as I know no other way to write it using said freepascal wiki guide. Yet I tried a sample OpenGL program and I'm pretty sure it had them and worked perfectly fine.

It makes me think I'm just doing something wrong. In which case its probably an easy fix.

The code for this one is here...

Code: Pascal  [Select]
  1. unit PGLSampleCode;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.         Classes, SysUtils, FileUtil, OpenGLContext, gl, Forms, Controls, Graphics,
  9.         Dialogs, ExtCtrls, ImagingOpenGL;
  10.  
  11. type
  12.          { TForm1 }
  13.         TForm1 = class(TForm)
  14.                 procedure FormCreate(Sender: TObject);
  15.           procedure GLPaint(Sender: TObject);
  16.         private
  17.  
  18.         public
  19.           GLBox: TOpenGLControl;
  20.         end;
  21.  
  22. var
  23.         Form1: TForm1;
  24.         MyImage: GLuint;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. { TForm1 }
  31.  
  32. procedure TForm1.FormCreate(Sender: TObject);
  33. begin
  34.         GLBox := TOpenGLControl.Create(Form1);
  35.         GLBox.AutoResizeViewport := true;
  36.         GLBox.Parent             := Form1;
  37.         GLBox.MultiSampling      := 4;
  38.         GLBox.Align              := alClient;
  39.         GLBox.OnPaint            := @Form1.GLPaint;
  40.         GLBox.invalidate;
  41.      MyImage := LoadGLTextureFromFile('test2.bmp');
  42.      glEnable(GL_TEXTURE_2D);
  43.         glNewList(1,GL_Compile);
  44.      glBegin(GL_QUADS);
  45.      glTexCoord2f(1, 0);
  46.      glVertex3f( 0.5, 0.5, 0);
  47.      glTexCoord2f(0, 0);
  48.      glVertex3f(-0.5, 0.5, 0);
  49.      glTexCoord2f(0, 1);
  50.      glVertex3f(-0.5,-0.5, 0);
  51.      glTexCoord2f(1, 1);
  52.      glVertex3f( 0.5,-0.5, 0);
  53.         glEnd;
  54.      glEndList;
  55. end;
  56.  
  57. procedure TForm1.GLPaint(Sender: TObject);
  58. begin
  59.      glClearColor(0,0.2,1, 1);
  60.      glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  61.      glLoadIdentity;
  62.      glBindTexture(GL_TEXTURE_2D, MyImage);
  63.      glCallList(1);
  64.      GLBox.SwapBuffers;
  65. end;
  66.  
  67. end.
  68.  

I'd appreciate any help I could get and appreciate your time even reading this. If you need any further details let me know and I'll get back to you as fast as I can, probably tomorrow, as my timezone is USA Eastern Standard Time.
« Last Edit: December 03, 2018, 05:23:29 am by Commando950 »

ChrisR

  • Jr. Member
  • **
  • Posts: 84
Re: [Noob Problems]Can't render textures and display lists don't work for me.
« Reply #1 on: December 03, 2018, 12:52:24 am »
The learning curve for OpenGL is steep. I would suggest using OpenGL 3.3 Core or later - this shader based version will make it easier to support cross-platform endeavors and also make it earier to move to OpenGL-ES, Vulkan, DirectX or Metal if you ever want to. Unlike older versions of OpenGL, in laterversions (e.g. 3.3), the texture are copied once to the GPU and stay their until you quit or delete them. This retained mode requires much less bandwidth than immediate mode, where the textures are transferred for every frame. These demos should help, but you probably will also benefit by getting a good book on OpenGL.
 

Commando950

  • Newbie
  • Posts: 4
Re: [Noob Problems]Can't render textures and display lists don't work for me.
« Reply #2 on: December 03, 2018, 01:24:22 am »
The learning curve for OpenGL is steep. I would suggest using OpenGL 3.3 Core or later - this shader based version will make it easier to support cross-platform endeavors and also make it earier to move to OpenGL-ES, Vulkan, DirectX or Metal if you ever want to. Unlike older versions of OpenGL, in laterversions (e.g. 3.3), the texture are copied once to the GPU and stay their until you quit or delete them. This retained mode requires much less bandwidth than immediate mode, where the textures are transferred for every frame. These demos should help, but you probably will also benefit by getting a good book on OpenGL.
 

Thanks for the reply! I might end up doing just that because I can tell everything seems outdated. You have me curious though, is everything on the wiki tutorial simply outdated?

Would this code ever had worked, or even now?

I think the only thing I would need to do is fix how I load those textures. I see some of the examples you sent actually just taking the image and not using that image library.

I'll look into those examples but I'm really curious for future reference why my current implementation fails.

Thanks!

Commando950

  • Newbie
  • Posts: 4
Re: [Noob Problems]Can't render textures and display lists don't work for me.
« Reply #3 on: December 03, 2018, 05:22:25 am »
Well I hate myself and everything else a little more. I finally got a working image on screen with OpenGL through digging around through those examples and random places.

Thanks ChrisR for the helpful link!

While there is much more for me to do I think this might prove useful for anyone else to see what I did.

Some things worth mentioning are...
  • I have no clue what is actually needed or unneeded.
  • It works for me somehow.
  • Its still dumb you could totally rewrite this better.
  • You really don't even need a GLStart procedure I just added it because I could...

Code: Pascal  [Select]
  1. unit YourUnitName;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.         Classes, SysUtils, FileUtil, Forms, Controls, Graphics,
  9.         Dialogs, ExtCtrls,
  10.         dglOpenGL, gl, OpenGLContext;
  11.  
  12. type
  13.          { TForm1 }
  14.         TForm1 = class(TForm)
  15.         procedure FormCreate(Sender: TObject);
  16.         procedure GLStart();
  17.         procedure GLPaint(Sender: TObject);
  18.         private
  19.  
  20.         public
  21.               GLBox: TOpenGlControl;
  22.         end;
  23.  
  24. var
  25.         Form1: TForm1;
  26.         Texture: GLuint;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33. procedure TForm1.FormCreate(Sender: TObject);
  34. begin
  35.      GLBox := TOpenGLControl.Create(Form1);
  36.      GLBox.AutoResizeViewport := true;
  37.      GLBox.Parent             := Form1;
  38.      GLBox.MultiSampling      := 4;
  39.      GLBox.OpenGLMajorVersion := 3;
  40.      GLBox.OpenGLMinorVersion := 3;
  41.      GLBox.Align              := alClient;
  42.      GLBox.OnPaint            := @Form1.GLPaint;
  43.      GLBox.MakeCurrent();
  44.      GLStart;
  45. end;
  46.  
  47. procedure TForm1.GLStart();
  48. var
  49.    SomeBitmap: TBitmap;
  50. begin
  51.      SomeBitmap := TBitmap.Create;
  52.      SomeBitmap.LoadFromFile('test.bmp');
  53.      glEnable(GL_TEXTURE_2D);
  54.      glGenTextures(1, @Texture);
  55.      glBindTexture(GL_TEXTURE_2D, Texture);
  56.      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_BGR, GL_UNSIGNED_BYTE, SomeBitmap.RawImage.Data);
  57.      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  58.      glBindTexture(GL_TEXTURE_2D, 0);
  59. end;
  60.  
  61. procedure TForm1.GLPaint(Sender: TObject);
  62. begin
  63.      glClearColor(0,0.2,1, 1);
  64.      glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  65.      glEnable(GL_TEXTURE_2D);
  66.      glBindTexture(GL_TEXTURE_2D, Texture);
  67.      glBegin(GL_QUADS);
  68.      glTexCoord2f(0.0, 1.0); glVertex2f(-0.5, -0.5);
  69.      glTexCoord2f(1.0, 1.0); glVertex2f(0.5, -0.5);
  70.      glTexCoord2f(1.0, 0.0); glVertex2f(0.5, 0.5);
  71.      glTexCoord2f(0.0, 0.0); glVertex2f(-0.5, 0.5);
  72.      glEnd;
  73.      GLBox.SwapBuffers;
  74. end;
  75.  
  76. end.
  77.  

I suppose I'll mark it solved for now(If I figure out how to do that real quick) but there might need to be some clarifications by other people on this such as my code.


ChrisR

  • Jr. Member
  • **
  • Posts: 84
Re: [Solved]Can't render textures and display lists don't work for me.
« Reply #4 on: December 03, 2018, 01:43:26 pm »
Nice job. Just a couple comments:
  • You are using legacy OpenGL calls (GL_QUADS, glBegin, no shaders), therefore I would suggest you set your project to use OpenGL 2.1. On Linux and Windows, OpenGL works in compatibility mode, so you can mix-and-match legacy calls with modern functions. In contrast, On MacOS you can either run legacy up to OpenGL 2.1, or you can run a more recent version of OpenGL that uses the Core specification. The Core specification drops support for all legacy functions. Therefore, for cross-platform compatiibility (as well as supporting older OpenGL hardware on Windows and Linux) it makes sense to target OpenGL 2.1 if you use any legacy calls.
  • Your project does not need dglOpenGL, so I would not include it. You should only include ONE of these three libraries: dglOpenGL, gl/glext, glcorearb. Personally, I would include the gl/glext units if you are targeting OpenGL 2.1. On the other hand, I would use the glcorearb if you want to target modern OpenGL Core. The nice thing about using glcorearb is that it removes the non-core functions, so it is easier to develop code on Windows and Linux that will run on MacOS. If you use use either dglOpenGL or gl/glext for modern OpenGL projects you can create projects that work on Windows and Linux but fail on MacOS as they use calls not in the core specification.
  • Note native openGL color order differs for MacOS versus Windows/Linux. That explains the glTexImage2D conditional.

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, OpenGLContext, gl;
  9.  
  10. type
  11.   TForm1 = class(TForm)
  12.     procedure FormShow(Sender: TObject);
  13.     procedure GLPaint(Sender: TObject);
  14.   private
  15.  
  16.   public
  17.         GLBox: TOpenGlControl;
  18.   end;
  19.  
  20. var
  21.   Form1: TForm1;
  22.   Texture: GLuint;
  23.  
  24. implementation
  25. {$R *.lfm}
  26.  
  27. procedure TForm1.GLPaint(Sender: TObject);
  28. begin
  29.      glClearColor(0,0.2,1, 1);
  30.      glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  31.      glEnable(GL_TEXTURE_2D);
  32.      glBindTexture(GL_TEXTURE_2D, Texture);
  33.      glBegin(GL_QUADS);
  34.        glTexCoord2f(0.0, 1.0); glVertex2f(-0.5, -0.5);
  35.        glTexCoord2f(1.0, 1.0); glVertex2f(0.5, -0.5);
  36.        glTexCoord2f(1.0, 0.0); glVertex2f(0.5, 0.5);
  37.        glTexCoord2f(0.0, 0.0); glVertex2f(-0.5, 0.5);
  38.      glEnd;
  39.      GLBox.SwapBuffers;
  40. end;
  41.  
  42. procedure TForm1.FormShow(Sender: TObject);
  43. var
  44.   fnm: string;
  45.   SomeBitmap: TBitmap;
  46. begin
  47.   //Create context
  48.   GLBox := TOpenGLControl.Create(Form1);
  49.   GLBox.AutoResizeViewport := true;
  50.   GLBox.Parent             := Form1;
  51.   GLBox.MultiSampling      := 4;
  52.   GLBox.OpenGLMajorVersion := 2;
  53.   GLBox.OpenGLMinorVersion := 1;
  54.   GLBox.Align              := alClient;
  55.   GLBox.OnPaint            := @Form1.GLPaint;
  56.   GLBox.MakeCurrent();
  57.   //Load Bitmap
  58.   fnm := ExtractFilePath(ParamStr(0))+ 'test.bmp';
  59.   if not FileExists(fnm) then begin
  60.      showmessage('Unable to find "'+fnm+'"');
  61.      exit;
  62.   end;
  63.   SomeBitmap := TBitmap.Create;
  64.   SomeBitmap.LoadFromFile(fnm);
  65.   glEnable(GL_TEXTURE_2D);
  66.   glGenTextures(1, @Texture);
  67.   glBindTexture(GL_TEXTURE_2D, Texture);
  68.   {$IFDEF Darwin}
  69.   //MacOS native format is GL_BGRA = $80E1
  70.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SomeBitmap.Width, SomeBitmap.Height, 0, $80E1, GL_UNSIGNED_BYTE, SomeBitmap.RawImage.Data);
  71.   {$ELSE}
  72.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SomeBitmap.Width, SomeBitmap.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, SomeBitmap.RawImage.Data);
  73.   {$ENDIF}
  74.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  75.   glBindTexture(GL_TEXTURE_2D, 0);
  76. end;
  77.  
  78. end.  
  79.