Anybody used "side by side" 3DStereo + OpenGL for HMD ?
I want to know a problem with new devices.
Like:
// Clear both back buffers
glDrawBuffer (GL_BACK);
glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT);
// Draw left eye view
glDrawBuffer (GL_BACK_LEFT);
glColor3b (0, 0, 127); // blue
glRectf (-0.8f, -0.8f, 0.2f, 0.2f);
// Draw right eye view
glColor3b (127, 0, 0); // red
glRectf (-0.2f, -0.2f, 0.8f, 0.8f);
// Put what was just drawn onto the display
BOOL bSuccess = wglSwapLayerBuffers (pCDC->m_hDC, WGL_SWAP_MAIN_PLANE);
As the above code example shows, you can still use glDrawBuffer(GL_BACK) to draw to both left and right back-buffers at once. Also note that you can use glDrawBuffer() to access the left and right front-buffers directly (GL_FRONT_LEFT and GL_FRONT_RIGHT).
Hi Vladimir,
what exactly is the problem you can see?
And what are the new devices :)? If you mean shutter glasses from NVIDIA, you can read quite a lot on the topic here: http://developer.nvidia.com/object/3d_stereo_dev.html
If it is some other kind of head mounted display, but if it is single widescreen area, and you need to draw two scenes side by side with camera shifted for each eye, I think it would be enough to:
- split screen to 2 areas using glViewport
- render the scene to left viewport with appropriately shifted camera
- render the scene to right viewport with appropriately shifted camera
- swap buffers classic way
I have read that quad-buffer stereo is not implemented fully on all cards, could that be root of your problem?
Did you tried your code with explicitly specifying both glDrawBuffer(GL_BACK_LEFT) and glDrawBuffer(GL_BACK_RIGHT)? There are some more sample codes using this approach on the web, such as:
http://www.tav.net/3d/3d_stereo.htm
http://www.orthostereo.com/geometryopengl.html
http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/stereographics/stereorender/
Petr
Hi Petr,
Quote from: Petr Schreiber on December 12, 2010, 10:10:40 AM
what exactly is the problem you can see?
And what are the new devices :)? If you mean shutter glasses from NVIDIA, you can read quite a lot on the topic here: http://developer.nvidia.com/object/3d_stereo_dev.html
I have read that quad-buffer stereo is not implemented fully on all cards, could that be root of your problem?
Did you tried your code with explicitly specifying both glDrawBuffer(GL_BACK_LEFT) and glDrawBuffer(GL_BACK_RIGHT)?
Idea, which I want to solve - is:
I have 3D-stereo 360 degree video stream, stereo format of video is "side by side" (from Pano-Pro lens).
I want to send this 3D-360 degree video stream to HMD (Head-mounted display).
I want to divide main frame of video: the left part to left HMD eye, the right part to right HMD eye... like shown "side by side" still image for HMD
(the second idea, - to add Trackir for HMD)
I tested the "headplay" HMD and have problem:
the "headplay" HMD not have SDK, developers of the "headplay" - say: "you need to change signal at Pin #12 in VGA socket"...
I tested some solution with glDrawBuffer(GL_BACK_RIGHT) - did try to show image only at right HMD eye, but no any good result (tested with ATI adapter)
I will see your links, but if you have some small example, then please show it for test.
Thank you,
--Vlad
Hi Vladimir,
so you don't need to render 3D scenes from code, you have ready set of prerendered images which you just need to plot on the screen?
How does the HMD behave - is it like single screen for both eyes separated by some physical obstacle so each eyes sees just its part? Or does it have 2 independent displays inside?
In case there are 2 separated displays, my previous advice won't be of any value, and you have to go for the OpenGL stereo. That would mean something like the following:
#1 Initialization
Make sure you request stereo pixel format:
DIM pfd AS PixelFormatDescriptor
...
pfd.dwFlags = %PFD_STEREO OR %PFD_DRAW_TO_WINDOW OR %PFD_SUPPORT_OPENGL OR %PFD_DOUBLEBUFFER
...
#2 Rendering
Explicitly specify when you draw for left and when for the right eye.
glDrawBuffer(%GL_BACK_LEFT)
glClear(%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)
' Set up Left View Frustum Here
' Draw quad with left image from video
glDrawBuffer(%GL_BACK_RIGHT)
glClear(%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)
' Set up Right View Frustum Here
' Draw quad with right image from video
wglSwapBuffers(hDC)
Petr
Hi Petr,
Quote from: Petr Schreiber on December 12, 2010, 12:14:43 PM
so you don't need to render 3D scenes from code, you have ready set of prerendered images which you just need to plot on the screen?
Yes
Quote from: Petr Schreiber on December 12, 2010, 12:14:43 PM
How does the HMD behave - is it like single screen for both eyes separated by some physical obstacle so each eyes sees just its part? Or does it have 2 independent displays inside?
It does have 2 independent displays. This is link for headplay HMD visor http://www.headplay.com/the-visor.html (http://www.headplay.com/the-visor.html)
Quote from: Petr Schreiber on December 12, 2010, 12:14:43 PM
In case there are 2 separated displays, my previous advice won't be of any value, and you have to go for the OpenGL stereo. That would mean something like the following:
#1 Initialization
Make sure you request stereo pixel format:
DIM pfd AS PixelFormatDescriptor
...
pfd.dwFlags = %PFD_STEREO OR %PFD_DRAW_TO_WINDOW OR %PFD_SUPPORT_OPENGL OR %PFD_DOUBLEBUFFER
...
#2 Rendering
Explicitly specify when you draw for left and when for the right eye.
glDrawBuffer(%GL_BACK_LEFT)
glClear(%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)
' Set up Left View Frustum Here
' Draw quad with left image from video
glDrawBuffer(%GL_BACK_RIGHT)
glClear(%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)
' Set up Right View Frustum Here
' Draw quad with right image from video
wglSwapBuffers(hDC)
Yes, I tested the example some like your example, but seem's the problem in my exmaple - with wglSwapBuffers(hDC)
--Vlad
Quote from: Petr Schreiber on December 12, 2010, 12:14:43 PM
In case there are 2 separated displays, my previous advice won't be of any value, and you have to go for the OpenGL stereo. That would mean something like the following:
#1 Initialization
Make sure you request stereo pixel format:
DIM pfd AS PixelFormatDescriptor
...
pfd.dwFlags = %PFD_STEREO OR %PFD_DRAW_TO_WINDOW OR %PFD_SUPPORT_OPENGL OR %PFD_DOUBLEBUFFER
...
this is simple "dirty" example from José code: http://www.jose.it-berater.org/smfforum/index.php?topic=2362.0 (http://www.jose.it-berater.org/smfforum/index.php?topic=2362.0)
for testing HMD. But this example cannot work Ok with 2 separated displays (for me)
' =======================================================================================
' The program opens a window (640x480), and renders a spinning colored triangle (it is
' controlled with both the TIMER function and the mouse). It also calculates the
' rendering speed (FPS), which is displayed in the window title bar.
' =======================================================================================
' SED_PBWIN - Use the PBWIN compiler
#COMPILE EXE
#DIM ALL
#INCLUDE "GLU.INC"
$WindowCaption = "Spinning Triangle"
%GL_WINDOWWIDTH = 640 ' Window width
%GL_WINDOWHEIGHT = 480 ' Window height
%GL_BITSPERPEL = 16 ' Color resolution in bits per pixel
%GL_DEPTHBITS = 16 ' Depth of the depth (z-axis) buffer
GLOBAL hDC AS LONG ' Device context handle
' =======================================================================================
' All the setup goes here
' =======================================================================================
SUB SetupScene (BYVAL hwnd AS DWORD, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG)
' Specify clear values for the color buffers
glClearColor 0.0!, 0.0!, 0.0!, 0.0!
glEnable(%GL_STEREO)
glDrawBuffer (%GL_BACK)
glClearColor(0.2, 0.2, 0.2, 0.0)'';
glClear (%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)'';
'' Draw left eye view
glDrawBuffer (%GL_BACK_LEFT)
glColor3b (0, 0, 127)''; // blue
glRectf (-0.8, -0.8, 0.2, 0.2)'';
''// Draw right eye view
glDrawBuffer (%GL_BACK_RIGHT)
glColor3b (127, 0, 0)''; // red
glRectf (-0.2, -0.2, 0.8, 0.8)'';
''// Put what was just drawn onto the display
END SUB
' =======================================================================================
' =======================================================================================
' Resize the scene
' =======================================================================================
SUB ResizeScene (BYVAL hwnd AS DWORD, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG)
' Prevent divide by zero making height equal one
IF nHeight = 0 THEN nHeight = 1
' Reset the current viewport
glViewport 0, 0, nWidth, nHeight
' Select the projection matrix
glMatrixMode %GL_PROJECTION
' Reset the projection matrix
glLoadIdentity
' Calculate the aspect ratio of the window
gluPerspective 65.0!, nWidth / nHeight, 1.0!, 100.0!
' Select the model view matrix
glMatrixMode %GL_MODELVIEW
' Reset the model view matrix
glLoadIdentity
END SUB
' =======================================================================================
' =======================================================================================
' Draw the scene
' =======================================================================================
SUB DrawScene (BYVAL hwnd AS DWORD, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG)
LOCAL pt AS POINTAPI
LOCAL t AS DOUBLE
GetCursorPos pt
''t = TIMER
glMatrixMode %GL_MODELVIEW
glDrawBuffer(%GL_BACK_RIGHT)
glClear (%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)'';
glLoadIdentity()
glClearColor(0.5, 0.5, 0.5, 0.0)'';
glMatrixMode %GL_MODELVIEW
glDrawBuffer(%GL_BACK_LEFT)
glClear (%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)'';
glLoadIdentity()
glClearColor(0.1, 0.1, 0.1, 0.0)'';
' Select and setup the modelview matrix
'' glMatrixMode %GL_MODELVIEW
glLoadIdentity
gluLookAt 0.0!, 1.0!, 0.0!, _ ' Eye-position
0.0!, 20.0!, 0.0!, _ ' View-point
0.0!, 0.0!, 1.0! ' Up-vector
' Draw a rotating colorful triangle
glTranslatef 0.0!, 14.0!, 0.0!
glRotatef 0.3! * pt.x + t * 100.0!, 0.0!, 0.0!, 1.0!
glBegin %GL_TRIANGLES
glColor3f 1.0!, 0.0!, 0.0!
glVertex3f -5.0!, 0.0!, -4.0!
glColor3f 0.0!, 1.0!, 0.0!
glVertex3f 5.0!, 0.0!, -4.0!
glColor3f 0.0!, 0.0!, 1.0!
glVertex3f 0.0!, 0.0!, 6.0!
glEnd
END SUB
' =======================================================================================
' =======================================================================================
' Processes keystrokes
' Parameters:
' * hwnd = Window hande
' * vKeyCode = Virtual key code
' * bKeyDown = %TRUE if key is pressed; %FALSE if it is released
' =======================================================================================
SUB ProcessKeystrokes (BYVAL hwnd AS DWORD, BYVAL vKeyCode AS LONG, BYVAL bKeyDown AS LONG)
SELECT CASE AS LONG vKeyCode
CASE %VK_ESCAPE
' Quit if Esc key pressed
SendMessage hwnd, %WM_CLOSE, 0, 0
END SELECT
END SUB
' =======================================================================================
' =======================================================================================
' Main
' =======================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS ASCIIZ PTR, BYVAL nCmdShow AS LONG) AS LONG
LOCAL hwnd AS DWORD
LOCAL wcex AS WNDCLASSEX
LOCAL szClassName AS ASCIIZ * 256
LOCAL szCaption AS ASCIIZ * 256
LOCAL msg AS tagMSG
LOCAL rc AS RECT
LOCAL bDone AS LONG
LOCAL nLeft AS LONG
LOCAL nTop AS LONG
LOCAL nWidth AS LONG
LOCAL nHeight AS LONG
LOCAL dwStyle AS DWORD
LOCAL dwStyleEx AS DWORD
STATIC vKeyCode AS LONG
STATIC bKeyDown AS LONG
LOCAL t AS DOUBLE
LOCAL t0 AS DOUBLE
LOCAL fps AS DOUBLE
LOCAL nFrames AS LONG
LOCAL dm AS DEVMODE
LOCAL bFullScreen AS LONG
LOCAL lResult AS LONG
' Register the window class
szClassName = "PBOPENGL"
wcex.cbSize = SIZEOF(wcex)
wcex.style = %CS_HREDRAW OR %CS_VREDRAW OR %CS_OWNDC
wcex.lpfnWndProc = CODEPTR(WndProc)
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hCursor = LoadCursor (%NULL, BYVAL %IDC_ARROW)
wcex.hbrBackground = %NULL
wcex.lpszMenuName = %NULL
wcex.lpszClassName = VARPTR(szClassName)
wcex.hIcon = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Sample, if resource icon: LoadIcon(hInst, "APPICON")
wcex.hIconSm = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Remember to set small icon too..
RegisterClassEx wcex
' Ask the user which screen mode he prefers
lResult = MessageBox(%NULL, "Would you like to run in fullscreen mode?", _
"Start fullScreen?", %MB_YESNOCANCEL OR %MB_ICONQUESTION)
SELECT CASE lResult
CASE %IDCANCEL : EXIT FUNCTION
CASE %IDYES : bFullScreen = %TRUE
CASE %IDNO : bFullScreen = %FALSE
END SELECT
' Window size
nWidth = %GL_WINDOWWIDTH
nHeight = %GL_WINDOWHEIGHT
IF bFullScreen THEN
' Change display settings
dm.dmSize = SIZEOF(dm)
dm.dmPelsWidth = nWidth
dm.dmPelsHeight = nHeight
dm.dmBitsPerPel = %GL_BITSPERPEL
dm.dmFields = %DM_BITSPERPEL OR %DM_PELSWIDTH OR %DM_PELSHEIGHT
IF ChangeDisplaySettings(dm, %CDS_FULLSCREEN) = 0 THEN ShowCursor %FALSE
END IF
' Window caption
szCaption = $WindowCaption
' Window styles
IF ISFALSE bFullScreen THEN
dwStyle = %WS_OVERLAPPEDWINDOW
dwStyleEx = %WS_EX_APPWINDOW OR %WS_EX_WINDOWEDGE
ELSE
dwStyle = %WS_POPUP
dwStyleEx = %WS_EX_APPWINDOW
END IF
' Create the window
hwnd = CreateWindowEx( _
dwStyleEx, _ ' extended styles
szClassName, _ ' window class name
szCaption, _ ' window caption
dwStyle, _ ' window style
nLeft, _ ' initial x position
nTop, _ ' initial y position
nWidth, _ ' initial x size
nHeight, _ ' initial y size
%NULL, _ ' parent window handle
0, _ ' window menu handle
hInstance, _ ' program instance handle
BYVAL %NULL) ' creation parameters
' Retrieve the coordinates of the window's client area
GetClientRect hwnd, rc
' Initialize the new OpenGl window
SetupScene hwnd, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop
' Show the window
ShowWindow hwnd, nCmdShow
UpdateWindow hwnd
DO UNTIL bDone
' Windows message pump
DO WHILE PeekMessage(msg, %NULL, 0, 0, %PM_REMOVE)
IF msg.message = %WM_QUIT THEN
bDone = %TRUE
ELSE
IF msg.message = %WM_KEYDOWN THEN
vKeyCode = msg.wParam
bKeyDown = %TRUE
ELSEIF msg.message = %WM_KEYUP THEN
vKeyCode = msg.wParam
bKeyDown = %FALSE
END IF
TranslateMessage msg
DispatchMessage msg
END IF
LOOP
IF ISFALSE bFullScreen THEN
' Get time and mouse position
t = INT(TIMER)
' Calculate and display FPS (frames per second)
IF t > t0 OR nFrames = 0 THEN
fps = nFrames \ (t - t0)
wsprintf szCaption, $WindowCaption & " (%i FPS)", BYVAL fps
SetWindowText hwnd, szCaption
t0 = t
nFrames = 0
END IF
nFrames = nFrames + 1
END IF
' Draw the scene
DrawScene hwnd, nWidth, nHeight
' Exchange the front and back buffers
SwapBuffers hDC
' Process the keystrokes
IF vKeyCode THEN
ProcessKeystrokes hwnd, vKeyCode, bKeyDown
vKeyCode = 0
END IF
LOOP
' Retore defaults
IF bFullScreen THEN
ChangeDisplaySettings BYVAL %NULL, 0
ShowCursor %TRUE
END IF
FUNCTION = msg.wParam
END FUNCTION
' =======================================================================================
' =======================================================================================
' Main window procedure
' =======================================================================================
FUNCTION WndProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL pf AS LONG
LOCAL pfd AS PIXELFORMATDESCRIPTOR
STATIC hRC AS LONG
SELECT CASE wMsg
CASE %WM_SYSCOMMAND
' Disable the Windows screensaver
IF (wParam AND &HFFF0) = %SC_SCREENSAVE THEN EXIT FUNCTION
' Close the window
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_CREATE
' Retrieve the device context handle
hDC = GetDC(hwnd)
' Fill the PIXELFORMATDESCRIPTOR structure
pfd.nSize = SIZEOF(PIXELFORMATDESCRIPTOR) ' Size of the structure
pfd.nVersion = 1 ' Version number
pfd.dwFlags = %PFD_DRAW_TO_WINDOW _ ' Format must support window
OR %PFD_SUPPORT_OPENGL _ ' Format must support OpenGL
OR %PFD_DOUBLEBUFFER OR %PFD_STEREO ' Format must support double buffering
pfd.iPixelType = %PFD_TYPE_RGBA ' Request an RGBA format
pfd.cColorBits = %GL_BITSPERPEL ' Number of color bitplanes in each color buffer
pfd.cRedBits = 0 ' Number of red bitplanes in each RGBA color buffer.
pfd.cRedShift = 0 ' Shift count for red bitplanes in each RGBA color buffer.
pfd.cGreenBits = 0 ' Number of green bitplanes in each RGBA color buffer.
pfd.cGreenShift = 0 ' Shift count for green bitplanes in each RGBA color buffer.
pfd.cBlueBits = 0 ' Number of blue bitplanes in each RGBA color buffer.
pfd.cBlueShift = 0 ' Shift count for blue bitplanes in each RGBA color buffer.
pfd.cAlphaBits = 0 ' Number of alpha bitplanes in each RGBA color buffer
pfd.cAlphaShift = 0 ' Shift count for alpha bitplanes in each RGBA color buffer.
pfd.cAccumBits = 0 ' Total number of bitplanes in the accumulation buffer.
pfd.cAccumRedBits = 0 ' Number of red bitplanes in the accumulation buffer.
pfd.cAccumGreenBits = 0 ' Number of gree bitplanes in the accumulation buffer.
pfd.cAccumBlueBits = 0 ' Number of blue bitplanes in the accumulation buffer.
pfd.cAccumAlphaBits = 0 ' Number of alpha bitplanes in the accumulation buffer.
pfd.cDepthBits = %GL_DEPTHBITS ' Depth of the depth (z-axis) buffer.
pfd.cStencilBits = 0 ' Depth of the stencil buffer.
pfd.cAuxBuffers = 0 ' Number of auxiliary buffers.
pfd.iLayerType = %PFD_MAIN_PLANE ' Ignored. Earlier implementations of OpenGL used this member, but it is no longer used.
pfd.bReserved = 0 ' Number of overlay and underlay planes.
pfd.dwLayerMask = 0 ' Ignored. Earlier implementations of OpenGL used this member, but it is no longer used.
pfd.dwVisibleMask = 0 ' Transparent color or index of an underlay plane.
pfd.dwDamageMask = 0 ' Ignored. Earlier implementations of OpenGL used this member, but it is no longer used.
' Find a matching pixel format
pf = ChoosePixelFormat(hDC, pfd)
IF ISFALSE pf THEN
MessageBox hwnd, "Can't find a suitable pixel format", _
"Error", %MB_OK OR %MB_ICONEXCLAMATION
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
' Set the pixel format
IF ISFALSE SetPixelFormat(hDC, pf, pfd) THEN
MessageBox hwnd, "Can't set the pixel format", _
"Error", %MB_OK OR %MB_ICONEXCLAMATION
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
' Create a new OpenGL rendering context
hRC = wglCreateContext(hDC)
IF ISFALSE hRC THEN
MessageBox hwnd, "Can't create an OpenGL rendering context", _
"Error", %MB_OK OR %MB_ICONEXCLAMATION
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
' Make it current
IF ISFALSE wglMakeCurrent(hDC,hRC) THEN
MessageBox hwnd, "Can't activate the OpenGL rendering context", _
"Error", %MB_OK OR %MB_ICONEXCLAMATION
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
EXIT FUNCTION
CASE %WM_DESTROY
' Release the device and rendering contexts
wglMakeCurrent hDC, 0
' Make the rendering context no longer current
wglDeleteContext hRC
' Release the device context
ReleaseDC hwnd, hDC
' Post an WM_QUIT message
PostQuitMessage 0
EXIT FUNCTION
CASE %WM_SIZE
ResizeScene hwnd, LO(WORD, lParam), HI(WORD, lParam)
EXIT FUNCTION
END SELECT
' Call the default window procedure to process unhandled messages
FUNCTION = DefWindowProc(hwnd, wMsg, wParam, lParam)
END FUNCTION
' =======================================================================================
Hi Vladimir,
do you think you could use digital camera and take a photo of what is on the displays?
I am not sure what "does not work" means - is the second screen black, does it lack the triangle, ...?
In any case, the code you did, will draw the triangle just to the left eye, is that what you needed? I think you must specify the scene for each eye completely, here I marked added section:
Quote
SUB DrawScene (BYVAL hwnd AS DWORD, BYVAL nWidth AS LONG, BYVAL nHeight AS LONG)
LOCAL pt AS POINTAPI
LOCAL t AS DOUBLE
GetCursorPos pt
''t = TIMER
glMatrixMode %GL_MODELVIEW
glDrawBuffer(%GL_BACK_RIGHT)
glClear (%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)'';
glLoadIdentity()
glClearColor(0.5, 0.5, 0.5, 0.0)'';
glLoadIdentity
gluLookAt 0.0!, 1.0!, 0.0!, _ ' Eye-position
0.0!, 20.0!, 0.0!, _ ' View-point
0.0!, 0.0!, 1.0! ' Up-vector
' Draw a rotating colorful triangle
glTranslatef 0.0!, 14.0!, 0.0!
glRotatef 0.3! * pt.x + t * 100.0!, 0.0!, 0.0!, 1.0!
glBegin %GL_TRIANGLES
glColor3f 1.0!, 0.0!, 0.0!
glVertex3f -5.0!, 0.0!, -4.0!
glColor3f 0.0!, 1.0!, 0.0!
glVertex3f 5.0!, 0.0!, -4.0!
glColor3f 0.0!, 0.0!, 1.0!
glVertex3f 0.0!, 0.0!, 6.0!
glEnd
glMatrixMode %GL_MODELVIEW
glDrawBuffer(%GL_BACK_LEFT)
glClear (%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT)'';
glLoadIdentity()
glClearColor(0.1, 0.1, 0.1, 0.0)'';
' Select and setup the modelview matrix
'' glMatrixMode %GL_MODELVIEW
glLoadIdentity
gluLookAt 0.0!, 1.0!, 0.0!, _ ' Eye-position
0.0!, 20.0!, 0.0!, _ ' View-point
0.0!, 0.0!, 1.0! ' Up-vector
' Draw a rotating colorful triangle
glTranslatef 0.0!, 14.0!, 0.0!
glRotatef 0.3! * pt.x + t * 100.0!, 0.0!, 0.0!, 1.0!
glBegin %GL_TRIANGLES
glColor3f 1.0!, 0.0!, 0.0!
glVertex3f -5.0!, 0.0!, -4.0!
glColor3f 0.0!, 1.0!, 0.0!
glVertex3f 5.0!, 0.0!, -4.0!
glColor3f 0.0!, 0.0!, 1.0!
glVertex3f 0.0!, 0.0!, 6.0!
glEnd
END SUB
Petr
Quote from: Petr Schreiber on December 12, 2010, 07:42:59 PM
do you think you could use digital camera and take a photo of what is on the displays?
I am not sure what "does not work" means - is the second screen black, does it lack the triangle, ...?
The Problem when: the Left and the Right eye - have the same image...
My example only for test left and right HMD eye (divide the left and the right frame), but Ok.
This is stereo example from OpenGL SDK (it also not working with HMD)
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
void
display(void)
{
glDrawBuffer(GL_BACK_LEFT);
glClearColor(1.0, 0.0, 0.0, 1.0); /* red */
glClear(GL_COLOR_BUFFER_BIT);
glDrawBuffer(GL_BACK_RIGHT);
glClearColor(0.0, 0.0, 1.0, 1.0); /* blue */
glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers();
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_STEREO);
glutCreateWindow("stereo example");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
or
#COMPILE EXE
#DIM ALL
#INCLUDE "GL.INC"
#INCLUDE "GLU.INC"
#INCLUDE "GLUT.INC"
DECLARE SUB glutGameModeString LIB "glut32.dll" ALIAS "glutGameModeString" (GameStr AS ASCIIZ)
DECLARE FUNCTION glutEnterGameMode LIB "glut32.dll" ALIAS "glutEnterGameMode" () AS LONG
DECLARE SUB glutLeaveGameMode LIB "glut32.dll" ALIAS "glutLeaveGameMode" ()
DECLARE FUNCTION glutGameModeGet LIB "glut32.dll" ALIAS "glutGameModeGet" (BYVAL MODE AS LONG) AS LONG
DECLARE SUB glutIgnoreKeyRepeat LIB "glut32.dll" ALIAS "glutIgnoreKeyRepeat" (BYVAL Ignore AS LONG)
%GLUT_GAME_MODE_POSSIBLE = 1
SUB DISPLAYX CDECL()
glDrawBuffer(%GL_BACK_LEFT)
glClearColor(1.0, 0.0, 0.0, 1.0) ''/* red */
glClear(%GL_COLOR_BUFFER_BIT)
glDrawBuffer(%GL_BACK_RIGHT)
glClearColor(0.0, 0.0, 1.0, 1.0) ''/* blue */
glClear(%GL_COLOR_BUFFER_BIT)
glutSwapBuffers()
END SUB
FUNCTION WINMAIN ( _
BYVAL hInstance AS DWORD, _
BYVAL hPrevInst AS DWORD, _
BYVAL lpszCmdLine AS ASCIIZ PTR, _
BYVAL nCmdShow AS LONG ) AS LONG
glutInit(1, " ")
glutInitDisplayMode(%GLUT_DOUBLE OR %GLUT_RGB OR %GLUT_STEREO)
glutGameModeString "1024x768:16"
IF glutGameModeGet(%GLUT_GAME_MODE_POSSIBLE) THEN
glutEnterGameMode
ELSE
glutGameModeString "800x600:16"
IF glutGameModeGet(%GLUT_GAME_MODE_POSSIBLE) THEN
glutEnterGameMode
ELSE
glutGameModeString "640x480:16"
IF glutGameModeGet(%GLUT_GAME_MODE_POSSIBLE) THEN
glutEnterGameMode
ELSE
PostQuitMessage 0
END IF
END IF
END IF
glutCreateWindow("stereo example")
glutDisplayFunc(CODEPTR(displayx))
glutIdleFunc CODEPTR(DisplayX)
glutMainLoop()
END FUNCTION
Vladimir,
I remember both major vendors provided special "Stereo" version of their drivers, so the functionality is not present in the default ones.
If even official samples fail, I am afraid this could be the case of yours...
Again please - does not work equals:
* no image rendered?
* just left image?
* just right image?
* left / right image the same?
Petr
Hi Petr,
Quote from: Petr Schreiber on December 12, 2010, 10:57:39 PM
Vladimir,
I remember both major vendors provided special "Stereo" version of their drivers, so the functionality is not present in the default ones.
If even official samples fail, I am afraid this could be the case of yours...
Again please - does not work equals:
* no image rendered?
* just left image?
* just right image?
* left / right image the same?
Petr
left / right image is the same.
Glut SDK examples is not working
I did see a source of glsp-0.6.0 GL SteereoPlayer (OpenGL based), but it works only with video stream, still images not have a stereo effect.
Or when video stream paused, stereo effect is Off (left / right image is the same).
Quote from: Petr Schreiber on December 12, 2010, 10:57:39 PM
Again please - does not work equals:
* no image rendered?
* just left image?
* just right image?
* left / right image the same?
ABout Glut
the parametr GLUT_STEREO make a finish of the app.
------------------------------------------------------------------------------
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO);
glutCreateWindow("triangle");
------------------------------------------------------------------------------
the app. stopped
This say - that video adapter is not support Stereo... for Glut
----
One mode of GL StereoPlayer works Ok (seem's without Glut)
Vladimir,
I think it will be best to directly contact the manufacturer of the HMD and ask him directly about the behavior, as it seems non-standard.
Petr
Hi Petr
Quote from: Petr Schreiber on December 14, 2010, 02:02:26 PM
I think it will be best to directly contact the manufacturer of the HMD and ask him directly about the behavior, as it seems non-standard.
Yes, I did ask they. They say "You need to change a signal at PIN 12 on the VGA connecting".
Also. I tested the "GL stereo player" and this simple (old) example.
The "GL stereo player" in some mode works Ok
This is dirty OpenGL stereo test (from old StereoSample.c)
The test not works as "StereoTest". The same image at the left eye and at the right eye.
The test uses "left.bmp" and "right.bmp" 24-bit in the current folder.
#COMPILE EXE
#DIM ALL
#INCLUDE "WIN32API.INC"
#INCLUDE "GL.INC"
#INCLUDE "GLU.INC"
#INCLUDE "GLAux.INC"
$leftbmp = "left.bmp"
$rightbmp = "right.bmp"
MACRO XVAL = 0.525731112119133606
MACRO ZVAL = 0.850650808352039932
MACRO MORPH_MIN = 0.25!
MACRO MORPH_MAX = 1.5!
MACRO EYE_OFFSET = 0.08!
MACRO EYE_ADJUST =-0.04!
MACRO PULL_BACK = 2.2!
GLOBAL szAppName AS ASCIIZ*255
GLOBAL szAppTitle AS ASCIIZ *255
GLOBAL hInstMain AS LONG
GLOBAL hAccel AS LONG
GLOBAL hdc AS LONG
GLOBAL hglrc AS LONG
GLOBAL szMessage AS ASCIIZ *2048
GLOBAL szInfo AS ASCIIZ *256
GLOBAL bStereo AS BYTE
GLOBAL bLButtonDown AS LONG
GLOBAL bRButtonDown AS LONG
GLOBAL bRotation AS LONG
GLOBAL nWidth AS LONG
GLOBAL nHeight AS LONG
GLOBAL aspectViewport AS SINGLE
GLOBAL eyeOffset AS SINGLE
GLOBAL eyeAdjust AS SINGLE
GLOBAL ptLast AS POINTL
GLOBAL ptCurrent AS POINTL
GLOBAL uiTimer AS DWORD
GLOBAL angleX AS SINGLE
GLOBAL angleY AS SINGLE
GLOBAL angleZ AS SINGLE
GLOBAL translateZ AS SINGLE
GLOBAL incZ AS SINGLE
GLOBAL factorMorph AS SINGLE
GLOBAL incMorph AS SINGLE
GLOBAL image_1 AS AUX_RGBImageRec PTR
GLOBAL image_2 AS AUX_RGBImageRec PTR
FUNCTION WINMAIN(BYVAL hInstance AS DWORD, _
BYVAL hPrevInstance AS DWORD, _
BYVAL lpCmdLine AS ASCIIZ PTR, _
BYVAL nCmdShow AS LONG ) AS LONG
szAppName = "OpenGL_Stereo_Test":
szAppTitle = "OpenGL Stereo Test":
bRotation = %TRUE
aspectViewport = 1.0!:
eyeOffset = EYE_OFFSET
eyeAdjust = EYE_ADJUST
incZ = 0.005!
factorMorph = 1.0
incMorph = 0.015!
DIM vIco(0:11,0:2) AS GLOBAL SINGLE
ARRAY ASSIGN vIco() = _
-XVAL, 0.0!, ZVAL ,_
XVAL, 0.0!, ZVAL ,_
-XVAL, 0.0!, -ZVAL ,_
XVAL, 0.0!, -ZVAL ,_
0.0!, ZVAL, XVAL ,_
0.0!, ZVAL, -XVAL ,_
0.0!, -ZVAL, XVAL ,_
0.0!, -ZVAL, -XVAL ,_
ZVAL, XVAL, 0.0! ,_
-ZVAL, XVAL, 0.0! ,_
ZVAL, -XVAL, 0.0! ,_
-ZVAL, -XVAL, 0.0!
DIM idxIco(0:19,0:2) AS GLOBAL LONG
ARRAY ASSIGN idxIco() = _
0, 1, 4 ,_'' 0
0, 4, 9 ,_'' 1
0, 9, 11 ,_'' 2
0, 6, 1 ,_'' 3
0, 11, 6 ,_'' 4
1, 6, 10 ,_'' 5
1, 10, 8 ,_'' 6
1, 8, 4 ,_'' 7
2, 3, 7 ,_'' 8
2, 5, 3 ,_'' 9
2, 9, 5 ,_'' 10
2, 11, 9 ,_'' 11
2, 7, 11 ,_'' 12
3, 5, 8 ,_'' 13
3, 8, 10 ,_'' 14
3, 10, 7 ,_'' 15
4, 5, 9 ,_'' 16
4, 8, 5 ,_'' 17
6, 7, 10 ,_'' 18
6, 11, 7 '' 19
DIM vDode(0:19,0:2) AS GLOBAL SINGLE
DIM idxDode(0:11,0:4) AS GLOBAL LONG
ARRAY ASSIGN idxDode() = _
0, 1, 2, 4, 3 ,_'' 0
0, 3, 5, 6, 7 ,_'' 1
9, 8, 12, 11, 10 ,_'' 2
9, 13, 14, 15, 8 ,_'' 3
0, 7, 17, 16, 1 ,_'' 4
9, 10, 16, 17, 13 ,_'' 5
18, 5, 3, 4, 19 ,_'' 6
15, 18, 19, 12, 8 ,_'' 7
6, 14, 13, 17, 7 ,_'' 8
1, 16, 10, 11, 2 ,_'' 9
5, 18, 15, 14, 6 ,_'' 10
2, 11, 12, 19, 4 '' 11
LOCAL msg AS tagMSG
IF (hPrevInstance = 0) THEN
IF InitApplication(hInstance) = 0 THEN
EXIT FUNCTION
END IF
END IF
IF InitInstance(hInstance, nCmdShow) = 0 THEN
EXIT FUNCTION
END IF
WHILE GetMessage(Msg, %NULL, 0, 0)
TranslateMessage Msg
DispatchMessage Msg
WEND
FUNCTION = msg.wParam
END FUNCTION
'__________________________________________________________________________
'
FUNCTION InitApplication(BYVAL hInstance AS LONG) AS LONG
LOCAL wc AS WNDCLASS
wc.style = %CS_HREDRAW OR %CS_VREDRAW:
wc.lpfnWndProc = CODEPTR(WndProc):
wc.cbClsExtra = 0:
wc.cbWndExtra = 0:
wc.hInstance = hInstance:
wc.hIcon = %NULL:
wc.hCursor = LoadCursor(%NULL, BYVAL %IDC_ARROW):
wc.hbrBackground = %NULL
wc.lpszMenuName = %NULL
wc.lpszClassName = VARPTR(szAppName):
FUNCTION = RegisterClass(wc):
END FUNCTION
'____________________________________________________________________________
'
FUNCTION InitInstance(BYVAL hInstance AS LONG,BYVAL nCmdShow AS LONG) AS LONG
LOCAL hwnd AS LONG
hInstMain = hInstance
hwnd = CreateWindow(szAppName,_
szAppTitle,_
%WS_OVERLAPPEDWINDOW OR %WS_CLIPCHILDREN OR %WS_CLIPSIBLINGS,_
%CW_USEDEFAULT,_
%CW_USEDEFAULT,_
%CW_USEDEFAULT,_
%CW_USEDEFAULT,_
%NULL,_
%NULL,_
hInstance,_
%NULL)
IF hwnd = 0 THEN
FUNCTION = %FALSE: EXIT FUNCTION
END IF
ShowWindow(hwnd, nCmdShow):
UpdateWindow(hwnd):
FUNCTION = %TRUE
END FUNCTION
'______________________________________________________________________
'
FUNCTION WndProc (BYVAL hwnd AS DWORD, BYVAL uMessage AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL pfd AS PIXELFORMATDESCRIPTOR
LOCAL iPixelFormat AS LONG
LOCAL offset AS LONG
SELECT CASE uMessage
CASE %WM_CREATE:
hdc = GetDC(hwnd):
pfd.nSize = SIZEOF(PIXELFORMATDESCRIPTOR):
pfd.nVersion = 1:
pfd.dwFlags = %PFD_DRAW_TO_WINDOW OR %PFD_SUPPORT_OPENGL OR %PFD_DOUBLEBUFFER OR %PFD_STEREO:
pfd.iPixelType = %PFD_TYPE_RGBA:
pfd.cColorBits = 24:
pfd.cRedBits = 0:
pfd.cRedShift = 0:
pfd.cGreenBits = 0:
pfd.cGreenShift = 0:
pfd.cBlueBits = 0:
pfd.cBlueShift = 0:
pfd.cAlphaBits = 0:
pfd.cAlphaShift = 0:
pfd.cAccumBits = 0:
pfd.cAccumRedBits = 0:
pfd.cAccumGreenBits = 0:
pfd.cAccumBlueBits = 0:
pfd.cAccumAlphaBits = 0:
pfd.cDepthBits = 24:
pfd.cStencilBits = 0:
pfd.cAuxBuffers = 0:
pfd.iLayerType = %PFD_MAIN_PLANE:
pfd.bReserved = 0:
pfd.dwLayerMask = 0:
pfd.dwVisibleMask = 0:
pfd.dwDamageMask = 0:
iPixelFormat = ChoosePixelFormat(hDC, pfd)
IF iPixelFormat <> 0 THEN
IF SetPixelFormat(hdc, iPixelFormat, pfd) THEN
hglrc = wglCreateContext(hdc)
IF (hglrc <> %NULL) THEN
IF wglMakeCurrent(hdc, hglrc) THEN
LOCAL a1 AS ASCIIZ PTR *255
LOCAL a2 AS ASCIIZ PTR *255
LOCAL a3 AS ASCIIZ PTR *255
LOCAL a4 AS STRING PTR *255
a1 = glGetString(%GL_VENDOR)
a2 = glGetString(%GL_RENDERER)
a3 = glGetString(%GL_VERSION)
a4 = glGetString(%GL_EXTENSIONS)
szMessage = "Current OpenGL Driver:n" & TRIM$(@a1) & $CR & TRIM$(@a2) & $CR & TRIM$(@a3) & $CR & TRIM$(@a4) & $CRLF
glGetBooleanv(%GL_STEREO, bStereo):
IF bStereo = 0 THEN
szMessage = szMessage & $CRLF & "%GL_STEREO = %GL_FALSE" & $CRLF
ELSE
szMessage = szMessage & $CRLF & "%GL_STEREO = %GL_TRUE" & $CRLF
END IF
szMessage = szMessage & $CRLF & "- Change stereo settings using mouse-buttons"
szMessage = szMessage & $CRLF & "- Halt motion using space-bar" & $CRLF
MessageBox(GetFocus(), szMessage, szAppTitle, %MB_SYSTEMMODAL OR %MB_OK OR %MB_ICONEXCLAMATION):
glClearColor(0.3!, 0.3!, 0.3!, 0.3!):
LightCreate():
Icosahedron():
MaterialCreate():
glEnable(%GL_DEPTH_TEST):
glDepthFunc(%GL_LESS):
glEnable(%GL_CULL_FACE):
glShadeModel(%GL_FLAT):
InitDodecahedron():
LOCAL x_name1 AS ASCIIZ *255
LOCAL x_name2 AS ASCIIZ *255
x_name1 = $leftbmp ''"left.bmp"
x_name2 = $rightbmp ''"right.bmp
image_1 = auxDIBImageLoad(x_name1):
IMAGE_2 = auxDIBImageLoad(x_name2):
ELSE
szMessage = "wglMakeCurrent returned FALSE." & $CRLF& "GetlastError() = " & STR$(GetLastError())
MessageBox(GetFocus(), szMessage, szAppTitle, %MB_SYSTEMMODAL OR %MB_OK OR %MB_ICONSTOP):
END IF
ELSE
szMessage = "wglCreateContext returned NULL." & $CRLF& "GetlastError() = " & STR$(GetLastError())
MessageBox(GetFocus(), szMessage, szAppTitle, %MB_SYSTEMMODAL OR %MB_OK OR %MB_ICONSTOP):
END IF
ELSE
szMessage = "SetPixelFormat returned FALSE." & $CRLF& "GetlastError() = " & STR$(GetLastError())
MessageBox(GetFocus(), szMessage, szAppTitle, %MB_SYSTEMMODAL OR %MB_OK OR %MB_ICONSTOP):
END IF
ELSE
szMessage = "ChoosePixelFormat returned 0. " & $CRLF& "GetlastError() = " & STR$(GetLastError())
MessageBox(GetFocus(), szMessage, szAppTitle, %MB_SYSTEMMODAL OR %MB_OK OR %MB_ICONSTOP)
END IF
uiTimer = SetTimer(hwnd, 1, 40, %NULL):
FUNCTION = 0: EXIT FUNCTION
CASE %WM_TIMER:
IF (bRotation) THEN
angleX += 0.6!: IF (angleX > 360.0!) THEN angleX -= 360.0!:
angleY += 1.0!: IF (angleY > 360.0!) THEN angleY -= 360.0!:
angleZ += 0.4!: IF (angleZ > 360.0!) THEN angleZ -= 360.0!:
translateZ += incZ:
IF (translateZ > 0.5!) THEN
translateZ = 0.5!:
incZ = -incZ:
ELSEIF (translateZ < -0.5!) THEN
translateZ = -0.5!:
incZ = -incZ:
END IF
factorMorph += incMorph:
IF (factorMorph > MORPH_MAX) THEN
factorMorph = MORPH_MAX:
incMorph = -incMorph:
ELSEIF (factorMorph < MORPH_MIN) THEN
factorMorph = MORPH_MIN:
incMorph = -incMorph:
END IF
END IF
InvalidateRect(hwnd, BYVAL %NULL, %FALSE):
FUNCTION = 0: EXIT FUNCTION
CASE %WM_ERASEBKGND:
FUNCTION = 1:EXIT FUNCTION
CASE %WM_SIZE:
nWidth = LOWRD(lParam):
nHeight = HIWRD(lParam):
glViewport(0, 0, nWidth, nHeight):
IF (nHeight > 0) THEN
aspectViewport = nWidth / nHeight:
ELSE
aspectViewport = 1.0!:
END IF
FUNCTION = 0: EXIT FUNCTION
CASE %WM_PAINT:
CALL DISPLAYX():
SwapBuffers(hdc):
ValidateRect(hwnd, BYVAL %NULL):
FUNCTION = 0: EXIT FUNCTION
CASE %WM_LBUTTONDOWN:
bLButtonDown = %TRUE:
ptLast.x = lParam AND &hFFFF:
ptLast.y = lParam * 65536
SetCapture(hwnd):
FUNCTION = 0: EXIT FUNCTION
CASE %WM_RBUTTONDOWN:
bRButtonDown = %TRUE:
ptLast.x = lParam AND &hFFFF
ptLast.y = lParam * 65536
SetCapture(hwnd):
FUNCTION = 0: EXIT FUNCTION
CASE %WM_LBUTTONUP:
bLButtonDown = %FALSE:
ReleaseCapture():
FUNCTION = 0: EXIT FUNCTION
CASE %WM_RBUTTONUP:
bRButtonDown = %FALSE:
ReleaseCapture():
FUNCTION = 0: EXIT FUNCTION
CASE %WM_MOUSEMOVE:
IF (bLButtonDown) THEN
ptCurrent.x = lParam AND &hFFFF
ptCurrent.y = lParam * 65536
offset = ptCurrent.x - ptLast.x:
IF (nWidth > 0) THEN
eyeOffset += 0.1! * offset / nWidth:
IF (eyeOffset < 0.0!) THEN eyeOffset = 0.0!:
IF (eyeOffset > EYE_OFFSET * 4) THEN eyeOffset = EYE_OFFSET * 4:
END IF
ptLast = ptCurrent:
InvalidateRect(hwnd, BYVAL %NULL, %FALSE):
ELSEIF (bRButtonDown) THEN
ptCurrent.x = lParam AND &hFFFF:
ptCurrent.y = lParam * 65536
offset = ptCurrent.x - ptLast.x:
IF (nWidth > 0) THEN
eyeAdjust += 0.02! * offset / nWidth:
IF (eyeAdjust > 0.0!) THEN eyeAdjust = 0.0!:
IF (eyeAdjust < EYE_ADJUST * 2) THEN eyeAdjust = EYE_ADJUST * 2:
END IF
ptLast = ptCurrent:
InvalidateRect(hwnd, BYVAL %NULL, %FALSE):
END IF
FUNCTION = 0: EXIT FUNCTION
CASE %WM_COMMAND:
LOCAL COMAND AS LONG
COMAND = LOWRD(wParam):
IF (COMAND = %IDCANCEL) THEN
PostMessage(hwnd, %WM_DESTROY, 0, 0):
ELSE
CommandHandler(hwnd, COMAND):
END IF
InvalidateRect(hwnd, BYVAL %NULL, %FALSE):
FUNCTION = 0: EXIT FUNCTION
CASE %WM_DESTROY: ''
IF (hglrc <> %NULL) THEN
IF (hdc <> %NULL) THEN
glDeleteLists(1, 1):
wglMakeCurrent(hdc, %NULL):
ReleaseDC(hwnd, hdc):
END IF
wglDeleteContext(hglrc):
END IF
PostQuitMessage(0):
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, uMessage, wParam, lParam)
END FUNCTION
SUB TRACEX(a AS STRING)
EXIT SUB
OPEN "debug.txt" FOR APPEND AS 1
PRINT# 1, a
CLOSE 1
END SUB
'____________________________________________________________________________________
'
'' Main drawing routine.
'' Contains the code for both eyes.
SUB DISPLAYX()
LOCAL frustumAdjust AS SINGLE
frustumAdjust = eyeAdjust * eyeOffset / EYE_OFFSET:
glDrawBuffer(%GL_BACK):
glClear (%GL_COLOR_BUFFER_BIT OR %GL_DEPTH_BUFFER_BIT):
glDrawBuffer(%GL_BACK_LEFT):
TRACEX "1"
'' Setup the projection for the left eye
glMatrixMode(%GL_PROJECTION):
glLoadIdentity():
glFrustum(-aspectViewport * 0.75 - frustumAdjust,_
aspectViewport * 0.75 - frustumAdjust,_
-0.75, 0.75, 0.65, 4.0):
glTranslatef(eyeOffset, 0.0!, 0.0!):
glTranslatef(0.0!, 0.0!, -PULL_BACK):
TRACEX "2"
'' Setup the transformation matrix for the object.
glMatrixMode(%GL_MODELVIEW):
glLoadIdentity():
glRotatef(angleZ, 0.0!, 0.0!, 1.0!):
glRotatef(angleY, 0.0!, 1.0!, 0.0!):
glRotatef(angleX, 1.0!, 0.0!, 0.0!):
glTranslatef(0.0!, 0.0!, translateZ):
TRACEX "3"
DodecahedronMorph():
TRACEX "4"
glCallList(1):
TRACEX "5"
'' Note that, in some OpenGL stereoscopy implementations, there
'' are two back buffers and two front buffers, but only one
'' z-buffer. If possible, software should assume that only one
'' z-buffer is available, and should clear that z-buffer before
'' rendering each new stereo view. If your application software
'' renders left- and right-eye stereo pair elements concurrently,
'' for performance reasons, perhaps, your software will only
'' do non-wireframe rendering properly on systems that implement
'' stereo using separate left- and right-eye z-buffers.
gluOrtho2D (0.0, 1024.0, 0.0, 768):
glRasterPos2i(100,100):
glPixelStorei(%GL_UNPACK_ALIGNMENT,1):
traceX "51"
glDrawPixels(@image_1.sizeX,_
@image_1.sizeY,_
%GL_RGB,_
%GL_UNSIGNED_BYTE,_
BYVAL @image_1.nDATA):
TRACEX "52"
glClear (%GL_DEPTH_BUFFER_BIT):
TRACEX "6"
'' Select back right buffer to recieve drawing
glDrawBuffer(%GL_BACK_RIGHT):
'' Draw the image for the right eye.
glMatrixMode(%GL_PROJECTION):
glLoadIdentity():
glFrustum(-aspectViewport * 0.75 + frustumAdjust,_
aspectViewport * 0.75 + frustumAdjust,_
-0.75, 0.75, 0.65, 4.0):
glTranslatef(-eyeOffset, 0.0!, 0.0!):
glTranslatef(0.0!, 0.0!, -PULL_BACK):
TRACEX "7"
glMatrixMode(%GL_MODELVIEW):
glLoadIdentity():
glRotatef(angleZ, 0.0!, 0.0!, 1.0!):
glRotatef(angleY, 0.0!, 1.0!, 0.0!):
glRotatef(angleX, 1.0!, 0.0!, 0.0!):
glTranslatef(0.0!, 0.0!, translateZ):
TRACEX "8="
DodecahedronMorph():
TRACEX "9="
glCallList(1):
gluOrtho2D (0.0, 1024.0, 0.0, 768):
glRasterPos2i(100,100):
glPixelStorei(%GL_UNPACK_ALIGNMENT,1):
glDrawPixels(@IMAGE_2.sizeX,_
@IMAGE_2.sizeY,_
%GL_RGB,_
%GL_UNSIGNED_BYTE,_
BYVAL @IMAGE_2.nDATA):
END SUB
'____________________________________________________________________________________
'
SUB CommandHandler(BYVAL hwnd AS LONG, BYVAL COMAND AS LONG)
SELECT CASE AS LONG COMAND
CASE %VK_1:
glEnable(%GL_CULL_FACE):
EXIT SELECT
CASE %VK_2:
glDisable(%GL_CULL_FACE):
EXIT SELECT
CASE %VK_RETURN:
eyeAdjust = EYE_ADJUST:
eyeOffset = EYE_OFFSET:
InvalidateRect(hwnd, BYVAL %NULL, %FALSE):
EXIT SELECT
CASE %VK_ESCAPE:
PostMessage(hwnd, %WM_DESTROY, 0, 0):
EXIT SELECT
CASE %VK_SPACE:
! xor bRotation,1 ;bRotation = !bRotation:
EXIT SELECT
END SELECT
END SUB
'____________________________________________________________________________________
'
SUB TriangleNormalVector(BYREF a() AS SINGLE,_
BYREF b() AS SINGLE,_
BYREF c() AS SINGLE,_
BYREF n() AS SINGLE) STATIC
!;**********************
LOCAL i AS LONG
LOCAL d AS SINGLE
DIM v1(0:2) AS SINGLE
DIM v2(0:2) AS SINGLE
FOR i = 0 TO 2
v1(i) = a(i) - b(i):
v2(i) = b(i) - c(i):
NEXT i
n(0) = v1(1) * v2(2) - v1(2) * v2(1):
n(1) = v1(2) * v2(0) - v1(0) * v2(2):
n(2) = v1(0) * v2(1) - v1(1) * v2(0):
d = SQR(n(0) * n(0) + n(1) * n(1) + n(2) * n(2)):
IF (ABS(d) > 0.00000001) THEN
d = 1.0! / d:
n(0) *= d:
n(1) *= d:
n(2) *= d:
END IF
END SUB
'____________________________________________________________________________________
'
SUB Icosahedron()
LOCAL i AS LONG
DIM norm(0:2) AS SINGLE
DIM a(0:2) AS SINGLE
DIM b(0:2) AS SINGLE
DIM c(0:2) AS SINGLE
glNewList(1, %GL_COMPILE):
glBegin(%GL_TRIANGLES):
FOR i = 0 TO 19
!;**********************
a(0) = vIco(idxIco(i+0,0))
a(1) = vIco(idxIco(i+1,0))
a(2) = vIco(idxIco(i+2,0))
b(0) = vIco(idxIco(i+0,1))
b(1) = vIco(idxIco(i+1,1))
b(2) = vIco(idxIco(i+2,1))
c(0) = vIco(idxIco(i+0,1))
c(1) = vIco(idxIco(i+1,1))
c(2) = vIco(idxIco(i+2,1))
TriangleNormalVector(a(), b(),c(), norm()):
glNormal3fv(norm(0)):
glVertex3fv(vIco(idxIco(i,0))):
glVertex3fv(vIco(idxIco(i,1))):
glVertex3fv(vIco(idxIco(i,2))):
NEXT i
glEnd():
glEndList():
END SUB
'____________________________________________________________________________________
'
SUB InitDodecahedron()
LOCAL i AS LONG
DIM n(0:2) AS SINGLE
LOCAL d AS SINGLE
FOR i = 0 TO 19
n(0) = vIco(idxIco(i,0),0) + vIco(idxIco(i,1),0) + vIco(idxIco(i,2),0):
n(1) = vIco(idxIco(i,0),1) + vIco(idxIco(i,1),1) + vIco(idxIco(i,2),1):
n(2) = vIco(idxIco(i,0),2) + vIco(idxIco(i,1),2) + vIco(idxIco(i,2),2):
d = SQR(n(0) * n(0) + n(1) * n(1) + n(2) * n(2)):
IF (ABS(d) > 0.00000001) THEN
d = 1.0! / d:
n(0) *= d:
n(1) *= d:
n(2) *= d:
END IF
vDode(i,0) = n(0):
vDode(i,1) = n(1):
vDode(i,2) = n(2):
NEXT i
END SUB
'____________________________________________________________________________________
'
SUB Dodecahedron()
LOCAL i AS LONG
FOR i = 0 TO 11
glBegin(%GL_POLYGON):
glNormal3fv(vIco(i)):
glVertex3fv(vDode(idxDode(i,0))):
glVertex3fv(vDode(idxDode(i,1))):
glVertex3fv(vDode(idxDode(i,2))):
glVertex3fv(vDode(idxDode(i,3))):
glVertex3fv(vDode(idxDode(i,4))):
glEnd():
NEXT i
END SUB
'____________________________________________________________________________________
'
SUB DodecahedronMorph()
LOCAL i AS LONG
DIM v(0:2) AS SINGLE
DIM norm(0:2) AS SINGLE
DIM a(0:2) AS SINGLE
DIM b(0:2) AS SINGLE
DIM c(0:2) AS SINGLE
FOR i = 0 TO 10
glBegin(%GL_TRIANGLE_FAN):
v(0) = factorMorph * vIco(i,0):
v(1) = factorMorph * vIco(i,1):
v(2) = factorMorph * vIco(i,2):
a(0) = vDode(idxDode(i+0,0))
a(1) = vDode(idxDode(i+1,0))
a(2) = vDode(idxDode(i+2,0))
b(0) = vDode(idxDode(i+0,1))
b(1) = vDode(idxDode(i+1,1))
b(2) = vDode(idxDode(i+2,1))
TriangleNormalVector(v(), a(), b(), norm()):
glNormal3fv(norm(0)):
glVertex3fv(v(0)): '' center
glVertex3fv(vDode(idxDode(i,0))):
glVertex3fv(vDode(idxDode(i,1))):
a(0) = vDode(idxDode(i+0,1))
a(1) = vDode(idxDode(i+1,1))
a(2) = vDode(idxDode(i+2,1))
b(0) = vDode(idxDode(i+0,2))
b(1) = vDode(idxDode(i+1,2))
b(2) = vDode(idxDode(i+2,2))
TriangleNormalVector(v(), a(), b(), norm()):
glNormal3fv(norm(0)):
glVertex3fv(vDode(idxDode(i,2))):
a(0) = vDode(idxDode(i+0,2))
a(1) = vDode(idxDode(i+1,2))
a(2) = vDode(idxDode(i+2,2))
b(0) = vDode(idxDode(i+0,3))
b(1) = vDode(idxDode(i+1,3))
b(2) = vDode(idxDode(i+2,3))
TriangleNormalVector(v(), a(), b(), norm()):
glNormal3fv(norm(0)):
glVertex3fv(vDode(idxDode(i,3))):
a(0) = vDode(idxDode(i+0,3))
a(1) = vDode(idxDode(i+1,3))
a(2) = vDode(idxDode(i+2,3))
b(0) = vDode(idxDode(i+0,4))
b(1) = vDode(idxDode(i+1,4))
b(2) = vDode(idxDode(i+2,4))
TriangleNormalVector(v(), a(), b(), norm()):
glNormal3fv(norm(0)):
glVertex3fv(vDode(idxDode(i,4))):
a(0) = vDode(idxDode(i+0,4))
a(1) = vDode(idxDode(i+1,4))
a(2) = vDode(idxDode(i+2,4))
b(0) = vDode(idxDode(i+0,0))
b(1) = vDode(idxDode(i+1,0))
b(2) = vDode(idxDode(i+2,0))
TriangleNormalVector(v(), a(), b(), norm()):
glNormal3fv(norm(0)):
glVertex3fv(vDode(idxDode(i,0))):
glEnd():
NEXT i
END SUB
'_________________________________________________________________________
'
SUB MaterialCreate()
DIM ambientGold(0:3) AS SINGLE
DIM diffuseGold(0:3) AS SINGLE
DIM specularGold(0:3) AS SINGLE
DIM ambientSilver(0:3) AS SINGLE
DIM diffuseSilver(0:3) AS SINGLE
DIM specularSilver(0:3) AS SINGLE
ARRAY ASSIGN ambientGold() = 0.1!, 0.05!, 0.0!, 1.0!
ARRAY ASSIGN diffuseGold() = 0.65!, 0.55!, 0.15!, 1.0!
ARRAY ASSIGN specularGold() = 0.85!, 0.75!, 0.45!, 1.0!
ARRAY ASSIGN ambientSilver() = 0.1!, 0.1!, 0.1!, 1.0!
ARRAY ASSIGN diffuseSilver() = 0.6!, 0.6!, 0.6!, 1.0!
ARRAY ASSIGN specularSilver() = 0.9!, 0.9!, 0.9!, 1.0!
LOCAL shininess AS SINGLE
shininess = 100.0!:
glMaterialfv(%GL_FRONT, %GL_AMBIENT, ambientGold(0)):
glMaterialfv(%GL_FRONT, %GL_DIFFUSE, diffuseGold(0)):
glMaterialfv(%GL_FRONT, %GL_SPECULAR, specularGold(0)):
glMaterialf(%GL_FRONT, %GL_SHININESS, shininess):
END SUB
'_________________________________________________________________________
'
SUB LightCreate()
DIM light0_ambient(0:3) AS SINGLE
DIM light0_diffuse(0:3) AS SINGLE
DIM light0_specular(0:3) AS SINGLE
DIM light0_position(0:3) AS SINGLE
DIM light1_ambient(0:3) AS SINGLE
DIM light1_diffuse(0:3) AS SINGLE
DIM light1_specular(0:3) AS SINGLE
DIM light1_position(0:3) AS SINGLE
ARRAY ASSIGN light0_ambient() = 1.0!, 1.0!, 1.0!, 1.0!:
ARRAY ASSIGN light0_diffuse() = 1.0!, 1.0!, 1.0!, 1.0!
ARRAY ASSIGN light0_specular() = 1.0!, 1.0!, 1.0!, 1.0!
ARRAY ASSIGN light0_position() = -5.0!, 5.0!, 5.0!, 1.0!
ARRAY ASSIGN light1_ambient() = 0.5!, 0.5!, 0.5!, 1.0!
ARRAY ASSIGN light1_diffuse() = 0.5!, 0.5!, 0.5!, 1.0!
ARRAY ASSIGN light1_specular() = 0.5!, 0.5!, 0.5!, 1.0!
ARRAY ASSIGN light1_position() = 5.0!, 0.0!, 0.0!, 1.0!
glLightfv(%GL_LIGHT0, %GL_AMBIENT, light0_ambient(0)):
glLightfv(%GL_LIGHT0, %GL_DIFFUSE, light0_diffuse(0)):
glLightfv(%GL_LIGHT0, %GL_SPECULAR, light0_specular(0)):
glLightfv(%GL_LIGHT0, %GL_POSITION, light0_position(0)):
glLightfv(%GL_LIGHT1, %GL_AMBIENT, light0_ambient(0)):
glLightfv(%GL_LIGHT1, %GL_DIFFUSE, light0_diffuse(0)):
glLightfv(%GL_LIGHT1, %GL_SPECULAR, light0_specular(0)):
glLightfv(%GL_LIGHT1, %GL_POSITION, light1_position(0)):
glEnable(%GL_LIGHTING):
glEnable(%GL_LIGHT0):
glEnable(%GL_LIGHT1):
END SUB
Hi Vladimir,
in that case, I am running out of explanations and hints.
I am bookmarking this thread, so if I find any new information I will supply it here.
Petr
One last thing,
don't you use, by any chance, the old OpenGL headers by Sublevel6?
They were great in its time, but José's OpenGL headers are of top quality, maybe you could try them as well if it makes any difference.
Petr
Hi Petr,
Quote from: Petr Schreiber on December 19, 2010, 03:25:37 PM
One last thing,
don't you use, by any chance, the old OpenGL headers by Sublevel6?
They were great in its time, but José's OpenGL headers are of top quality, maybe you could try them as well if it makes any difference.
I solved the problem, used D3D9 solution, as frame by frame (like shooter glasses),
Based at example:
http://www.jose.it-berater.org/smfforum/index.php?topic=2808.0 (http://www.jose.it-berater.org/smfforum/index.php?topic=2808.0)
Thanks for sharing the info about solution Vladimir!
But I am still confused why OpenGL didn't work in this case, very unpleasant... will investigate more once some time can be allocated to it.
Petr