歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenGL中的FBO如何使用模板緩沖區

FBO常用框架

一般需求只有color buffer,depth buffer,前者一般用紋理,後者一般用rbo。標准程序如下:

// 創建
 // frame buffer object
 glGenFramebuffers(1, &fboId);
 glBindFramebuffer(GL_FRAMEBUFFER, fboId);

 // color buffer with texture object
 glGenTextures(1, &color_rboId);
 glBindTexture(GL_TEXTURE_2D, color_rboId);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, targetWidth, targetHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

 // depth buffer with render buffer object
 glGenRenderbuffers(1, &depth_rboId);
 glBindRenderbuffer(GL_RENDERBUFFER, depth_rboId);
 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, targetWidth, targetHeight);
 
 // Attach color buffer to FBO
 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_rboId, 0);
 
 //Attach depth buffer to FBO
 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rboId);
 
 
 //Also attach as a stencil
 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth_stencil_rb);

// 刪除
 if (fboId != 0)
 {
  glDeleteFramebuffers(1, &fboId);
  fboId = 0;
 }

 if (depth_rboId != 0)
 {
  glDeleteRenderbuffers(1, &depth_rboId);
  depth_rboId = 0;
 }
 
 if (color_rboId)
 {
  glDeleteTextures(1, &color_rboId);
  color_rboId = 0;
 }

FBO中如何增加stencil buffer

正常人都會認為stencil buffer 跟depth buffer類似,於是乎寫出一套類似depth buffer的框架:

// 創建stencil buffer以RBO形式
 glGenRenderbuffers(1, &stencil_rboId);
 glBindRenderbuffer(GL_RENDERBUFFER, stencil_rboId);
 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX, targetWidth, targetHeight);
 
// 關聯stencil buffer 和FBO
 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil_rboId);
 
// 刪除stencil buffer
 glDeleteRenderbuffers(1, &stencil_rboId);

但實際測試,發現stencil buffer根本不起作用,下面是一個測試函數:

void stencilRenderTest()
{
 GLdouble dRadius = 0.1; // Initial radius of spiral
 GLdouble dAngle;        // Looping variable
 float x = 100;
 float y = 100;
 float rsize = 25;

 // Clear blue window
 glClearColor(0.0f, 0.0f, 1.0f, 0.0f);

 // Use 0 for clear stencil, enable stencil test
 glClearStencil(0.0f);
 glEnable(GL_STENCIL_TEST);

 // Clear color and stencil buffer
 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

 // All drawing commands fail the stencil test, and are not
 // drawn, but increment the value in the stencil buffer.
 glStencilFunc(GL_NEVER, 0x0, 0x0);
 glStencilOp(GL_INCR, GL_INCR, GL_INCR);

 // Spiral pattern will create stencil pattern
 // Draw the spiral pattern with white lines. We
 // make the lines  white to demonstrate that the
 // stencil function prevents them from being drawn
 glColor3f(1.0f, 1.0f, 1.0f);
 glBegin(GL_LINE_STRIP);
 for(dAngle = 0; dAngle < 400.0; dAngle += 0.1)
 {
  glVertex2d(dRadius * cos(dAngle), dRadius * sin(dAngle));
  dRadius *= 1.002;
 }
 glEnd();

 // Now, allow drawing, except where the stencil pattern is 0x1
 // and do not make any further changes to the stencil buffer
 glStencilFunc(GL_NOTEQUAL, 0x1, 0x1);
 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

 // Now draw red bouncing square
 // (x and y) are modified by a timer function
 glColor3f(1.0f, 0.0f, 0.0f);
 glRectf(x, y, x + rsize, y - rsize);

}

stencil正確時,結果顯示是一個藍色背景,紅色小矩形塊,矩形內部可以看到圓弧,下圖右。

stencil不正確結果是藍色背景同心圓環 以及一個矩形紅色塊,圖左。  
Copyright © Linux教程網 All Rights Reserved