Domanda

I'm trying to create some interlaced images to output on a 3DTV. My method uses OpenGL's stencil buffer to draw a grid of lines on each even row of pixels. On my laptop, the resulting image looks interlaced, but when I output to the 3DTV (via HDMI cable), it looks as though the lines are not drawn on each even row of pixels. The vertical resolution of my laptop and the TV is 1080 pixels. The screen coordinates used below range from (-1, -1) for bottom left of the screen to (1, 1) for top right. Here is the code I am using to draw the grid on the stencil buffer. I'd be grateful if someone could sanity check it for me, to see if I'm doing something fundamentally wrong. If my code is fine, the problem might be the TV resizing the output from the laptop.

glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE); 
glDisable(GL_DEPTH_TEST);
glStencilFunc(GL_ALWAYS,1,1); 
const int stencilsize = 2500;
// hardcoding 2500, not the greatest solution in the world i know...
GLfloat stencilVertices[stencilsize] = {0.0};
//if we know the window height, we can draw a line in the stencil buffer on even row of pixels in the window
currheight = 1080; 
GLint i = 0;
GLfloat ht = -1;
/*start ht @ -1, increase by 4/currheight each time, until 1 is reached*/
while ((ht < 1) && (i < stencilsize-4)) 
{
    stencilVertices[i] = -1;    //left edge of screen
    i++;
    stencilVertices[i] = ht;    //current line's y coord
    i++;
    stencilVertices[i] = 1;     //right edge of screen
    i++;
    stencilVertices[i] = ht;    //current line's y coord
    i++;
    ht += 4.0/currheight;   //increase ht by (4/(height of window)) each time to mark even rows only (until ht == 1)
}
glGenBuffers(1, &m_ui32Stencilpattern); 
glBindBuffer(GL_ARRAY_BUFFER, m_ui32Stencilpattern);
glBufferData(GL_ARRAY_BUFFER, (stencilsize * sizeof(GLfloat)), stencilVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(VERTEX_ARRAY);
glVertexAttribPointer(VERTEX_ARRAY, 2, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_LINES, 0, stencilsize);
È stato utile?

Soluzione

I think the stencil buffer is not quite the right tool for this. Line interlacing is more easily done using a fragment shader these days. And in the days before OpenGL-3 I'd do this using a polygon stipple (like I did in my interlaced 3D TV patch I got included into mplayer). This saves you the struggle with getting your geometry at the right position.

In the shader you can select between the two source images on a per pixel basis, using the gl_FragCoord viewport pixel coordinate as conditional. Or you draw two passes and discard fragments of either line/column.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top