Port stereo stuff from tuhopuu2: anaglyph, vinterlace

This commit is contained in:
Kester Maddock 2004-10-24 11:03:18 +00:00
parent 6424bf6eb0
commit 657eff7ed7
8 changed files with 190 additions and 13 deletions

@ -841,13 +841,13 @@ static uiBlock *post_render_menu(void *arg_unused)
static uiBlock *framing_render_menu(void *arg_unused)
{
uiBlock *block;
short yco = 170, xco = 0;
short yco = 190, xco = 0;
int randomcolorindex = 1234;
block= uiNewBlock(&curarea->uiblocks, "framing_options", UI_EMBOSS, UI_HELV, curarea->win);
/* use this for a fake extra empy space around the buttons */
uiDefBut(block, LABEL, 0, "", -10, -10, 300, 209, NULL, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "", -10, -10, 300, 229, NULL, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, B_NOP, "Framing:", xco, yco, 68,19, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
@ -886,12 +886,18 @@ static uiBlock *framing_render_menu(void *arg_unused)
* RAS_STEREO_QUADBUFFERED 2
* RAS_STEREO_ABOVEBELOW 3
* RAS_STEREO_INTERLACED 4 future
* RAS_STEREO_ANAGLYPH 5
* RAS_STEREO_SIDEBYSIDE 6
* RAS_STEREO_VINTERLACE 7
*/
uiDefBut(block, LABEL, 0, "Stereo:", xco, yco-=30, 68, 19, 0, 0.0, 0.0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButS(block, ROW, 0, "None", xco+=70, yco, 68, 19, &(G.scene->r.stereomode), 6.0, 1.0, 0, 0, "Disables stereo");
uiDefButS(block, ROW, 0, "Pageflip", xco+=70, yco, 68, 19, &(G.scene->r.stereomode), 6.0, 2.0, 0, 0, "Enables hardware pageflip stereo method");
uiDefButS(block, ROW, 0, "Syncdouble", xco+=70, yco, 68, 19, &(G.scene->r.stereomode), 6.0, 3.0, 0, 0, "Enables syncdoubling stereo method");
uiDefButS(block, ROW, 0, "No Stereo", xco, yco-=30, 88, 19, &(G.scene->r.stereomode), 7.0, 1.0, 0, 0, "Disables stereo");
uiDefButS(block, ROW, 0, "Pageflip", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 2.0, 0, 0, "Enables hardware pageflip stereo method");
uiDefButS(block, ROW, 0, "Syncdouble", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 3.0, 0, 0, "Enables syncdoubling stereo method");
uiDefButS(block, ROW, 0, "Anaglyph", xco-=180, yco-=21, 88, 19, &(G.scene->r.stereomode), 7.0, 5.0, 0, 0, "Enables anaglyph (Red-Blue) stereo method");
uiDefButS(block, ROW, 0, "Side by Side", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 6.0, 0, 0, "Enables side by side left and right images");
uiDefButS(block, ROW, 0, "V Interlace", xco+=90, yco, 88, 19, &(G.scene->r.stereomode), 7.0, 7.0, 0, 0, "Enables interlaced vertical strips for autostereo display");
uiBlockEndAlign(block);
uiBlockSetDirection(block, UI_TOP);

@ -124,6 +124,7 @@ void usage(char* program)
printf(" syncdoubling (Above Below)\n");
printf(" sidebyside (Left Right)\n");
printf(" anaglyph (Red-Blue glasses)\n");
printf(" vinterlace (Vertical interlace for autostereo display)\n");
printf(" depending on the type of stereo you want\n");
#ifdef _WIN32
printf(" -c: keep console window open\n");
@ -379,6 +380,10 @@ int main(int argc, char** argv)
i++;
if ((i + 1) < argc)
{
stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
if(!strcmp(argv[i], "nostereo")) // ok, redundant but clear
stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
@ -395,6 +400,10 @@ int main(int argc, char** argv)
if(!strcmp(argv[i], "sidebyside"))
stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;
if(!strcmp(argv[i], "vinterlace"))
stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;
#if 0
// future stuff
if(strcmp(argv[i], "stencil")

@ -341,7 +341,51 @@ static PyObject* gPySetMousePosition(PyObject*,
Py_Return;
}
static PyObject* gPySetEyeSeparation(PyObject*,
PyObject* args,
PyObject*)
{
float sep;
if (PyArg_ParseTuple(args, "f", &sep))
{
if (gp_Rasterizer)
gp_Rasterizer->SetEyeSeparation(sep);
Py_Return;
}
return NULL;
}
static PyObject* gPyGetEyeSeparation(PyObject*, PyObject*, PyObject*)
{
if (gp_Rasterizer)
return PyFloat_FromDouble(gp_Rasterizer->GetEyeSeparation());
return NULL;
}
static PyObject* gPySetFocalLength(PyObject*,
PyObject* args,
PyObject*)
{
float focus;
if (PyArg_ParseTuple(args, "f", &focus))
{
if (gp_Rasterizer)
gp_Rasterizer->SetFocalLength(focus);
Py_Return;
}
return NULL;
}
static PyObject* gPyGetFocalLength(PyObject*, PyObject*, PyObject*)
{
if (gp_Rasterizer)
return PyFloat_FromDouble(gp_Rasterizer->GetFocalLength());
return NULL;
}
static PyObject* gPySetBackgroundColor(PyObject*,
PyObject* args,
@ -461,6 +505,10 @@ static struct PyMethodDef rasterizer_methods[] = {
{"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
{"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
{"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"},
{"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_VARARGS, "get the eye separation for stereo mode"},
{"setFocalLength", (PyCFunction) gPySetFocalLength, METH_VARARGS, "set the focal length for stereo mode"},
{"getFocalLength", (PyCFunction) gPyGetFocalLength, METH_VARARGS, "get the focal length for stereo mode"},
{ NULL, (PyCFunction) NULL, 0, NULL }
};

@ -56,6 +56,15 @@ def makeScreenshot(filename):
"""
Writes a screenshot to the given filename.
If filename starts with // the image will be saved relative to the current directory.
If the filename contains # it will be replaced with the frame number.
The standalone player saves .png files. It does not support colour space conversion
or gamma correction.
When run from Blender, makeScreenshot supports Iris, IrisZ, TGA, Raw TGA, PNG, HamX, and Jpeg.
Gamma, Colourspace conversion and Jpeg compression are taken from the Render settings panels.
@type filename: string
"""
@ -106,4 +115,42 @@ def setMistEnd(end):
@type end: float
"""
def setEyeSeparation(eyesep):
"""
Sets the eye separation for stereo mode.
@param eyesep: The distance between the left and right eye.
If eyesep < 0.0, eye separation will be automatically determined from the projection
matrix.
@type eyesep: float
"""
def getEyeSeparation():
"""
Gets the current eye separation for stereo mode.
If the returned eye separation is < 0.0, the eye separation will be
automatically set on the next frame.
@rtype: float
"""
def setFocalLength(focallength):
"""
Sets the focal length for stereo mode.
@param focallength: The focal length. If focallength < 0.0, the focal length will
be automatically determined.
@type focallength: float
"""
def getFocalLength():
"""
Gets the current focal length for stereo mode.
If the returned focal length is < 0.0, the focal length will be
automatically set on the next frame.
@rtype: float
"""

@ -8,6 +8,8 @@ This document lists what has been changed in the Game Engine Python API.
Blender CVS
------------
- Added tic rate methods to L{GameLogic}
- Added stereo eye separation and focal length methods to L{Rasterizer}.
- Fixed L{Raterizer}.makeScreenshot() method.
Blender 2.34
------------

@ -93,7 +93,10 @@ public:
RAS_STEREO_ABOVEBELOW,
RAS_STEREO_INTERLACED,
RAS_STEREO_ANAGLYPH,
RAS_STEREO_SIDEBYSIDE
RAS_STEREO_SIDEBYSIDE,
RAS_STEREO_VINTERLACE,
RAS_STEREO_MAXSTEREO
};
/**
* Render pass identifiers for stereo.
@ -157,12 +160,17 @@ public:
* Sets which eye buffer subsequent primitives will be rendered to.
*/
virtual void SetEye(const StereoEye eye)=0;
virtual StereoEye GetEye()=0;
/**
* Sets the distance between eyes for stereo mode.
*/
virtual void SetEyeSeparation(const float eyeseparation)=0;
virtual float GetEyeSeparation() = 0;
/**
* Sets the focal length for stereo mode.
*/
virtual void SetFocalLength(const float focallength)=0;
virtual float GetFocalLength() = 0;
/**
* SwapBuffers swaps the back buffer with the front buffer.
*/

@ -58,6 +58,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_time(0.0),
m_stereomode(RAS_STEREO_NOSTEREO),
m_curreye(RAS_STEREO_LEFTEYE),
m_eyeseparation(-1.0f),
m_focallength(-1.0f),
m_noOfScanlines(32),
m_materialCachingInfo(0)
{
@ -265,7 +267,9 @@ void RAS_OpenGLRasterizer::Exit()
glDepthMask (GL_TRUE);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_POLYGON_STIPPLE);
glDisable(GL_LIGHTING);
if (bgl::QueryExtension(bgl::_GL_EXT_separate_specular_color) || bgl::QueryVersion(1, 2))
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
@ -273,15 +277,21 @@ void RAS_OpenGLRasterizer::Exit()
EndFrame();
}
bool RAS_OpenGLRasterizer::InterlacedStereo() const
{
return m_stereomode == RAS_STEREO_VINTERLACE || m_stereomode == RAS_STEREO_INTERLACED;
}
bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
{
m_time = time;
m_drawingmode = drawingmode;
m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
if (!InterlacedStereo() || m_curreye == RAS_STEREO_LEFTEYE)
{
m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
}
// Blender camera routine destroys the settings
if (m_drawingmode < KX_SOLID)
@ -459,23 +469,63 @@ void RAS_OpenGLRasterizer::SetEye(StereoEye eye)
ClearDepthBuffer();
}
break;
case RAS_STEREO_VINTERLACE:
{
GLuint pat[32];
const unsigned char mask = 0x55; // 01010101
memset(pat, m_curreye == RAS_STEREO_RIGHTEYE?~mask:mask, sizeof(pat));
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple((const GLubyte*) pat);
if (m_curreye == RAS_STEREO_RIGHTEYE)
ClearDepthBuffer();
break;
}
case RAS_STEREO_INTERLACED:
{
GLuint pat[32];
GLuint mask = m_curreye == RAS_STEREO_LEFTEYE?~0:0;
for (int y = 0; y < 32; y+=2)
{
pat[y] = mask;
pat[y+1] = ~mask;
}
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple((const GLubyte*) pat);
if (m_curreye == RAS_STEREO_RIGHTEYE)
ClearDepthBuffer();
break;
}
default:
break;
}
}
RAS_IRasterizer::StereoEye RAS_OpenGLRasterizer::GetEye()
{
return m_curreye;
}
void RAS_OpenGLRasterizer::SetEyeSeparation(float eyeseparation)
{
m_eyeseparation = eyeseparation;
}
float RAS_OpenGLRasterizer::GetEyeSeparation()
{
return m_eyeseparation;
}
void RAS_OpenGLRasterizer::SetFocalLength(float focallength)
{
m_focallength = focallength;
}
float RAS_OpenGLRasterizer::GetFocalLength()
{
return m_focallength;
}
void RAS_OpenGLRasterizer::SwapBuffers()
{
@ -1109,8 +1159,10 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
{
float near_div_focallength;
// next 2 params should be specified on command line and in Blender publisher
m_focallength = 1.5 * right; // derived from example
m_eyeseparation = 0.18 * right; // just a guess...
if (m_focallength < 0.0f)
m_focallength = 1.5 * right; // derived from example
if (m_eyeseparation < 0.0f)
m_eyeseparation = 0.18 * right; // just a guess...
near_div_focallength = frustnear / m_focallength;
switch(m_curreye)

@ -74,6 +74,8 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
float m_eyeseparation;
float m_focallength;
int m_noOfScanlines;
bool InterlacedStereo() const;
protected:
int m_drawingmode;
@ -113,8 +115,11 @@ public:
virtual void SetStereoMode(const StereoMode stereomode);
virtual bool Stereo();
virtual void SetEye(const StereoEye eye);
virtual StereoEye GetEye();
virtual void SetEyeSeparation(const float eyeseparation);
virtual float GetEyeSeparation();
virtual void SetFocalLength(const float focallength);
virtual float GetFocalLength();
virtual void SwapBuffers();
virtual void IndexPrimitives(