• Welcome to Jose's Read Only Forum 2023.
 

Stereo + OpenGL for HMD

Started by Vladimir Shulakov, December 11, 2010, 11:04:06 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Vladimir Shulakov

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).



Petr Schreiber

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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Vladimir Shulakov

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

Petr Schreiber

#3
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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Vladimir Shulakov

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



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

Vladimir Shulakov

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
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
' =======================================================================================






Petr Schreiber

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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Vladimir Shulakov

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


Petr Schreiber

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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Vladimir Shulakov

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).


Vladimir Shulakov

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)


Petr Schreiber

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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Vladimir Shulakov

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








Petr Schreiber

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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Petr Schreiber

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
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com