OpenGL/GLSL: render to texture

Just starting out? Need help? Post your questions and find answers here.
Mr.L
Enthusiast
Enthusiast
Posts: 107
Joined: Sun Oct 09, 2011 7:39 am

OpenGL/GLSL: render to texture

Post by Mr.L »

Hi there,
can somebody provide a sample how to render to a simple 2D texture using GLSL and display the texture afterwards?
I just can't seem to make it work and have spend several hours without success.

This is how i create the framebuffer

Code: Select all

Procedure Init_FrameBuffer(index)
    glCreateFramebuffers(1, @Setup\frameBuffer(index))
    glCreateTextures(#GL_TEXTURE_2D, 1, @Setup\texture(index))

    glBindFramebuffer(#GL_FRAMEBUFFER, Setup\frameBuffer(index))
    glBindTexture_(#GL_TEXTURE_2D, Setup\texture(index))
    glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGB, Setup\ShaderWidth, Setup\ShaderHeight, 0, #GL_RGB, #GL_UNSIGNED_BYTE, 0)
    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)
    glFramebufferTexture(#GL_FRAMEBUFFER, #GL_COLOR_ATTACHMENT0, Setup\texture(index), 0)
	
    Protected drawBuffer.l = #GL_COLOR_ATTACHMENT0
    glDrawBuffers(1, @drawBuffer)
	
    If glCheckFramebufferStatus(#GL_FRAMEBUFFER) <> #GL_FRAMEBUFFER_COMPLETE
        MessageRequester("Error", "Frambuffer Nr. " + Str(index) + " not complete")
        End
    EndIf
EndProcedure
here I try to render to the framebuffer and display the result using two seperate shaders

Code: Select all

Procedure Render()
    With Setup
        Protected *program.Program 

        *program = Setup\Program("prg_1")
        glUseProgram(*program\ID)
        glUniform1i(*program\uniform("texture0"), \texture(0))
        glUniform1i(*program\uniform("frameNr"), \frameNr)

        glBindFramebuffer(#GL_FRAMEBUFFER, Setup\frameBuffer(0))
        glBegin_(#GL_QUADS)
        glTexCoord2f_(0,0)
        glTexCoord2f_(1,0)
        glTexCoord2f_(1,1)
        glTexCoord2f_(0,1)
        glVertex2f_(-1, -1)
        glVertex2f_( 1, -1)
        glVertex2f_( 1, 1)
        glVertex2f_(-1, 1)
        glEnd_()
		
        *program = Setup\Program("prg_2")
        glUseProgram(*program\ID)
        glUniform1i(*program\uniform("texture0"), \texture(0))

        glBindFramebuffer(#GL_FRAMEBUFFER, 0)
        glBegin_(#GL_QUADS)
        glTexCoord2f_(0,0)
        glTexCoord2f_(1,0)
        glTexCoord2f_(1,1)
        glTexCoord2f_(0,1)
        glVertex2f_(-1, -1)
        glVertex2f_( 1, -1)
        glVertex2f_( 1, 1)
        glVertex2f_(-1, 1)
        glEnd_()

        \frameNr + 1
    EndWith

    SetGadgetAttribute(#Gad_OpenGL, #PB_OpenGL_FlipBuffers, 1)
EndProcedure
and finally the fragment and vertex shaders for program 1 and 2...

Program 1
VertexShader

Code: Select all

#version 330
layout(location = 0) in vec4 in_position;
out vec2 UV;
void main(){
    gl_Position  = in_position;
    UV = (in_position.xy + vec2(1,1))/2;
}
FragmentShader

Code: Select all

#version 330
uniform sampler2D texture0;
uniform int frameNr;
layout(location = 0) out vec3 out_color;
in vec2 fragCoord;

int Cell(in ivec2 p){
    ivec2 r = ivec2(textureSize(texture0, 0));
    p = (p + r) % r;
    return (texelFetch(texture0, p, 0).r > 0.5 ) ? 1 : 0;
}

float hash1(float n){return fract(sin(n)*138.5453123);}

void main(){
    ivec2 px = ivec2(gl_FragCoord.xy);
    int k =  Cell(px+ivec2(-1,-1)) + Cell(px+ivec2(0,-1)) + Cell(px+ivec2(1,-1))
           + Cell(px+ivec2(-1, 0))                        + Cell(px+ivec2(1, 0))
           + Cell(px+ivec2(-1, 1)) + Cell(px+ivec2(0, 1)) + Cell(px+ivec2(1, 1));
    int e = Cell(px);
    float f = (((k == 2) && (e == 1)) || (k == 3) ) ? 1 : 0;
    if (frameNr ==  0)f = step(0.5, hash1(gl_FragCoord.x * 13.0 + hash1(gl_FragCoord.y * 71.1)));
    out_color = vec3(f, f, f);
}
Program 2
VertexShader

Code: Select all

#version 330
layout(location = 0) in vec4 in_position;
out vec2 UV;
void main(){
    gl_Position  = in_position;
    UV = (in_position.xy + vec2(1,1))/2;
}
FragmentShader

Code: Select all

#version 330
in vec2 UV;
out vec3 color;
uniform sampler2D texture0;
void main(){
    color = texture(texture0, UV).xyz;
}
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

Ooch... I am very far to help you, by debugging your examples.

I am just perplex with this:

Code: Select all

if (frameNr == 0)f = step(0.5, hash1(gl_FragCoord.x * 13.0 + hash1(gl_FragCoord.y * 71.1)));
No syntax problem? Suggest:

Code: Select all

if (frameNr == 0){f = step(0.5, hash1(gl_FragCoord.x * 13.0 + hash1(gl_FragCoord.y * 71.1)))};
Here:

Code: Select all

*program = Setup\Program("prg_1")
glUseProgram(*program\ID)
Here it misses something also.

Could you give the pb structures and interfaces initializing for the people who could help you? It misses just a whole code.
Last edited by Olli on Sun Feb 07, 2021 9:59 pm, edited 1 time in total.
DarkDragon
Addict
Addict
Posts: 2228
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: OpenGL/GLSL: render to texture

Post by DarkDragon »

To the previous answer: {} can be omitted, if the scope just vonsists of one expression.

To the topic owner:
glCreateTextures is new. OpenGL 4.5 is required. Did you try glGenTextures and initializing the texture with dome data? glTexImage2D, because that also specifies the data type on texture site. You also don't transform the vertices into screen space or similar, which is unusual. Does it work like that without render to texture?
bye,
Daniel
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

@Darkdragon

thank you for the syntax detail.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

I suppose a source code structure like this:

Code: Select all

a) PB initializing
b) VBA init
c) vectices shaders
d) fragment shaders
e) VBA rendering

Code: Select all

;Init VBA part

;Dim vertices.F(255)
;Dim indices.U(255)

; Original author : Giles Thomas? 2011 ==> comments can be googlized

; Create an empty buffer object to store vertex buffer
vertex_buffer = glCreateBuffer_()

; Bind appropriate array buffer to it
glBindBuffer_(#GL_ARRAY_BUFFER, vertex_buffer)


; Pass the vertex data to the buffer
glbufferData_(#GL_ARRAY_BUFFER,@vertices(), #GL_STATIC_DRAW)

; Unbind the buffer
glbindBuffer_(#GL_ARRAY_BUFFER, 0)

; Create an empty buffer object to store Index buffer
Index_Buffer = glCreateBuffer_()

; Bind appropriate array buffer to it
glbindBuffer_(#GL_ELEMENT_ARRAY_BUFFER,
Index_Buffer)

; Pass the vertex data to the buffer
glBufferData_(#GL_ELEMENT_ARRAY_BUFFER, @indices(), #GL_STATIC_DRAW)

; Unbind the buffer
glBindBuffer_(#GL_ELEMENT_ARRAY_BUFFER, 0)
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

Code: Select all

; vertex shader part

; Vertex shader source code
vertCode.S =
"attribute vec3 coordinates;" +
"void main(void) {" +
" gl_Position = vec4(coordinates, 1.0);" +
"}"
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

Code: Select all

; fragment shader source code

fragCode.S =
"void main(void) {" +
" gl_FragColor = vec4(1.0, 0.0, 0.0, 0.9);" +
"}"
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

Code: Select all

; salt

; Create a vertex shader object
vertShader = glCreateShader_(#GL_VERTEX_SHADER)

; Attach vertex shader source code
glShaderSource_(vertShader, @vertCode)

; Compile the vertex shader
glCompileShader_(vertShader)


; sugar

; Create fragment shader object
fragShader = glCreateShader_(#GL_FRAGMENT_SHADER)

; Attach fragment shader source code
glShaderSource_(fragShader,@fragCode)

; Compile the fragmentt shader
glCompileShader_(fragShader)




; salt and sugar

; Create a shader program object to store
; the combined shader program
shaderProgram = glCreateProgram_()

; Attach a vertex shader
glAttachShader_(shaderProgram, vertShader)

; Attach a fragment shader
glAttachShader_(shaderProgram, fragShader)

; Link both the programs
glLinkProgram_(shaderProgram)

; Use the combined shader program object
glUseProgram_(shaderProgram)



; cooking...

;======= Associating shaders to buffer objects =======
; Bind vertex buffer object
glBindBuffer_(#GL_ARRAY_BUFFER, vertex_buffer)

; Bind index buffer object
glBindBuffer_(#GL_ELEMENT_ARRAY_BUFFER,
Index_Buffer)

; Get the attribute location
coord = glGetAttribLocation_(shaderProgram,
@"coordinates")
; Point an attribute to the currently bound VBO
glVertexAttribPointer_(coord, 3, #GL_FLOAT, #False, 0, 0)

; Enable the attribute
glEnableVertexAttribArray_(coord)






Procedure Render()
; =========Drawing the triangle===========
; Clear the gadget
glClearColor_(0.5, 0.5, 0.6, 0.9)
; Enable the depth test
glEnable_(#GL_DEPTH_TEST)
; Clear the color buffer bit
glClear_(#GL_COLOR_BUFFER_BIT)
; Set the view port
glViewport_(0,0,GadgetWidth(ogl), GadgetHeight(ogl) )
; Draw the triangle
glDrawElements_(#GL_TRIANGLES, ArraySize(indices() ), #GL_UNSIGNED_SHORT, 0)
EndProcedure
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

Without computer, it is like run on a bike with no handlebars...

What does it miss... a window, 2 global arrays, 1 global variable (ogl), an ogl gadget and a main loop calling Render() procedure, and setting the ogl gadget attributes just to flip buffers...

But now, I am tired... apologize...
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

Normally, it does not miss anything. Just copy all these codes in the right order. I would have had all nested in several macros to simplify...

Code: Select all

Macro DemoCreate()

OpenWindow(123,0,0,640,480,"OpenGL: VBA & GLSL",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)

Global ogl
Global Dim vertices.F(255)
Global Dim indices.U(2) ; <-- the size causes the capture

vertices(0) = 0.0  ; 1st vertex (x0)
vertices(1) = 0.0 ; (y0)
vertices(2) = 0.0 ; (z0)
vertices(3) = 1.0 ; 2nd vertex (x1)
vertices(4) = 0.0 ; (y1)
vertices(5) = 0.0 ; (z1)
vertices(6) = 0.0 ; 3rd vertex (x2)
vertices(7) = 1.0 ; (y2)
vertices(8) = 0.0 ; (z2)

indices(0) = 0
indices(1) = 1
indices(2) = 2

ogl = OpenGLGadget(456,0,0,640,480)
SetGadgetAttribute(ogl, #PB_OpenGL_SetContext, #True) ; I suppose it's required
EndMacro





Macro DemoMain()

Repeat
 Ev = WindowEvent()
 Delay(3)
 Render()
 SetGadgetAttribute(ogl, #PB_OpenGL_FlipBuffers, #True)
Until Ev = #PB_Event_CloseWindow

EndMacro
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

I retrieve the root site which published freely these codes (ECMA) : https://www.tutorialspoint.com/.

And the page : https://www.tutorialspoint.com/webgl/we ... _guide.htm

:D
Mr.L
Enthusiast
Enthusiast
Posts: 107
Joined: Sun Oct 09, 2011 7:39 am

Re: OpenGL/GLSL: render to texture

Post by Mr.L »

Thanks Olli, for all the effort, so far and sorry for my late response :D

I'm still struggling with my problem...

here is my code (shrunken to the necessary parts)
all it should do is paint the texture in the color red and then copy the texture to the screen.

Code: Select all

EnableExplicit

#GL_UNIFORM_BUFFER = $8A11
#GL_FRAGMENT_SHADER = $8B30
#GL_VERTEX_SHADER = $8B31
#GL_COMPILE_STATUS = $8B81
#GL_INFO_LOG_LENGTH = $8B84
#GL_DRAW_FRAMEBUFFER = $8CA9
#GL_FRAMEBUFFER_COMPLETE = $8CD5
#GL_COLOR_ATTACHMENT0 = $8CE0
#GL_FRAMEBUFFER = $8D40
#GL_READ_FRAMEBUFFER = $8CA8

Enumeration
        #Window_Main
        #Gad_OpenGL
EndEnumeration

Prototype glCreateShader(type.l) : Global glCreateShader.glCreateShader
Prototype glCreateProgram() : Global glCreateProgram.glCreateProgram
Prototype glCompileShader(shader.l) : Global glCompileShader.glCompileShader
Prototype glLinkProgram(shader.l) : Global glLinkProgram.glLinkProgram
Prototype glUseProgram(shader.l) : Global glUseProgram.glUseProgram
Prototype glAttachShader(Program.l, shader.l) : Global glAttachShader.glAttachShader
Prototype glShaderSource(shader.l, numOfStrings.l, *strings, *lenOfStrings) : Global glShaderSource.glShaderSource
Prototype glGetUniformLocation(program.l, name.p-Ascii) : Global glGetUniformLocation.glGetUniformLocation
Prototype glUniform1i(location, v0) : Global glUniform1i.glUniform1i
Prototype glUniform2i(location, v0, v1) : Global glUniform2i.glUniform2i
Prototype glUniform1f(location, v0.f) : Global glUniform1f.glUniform1f
Prototype glUniform2f(location, v0.f, v1.f) : Global glUniform2f.glUniform2f
Prototype glGetShaderInfoLog(shader, bufSize.l, *length_l, *infoLog) : Global glGetShaderInfoLog.glGetShaderInfoLog
Prototype glGenTextures(nrTextures, *textures) : Global glGenTextures.glGenTextures
Prototype glGenFramebuffers(count, *names) : Global glGenFramebuffers.glGenFramebuffers
Prototype glBindFrameBuffer(target, frameBuffer) : Global glBindFramebuffer.glBindFramebuffer
Prototype glFramebufferTexture(target, attachment, texture, level) : Global glFramebufferTexture.glFramebufferTexture
Prototype glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) : Global glFramebufferRenderbuffer.glFramebufferRenderbuffer
Prototype glCheckFramebufferStatus(target) : Global glCheckFramebufferStatus.glCheckFramebufferStatus
Prototype glGetShaderiv(shader, pName, *params) : Global glGetShaderiv.glGetShaderiv
Prototype glDeleteShader(shader) : Global glDeleteShader.glDeleteShader
Prototype glDeleteProgram(program) : Global glDeleteProgram.glDeleteProgram
Prototype glDrawBuffers(size, *buffers) : Global glDrawBuffers.glDrawBuffers

Structure Program
        ID.l
        vertexShaderCode.s
        vertexShaderID.l
        
        fragmentShaderCode.s
        fragmentShaderID.l
        
        Map uniformLocation.l()
EndStructure

Structure Setup
        Array program.Program(1)
        
        Array texture.l(1)
        Array frameBuffer.l(1)
        
        ShaderWidth.f
        ShaderHeight.f
        
        time.l
        startTime.l
        frameNr.l
EndStructure

Global Setup.Setup

Procedure Init_Main(width, height)
        Setup\ShaderWidth = width
        Setup\ShaderHeight = height
        
        OpenWindow(#Window_Main, 0, 0, width + 10, height + 10, "OpenGL", #PB_Window_SystemMenu)
        OpenGLGadget(#Gad_OpenGL, 5, 5, width, height, #PB_OpenGL_Keyboard | #PB_OpenGL_NoDepthBuffer)
        
        glCreateShader = wglGetProcAddress_("glCreateShader")
        glCreateProgram = wglGetProcAddress_("glCreateProgram")
        glCompileShader = wglGetProcAddress_("glCompileShader")
        glLinkProgram = wglGetProcAddress_("glLinkProgram")
        glUseProgram = wglGetProcAddress_("glUseProgram")
        glAttachShader = wglGetProcAddress_("glAttachShader")
        glShaderSource = wglGetProcAddress_("glShaderSource")
        glGetUniformLocation = wglGetProcAddress_("glGetUniformLocation")
        glUniform1i = wglGetProcAddress_("glUniform1i")
        glUniform2i = wglGetProcAddress_("glUniform2i")
        glUniform1f = wglGetProcAddress_("glUniform1f")
        glUniform2f = wglGetProcAddress_("glUniform2f")
        glGetShaderInfoLog = wglGetProcAddress_("glGetShaderInfoLog")
        glGenTextures = wglGetProcAddress_("glGenTextures")
        glGenFramebuffers = wglGetProcAddress_("glGenFramebuffers")
        glBindFramebuffer = wglGetProcAddress_("glBindFramebuffer")
        glFramebufferTexture = wglGetProcAddress_("glFramebufferTexture")
        glFramebufferRenderbuffer = wglGetProcAddress_("glFramebufferRenderbuffer")
        glCheckFramebufferStatus = wglGetProcAddress_("glCheckFramebufferStatus")
        glGetShaderiv = wglGetProcAddress_("glGetShaderiv")
        glDeleteShader = wglGetProcAddress_("glDeleteShader")
        glDeleteProgram = wglGetProcAddress_("glDeleteProgram")
        glDrawBuffers = wglGetProcAddress_("glDrawBuffers")
EndProcedure

Procedure Init_FrameBuffer()
        glGenFramebuffers(2, @Setup\frameBuffer())
        glGenTextures(2, @Setup\texture())
        
        Protected i
        For i = 0 To 1
                glBindFramebuffer(#GL_FRAMEBUFFER, Setup\frameBuffer(i))
                glBindTexture_(#GL_TEXTURE_2D, Setup\texture(i))
                glTexImage2D_(#GL_TEXTURE_2D, 0, #GL_RGBA, Setup\ShaderWidth, Setup\ShaderHeight, 0, #GL_RGBA, #GL_UNSIGNED_BYTE, 0)
                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)
                glFramebufferTexture(#GL_FRAMEBUFFER, #GL_COLOR_ATTACHMENT0, Setup\texture(i), 0)
                
                If glCheckFramebufferStatus(#GL_FRAMEBUFFER) <> #GL_FRAMEBUFFER_COMPLETE
                        MessageRequester("Error", "Frambuffer Nr. " + Str(i) + " not complete")
                        End
                EndIf
        Next
        
        glBindFramebuffer(#GL_FRAMEBUFFER, 0)
EndProcedure

Procedure Shader_Create(type, code.s)
        Protected shader = glCreateShader(type)
        If shader
                Protected Textlength, infoLogSize, *InfoLog
                Protected *txtPointer = Ascii(code)
                If *txtPointer
                        glShaderSource(shader, 1, @*txtPointer, #Null)
                        glCompileShader(shader)
                        
                        glGetShaderiv(shader, #GL_INFO_LOG_LENGTH, @infoLogSize)
                        If infoLogSize
                                *InfoLog = AllocateMemory(infoLogSize)
                                If *InfoLog
                                        glGetShaderInfoLog(shader, infoLogSize, @Textlength, *InfoLog)
                                        Debug PeekS(*InfoLog, -1, #PB_Ascii)
                                        FreeMemory(*InfoLog)
                                EndIf
                        EndIf
                        FreeMemory(*txtPointer)
                EndIf
        EndIf
        ProcedureReturn shader
EndProcedure

Procedure Shader_Compile()
        Protected i
        For i = 0 To 1
                With Setup\program(i)
                        \ID = glCreateProgram()
                        \vertexShaderID = Shader_Create(#GL_VERTEX_SHADER, \vertexShaderCode)
                        \fragmentShaderID = Shader_Create(#GL_FRAGMENT_SHADER, \fragmentShaderCode)
                        
                        glAttachShader(\ID, \vertexShaderID)
                        glAttachShader(\ID, \fragmentShaderID)
                        
                        glLinkProgram(\ID)
                        
                        \uniformLocation("texture0") = glGetUniformLocation(\ID, "texture0")
                        \uniformLocation("frameNr") = glGetUniformLocation(\ID, "frameNr")
                EndWith
        Next
        
        Setup\startTime = ElapsedMilliseconds()
        Setup\frameNr = 0
EndProcedure

Macro NewCodeLine(code_, textLine_)
        code_ + textLine_ + #LF$
EndMacro

Procedure Init_SourceCode()
        With Setup\program(0)
                NewCodeLine(\vertexShaderCode, "#version 330")
                NewCodeLine(\vertexShaderCode, "layout(location = 0) in vec4 in_position;")
                NewCodeLine(\vertexShaderCode, "void main(){")
                NewCodeLine(\vertexShaderCode, "    gl_Position  = in_position;")
                NewCodeLine(\vertexShaderCode, "}")	
                
                NewCodeLine(\fragmentShaderCode, "#version 330")
                NewCodeLine(\fragmentShaderCode, "layout(location = 0) out vec4 out_color;")
                NewCodeLine(\fragmentShaderCode, "void main(){")
                NewCodeLine(\fragmentShaderCode, "    out_color = vec4(1,0,0,1);")
                NewCodeLine(\fragmentShaderCode, "}")
        EndWith
        
        With Setup\program(1)		
                NewCodeLine(\vertexShaderCode, "#version 330")
                NewCodeLine(\vertexShaderCode, "layout (location = 0) in vec3 position;")
                NewCodeLine(\vertexShaderCode, "layout (location = 1) in vec2 texCoordIn;")
                NewCodeLine(\vertexShaderCode, "out vec2 texCoordOut;")
                NewCodeLine(\vertexShaderCode, "void main(){")
                NewCodeLine(\vertexShaderCode, "    gl_Position = vec4(position, 1.0f);")
                NewCodeLine(\vertexShaderCode, "    texCoordOut = texCoordIn;")
                NewCodeLine(\vertexShaderCode, "}")
                
                NewCodeLine(\fragmentShaderCode, "#version 330")
                NewCodeLine(\fragmentShaderCode, "in vec2 texCoordOut;")
                NewCodeLine(\fragmentShaderCode, "out vec4 out_color;")
                NewCodeLine(\fragmentShaderCode, "uniform sampler2D texture0;")
                NewCodeLine(\fragmentShaderCode, "uniform int frameNr;")
                NewCodeLine(\fragmentShaderCode, "void main(){")
                NewCodeLine(\fragmentShaderCode, "    out_color = texture(texture0, texCoordOut);")
                NewCodeLine(\fragmentShaderCode, "}")
        EndWith
EndProcedure

Procedure Render()
        With Setup
                ; render texture
                glUseProgram(\program(0)\ID)
                glBindFramebuffer(#GL_FRAMEBUFFER, \frameBuffer(0))
                glBegin_(#GL_QUADS)
                glVertex2f_(-1, -1)
                glVertex2f_( 1, -1)
                glVertex2f_( 1, 1)
                glVertex2f_(-1, 1)
                glEnd_()
                
                ; copy texture to screen
                glUseProgram(\program(1)\ID)
                glUniform1i(\program(1)\uniformLocation("texture0"), \texture(0))
                glUniform1i(\program(1)\uniformLocation("frameNr"), \frameNr)
                glBindFramebuffer(#GL_FRAMEBUFFER, 0)
                glBegin_(#GL_QUADS)
                glTexCoord2f_(0,0)
                glTexCoord2f_(1,0)
                glTexCoord2f_(1,1)
                glTexCoord2f_(0,1)
                glVertex2f_(-1, -1)
                glVertex2f_( 1, -1)
                glVertex2f_( 1, 1)
                glVertex2f_(-1, 1)
                glEnd_()
                
                \frameNr + 1
        EndWith
        
        SetGadgetAttribute(#Gad_OpenGL, #PB_OpenGL_FlipBuffers, #True)
EndProcedure

Init_Main(512, 512)
Init_FrameBuffer()
Init_SourceCode()

Shader_Compile()

Define UpdateTime, event, quit

Repeat	
        With Setup
                Repeat
                        event = WindowEvent()
                        Select event
                                Case #PB_Event_CloseWindow
                                        quit = #True
                        EndSelect
                Until quit Or (event = 0)
                
                \time = ElapsedMilliseconds()		
                If \time >= UpdateTime
                        UpdateTime = \time + 25
                        Render()
                EndIf
        EndWith
        
        Delay(25)
Until quit
Last edited by Mr.L on Mon Feb 08, 2021 2:59 pm, edited 1 time in total.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: OpenGL/GLSL: render to texture

Post by Olli »

Ok. Good work of interfacing the GL methods.
Maybe you could copy the DLL in the Libraries directory to reduce the size of the source code. This allows you to remove the interfacing (prototypes, etc...), but it is not very important.

I just see you do not set the OGL gadget on the start, and on each frame render (after the GL render procedure call).

Start:

Code: Select all

SetGadgetAttribute(#Gad_OpenGL, #PB_OpenGL_SetContext, #True)
On each frame render: (as RenderWorld() on Ogre3D)

Code: Select all

SetGadgetAttribute(#Gad_OpenGL, #PB_OpenGL_FlipBuffers, #True)
It should be, in my humble opinion, always set to #True.

Maybe the problem is there...
Mr.L
Enthusiast
Enthusiast
Posts: 107
Joined: Sun Oct 09, 2011 7:39 am

Re: OpenGL/GLSL: render to texture

Post by Mr.L »

I have tried every possible combination. But it just makes not difference - The screen is black instead of red :|

You're of course right, this has to be set to True, but it doesn't solve my problem.

Code: Select all

SetGadgetAttribute(#Gad_OpenGL, #PB_OpenGL_FlipBuffers, #True)
This line also doen't make it work.

Code: Select all

SetGadgetAttribute(#Gad_OpenGL, #PB_OpenGL_SetContext, #True)
Maybe it has something to do with the internal double buffering of the OpenGL Gadget?
Mr.L
Enthusiast
Enthusiast
Posts: 107
Joined: Sun Oct 09, 2011 7:39 am

Re: OpenGL/GLSL: render to texture

Post by Mr.L »

I have found a solution!

Instead of using a shader to copy the texture to the screen, I just do it like that:

Code: Select all

glBindFramebuffer(#GL_FRAMEBUFFER, 0)
glBindTexture_(#GL_TEXTURE_2D, Setup\texture(0))
glBegin_(#GL_QUADS)
glTexCoord2f_(0,0)
glVertex2f_(-1, -1)
glTexCoord2f_(1,0)
glVertex2f_( 1, -1)
glTexCoord2f_(1,1)
glVertex2f_( 1, 1)
glTexCoord2f_(0,1)
glVertex2f_(-1, 1)
glEnd_()
Post Reply