Zoeken…


Basisprincipes van framebuffers

Framebuffer is een type buffer dat kleurwaarden , diepte en stencilinformatie van pixels in het geheugen opslaat. Wanneer u iets in OpenGL tekent, wordt de uitvoer opgeslagen in de standaard framebuffer en ziet u de kleurwaarden van deze buffer op het scherm. Je kunt ook je eigen framebuffer maken die kan worden gebruikt voor veel coole nabewerkingseffecten zoals grijsschaal, vervaging, scherptediepte, vervormingen, reflecties ...

Om te beginnen moet u een framebuffer-object ( FBO ) maken en dit als elk ander object in OpenGL binden:

unsigned int FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);  

Nu moet u ten minste één bijlage (kleur, diepte of sjabloon) toevoegen aan de framebuffer. Een bijlage is een geheugenlocatie die fungeert als buffer voor de framebuffer. Het kan een textuur of een renderbuffer-object zijn . Het voordeel van het gebruik van een textuur is dat u deze textuur gemakkelijk kunt gebruiken in een nabewerking van shaders. Het maken van de textuur is vergelijkbaar met een normale textuur:

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

De width en height moeten hetzelfde zijn als de grootte van uw renderingvenster. De structuurgegevenspointer is NULL omdat u alleen het geheugen wilt toewijzen en de textuur niet met gegevens wilt vullen. De textuur is klaar, zodat je hem daadwerkelijk aan de framebuffer kunt bevestigen:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);  

Je framebuffer zou nu klaar moeten zijn voor gebruik, maar je kunt ook diepte-bevestiging of diepte- en stencil-bijlagen toevoegen. Als u deze wilt toevoegen als textuurbijlagen (en ze wilt gebruiken voor wat verwerking), kunt u een andere structuur maken zoals hierboven. Het enige verschil zou zijn in deze regels:

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, 
    GL_DEPTH_COMPONENT, GL_FLOAT, NULL
);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

Of deze als u diepte- en stencilbevestiging in één textuur wilt gebruiken:

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, 
    GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);

U kunt ook een renderbuffer in plaats van een textuur gebruiken als bijlage voor diepte- en stencilbuffers als u de waarden later niet wilt verwerken. (Dit wordt in een ander voorbeeld uitgelegd ...)

U kunt controleren of de framebuffer zonder fouten is gemaakt en voltooid:

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
    // do something...

En vergeet ten slotte niet om de framebuffer te ontbinden, zodat u er niet per ongeluk aan terugkeert:

glBindFramebuffer(GL_FRAMEBUFFER, 0);  

grenzen

Het maximale aantal kleurenbuffers dat aan een enkele framebuffer kan worden gekoppeld , kan worden bepaald door de OGL-functie glGetIntegerv , met behulp van de parameter GL_MAX_COLOR_ATTACHMENTS :

GLint maxColAttchments = 0;
glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS, &maxColAttchments );

De framebuffer gebruiken

Het gebruik is vrij eenvoudig. Eerst bind je je framebuffer en maak je je scène erin. Maar je zult eigenlijk nog niets zien omdat je renderbuffer niet zichtbaar is. Dus het tweede deel is om je framebuffer als een textuur van een fullscreen quad op het scherm weer te geven. Je kunt het gewoon laten zoals het is of wat nabewerkingseffecten doen.

Dit zijn de hoekpunten voor een quad op volledig scherm:

float vertices[] = {
//   positions     texture coordinates
    -1.0f,  1.0f,  0.0f, 1.0f,
    -1.0f, -1.0f,  0.0f, 0.0f,
     1.0f, -1.0f,  1.0f, 0.0f,

    -1.0f,  1.0f,  0.0f, 1.0f,
     1.0f, -1.0f,  1.0f, 0.0f,
     1.0f,  1.0f,  1.0f, 1.0f
};

U moet ze opslaan in een VBO of renderen met behulp van kenmerkaanwijzers. Je hebt ook een basisprogramma nodig voor het renderen van de quad op volledig scherm met textuur.

Vertex shader:

in vec2 position;
in vec2 texCoords;

out vec2 TexCoords;

void main()
{
    gl_Position = vec4(position.x, position.y, 0.0, 1.0); 
    TexCoords = texCoords;
}  

Fragment shader:

in vec2 TexCoords;
out vec4 color;

uniform sampler2D screenTexture;

void main()
{ 
    color = texture(screenTexture, TexCoords);
}

Opmerking: mogelijk moet u de shaders aanpassen voor uw versie van GLSL .

Nu kunt u de daadwerkelijke rendering uitvoeren. Zoals hierboven beschreven, is het eerste wat je moet doen de scène weergeven in je FBO. Om dat te doen, bindt u eenvoudig uw FBO, wist u deze en tekent u de scène:

glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
// draw your scene here...   

Opmerking: in de glClear functie moet u alle framebuffer-bijlagen opgeven die u gebruikt (in dit voorbeeld kleur- en dieptebevestiging).

Nu kunt u uw FBO als een fullscreen quad op de standaard framebuffer weergeven, zodat u deze kunt zien. Om dit te doen, ontbindt u eenvoudig uw FBO en geeft de quad weer:

glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind your FBO to set the default framebuffer
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

shader.Use(); // shader program for rendering the quad  

glBindTexture(GL_TEXTURE_2D, texture); // color attachment texture
glBindBuffer(GL_ARRAY_BUFFER, VBO); // VBO of the quad
// You can also use VAO or attribute pointers instead of only VBO...
glDrawArrays(GL_TRIANGLES, 0, 6); 
glBindBuffer(GL_ARRAY_BUFFER, 0);

En dat is alles! Als je alles correct hebt gedaan, zou je dezelfde scène als voorheen moeten zien, maar dan weergegeven op een fullscreen quad. De visuele uitvoer is hetzelfde als voorheen, maar nu kunt u eenvoudig nabewerkingseffecten toevoegen door de fragment-arcering te bewerken. (Ik voeg effecten toe aan een ander voorbeeld en koppel het hier)



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow