DGL
https://delphigl.com/forum/

Filling a texture passed to GLSL
https://delphigl.com/forum/viewtopic.php?f=19&t=11040
Seite 1 von 1

Autor:  GL123 [ Di Dez 10, 2013 00:07 ]
Betreff des Beitrags:  Filling a texture passed to GLSL

I am trying to fill a texture before passing it to GLSL.

Normally the backbuffer texture is blank initialised to nil like

Code:
  1.      glGenTextures(1,@backbuffer);
  2.      glBindTexture(GL_TEXTURE_2D,backbuffer);
  3.      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  4.      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  5.      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imwidth, imheight, 0, GL_RGBA,GL_UNSIGNED_BYTE,nil);


But for a certain shader I want to be able to fill backbuffer.

I define an array of unsigned byte type

Code:
  1.     background:array of array of TGLVectorub4;
  2.     backgroundcolor:TGLVectorub4;


And then change the texture code to fill it

Code:
  1.           glGenTextures(1,@backbuffer);
  2.           glBindTexture(GL_TEXTURE_2D,backbuffer);
  3.           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  4.           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);          
  5.           setlength(background,imwidth,imheight);
  6.           for yloop:=0 to imheight-1 do
  7.           begin
  8.                for xloop:=0 to imwidth-1 do
  9.                begin
  10.                     backgroundcolor[0]:=255;
  11.                     backgroundcolor[1]:=1;
  12.                     backgroundcolor[2]:=1;
  13.                     backgroundcolor[3]:=1;
  14.                     background[xloop,yloop]:=backgroundcolor;
  15.                end;
  16.           end;
  17.           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imwidth, imheight, 0, GL_RGBA,GL_UNSIGNED_BYTE,background);
  18.           setlength(background,0,0); 


But all I get is a blank/black backbuffer texture (the above should be red)? Any ideas on what I am doing wrong?

Thanks for any ideas.

Autor:  mori [ Di Dez 10, 2013 10:34 ]
Betreff des Beitrags:  Re: Filling a texture passed to GLSL

Hi,
the code seems ok to me, except for the glTexImage2D call. The last argument has to be an pointer, so I would try passing @background instead of the array itself. (Even if delphi passes an pointer without the @ and this does not solve the problem i would recommend you to use @... to make clear that you are trying to pass a pointer).

Autor:  Lord Horazont [ Di Dez 10, 2013 13:07 ]
Betreff des Beitrags:  Re: Filling a texture passed to GLSL

You cannot use `array of array of something' here.

An array of array of something is an array of pointers. Thus, it is not a contigous block of memory, which is what opengl needs. You have to use a 1D-array of. So you would define:
Code:
  1. var background: array of TGLVectorub4;
  2.    backgroundcolor: TGLVectorub4;
  3.    loop: Integer;
  4. begin
  5.   // glGenTextures et. al.
  6.   SetLength(background, imwidth*imheight);
  7.   backgroundcolor[0] := 255;
  8.   backgroundcolor[1] := 1;
  9.   backgroundcolor[2] := 1;
  10.   backgroundcolor[3] := 1;
  11.   for loop:=0 to imwidth*imheight-1 do
  12.   begin
  13.     background[loop] := backgroundcolor;
  14.   end;
  15.   // glTexImage2D
  16. end;


Adding an @ would be wrong, you would be passing a pointer to the pointer to the first element of the array of array of.

regards,
horazont

Autor:  mori [ Di Dez 10, 2013 14:19 ]
Betreff des Beitrags:  Re: Filling a texture passed to GLSL

Lord Horazont is right, of course. I haven't written code in Delphi for a while and I think I used @background[0] on one dimensional arrays, to easier adjust the starting index if it isn't 0.

Autor:  GL123 [ Di Dez 10, 2013 21:18 ]
Betreff des Beitrags:  Re: Filling a texture passed to GLSL

OK, changing the code to the 1 dimensional version gets it compiling/running

Code:
  1.           setlength(background,imwidth*imheight);
  2.           for loop:=0 to imheight*imwidth-1 do
  3.           begin
  4.                     backgroundcolor[0]:=255;
  5.                     backgroundcolor[1]:=0;
  6.                     backgroundcolor[2]:=0;
  7.                     backgroundcolor[3]:=0;
  8.                     background[loop]:=backgroundcolor;
  9.           end;
  10.           glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imwidth, imheight, 0, GL_RGBA,GL_UNSIGNED_BYTE,background);
  11.           setlength(background,0);


But, any change I make to the texture colors never shows up in the shader. Even the most simple shader code as follows always shows black.

Code:
  1. uniform vec2 resolution;
  2. uniform sampler2D backbuffer;
  3.  
  4. void main( void ) {
  5.     vec2 position = ( gl_FragCoord.xy / resolution.xy );
  6.     gl_FragColor = texture2D(backbuffer, position);
  7. }


I know the rest of the code works as I use this backbuffer texture when ping-ponging so it is created and later used correctly.

But those initial colors I set the texture to are ignored?

Autor:  GL123 [ Di Dez 10, 2013 21:26 ]
Betreff des Beitrags:  Re: Filling a texture passed to GLSL

OK, got it. Because I had 2 backbuffers, I had to assign the texture to the second backbuffer which was bound to the FBO last.

Code:
  1.      glGenFramebuffers(1,@fbo);
  2.      glBindFramebuffer(GL_FRAMEBUFFER,fbo);
  3.      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, backbuffer, 0);
  4.      glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,GL_TEXTURE_2D, backbuffer2, 0);


Then when refering to "backbuffer" in the shader it correctly references the passed texture data.

Thanks for the help guys. This was annoying me for days.

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/