I have 4 3D textures and I am writing on them using imageStore in a single call, everything works fine. The only problem is how I clear them in each frame. This is how I create them
for (int i = 0; i < MIPLEVELS; ++i){
glGenTextures(1, &volumeTexture[i]);
glBindTexture(GL_TEXTURE_3D, volumeTexture[i]);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, volumeDimensions / (1 << i), volumeDimensions / (1 << i), volumeDimensions / (1 << i), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glBindTexture(GL_TEXTURE_3D, 0);
glGenFramebuffers(1, &volumeFbo[i]);
glBindFramebuffer(GL_FRAMEBUFFER, volumeFbo[i]);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, volumeTexture[i], 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
for (int i = 0; i < MIPLEVELS; ++i){
glBindFramebuffer(GL_FRAMEBUFFER, volumeFbo[i]);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
and this is what I do to clear them each frame
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (int i = 0; i < MIPLEVELS; ++i){
glBindFramebuffer(GL_FRAMEBUFFER, volumeFbo[i]);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
As you can see I am using 4 different FBOs which is a big waste. I tried using 4 targets but they don't get cleared. I did it this way:
I binded a single FBO and created 4 targets using glFrameBufferTexture3D and then each frame I called
glBindFramebuffer(GL_FRAMEBUFFER, volumeFbo[0]);
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers(4, buffers);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
But nothing happened.
I believe there are two ways of solving this issue.
You either do a loop where you attach each texture as GL_COLOR_ATTACHMENT0 and clear each texture.
Otherwise, you can also use the glClearBuffer family of textures:
https://www.opengl.org/sdk/docs/man3/xhtml/glClearBuffer.xml
Related
I have rendered a depth map to a framebuffer in the following way:
// the framebuffer
glGenFramebuffers(1, &depthMapFBO);
// completion: attacching a texture
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, SCR_WIDTH, SCR_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); // i.e. allocate memory, to be filled later at rendering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// bind framebuffer and attach depth texture
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffer(GL_NONE); // i.e. explicitly tell we want no color data
glReadBuffer(GL_NONE); // i.e. explicitly tell we want no color data
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Note the use of GL_DEPTH_COMPONENT32F because I want a high precision.
Now I want to put the values stored in the depth buffer of the framebuffer into an array, preserving the precision. How to do so? Here is what I had in mind:
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
[ render the scene to framebuffer]
GLfloat * d= new GLfloat[conf::SCR_WIDTH * conf::SCR_HEIGHT];
glReadPixels(0, 0, conf::SCR_WIDTH, conf::SCR_HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, d);
for (int i{ 0 }; i < conf::SCR_HEIGHT; ++i) {
for (int j{ 0 }; j < SCR_WIDTH; ++j) {
std::cout << d[i * SCR_WIDTH + j] << " ";
}
std::cout << std::endl;
}
However, this always prints 0.956376. Why so? I know I still have to re-linearize the depths... but why is always printed a constant value, and how can I fix this? Furthermore, is my approach correct, with regards to the lossless retrieval of information? Thanks in advance.
The same thing happens with:
GLfloat * d= new GLfloat[conf::SCR_WIDTH * conf::SCR_HEIGHT * 4];
glBindTexture(GL_TEXTURE_2D, depthMap);
glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, d);
I am trying to render to an (RGBA32UI) unsigned-integer texture2D and then read pixel data using glReadPixels. But it does not work
GLuint FramebufferName = 0;
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
// The texture we're going to render to
GLuint renderedTexture;
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, windowWidth, windowHeight, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);
// The depth buffer
GLuint depthrenderbuffer;
glGenRenderbuffers(1, &depthrenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, windowWidth, windowHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
render_scene();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindBuffer(GL_READ_BUFFER, FramebufferName);
glReadBuffer(GL_COLOR_ATTACHMENT0);
GLuint data[3];
for (int i=0; i < windowWidth; i++)
for (int j = 0; j < windowHeight; j++)
{
glReadPixels(i, j, 1, 1, GL_RGB32UI, GL_UNSIGNED_INT, data);
if (data[0] == 1 && data[1] == 2 && data[2] == 3)
int a = 1;
}
Shader (GLSL)
#version 450 core
out uvec3 output_color;
void main()
{
output_color = uvec3(1, 2, 3);
}
Is there anyone experienced this problem? Please, help me.
The command
glBindBuffer(GL_READ_BUFFER, FramebufferName);
is wrong. glBindBuffer does not have the target GL_READ_BUFFER, so this should result in an GL_INVALID_ENUM error. (You should really add some error checking, preferably via debug output if available.) You can never bind an FBO with glBindBuffer. FBOs can only be bound with glBindFramebuffer. What You actually wanted to do is:
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferName);
glReadBuffer(GL_COLOR_ATTACHMENT0);
Also note that glBindFramebuffer(GL_FRAMEBUFFER, ...); is just a shortcut to bind GL_DRAW_FRAMEBUFFER and GL_READ_FRAMEBUFFER at once.
I'm trying to have a FBO with separate depth and stencil buffers.
I know that NVidia GPU's historically only supported packed depth/stencil.
However I stumbled on the ARB_texture_stencil8 extension and wonder how to use it against a FBO.
This code gives gl error 1159 on glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, fboStencilTexture, 0):
static GLuint fboId, rboDepth, rboStencil, TEXTURE_WIDTH, TEXTURE_HEIGHT;
if (!fboColorTexture) {
fboDepthTexture = fboId = rboDepth = rboStencil = TEXTURE_WIDTH = TEXTURE_HEIGHT = 0; // vid restart?
glGenTextures(1, &fboColorTexture);
glBindTexture(GL_TEXTURE_2D, fboColorTexture);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
if (!fboDepthTexture) {
glGenTextures(1, &fboDepthTexture);
glBindTexture(GL_TEXTURE_2D, fboDepthTexture);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
if (!fboStencilTexture) {
glGenTextures(1, &fboStencilTexture);
glBindTexture(GL_TEXTURE_2D, fboStencilTexture);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
GLuint curWidth = r_virtualResolution.GetFloat() * glConfig.vidWidth, curHeight = r_virtualResolution.GetFloat() * glConfig.vidHeight;
if (curWidth != TEXTURE_WIDTH || curHeight != TEXTURE_HEIGHT) {
TEXTURE_WIDTH = curWidth;
TEXTURE_HEIGHT = curHeight;
glBindTexture(GL_TEXTURE_2D, fboColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); //NULL means reserve texture memory, but texels are undefined
glBindTexture(GL_TEXTURE_2D, fboDepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glBindTexture(GL_TEXTURE_2D, fboStencilTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_STENCIL_INDEX, GL_FLOAT, 0);
}
//-------------------------
if (!fboId) {
// create a framebuffer object, you need to delete them when program exits.
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
// attach a texture to FBO color attachement point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboColorTexture, 0);
// attach a renderbuffer to depth attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, fboDepthTexture, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, fboStencilTexture, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
The purpose of ARB_texture_stencil8 is to permit you to use stencil-only formats as textures. That is, reading from them in shaders.
This does not mean that you can separate your stencil and depth buffers. The idea behind stencil-8 textures is that you would generate their data by either copying the stencil portion of a depth/stencil texture, or you would render without a depth buffer entirely.
So you cannot use this extension to guarantee that you can render to separate depth and stencil images. That's still hardware dependent.
Also, if you're going to use new features like ARB_texture_stencil8, you shouldn't be combining them with old EXT_framebuffer_object APIs. So stop using glFramebufferTexture2DEXT and start using glFramebufferTexture.
I'm trying to render to texture.Using opengl-es 2.0.I wanna make Black and white postprocessing.But all I see, is black texture.On scene I have lightsources, and two spheres.But when I'm trying to render my texture that attached to framebuffer, I see black square.
this->frameBuffersCount = 3;
this->frameBuffers = new int[frameBuffersCount];
glGenFramebuffers(frameBuffersCount, (GLuint*)this->frameBuffers);
this->texturesCount = this->frameBuffersCount * 2;
this->bufferTextures = new int[this->texturesCount];
glGenTextures(this->texturesCount, (GLuint*)this->bufferTextures);
for(int i = 0; i < this->texturesCount / 2; ++i)
{
glBindTexture(GL_TEXTURE_2D, this->bufferTextures[2*i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,0);
glBindTexture(GL_TEXTURE_2D, this->bufferTextures[2*i + 1]);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT, screenWidth, screenHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D,0);
}
for(int i = 0; i < this->frameBuffersCount; ++i)
{
glBindFramebuffer(GL_FRAMEBUFFER, this->frameBuffers[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
this->bufferTextures[2*i],
0);
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D,
this->bufferTextures[2*i + 1],
0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
this->ordinaryQuad = new ModelVertex[4];
this->ordinaryQuad[0].UV = Vector2(0.0,0.0);
this->ordinaryQuad[0].position = Vector3(-1, -1, 0.0);
this->ordinaryQuad[1].UV = Vector2(0.0,1.0);
this->ordinaryQuad[1].position = Vector3(-1.0, 1.0, 0.0);
this->ordinaryQuad[2].UV = Vector2(1.0,1.0);
this->ordinaryQuad[2].position = Vector3(1.0, 1.0, 0.0);
this->ordinaryQuad[3].UV = Vector2(1.0,0.0);
this->ordinaryQuad[3].position = Vector3(1.0, -1.0, 0.0);
This is rendering code.
void EffectManager::applyBnW()
{
glBindFramebuffer(GL_FRAMEBUFFER, this->frameBuffers[0]);
auto res = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(res == GL_FRAMEBUFFER_COMPLETE)
{
SceneManager::GetInstance().DrawScene();
glDisable(GL_DEPTH_TEST);
unsigned short indices[6] = {0,2,1,2,0,3};
Shaders shaders;
shaders.Init("../Resources/Shaders/BlackAndWhiteVS.vs", "../Resources/Shaders/BlackAndWhiteFS.fs", 0);
glUseProgram(shaders.program);
unsigned int hVBuff,hInBuff;
glGenBuffers(1, &hVBuff);
glGenBuffers(1, &hInBuff);
glBindBuffer(GL_ARRAY_BUFFER, hVBuff);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(SEngine::ModelVertex), this->ordinaryQuad, GL_STATIC_DRAW);
//glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, hInBuff);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned short), indices, GL_STATIC_DRAW);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->bufferTextures[0]);
glGenerateMipmap(GL_TEXTURE_2D);
if(shaders.positionAttribute != -1)
{
glEnableVertexAttribArray(shaders.positionAttribute);
glVertexAttribPointer(shaders.positionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(SEngine::ModelVertex), 0);
}
if(shaders.UVAttribute != -1)
{
glEnableVertexAttribArray(shaders.UVAttribute);
glVertexAttribPointer(shaders.UVAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(SEngine::ModelVertex), (void*)(sizeof(Vector3)));
}
if(shaders.samplerUniform != -1)
{
glUniform1i(shaders.samplerUniform, 0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)0);
//glDrawArrays(GL_TRIANGLES,0,4);
}
What is wrong?
Not a clear answer can be given since there is not enough information/code provided in your question.
Did you clear the depth buffer ?
When you generated the color in the fragment shader for the rendered objects, did you correctly calculate the White color?
One way I do in these situations to help me debug the issue is to remove potential error areas.
Clear the framebuffer to Red color and Alpha channel = 1.0
Clear depth buffer
Hard code gl_FragColor to vec4(1,1,1,1)
By doing this you can see if the output is all red? Then the issue is with the object rendering, such as transformation, clipping, depth rejection or other reason.
If you can see the objects with White color? Then you know it's the issue with your fragment shader
I would also recommend you to remove the line
glGenerateMipmap(GL_TEXTURE_2D);
As from what I can see in your code, it does not add any extra. If not this is the root-cause to your error.
Generating mipmaps on the texture that still being used and attached to a framebuffer object is not very effecient, especially if the driver internally would have to reallocate the memory for being able to store the new mipmap levels.
Solved.It was problems with index buffer and I forget to disable depth_test.
I'm trying to render to two textures, rendering from the first to the second, and then from the second to the first etc. The problem is that when I'm rendering the first texture to the second, it works fine but rendering the second to the first leaves a white texture, when it's supposed to be a purple one. I'm working with Qt and OpenGL.
Both textures are bound to the same FBO, and I'm switching them through glDrawBuffer(GL_COLOR_ATTACHMENT_i)
Here is my initialization code:
void GlWidget::initializeGL() {
glewInit();
src = true;
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
//glEnable(GL_CULL_FACE);
// Generate the texture to be drawn
tex = new float[256*256*4];
for(int i = 0; i < 256*256*4; i++){
if (i % 4 == 0){
tex[i] = 0.5;
}else if (i % 4 == 1){
tex[i] = 0.3;
}else if (i % 4 == 2){
tex[i] = 0.5;
}else if (i % 4 == 3){
tex[i] = 0;
}
}
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, 256, 0, GL_RGBA, GL_FLOAT, tex);
glGenTextures(1, &targetTex);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, targetTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, 256, 0, GL_RGBA, GL_FLOAT, NULL);
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
//Attach 2D texture to this FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, targetTex, 0);
glDrawBuffer (GL_COLOR_ATTACHMENT1);
//-------------------------
glGenRenderbuffers(1, &depth_rb);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_rb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER, depth_rb);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
shaderProgram.link();
vertices << QVector3D(-1, -1, -2) << QVector3D(-1, 1, -2) << QVector3D(1, 1, -2) << QVector3D(1, -1, -2);
texCoords << QVector2D(0, 0) << QVector2D(0, 1) << QVector2D(1, 1) << QVector2D(1, 0);
}
And here is my drawing code:
void GlWidget::render_to_screen () {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
qglClearColor(QColor(Qt::blue));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(src){
glActiveTexture(GL_TEXTURE0);
}else{
glActiveTexture(GL_TEXTURE1);
}
shaderProgram.enableAttributeArray("textureCoordinates");
shaderProgram.enableAttributeArray("vertex");
glDrawArrays(GL_QUADS, 0, vertices.size());
shaderProgram.disableAttributeArray("vertex");
shaderProgram.disableAttributeArray("textureCoordinates");
}
void GlWidget::paintGL()
{
qDebug() << "Updating";
glBindFramebuffer(GL_FRAMEBUFFER, fb);
if(src) {
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glActiveTexture(GL_TEXTURE0);
}else {
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glActiveTexture(GL_TEXTURE1);
}
src = !src;
qglClearColor(QColor(Qt::white));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 mMatrix;
QMatrix4x4 vMatrix;
shaderProgram.bind();
shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
shaderProgram.setAttributeArray ("textureCoordinates", texCoords.constData ());
shaderProgram.enableAttributeArray("textureCoordinates");
shaderProgram.setAttributeArray("vertex", vertices.constData());
shaderProgram.enableAttributeArray("vertex");
glDrawArrays(GL_QUADS, 0, vertices.size());
shaderProgram.disableAttributeArray("vertex");
shaderProgram.disableAttributeArray("textureCoordinates");
render_to_screen ();
shaderProgram.release();
}
I'm supposed to be getting a blue screen with a purple quad in the center, instead I'm getting a white quad in the center. What am I doing wrong here?
I see several places in your code where you set the active texture. But setting the active texture means nothing as far as what texture unit the program will pull from. That's decided by the texture image unit set into the sampler uniform that's accessing the texture. You need to change that uniform, not the active texture.
Or better yet, just bind the other texture to the context. There's no need to set the active texture image unit; just bind the texture you want to sample from. Really, there's no point in any of the glActiveTexture calls you're making.