⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dglwgl.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
	}

	// (Re)Initialise all the Direct3D renderstates
	dglInitStateD3D(ctx);

	// Now we have to recreate all of our textures (+ mipmaps).
	// Walk over all textures in hash table
	// XXX what about the default texture objects (id=0)?
	{
		struct _mesa_HashTable *textures = ctx->Shared->TexObjects;
		GLuint id;
		for (id = _mesa_HashFirstEntry(textures);
				 id;
				 id = _mesa_HashNextEntry(textures, id)) {
			tObj = (struct gl_texture_object *) _mesa_HashLookup(textures, id);
			if (tObj->DriverData) {
				// We could call our TexImage function directly, but it's
				// safer to use the driver pointer.
				for (i=0; i<MAX_TEXTURE_LEVELS; i++) {
					image = tObj->Image[i];
					if (image) {
						switch (tObj->Dimensions){
						case 1:
							if (ctx->Driver.TexImage)
								(*ctx->Driver.TexImage)(ctx, GL_TEXTURE_1D, tObj, i, image->Format, image);
							break;
						case 2:
							if (ctx->Driver.TexImage)
								(*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, tObj, i, image->Format, image);
							break;
						default:
							break;
						}
					}
				}
			}
		}
	}

	// Re-Bind each texture Unit
	for (i=0; i<glb.wMaxSimultaneousTextures; i++) {
		tObj = ctx->Texture.Unit[i].Current;
		if (tObj) {
			DGL_texture *lpTex = (DGL_texture *)tObj->DriverData;
			hResult = dglSetTexture(dgl, i, lpTex ? lpTex->lpTexture : NULL);
			if (FAILED(hResult)) {
				ddlogError(DDLOG_ERROR, "dglResize: SetTexture failed", hResult);
			}
		}
	}
#endif // _USE_GLD3_WGL

	dgl->bCanRender = TRUE;

#ifdef GLD_THREADS
	// Release serialized access
	if (glb.bMultiThreaded)
		LeaveCriticalSection(&CriticalSection);
#endif

	// SUCCESS.
	return TRUE;

cleanup_and_return_with_error:
	// Relase all interfaces before returning.
#ifdef _USE_GLD3_WGL
	_gldDriver.DestroyDrawable(dgl);
#else // _USE_GLD3_WGL
	RELEASE(dgl->lpDev3);
	RELEASE(dgl->lpDepth4);
	RELEASE(dgl->lpBack4);
	if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary)
		;
	else
	RELEASE(dgl->lpFront4);

#undef DDLOG_CRITICAL_OR_WARN
#endif // _USE_GLD3_WGL

	// Mark context as not being able to render
	dgl->bCanRender = FALSE;

#ifdef GLD_THREADS
	// Release serialized access
	if (glb.bMultiThreaded)
		LeaveCriticalSection(&CriticalSection);
#endif

	return FALSE;
}

// ***********************************************************************
// ***********************************************************************
// Support for bitmap fonts.
// ***********************************************************************
// ***********************************************************************

/*****************************************************************************
**
** InvertGlyphBitmap.
**
** Invert the bitmap so that it suits OpenGL's representation.
** Each row starts on a double word boundary.
**
*****************************************************************************/

static void InvertGlyphBitmap(
	int w,
	int h,
	DWORD *fptr,
	DWORD *tptr)
{
	int dWordsInRow = (w+31)/32;
	int i, j;
	DWORD *tmp = tptr;

	if (w <= 0 || h <= 0) {
	return;
	}

	tptr += ((h-1)*dWordsInRow);
	for (i = 0; i < h; i++) {
	for (j = 0; j < dWordsInRow; j++) {
		*(tptr + j) = *(fptr + j);
	}
	tptr -= dWordsInRow;
	fptr += dWordsInRow;
	}
}

// ***********************************************************************

/*****************************************************************************
 * wglUseFontBitmaps
 *
 * Converts a subrange of the glyphs in a GDI font to OpenGL display
 * lists.
 *
 * Extended to support any GDI font, not just TrueType fonts. (DaveM)
 *
 *****************************************************************************/

BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsA)(
	HDC hDC,
	DWORD first,
	DWORD count,
	DWORD listBase)
{
	int					i, ox, oy, ix, iy;
	int					w, h;
	int					iBufSize, iCurBufSize = 0;
	DWORD				*bitmapBuffer = NULL;
	DWORD				*invertedBitmapBuffer = NULL;
	BOOL				bSuccessOrFail = TRUE;
	BOOL				bTrueType = FALSE;
	TEXTMETRIC			tm;
	GLYPHMETRICS		gm;
	RASTERIZER_STATUS	rs;
	MAT2				mat;
	SIZE				size;
	RECT				rect;
	HDC					hDCMem;
	HBITMAP				hBitmap;
	BITMAPINFO			bmi;
	HFONT				hFont;

	// Validate SciTech DirectGL license
	if (!dglValidate())
		return FALSE;

	// Set up a unity matrix.
	ZeroMemory(&mat, sizeof(mat));
	mat.eM11.value = 1;
	mat.eM22.value = 1;

	// Test to see if selected font is TrueType or not
	ZeroMemory(&tm, sizeof(tm));
	if (!GetTextMetrics(hDC, &tm)) {
		ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Font metrics error\n");
		return (FALSE);
	}
	bTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) ? TRUE : FALSE;

	// Test to see if TRUE-TYPE capabilities are installed
	// (only necessary if TrueType font selected)
	ZeroMemory(&rs, sizeof(rs));
	if (bTrueType) {
		if (!GetRasterizerCaps (&rs, sizeof (RASTERIZER_STATUS))) {
			ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Raster caps error\n");
			return (FALSE);
		}
		if (!(rs.wFlags & TT_ENABLED)) {
			ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: No TrueType caps\n");
			return (FALSE);
		}
	}

	// Trick to get the current font handle
	hFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
	SelectObject(hDC, hFont);

	// Have memory device context available for holding bitmaps of font glyphs
	hDCMem = CreateCompatibleDC(hDC);
	SelectObject(hDCMem, hFont);
	SetTextColor(hDCMem, RGB(0xFF, 0xFF, 0xFF));
	SetBkColor(hDCMem, 0);

	for (i = first; (DWORD) i < (first + count); i++) {
		// Find out how much space is needed for the bitmap so we can
		// Set the buffer size correctly.
		if (bTrueType) {
			// Use TrueType support to get bitmap size of glyph
			iBufSize = GetGlyphOutline(hDC, i, GGO_BITMAP, &gm,
				0, NULL, &mat);
			if (iBufSize == GDI_ERROR) {
				bSuccessOrFail = FALSE;
				break;
			}
		}
		else {
			// Use generic GDI support to compute bitmap size of glyph
			w = tm.tmMaxCharWidth;
			h = tm.tmHeight;
			if (GetTextExtentPoint32(hDC, (LPCTSTR)&i, 1, &size)) {
				w = size.cx;
				h = size.cy;
			}
			iBufSize = w * h;
			// Use DWORD multiple for compatibility
			iBufSize += 3;
			iBufSize /= 4;
			iBufSize *= 4;
		}

		// If we need to allocate Larger Buffers, then do so - but allocate
		// An extra 50 % so that we don't do too many mallocs !
		if (iBufSize > iCurBufSize) {
			if (bitmapBuffer) {
				__wglFree(bitmapBuffer);
			}
			if (invertedBitmapBuffer) {
				__wglFree(invertedBitmapBuffer);
			}

			iCurBufSize = iBufSize * 2;
			bitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize);
			invertedBitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize);

			if (bitmapBuffer == NULL || invertedBitmapBuffer == NULL) {
				bSuccessOrFail = FALSE;
				break;
			}
		}

		// If we fail to get the Glyph data, delete the display lists
		// Created so far and return FALSE.
		if (bTrueType) {
			// Use TrueType support to get bitmap of glyph
			if (GetGlyphOutline(hDC, i, GGO_BITMAP, &gm,
					iBufSize, bitmapBuffer, &mat) == GDI_ERROR) {
				bSuccessOrFail = FALSE;
				break;
			}

			// Setup glBitmap parameters for current font glyph
			w  = gm.gmBlackBoxX;
			h  = gm.gmBlackBoxY;
			ox = gm.gmptGlyphOrigin.x;
			oy = gm.gmptGlyphOrigin.y;
			ix = gm.gmCellIncX;
			iy = gm.gmCellIncY;
		}
		else {
			// Use generic GDI support to create bitmap of glyph
			ZeroMemory(bitmapBuffer, iBufSize);

			if (i >= tm.tmFirstChar && i <= tm.tmLastChar) {
				// Only create bitmaps for actual font glyphs
				hBitmap = CreateBitmap(w, h, 1, 1, NULL);
				SelectObject(hDCMem, hBitmap);
				// Make bitmap of current font glyph
				SetRect(&rect, 0, 0, w, h);
				DrawText(hDCMem, (LPCTSTR)&i, 1, &rect,
					DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP);
				// Make copy of bitmap in our local buffer
				ZeroMemory(&bmi, sizeof(bmi));
				bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
				bmi.bmiHeader.biWidth = w;
				bmi.bmiHeader.biHeight = -h;
				bmi.bmiHeader.biPlanes = 1;
				bmi.bmiHeader.biBitCount = 1;
				bmi.bmiHeader.biCompression = BI_RGB;
				GetDIBits(hDCMem, hBitmap, 0, h, bitmapBuffer, &bmi, 0);
				DeleteObject(hBitmap);
			}
			else {
				// Otherwise use empty display list for non-existing glyph
				iBufSize = 0;
			}

			// Setup glBitmap parameters for current font glyph
			ox = 0;
			oy = tm.tmDescent;
			ix = w;
			iy = 0;
		}

		// Create an OpenGL display list.
		_GLD_glNewList((listBase + i), GL_COMPILE);

		// Some fonts have no data for the space character, yet advertise
		// a non-zero size.
		if (0 == iBufSize) {
			_GLD_glBitmap(0, 0, 0.0f, 0.0f, (GLfloat) ix, (GLfloat) iy, NULL);
		} else {
			// Invert the Glyph data.
			InvertGlyphBitmap(w, h, bitmapBuffer, invertedBitmapBuffer);

			// Render an OpenGL bitmap and invert the origin.
			_GLD_glBitmap(w, h,
				(GLfloat) ox, (GLfloat) (h-oy),
				(GLfloat) ix, (GLfloat) iy,
				(GLubyte *) invertedBitmapBuffer);
		}

		// Close this display list.
		_GLD_glEndList();
	}

	if (bSuccessOrFail == FALSE) {
		ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Get glyph failed\n");
		_GLD_glDeleteLists((i+listBase), (i-first));
	}

	// Release resources used
	DeleteObject(hFont);
	DeleteDC(hDCMem);

	if (bitmapBuffer)
		__wglFree(bitmapBuffer);
	if (invertedBitmapBuffer)
		__wglFree(invertedBitmapBuffer);

	return(bSuccessOrFail);
}

// ***********************************************************************

BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsW)(
	HDC a,
	DWORD b,
	DWORD c,
	DWORD d)
{
	// Validate license
	if (!dglValidate())
		return FALSE;

	return _GLD_WGL_EXPORT(UseFontBitmapsA)(a, b, c, d);
}

// ***********************************************************************
// ***********************************************************************
// Support for outline TrueType fonts.
// ***********************************************************************
// ***********************************************************************

void * __wglRealloc(
	void *oldPtr,
	size_t newSize)
{
    void *newPtr = NULL;
	
    if (newSize != 0) {
		newPtr = (void *) GlobalAlloc(GPTR, newSize);
		if (oldPtr && newPtr) {
			DWORD oldSize = GlobalSize(oldPtr);
			
			memcpy(newPtr, oldPtr, (oldSize <= newSize ? oldSize : newSize));
			GlobalFree(oldPtr);
		}
    } else if (oldPtr) {
		GlobalFree(oldPtr);
    }
    if (newPtr == NULL) {
		return NULL;	/* XXX out of memory error */
    }
    return newPtr;
}

// ***********************************************************************


/*****************************************************************************
 * wglUseFontOutlinesW
 *
 * Converts a subrange of the glyphs in a TrueType font to OpenGL display
 * lists.
 *****************************************************************************/

BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesW)(
	IN	HDC			hDC,
	IN	DWORD			first,
	IN	DWORD			count,
	IN	DWORD			listBase,
	IN	FLOAT			chordalDeviation,
	IN	FLOAT			extrusion,
	IN	INT			format,
	OUT	LPGLYPHMETRICSFLOAT	lpgmf)
{
	return _GLD_WGL_EXPORT(UseFontOutlinesA)(hDC, first, count, listBase,
		chordalDeviation, extrusion, format, lpgmf);
}

/*****************************************************************************
 * wglUseFontOutlinesA
 *
 * Converts a subrange of the glyphs in a TrueType font to OpenGL display
 * lists.
 *****************************************************************************/

BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesA)(
	IN	HDC			hDC,
			IN	DWORD			first,
			IN	DWORD			count,
			IN	DWORD			listBase,
			IN	FLOAT			chordalDeviation,
			IN	FLOAT			extrusion,
			IN	INT			format,
			OUT	LPGLYPHMETRICSFLOAT	glyphMetricsFloatArray)
	{
	DWORD	glyphIndex;
	UCHAR*	glyphBuf;
	DWORD	glyphBufSize;


	/*
	 * Flush any previous OpenGL errors.  This allows us to check for
	 * new errors so they can be reported via the function return value.
	 */
	while (_GLD_glGetError() != GL_NO_ERROR)
		;

	/*
	 * Make sure that the current font can be sampled accurately.
	 */
	hNewFont = CreateHighResolutionFont(hDC);
	if (!hNewFont)
		return FALSE;

	hOldFont = SelectObject(hDC, hNewFont);
	if (!hOldFont)
		return FALSE;

	/*
	 * Preallocate a buffer for the outline data, and track its size:
	 */
	glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = 10240);
	if (!glyphBuf)
		return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/

	/*
	 * Process each glyph in the given range:
	 */
	for (glyphIndex = first; glyphIndex - first < count; ++glyphIndex)
		{
		GLYPHMETRICS	glyphMetrics;
		DWORD		glyphSize;
		static MAT2	matrix =
			{
			{0, 1},		{0, 0},

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -