Question on setContext() & 3D

I’m working on a Pick Buffer for detecting which object in the 3D scene was touched. The implementation involves using setContext() to redraw the same scene, but using colors as hints ← as was discussed in another thread elsewhere in the forum. I tried doing so, but the 3D scene will not render correctly.

Am I missing something?

I’ve modified the original 3D Lab test to use setContext to render into an image (self.buffer), before using sprite() to blit it onto the screen. You should be able to see the “effect” I’m suffering from.

`
function Test2:draw()
    pushMatrix()
    pushStyle()
    
    setContext(self.buffer)
    background(0, 0, 0, 255)
    
    -- Make a floor
    translate(0,-Size/2,0)
    rotate(Angle,0,1,0)
    rotate(90,1,0,0)
    sprite("SpaceCute:Background", 0, 0, 300, 300) 

    -- render each block in turn
    for zi,zv in ipairs(self.scene) do
        for yi,yv in ipairs(zv) do
            for xi, xv in ipairs(yv) do
                -- apply each transform  need - rotate, scale, translate to the correct place
                resetMatrix()
                rotate(Angle,0,1,0)
                
                local s = Size*0.25
                scale(s,s,s)
                
                translate(xi-2, yi-2, zi-2)    -- renders based on corner
                                               -- so -2 fudges it near center
                
                if xv > 0 then
                    self.blocks[xv]:draw()
                end
            end
        end
    end
    
    popStyle()
    popMatrix()
    
    setContext()
    
    pushMatrix()
    pushStyle()
    ortho()
    viewMatrix(matrix())
    translate(0, 0)
    sprite(self.buffer, WIDTH/2, HEIGHT/2)
    popStyle()
    popMatrix()    
end
`

This can’t be the whole code - right? I don’t see where you create self.buffer. Without the complete code (or at least a working subset), it’s harder to see what the problem is you’re seeing - or, maybe that’s it, and what you’re actually sprite()ing is “nil”.

It’s not the whole code. As I mentioned, this is a modification of the “Test2” program of the “3D Lab” sample that came with the package. The self.buffer was created in the Test2:init() function as follows:

self.buffer = image(WIDTH, HEIGHT)

And this was what I saw:

Looks as if the Z buffer is missing in contexts other than the main screen.

So is this a bug? Or is there something I can do to resolve this?

@tllau it is a bug, but we new about it when we implemented setContext(). The setContext() function doesn’t allocate a depth buffer for the given image. We initially did this due to memory and performance concerns.

However I’ll add it and test performance some more. It might even make it into 1.4.

@Simeon thanks, I hope to see it in 1.4 too. Project is at a point where interaction is required.

However, if this does not make the cut, any suggestion to Pick Buffer alternatives? Say GluUnProject, etc. ?

I’d suggest raycasting into a bounding volume hierarchy. Such as an octree. I think that’s the best and most modern solution.

However it is the trickiest to implement.

Sounds too complicated for my taste… fingers crossed on seeing the setContext() fix soon :slight_smile: