Stenciling not working with rendertotexture?

Continuing my forays into deferred rendering, I’m having problems getting stenciling to work with the offscreen buffers. Stenciling works as expected with the base buffer, but seems to fail with the offscreen buffer. buffer.getFbPropertities() does report that a stencil buffer is attached to the offscreen buffer.

Does anyone have any experience with this?

import direct.directbase.DirectStart
from pandac.PandaModules import *
import math
import time

def CreateFBO(strName = "Buffer", intSort = -10, intSizeX = None, intSizeY = None, 
				intAuxRGBA = 0):
	winprops = WindowProperties()
	winprops.setSize( intSizeX , intSizeY )
	fbprops = FrameBufferProperties()
	fbprops.setColorBits(1)
	fbprops.setAlphaBits(1)
	fbprops.setDepthBits(1)
	fbprops.setStencilBits (1)
	if intAuxRGBA:
		fbprops.setAuxRgba( intAuxRGBA )
	objBuffer = base.graphicsEngine.makeOutput(base.pipe, strName, intSort, fbprops, winprops, GraphicsPipe.BFRefuseWindow, base.win.getGsg(), base.win)
	return objBuffer

texDepth = Texture()
texDepth.setFormat(Texture.FDepthStencil)
texBuffer0 = Texture()
texBuffer1 = Texture()
texBuffer2 = Texture()
texBuffer3 = Texture()

rtmbuffer = CreateFBO(strName = "model buffer", intSort = -5, intSizeX = 1024, intSizeY = 1024, intAuxRGBA = 3)
rtmbuffer.addRenderTexture( texDepth,  GraphicsOutput.RTMCopyTexture, GraphicsOutput.RTPDepthStencil )
rtmbuffer.addRenderTexture( texBuffer0, GraphicsOutput.RTMCopyTexture, GraphicsOutput.RTPColor )
rtmbuffer.addRenderTexture( texBuffer1, GraphicsOutput.RTMCopyTexture, GraphicsOutput.RTPAuxRgba0 )
rtmbuffer.addRenderTexture( texBuffer2, GraphicsOutput.RTMCopyTexture, GraphicsOutput.RTPAuxRgba1 )
rtmbuffer.addRenderTexture( texBuffer3, GraphicsOutput.RTMCopyTexture, GraphicsOutput.RTPAuxRgba2 )

rtmcamMask = 1
rtmcam=base.makeCamera( rtmbuffer, sort = 0, lens=base.camLens, scene=render, mask = rtmcamMask, camName = 'TestCam' )
rtmcam.setPos( 0, -20, 0)
rtmcam.node().getDisplayRegion(0).setClearColorActive(True)
rtmbuffer.setClearColorActive(True)
rtmbuffer.setClearDepthActive(True)
	
shader = loader.loadShader( "testdef.c")

npModel = loader.loadModel( 'smiley.egg' )
npModel.reparentTo( render )
npModel.setShader( shader )
npModel.setAttrib( StencilAttrib.make(1,StencilAttrib.SCFAlways,StencilAttrib.SOZero, StencilAttrib.SOReplace,StencilAttrib.SOReplace, 1, 0, 1) )

npModel2 = loader.loadModel( 'smiley.egg' )
npModel2.reparentTo( render )
npModel2.setBin("fixed", 40)
npModel2.setPos( 0, -5, 0 )
npModel2.setAttrib( StencilAttrib.make(1,StencilAttrib.SCFEqual,StencilAttrib.SOKeep, StencilAttrib.SOKeep,StencilAttrib.SOKeep,1,1,0) )
shader2 = loader.loadShader( "testdef2.c")
npModel2.setShader( shader2 )

base.cam.setPos(0,-20, 0)
base.bufferViewer.toggleEnable()

def move(task):
	base.cam.setPos( 3*math.sin(time.time()), -20, 0 )
	rtmcam.setPos( 3*math.sin(time.time()), -20, 0 )
	return task.cont

taskMgr.add( move, 'move' )

run()

shader 1 - testdef.c

//Cg
//
//Cg profile arbvp1 arbfp1

void vshader(float4 vtx_position : POSITION,
             uniform float4x4 mat_modelproj,
			 in float2 vtx_texcoord0 : TEXCOORD0,
			out float2 l_texcoord0 : TEXCOORD0, 
			out float4 l_position : POSITION)
{
  l_position=mul(mat_modelproj, vtx_position);
  l_texcoord0 = vtx_texcoord0;
}

void fshader( in float2 l_texcoord0 : TEXCOORD0,
						uniform sampler2D tex_0 : TEXUNIT0,
						out float4 o_color0: COLOR0,
						out float4 o_color1: COLOR1,
						out float4 o_color2: COLOR2,
						out float4 o_color3: COLOR3 )
{
  o_color0 = float4( 1, 0, 0, 1);
  o_color1 = float4( 0, 1, 0, 1);
  o_color2 = float4( 0, 0, 1, 1);
  o_color3 = float4( 1, 1, 0, 1);
 }

shader 2 - testdef2.c

void vshader(float4 vtx_position : POSITION,
             uniform float4x4 mat_modelproj,
			 in float2 vtx_texcoord0 : TEXCOORD0,
			out float2 l_texcoord0 : TEXCOORD0, 
			out float4 l_position : POSITION)
{
  l_position=mul(mat_modelproj, vtx_position);
  l_texcoord0 = vtx_texcoord0;
}

void fshader( in float2 l_texcoord0 : TEXCOORD0,
						uniform sampler2D tex_0 : TEXUNIT0,
						out float4 o_color0: COLOR0,
						out float4 o_color1: COLOR1,
						out float4 o_color2: COLOR2,
						out float4 o_color3: COLOR3 )
{
  o_color0 = float4( 1, 1, 1, 1);
  o_color1 = float4( 0, 1, 0, 1);
  o_color2 = float4( 0, 0, 1, 1);
  o_color3 = float4( 1, 1, 0, 1);
 }

The stenciling issue works fine in version 1.6.2, but is broken in 1.7.0 and 1.7.1. The buffer clearing problem still exists in 1.6.2

Interesting. Sounds like this bears investigation.

David