Silverfrost Forums

Welcome to our forums

SAVE BITMAP to a file

5 May 2008 9:14 #3151

I was helped by John Horspool to solve my problem: 'save bitmap from my OpenGL Window to file on my hard disk'.

I prepared a small program witch draws red sphere on yello background. The program should save conten of window to disk as a bitmap file called Junk_BMP.bmp. I have bitmap but there is only black square nothing more. There is something wrong! Are there anybody who would correct the program to achieve the goal (saving bitmap to file).

Leszek Flis

  PROGRAM STENCIL
  include <clearwin.ins>,nolist
  include <opengl.ins>  ,nolist

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! parameters for opengl window !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! parameter (kw_ogl=400,kh_ogl=400)

  integer  i,koff,kount,k,j
  integer  opengl_proc
  external opengl_proc

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Coded by JohnHorspool to is needed to save bitmap file !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CHARACTER1 ImageData(3(kw_ogl+3)*kh_ogl),ImageDib(3,kw_ogl,kh_ogl)

  i=winio@('%es%ca[Saving BITMAP]%sp%ww[no_border]%pv%^og[depth32,stencil]',0,0,kw_ogl,kh_ogl,opengl_proc)

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! MAIN part Coded by JohnHorspool - is needed to save bitmap file !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ImageData=' ' ImageDib =' '

  call glReadPixels(0,0,kw_ogl,kh_ogl,GL_RGB,GL_UNSIGNED_BYTE,ImageData)

  koff=mod(kw_ogl,4)
  kount=0
   do j=1,kh_ogl
   do i=1,kw_ogl
  do k=1,3
  kount=kount+1
  ImageDib(k,i,kh_ogl-j+1)=ImageData(kount)
  end do
  end do
  kount=kount+koff
  end do

  call put_dib_block@('Junk_bmp.bmp',ImageDib,kw_ogl,kh_ogl,0,0,kw_ogl,kh_ogl,24,ierr)

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! MAIN part Coded by JohnHorspool - is needed to save bitmap file !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  CALL glutMainLoop

  END

! Subroutines ! Draw a sphere subroutine display() include <opengl.ins>,nolist

  call glClearColor(1.0,1.0,0.0,1.0)
  call glClear(OR(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT))
  call glColor3f(1.0,0.0,0.0)
  call auxSolidSphere (1.0d0)
  call glFlush()
  end

! Whenever the window is reshaped, redefine the ! coordinate system and redraw the stencil area. subroutine myReshape(width,height)

  INCLUDE <opengl.ins>,nolist
  INTEGER  width,height
  REAL*8   r

  r=1.0
  IF  (height==0) height=1
  CALL glViewport(0, 0, width, height)
  CALL glMatrixMode(GL_PROJECTION)
  CALL glLoadIdentity()
  IF(width<=height) then
  CALL glOrtho(-r,r,-r*height/width,r*height/width,-r,r)
  ELSE
  CALL glOrtho(-r*width/height,r*width/height,-r,r,-r,r)
  ENDIF

  CALL glMatrixMode(GL_MODELVIEW)
  CALL glLoadIdentity()

  end

  integer function opengl_proc()
  include <clearwin.ins>,nolist
  include <opengl.ins>,nolist
  integer w,h
  character*256 reason
  reason=clearwin_string@('CALL_BACK_REASON')
  if(reason.eq.'SETUP')then
  call glEnable(GL_DEPTH_TEST)
  else if(reason.eq.'RESIZE')then
    w=clearwin_info@('OPENGL_WIDTH')
    h=clearwin_info@('OPENGL_DEPTH')
    call myReshape(w,h)
  else if(reason.eq.'DIRTY')then
    call display()
  end if
  opengl_proc=2
  end
5 May 2008 8:45 #3155

Leszek,

Here is the stencil example supplied with the installation, I have modified it to include a save to bitmap routine. I have done very little to the original code, just put the width and height variables (w,h) into common, put in a menu and added the bit map creation routine, you can resize the window and create multiple bitmaps.

cheers John

*  stencil.c                        
*  This program draws two rotated tori in a window.
*  A diamond in the center of the window masks out part
*  of the scene.  Within this mask, a different model
*  (a sphere) is drawn in a different color.
*
      subroutine myinit()
      include <opengl.ins>,nolist
      real yellow_diffuse(4)
      real yellow_specular(4)

      real blue_diffuse(4)
      real blue_specular(4)

      real position_one(4)

      integer YELLOWMAT
      integer BLUEMAT
      parameter(YELLOWMAT = 1)
      parameter(BLUEMAT = 2)

      data yellow_diffuse  / 0.7, 0.7, 0.0, 1.0 /
      data yellow_specular / 1.0, 1.0, 1.0, 1.0 /

      data blue_diffuse    / 0.1, 0.1, 0.7, 1.0 /
      data blue_specular   / 0.1, 1.0, 1.0, 1.0 /

      data position_one    / 1.0, 1.0, 1.0, 0.0 /


      call glNewList(YELLOWMAT, GL_COMPILE)
      call glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow_diffuse)
      call glMaterialfv(GL_FRONT, GL_SPECULAR, yellow_specular)
      call glMaterialf(GL_FRONT, GL_SHININESS, 64.0)
      call glEndList()

      call glNewList(BLUEMAT, GL_COMPILE)
      call glMaterialfv(GL_FRONT, GL_DIFFUSE, blue_diffuse)
      call glMaterialfv(GL_FRONT, GL_SPECULAR, blue_specular)
      call glMaterialf(GL_FRONT, GL_SHININESS, 45.0)
      call glEndList()

      call glLightfv(GL_LIGHT0, GL_POSITION, position_one)

      call glEnable(GL_LIGHT0)
      call glEnable(GL_LIGHTING)
      call glDepthFunc(GL_LESS)
      call glEnable(GL_DEPTH_TEST)

      call glClearStencil(z'0')
      call glEnable(GL_STENCIL_TEST)

      end

*  Draw a sphere in a diamond-shaped section in the
*  middle of a window with 2 tori.
*
      subroutine display()
      include <opengl.ins>,nolist

      integer YELLOWMAT
      integer BLUEMAT
      parameter(YELLOWMAT = 1)
      parameter(BLUEMAT = 2)

      call glClear(OR(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT))

* draw blue sphere where the stencil is 1 */
      call glStencilFunc (GL_EQUAL, z'1', z'1')
      call glCallList (BLUEMAT)
      call auxSolidSphere (0.5d0)

* draw the tori where the stencil is not 1 */
      call glStencilFunc (GL_NOTEQUAL, z'1', z'1')
      call glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP)
      call glPushMatrix()
      call glRotatef (45.0, 0.0, 0.0, 1.0)
      call glRotatef (45.0, 0.0, 1.0, 0.0)
      call glCallList (YELLOWMAT)
      call auxSolidTorus (0.275d0, 0.85d0)
      call glPushMatrix()
      call glRotatef (90.0, 1.0, 0.0, 0.0)
      call auxSolidTorus (0.275d0, 0.85d0)
      call glPopMatrix()
      call glPopMatrix()
      call glFlush()
      end

*  Whenever the window is reshaped, redefine the
*  coordinate system and redraw the stencil area.
*
      subroutine myReshape()
      include <opengl.ins>,nolist

      integer w,h
      double precision aspect_ratio

      common /size/w,h

      if (h.ne.0) then
          aspect_ratio=dble(w)/h
          call glViewport(0, 0, w, h)

          call glClear(GL_STENCIL_BUFFER_BIT)
* create a diamond shaped stencil area *
          call glMatrixMode(GL_PROJECTION)
          call glLoadIdentity()
          call glOrtho(-3d0, 3d0, -3d0, 3d0, -1d0, 1d0)
          call glMatrixMode(GL_MODELVIEW)
          call glLoadIdentity()

          call glStencilFunc (GL_ALWAYS, z'1', z'1')
          call glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE)
          call glBegin(GL_QUADS)
          call glVertex3f (-1.0, 0.0, 0.0)
          call glVertex3f (0.0, 1.0, 0.0)
          call glVertex3f (1.0, 0.0, 0.0)
          call glVertex3f (0.0, -1.0, 0.0)
          call glEnd()

          call glMatrixMode(GL_PROJECTION)
          call glLoadIdentity()
          call gluPerspective(45d0, aspect_ratio, 3d0, 7d0)
          call glMatrixMode(GL_MODELVIEW)
          call glLoadIdentity()
          call glTranslatef(0.0, 0.0, -5.0)
      endif
      end

      integer function opengl_proc()
      include <clearwin.ins>,nolist
      integer w,h

      common /size/w,h

      character*256 reason
      reason=clearwin_string@('CALL_BACK_REASON')
      if(reason.eq.'SETUP')then
        call myinit()
      else if(reason.eq.'RESIZE')then
        w=clearwin_info@('OPENGL_WIDTH')
        h=clearwin_info@('OPENGL_DEPTH')
        call myReshape()
      else if(reason.eq.'DIRTY')then
        call display()
      end if
      opengl_proc=2
      end

      program Stencil
      include <clearwin.ins>,nolist
      integer i
      integer opengl_proc,Make_Bitmap
      external opengl_proc,Make_Bitmap
      integer w,h

      common /size/w,h

      w=400
      h=400

      i=winio@('%es%ca[Stencil Test]&')
      i=winio@('%mn[Make Bitmap]&',Make_Bitmap)

      i=winio@('%sp%ww[no_border]%pv%^og[depth16,stencil]'
     +      ,0,0,w,h,opengl_proc)
      end

      integer function Make_Bitmap()

      integer w,h

      common /size/w,h

      call do_bitmap(w,h)

      Make_Bitmap=2
      end

      subroutine do_bitmap(w,h)

      include <clearwin.ins>,nolist
      include <opengl.ins>,nolist 

      integer w,h,ierr,koff,kount,i,j,k

      CHARACTER*1 ImageData(3*(w+3)*h),
     *            ImageDib(3,w,h)


      CHARACTER*12 file_name

      logical exst

      ImageData=' ' 
      ImageDib =' ' 

      call glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE,ImageData)

      koff=mod(w,4) 

      kount=0 

        do j=1,h 

            do i=1,w 

              do k=1,3 
                kount=kount+1 
                ImageDib(k,i,h-j+1)=ImageData(kount) 
              end do 

            end do 

          kount=kount+koff 
        end do 

      file_name='Image   .bmp'

      k=0
    5 k=k+1

      write(file_name(6:8),'(I3)')k

      if (file_name(6:6).eq.' ') file_name(6:6)='0'
      if (file_name(7:7).eq.' ') file_name(7:7)='0'

      INQUIRE(FILE=file_name,EXIST=EXST)

      IF (EXST) go to 5

      call put_dib_block@(file_name,ImageDib,w,h,0,0,w,h,24,ierr)

      return
      end
5 May 2008 8:46 #3156

and the rest (I hope!)

          call glMatrixMode(GL_MODELVIEW)
          call glLoadIdentity()

          call glStencilFunc (GL_ALWAYS, z'1', z'1')
          call glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE)
          call glBegin(GL_QUADS)
          call glVertex3f (-1.0, 0.0, 0.0)
          call glVertex3f (0.0, 1.0, 0.0)
          call glVertex3f (1.0, 0.0, 0.0)
          call glVertex3f (0.0, -1.0, 0.0)
          call glEnd()

          call glMatrixMode(GL_PROJECTION)
          call glLoadIdentity()
          call gluPerspective(45d0, aspect_ratio, 3d0, 7d0)
          call glMatrixMode(GL_MODELVIEW)
          call glLoadIdentity()
          call glTranslatef(0.0, 0.0, -5.0)
      endif
      end

      integer function opengl_proc()
      include <clearwin.ins>,nolist
      integer w,h

      common /size/w,h

      character*256 reason
      reason=clearwin_string@('CALL_BACK_REASON')
      if(reason.eq.'SETUP')then
        call myinit()
      else if(reason.eq.'RESIZE')then
        w=clearwin_info@('OPENGL_WIDTH')
        h=clearwin_info@('OPENGL_DEPTH')
        call myReshape()
      else if(reason.eq.'DIRTY')then
        call display()
      end if
      opengl_proc=2
      end

      program Stencil
      include <clearwin.ins>,nolist
      integer i
      integer opengl_proc,Make_Bitmap
      external opengl_proc,Make_Bitmap
      integer w,h

      common /size/w,h

      w=400
      h=400

      i=winio@('%es%ca[Stencil Test]&')
      i=winio@('%mn[Make Bitmap]&',Make_Bitmap)

      i=winio@('%sp%ww[no_border]%pv%^og[depth16,stencil]'
     +      ,0,0,w,h,opengl_proc)
      end

      integer function Make_Bitmap()

      integer w,h

      common /size/w,h

      call do_bitmap(w,h)

      Make_Bitmap=2
      end

      subroutine do_bitmap(w,h)

      include <clearwin.ins>,nolist
      include <opengl.ins>,nolist 

      integer w,h,ierr,koff,kount,i,j,k

      CHARACTER*1 ImageData(3*(w+3)*h),
     *            ImageDib(3,w,h)


      CHARACTER*12 file_name

      logical exst

      ImageData=' ' 
      ImageDib =' ' 

      call glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE,ImageData)

      koff=mod(w,4) 

      kount=0 

        do j=1,h 

            do i=1,w 

              do k=1,3 
                kount=kount+1 
                ImageDib(k,i,h-j+1)=ImageData(kount) 
              end do 

            end do 

          kount=kount+koff 
        end do 

      file_name='Image   .bmp'

      k=0
    5 k=k+1

      write(file_name(6:8),'(I3)')k

      if (file_name(6:6).eq.' ') file_name(6:6)='0'
      if (file_name(7:7).eq.' ') file_name(7:7)='0'

      INQUIRE(FILE=file_name,EXIST=EXST)

      IF (EXST) go to 5

      call put_dib_block@(file_name,ImageDib,w,h,0,0,w,h,24,ierr)

      return
      end
Please login to reply.