Hi there,
my project is described here:
https://www.opengl.org/discussion_boards/showthread.php/198350-Render-offscreen-to-texture-basic-questions?goto=newpost
… and it is still flickering.
There are two modules (classes) sharing most of their functions, as there are especially the creation and destroying-function, the pointer-management, etc. Both functions are performing two render-passes. The first pass generates a texture for later use, while the second one generates a preview-thumbnail as output in the modules-window.
Inside, one module is rendering two 2d-textures for blending them (works), while the other one renders some single-colored quads (causes flickering of the main-output).
Here is the code (i know, that some things i do, can be done more elegant, but this i’ll do later…)
Working code (note: for each module, GLbuffer is the class containig the associated output-texture - the code for GLBuffer.Set(w,h) you’ll find below):
w = vcW->GetValue(); h = vcH->GetValue();
if (w != GLBuffer.W || h != GLBuffer.H) GLBuffer.Set(w,h);
GLuint FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, GLBuffer.Texture, 0);
glViewport (0, 0, (GLint)w, (GLint)h);
glClearColor (0.0, 0.0, 0.0, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION); glLoadIdentity(); gluPerspective (90.0, 1, 0.9, 3);
glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glTranslatef (0, 0, -1);
glEnable (GL_TEXTURE_2D); glDisable(GL_BLEND);
if (src1 > 0) {
double sc = vcScale1->GetValue();
double r = vcRotate1->GetValue();
double x = vcX1->Get01();
double y = vcY1->Get01();
glBindTexture (GL_TEXTURE_2D, _TEXTURE(src1));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glPushMatrix();
glRotatef (r, 0.0, 0.0, -1.0);
glBegin(GL_QUADS);
glTexCoord2f (x , y ); glVertex3f (-sc, sc, 0);
glTexCoord2f (x+1, y ); glVertex3f ( sc, sc, 0);
glTexCoord2f (x+1, y+1); glVertex3f ( sc, -sc, 0);
glTexCoord2f (x , y+1); glVertex3f (-sc, -sc, 0);
glEnd();
glPopMatrix();
glFlush();
}
int blendSrc = blendSrcVal[selBlend1->GetValue()]; int blendDst = blendDstVal[selBlend2->GetValue()];
glEnable (GL_BLEND);
glBlendFunc (blendSrc, blendDst);
if (src2 > 0) {
double sc = vcScale2->GetValue();
double r = vcRotate2->GetValue();
double x = vcX2->Get01();
double y = vcY2->Get01();
glBindTexture (GL_TEXTURE_2D, _TEXTURE(src2));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tmodeVal[selTexMode->GetValue()]);
glPushMatrix();
glRotatef (r, 0.0, 0.0, -1.0);
glBegin(GL_QUADS);
glTexCoord2f (x , y ); glVertex3f (-sc, sc, 0);
glTexCoord2f (x+1, y ); glVertex3f ( sc, sc, 0);
glTexCoord2f (x+1, y+1); glVertex3f ( sc, -sc, 0);
glTexCoord2f (x , y+1); glVertex3f (-sc, -sc, 0);
glEnd();
glPopMatrix();
glFlush();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glActiveTexture(GL_TEXTURE0);
glDeleteFramebuffers(1, &FBO);
Canvas->Refresh();
Flickering:
w = vcW->GetValue(); h = vcH->GetValue();
if (w != GLBuffer.W || h != GLBuffer.H) GLBuffer.Set(w,h);
GLuint FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, GLBuffer.Texture, 0);
glViewport (0, 0, (GLint)w, (GLint)h);
glClearColor (0.0, 0.0, 0.0, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION); glLoadIdentity(); gluPerspective (90.0, 1, 0.9, 3);
glMatrixMode (GL_MODELVIEW); glLoadIdentity(); glTranslatef (0, 0, -1);
glDisable (GL_TEXTURE_2D); glDisable(GL_BLEND);
for (double cx = 0; cx < w; cx = cx++) {
for (double cy = 0; cy < h; cy = cy++) {
double tr=0,tg=0,tb=0,ta=1;
double pxs = cx * 2 - w;
double pys = cy * 2 - h;
double px = fabs((pxs+1) / w); double lxf = (sin(px * LiW)/2+0.5);
double py = fabs((pys+1) / h); double lyf = (sin(py * LiH)/2+0.5);
double rr = px + py;
double rc = pow(px * px + py * py, 0.5);
double rs = px > py ? px : py;
double rad = shape < 0 ? ((1 + shape) * rc - shape * rr) : ((1 - shape) * rc + shape * rs);
rad = (rad * inner - inner + 1) / 2;
rad = rad > 1 ? 1 : rad < -1 ? -1 : rad;
double dif = pow(cos(rad * M_PI), 1 / edge) + (1-lxf*lyf)*LiF;
if (dif >= 0) {
double nze = 1.0 - (noise == 0 ? 0 : fmodf(rand(), noise) / 256);
tr = (dif * r) * nze;
tg = (dif * g) * nze;
tb = (dif * b) * nze;
tr = (tr > 255 ? 255 : tr)/255;
tg = (tg > 255 ? 255 : tg)/255;
tb = (tb > 255 ? 255 : tb)/255;
}
else {
tr = 0;
tg = 0;
tb = 0;
ta = 1;
}
glBegin(GL_QUADS);
glColor4f(tr, tg, tb, ta); glVertex3f ((pxs-0)/w, (pys-0)/h, 0);
glColor4f(tr, tg, tb, ta); glVertex3f ((pxs+2)/w, (pys-0)/h, 0);
glColor4f(tr, tg, tb, ta); glVertex3f ((pxs+2)/w, (pys+2)/h, 0);
glColor4f(tr, tg, tb, ta); glVertex3f ((pxs-0)/w, (pys+2)/h, 0);
glEnd();
}
}
glFlush();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glActiveTexture(GL_TEXTURE0);
glDeleteFramebuffers(1, &FBO);
Canvas->Refresh();
The following functions are part of GLbuffer-class and used by both (note: “Texture” is a gl texture pointer created with the module):
clsBuffer *clsBuffer::Set(int w, int h, wxString name, int depth) {
if (name != "") Name = name;
useAlpha = true;
TexEmpty(w,h);
return this;
}
clsBuffer *clsBuffer::TexEmpty(int w, int h, bool ua) {
W = w; H = h;
glBindTexture (GL_TEXTURE_2D, Texture);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return this;
}
What i already found out is:
- The thumbnail for both modules is generated correctly. So the renderin-process itself works fine.
- Flickering appears each time, the module is updated, which may be n times slower then the main-output.
- If the update-frequence is identical to the main output (n=1) the main output stays totally black.
- The module-thumbnail doesn’t flicker. Only the main-output and some other preview-windows.
- Commenting out the GLBuffer.Set(w,h)-call which is only needed for resizing, has no effect on the problem.
- Most strange: Commenting out the four lines between glBegin(GL_QUADS); and glEnd();, flickering stops.
Any ideas what is wrong???
Maybe i’m blind and i do not see some very simple thing…
Thanks for reading,
Frank