예제 #1
0
PDGL_API void pdglReadPixels( GLint x, GLint y,
	GLsizei width, GLsizei height, GLenum format,
	GLenum type, GLvoid *pixels)
{
	if(pglReadPixels)
	{
		pglReadPixels(x, y, width, height, format, type, pixels);
		return;
	}
	pglReadPixels=pdglGetProcAddress("glReadPixels");
	pglReadPixels(x, y, width, height, format, type, pixels);
}
예제 #2
0
파일: gl_backend.c 프로젝트: jeefo/xash3d
qboolean VID_ScreenShot( const char *filename, int shot_type )
{
	rgbdata_t *r_shot;
	uint	flags = IMAGE_FLIP_Y;
	int	width = 0, height = 0;
	qboolean	result;

	r_shot = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));
	r_shot->width = (glState.width + 3) & ~3;
	r_shot->height = (glState.height + 3) & ~3;
	r_shot->flags = IMAGE_HAS_COLOR | IMAGE_HAS_ALPHA;
	r_shot->type = PF_RGBA_32;
	r_shot->size = r_shot->width * r_shot->height * PFDesc[r_shot->type].bpp;
	r_shot->palette = NULL;
	r_shot->buffer = Mem_Alloc( r_temppool, r_shot->size );

	// get screen frame
	pglPixelStorei(GL_PACK_ALIGNMENT, 1);	// PANDORA, just in case
	pglReadPixels( 0, 0, r_shot->width, r_shot->height, GL_RGBA, GL_UNSIGNED_BYTE, r_shot->buffer );
	switch( shot_type )
	{
	case VID_SCREENSHOT:
		if( !gl_overview->integer )
			VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // scrshot gamma
		break;
	case VID_SNAPSHOT:
		if( !gl_overview->integer )
			VID_ImageAdjustGamma( r_shot->buffer, r_shot->width, r_shot->height ); // scrshot gamma
		FS_AllowDirectPaths( true );
		break;
	case VID_LEVELSHOT:
		flags |= IMAGE_RESAMPLE;
		if( glState.wideScreen )
		{
			height = 480;
			width = 800;
		}
		else
		{
			height = 480;
			width = 640;
		}
		break;
	case VID_MINISHOT:
		flags |= IMAGE_RESAMPLE;
		height = 200;
		width = 320;
		break;
	case VID_MAPSHOT:
		V_WriteOverviewScript();		// store overview script too
		flags |= IMAGE_RESAMPLE|IMAGE_QUANTIZE;	// GoldSrc request overviews in 8-bit format
		height = 768;
		width = 1024;
		break;
	}

	Image_Process( &r_shot, width, height, 0.0f, flags, NULL );

	// write image
	result = FS_SaveImage( filename, r_shot );
	host.write_to_clipboard = false;		// disable write to clipboard
	FS_AllowDirectPaths( false );			// always reset after store screenshot
	FS_FreeImage( r_shot );

	return result;
}
예제 #3
0
파일: gl_backend.c 프로젝트: jeefo/xash3d
/*
=================
VID_CubemapShot
=================
*/
qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot )
{
	rgbdata_t		*r_shot, *r_side;
	byte		*temp = NULL;
	byte		*buffer = NULL;
	string		basename;
	int		i = 1, flags, result;

	if( !RI.drawWorld || !cl.worldmodel )
		return false;

	// make sure the specified size is valid
	while( i < size ) i<<=1;

	if( i != size ) return false;
	if( size > glState.width || size > glState.height )
		return false;

	// setup refdef
	RI.params |= RP_ENVVIEW;	// do not render non-bmodel entities

	// alloc space
	temp = Mem_Alloc( r_temppool, size * size * 3 );
	buffer = Mem_Alloc( r_temppool, size * size * 3 * 6 );
	r_shot = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));
	r_side = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));

	// use client vieworg
	if( !vieworg ) vieworg = cl.refdef.vieworg;

	for( i = 0; i < 6; i++ )
	{
		// go into 3d mode
		R_Set2DMode( false );

		if( skyshot )
		{
			R_DrawCubemapView( vieworg, r_skyBoxInfo[i].angles, size );
			flags = r_skyBoxInfo[i].flags;
		}
		else
		{
			R_DrawCubemapView( vieworg, r_envMapInfo[i].angles, size );
			flags = r_envMapInfo[i].flags;
		}

		pglReadPixels( 0, 0, size, size, GL_RGB, GL_UNSIGNED_BYTE, temp );
		r_side->flags = IMAGE_HAS_COLOR;
		r_side->width = r_side->height = size;
		r_side->type = PF_RGB_24;
		r_side->size = r_side->width * r_side->height * 3;
		r_side->buffer = temp;

		if( flags ) Image_Process( &r_side, 0, 0, 0.0f, flags, NULL );
		Q_memcpy( buffer + (size * size * 3 * i), r_side->buffer, size * size * 3 );
	}

	RI.params &= ~RP_ENVVIEW;

	r_shot->flags = IMAGE_HAS_COLOR;
	r_shot->flags |= (skyshot) ? IMAGE_SKYBOX : IMAGE_CUBEMAP;
	r_shot->width = size;
	r_shot->height = size;
	r_shot->type = PF_RGB_24;
	r_shot->size = r_shot->width * r_shot->height * 3 * 6;
	r_shot->palette = NULL;
	r_shot->buffer = buffer;

	// make sure what we have right extension
	Q_strncpy( basename, base, MAX_STRING );
	FS_StripExtension( basename );
	FS_DefaultExtension( basename, ".tga" );

	// write image as 6 sides
	result = FS_SaveImage( basename, r_shot );
	FS_FreeImage( r_shot );
	FS_FreeImage( r_side );

	return result;
}
예제 #4
0
// read depth buffer and update visibility flag of depth points
static void UpdateDepthPointsVisibility( const CDrawPort *pdp, const INDEX iMirrorLevel,
                                         DepthInfo *pdi, const INDEX ctCount)
{
  const GfxAPIType eAPI = _pGfx->gl_eCurrentAPI;
  ASSERT(GfxValidApi(eAPI));
  ASSERT( pdp!=NULL && ctCount>0);
  const CRaster *pra = pdp->dp_Raster;

  // OpenGL
  if( eAPI==GAT_OGL)
  { 
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    FLOAT fPointOoK;
    // for each stored point
    for( INDEX idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      const PIX pixJ = pra->ra_Height-1 - di.di_pixJ; // OpenGL has Y-inversed buffer!
      pglReadPixels( di.di_pixI, pixJ, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &fPointOoK);
      OGL_CHECKERROR;
      // it is visible if there is nothing nearer in z-buffer already
      di.di_bVisible = (di.di_fOoK<fPointOoK);
    }
    // done
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }

  // Direct3D
#ifdef SE1_D3D
  if( eAPI==GAT_D3D)
  {
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // ok, this will get really complicated ...
    // We'll have to do it thru back buffer because darn DX8 won't let us have values from z-buffer;
    // Anyway, we'll lock backbuffer, read color from the lens location and try to write little triangle there
    // with slightly modified color. Then we'll readout that color and see if triangle passes z-test. Voila! :)
    // P.S. To avoid lock-modify-lock, we need to batch all the locks in one. Uhhhh ... :(
    COLOR col;
    INDEX idi;
    SLONG slColSize;
    HRESULT hr;
    D3DLOCKED_RECT rectLocked;
    D3DSURFACE_DESC surfDesc;
    LPDIRECT3DSURFACE8 pBackBuffer;
    // fetch back buffer (different for full screen and windowed mode)
    const BOOL bFullScreen = _pGfx->gl_ulFlags & GLF_FULLSCREEN;
    if( bFullScreen) {
      hr = _pGfx->gl_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    } else {
      hr = pra->ra_pvpViewPort->vp_pSwapChain->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
    }
    // what, cannot get a back buffer?
    if( hr!=D3D_OK) { 
      // to hell with it all
      _sfStats.StopTimer(CStatForm::STI_GFXAPI);
      return;
    }
    // keep format of back-buffer
    pBackBuffer->GetDesc(&surfDesc);
    const D3DFORMAT d3dfBack = surfDesc.Format;
    
    // prepare array that'll back-buffer colors from depth point locations
    _acolDelayed.Push(ctCount);
    // store all colors
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      // skip if not in required mirror level or was already checked in this iteration
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest) continue;
      // fetch pixel
      _acolDelayed[idi] = 0;
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read, convert and store original color
      _acolDelayed[idi] = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
    }

    // prepare to draw little triangles there with slightly adjusted colors
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    gfxEnableDepthTest();
    gfxDisableDepthWrite();
    gfxDisableBlend();
    gfxDisableAlphaTest();
    gfxDisableTexture();
    _sfStats.StartTimer(CStatForm::STI_GFXAPI);
    // prepare array and shader
    _avtxDelayed.Push(ctCount*3);
    d3dSetVertexShader(D3DFVF_CTVERTEX);

    // draw one trianle around each depth point
    INDEX ctVertex = 0;
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      const ULONG d3dCol = rgba2argb(col^0x20103000);
      const PIX pixI = di.di_pixI - pdp->dp_MinI; // convert raster loc to drawport loc
      const PIX pixJ = di.di_pixJ - pdp->dp_MinJ;
      // batch it and advance to next triangle
      CTVERTEX &vtx0 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx1 = _avtxDelayed[ctVertex++];
      CTVERTEX &vtx2 = _avtxDelayed[ctVertex++];
      vtx0.fX=pixI;   vtx0.fY=pixJ-2; vtx0.fZ=di.di_fOoK; vtx0.ulColor=d3dCol; vtx0.fU=vtx0.fV=0;
      vtx1.fX=pixI-2; vtx1.fY=pixJ+2; vtx1.fZ=di.di_fOoK; vtx1.ulColor=d3dCol; vtx1.fU=vtx0.fV=0;
      vtx2.fX=pixI+2; vtx2.fY=pixJ;   vtx2.fZ=di.di_fOoK; vtx2.ulColor=d3dCol; vtx2.fU=vtx0.fV=0;
    }
    // draw a bunch
    hr = _pGfx->gl_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, ctVertex/3, &_avtxDelayed[0], sizeof(CTVERTEX));
    D3D_CHECKERROR(hr);

    // readout colors again and compare to old ones
    for( idi=0; idi<ctCount; idi++) {
      DepthInfo &di = pdi[idi];
      col = _acolDelayed[idi];
      // skip if not in required mirror level or was already checked in this iteration, or wasn't fetched at all
      if( iMirrorLevel!=di.di_iMirrorLevel || _iCheckIteration!=di.di_iSwapLastRequest || col==0) continue;
      // fetch pixel
      const RECT rectToLock = { di.di_pixI, di.di_pixJ, di.di_pixI+1, di.di_pixJ+1 };
      hr = pBackBuffer->LockRect( &rectLocked, &rectToLock, D3DLOCK_READONLY);
      if( hr!=D3D_OK) continue; // skip if lock didn't make it
      // read new color
      const COLOR colNew = UnpackColor_D3D( (UBYTE*)rectLocked.pBits, d3dfBack, slColSize) | CT_OPAQUE;
      pBackBuffer->UnlockRect();
      // if we managed to write adjusted color, point is visible!
      di.di_bVisible = (col!=colNew);
    }
    // phew, done! :)
    D3DRELEASE( pBackBuffer, TRUE);
    _acolDelayed.PopAll();
    _avtxDelayed.PopAll();
    _sfStats.StopTimer(CStatForm::STI_GFXAPI);
    return;
  }
#endif // SE1_D3D
}