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

📄 dglwgl.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
			{0, 0},		{0, 1}
			};
		LPGLYPHMETRICSFLOAT glyphMetricsFloat =
			&glyphMetricsFloatArray[glyphIndex - first];


		/*
		 * Determine how much space is needed to store the glyph's
		 * outlines.  If our glyph buffer isn't large enough,
		 * resize it.
		 */
		glyphSize = GetGlyphOutline(	hDC,
						glyphIndex,
						GGO_NATIVE,
						&glyphMetrics,
						0,
						NULL,
						&matrix
						);
		if (glyphSize < 0)
			return FALSE; /*WGL_STATUS_FAILURE*/
		if (glyphSize > glyphBufSize)
			{
			__wglFree(glyphBuf);
			glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = glyphSize);
			if (!glyphBuf)
				return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/
			}


		/*
		 * Get the glyph's outlines.
		 */
		if (GetGlyphOutline(	hDC,
					glyphIndex,
					GGO_NATIVE,
					&glyphMetrics,
					glyphBufSize,
					glyphBuf,
					&matrix
					) < 0)
			{
			__wglFree(glyphBuf);
			return FALSE; /*WGL_STATUS_FAILURE*/
			}
		
		glyphMetricsFloat->gmfBlackBoxX =
			(FLOAT) glyphMetrics.gmBlackBoxX * ScaleFactor;
		glyphMetricsFloat->gmfBlackBoxY =
			(FLOAT) glyphMetrics.gmBlackBoxY * ScaleFactor;
		glyphMetricsFloat->gmfptGlyphOrigin.x =
			(FLOAT) glyphMetrics.gmptGlyphOrigin.x * ScaleFactor;
		glyphMetricsFloat->gmfptGlyphOrigin.y =
			(FLOAT) glyphMetrics.gmptGlyphOrigin.y * ScaleFactor;
		glyphMetricsFloat->gmfCellIncX =
			(FLOAT) glyphMetrics.gmCellIncX * ScaleFactor;
		glyphMetricsFloat->gmfCellIncY =
			(FLOAT) glyphMetrics.gmCellIncY * ScaleFactor;
		
		/*
		 * Turn the glyph into a display list:
		 */
		if (!MakeDisplayListFromGlyph(	(glyphIndex - first) + listBase,
						glyphBuf,
						glyphSize,
						glyphMetricsFloat,
						chordalDeviation + ScaleFactor,
						extrusion,
						format))
			{
			__wglFree(glyphBuf);
			return FALSE; /*WGL_STATUS_FAILURE*/
			}
		}


	/*
	 * Clean up temporary storage and return.  If an error occurred,
	 * clear all OpenGL error flags and return FAILURE status;
	 * otherwise just return SUCCESS.
	 */
	__wglFree(glyphBuf);

	SelectObject(hDC, hOldFont);

	if (_GLD_glGetError() == GL_NO_ERROR)
		return TRUE; /*WGL_STATUS_SUCCESS*/
	else
		{
		while (_GLD_glGetError() != GL_NO_ERROR)
			;
		return FALSE; /*WGL_STATUS_FAILURE*/
		}
	}



/*****************************************************************************
 * CreateHighResolutionFont
 *
 * Gets metrics for the current font and creates an equivalent font
 * scaled to the design units of the font.
 * 
 *****************************************************************************/

static HFONT
CreateHighResolutionFont(HDC hDC)
	{
	UINT otmSize;
	OUTLINETEXTMETRIC *otm;
	LONG fontHeight, fontWidth, fontUnits;
	LOGFONT logFont;

	otmSize = GetOutlineTextMetrics(hDC, 0, NULL);
	if (otmSize == 0) 
		return NULL;

	otm = (OUTLINETEXTMETRIC *) __wglMalloc(otmSize);
	if (otm == NULL)
		return NULL;

	otm->otmSize = otmSize;
	if (GetOutlineTextMetrics(hDC, otmSize, otm) == 0) 
		return NULL;
	
	fontHeight = otm->otmTextMetrics.tmHeight -
			otm->otmTextMetrics.tmInternalLeading;
	fontWidth = otm->otmTextMetrics.tmAveCharWidth;
	fontUnits = (LONG) otm->otmEMSquare;
	
	ScaleFactor = 1.0F / (FLOAT) fontUnits;

	logFont.lfHeight = - ((LONG) fontUnits);
	logFont.lfWidth = (LONG)
		((FLOAT) (fontWidth * fontUnits) / (FLOAT) fontHeight);
	logFont.lfEscapement = 0;
	logFont.lfOrientation = 0;
	logFont.lfWeight = otm->otmTextMetrics.tmWeight;
	logFont.lfItalic = otm->otmTextMetrics.tmItalic;
	logFont.lfUnderline = otm->otmTextMetrics.tmUnderlined;
	logFont.lfStrikeOut = otm->otmTextMetrics.tmStruckOut;
	logFont.lfCharSet = otm->otmTextMetrics.tmCharSet;
	logFont.lfOutPrecision = OUT_OUTLINE_PRECIS;
	logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
	logFont.lfQuality = DEFAULT_QUALITY;
	logFont.lfPitchAndFamily =
		otm->otmTextMetrics.tmPitchAndFamily & 0xf0;
	strcpy(logFont.lfFaceName,
	       (char *)otm + (int)otm->otmpFaceName);

	hNewFont = CreateFontIndirect(&logFont);
	if (hNewFont == NULL)
		return NULL;

	__wglFree(otm);

	return hNewFont;
	}



/*****************************************************************************
 * MakeDisplayListFromGlyph
 * 
 * Converts the outline of a glyph to an OpenGL display list.
 *
 * Return value is nonzero for success, zero for failure.
 *
 * Does not check for OpenGL errors, so if the caller needs to know about them,
 * it should call glGetError().
 *****************************************************************************/

static int
MakeDisplayListFromGlyph(	IN  DWORD		listName,
				IN  UCHAR*		glyphBuf,
				IN  DWORD		glyphSize,
				IN  LPGLYPHMETRICSFLOAT	glyphMetricsFloat,
				IN  FLOAT		chordalDeviation,
				IN  FLOAT		extrusion,
				IN  INT			format)
	{
	int status;

	_GLD_glNewList(listName, GL_COMPILE);
		status = DrawGlyph(	glyphBuf,
					glyphSize,
					chordalDeviation,
					extrusion,
					format);
		
	_GLD_glTranslatef(glyphMetricsFloat->gmfCellIncX,
		     glyphMetricsFloat->gmfCellIncY,
		     0.0F);
	_GLD_glEndList();

	return status;
	}



/*****************************************************************************
 * DrawGlyph
 * 
 * Converts the outline of a glyph to OpenGL drawing primitives, tessellating
 * as needed, and then draws the glyph.  Tessellation of the quadratic splines
 * in the outline is controlled by "chordalDeviation", and the drawing
 * primitives (lines or polygons) are selected by "format".
 *
 * Return value is nonzero for success, zero for failure.
 *
 * Does not check for OpenGL errors, so if the caller needs to know about them,
 * it should call glGetError().
 *****************************************************************************/

static int
DrawGlyph(	IN  UCHAR*	glyphBuf,
		IN  DWORD	glyphSize,
		IN  FLOAT	chordalDeviation,
		IN  FLOAT	extrusion,
		IN  INT		format)
	{
	INT			status = 0;
	FLOAT*			p;
	DWORD			loop;
	DWORD			point;
	GLUtesselator*		tess = NULL;


	/*
	 * Initialize the global buffer into which we place the outlines:
	 */
	if (!InitLineBuf())
		goto exit;


	/*
	 * Convert the glyph outlines to a set of polyline loops.
	 * (See MakeLinesFromGlyph() for the format of the loop data
	 * structure.)
	 */
	if (!MakeLinesFromGlyph(glyphBuf, glyphSize, chordalDeviation))
		goto exit;
	p = LineBuf;


	/*
	 * Now draw the loops in the appropriate format:
	 */
	if (format == WGL_FONT_LINES)
		{
		/*
		 * This is the easy case.  Just draw the outlines.
		 */
		for (loop = (DWORD) *p++; loop; --loop)
			{
			_GLD_glBegin(GL_LINE_LOOP);
				for (point = (DWORD) *p++; point; --point)
					{
					_GLD_glVertex2fv(p);
					p += 2;
					}
			_GLD_glEnd();
			}
		status = 1;
		}

	else if (format == WGL_FONT_POLYGONS)
		{
		double v[3];
		FLOAT *save_p = p;
		GLfloat z_value;
		
		/*
		 * This is the hard case.  We have to set up a tessellator
		 * to convert the outlines into a set of polygonal
		 * primitives, which the tessellator passes to some
		 * auxiliary routines for drawing.
		 */
		if (!LoadGLUTesselator())
			goto exit;
		if (!InitVertBuf())
			goto exit;
		if (!(tess = gluNewTessProc()))
			goto exit;
		gluTessCallbackProc(tess,	GLU_BEGIN,	(void(CALLBACK *)()) _GLD_glBegin);
		gluTessCallbackProc(tess,	GLU_TESS_VERTEX_DATA,
				    (void(CALLBACK *)()) TessVertexOutData);
		gluTessCallbackProc(tess,	GLU_END,	(void(CALLBACK *)()) _GLD_glEnd);
		gluTessCallbackProc(tess,	GLU_ERROR,	(void(CALLBACK *)()) TessError);
		gluTessCallbackProc(tess,	GLU_TESS_COMBINE, (void(CALLBACK *)()) TessCombine);
		gluTessNormalProc(tess,	0.0F, 0.0F, 1.0F);

		TessErrorOccurred = 0;
		_GLD_glNormal3f(0.0f, 0.0f, 1.0f);
		v[2] = 0.0;
		z_value = 0.0f;

		gluTessBeginPolygonProc(tess, (void *)*(int *)&z_value);
			for (loop = (DWORD) *p++; loop; --loop)
				{
				gluTessBeginContourProc(tess);
				
				for (point = (DWORD) *p++; point; --point)
					{
					v[0] = p[0];
					v[1] = p[1];
					gluTessVertexProc(tess, v, p);
					p += 2;
					}

				gluTessEndContourProc(tess);
				}
		gluTessEndPolygonProc(tess);

		status = !TessErrorOccurred;

		/* Extrusion code */
		if (extrusion) {
			DWORD loops;
			GLfloat thickness = (GLfloat) -extrusion;
			FLOAT *vert, *vert2;
			DWORD count;

			p = save_p;
			loops = (DWORD) *p++;

			for (loop = 0; loop < loops; loop++) {
				GLfloat dx, dy, len;
				DWORD last;

				count = (DWORD) *p++;
				_GLD_glBegin(GL_QUAD_STRIP);

				/* Check if the first and last vertex are identical
				 * so we don't draw the same quad twice.
				 */
				vert = p + (count-1)*2;
				last = (p[0] == vert[0] && p[1] == vert[1]) ? count-1 : count;

				for (point = 0; point <= last; point++) {
					vert  = p + 2 * (point % last);
					vert2 = p + 2 * ((point+1) % last);

					dx = vert[0] - vert2[0];
					dy = vert[1] - vert2[1];
					len = (GLfloat)sqrt(dx * dx + dy * dy);

					_GLD_glNormal3f(dy / len, -dx / len, 0.0f);
					_GLD_glVertex3f((GLfloat) vert[0],
							   (GLfloat) vert[1], thickness);
					_GLD_glVertex3f((GLfloat) vert[0],
							   (GLfloat) vert[1], 0.0f);
				}

				_GLD_glEnd();
				p += count*2;
			}

			/* Draw the back face */
			p = save_p;
			v[2] = thickness;
			_GLD_glNormal3f(0.0f, 0.0f, -1.0f);
			gluTessNormalProc(tess,	0.0F, 0.0F, -1.0F);

			gluTessBeginPolygonProc(tess, (void *)*(int *)&thickness);

			for (loop = (DWORD) *p++; loop; --loop)
			{
				count = (DWORD) *p++;

				gluTessBeginContourProc(tess);
				
				for (point = 0; point < count; point++)
				{
					vert = p + ((count-point-1)<<1);
					v[0] = vert[0];
					v[1] = vert[1];
					gluTessVertexProc(tess, v, vert);
				}
				p += count*2;

				gluTessEndContourProc(tess);
			}
			gluTessEndPolygonProc(tess);
		}

#if DEBUG
	if (TessErrorOccurred)
		printf("Tessellation error %s\n",
			gluErrorString(TessErrorOccurred));
#endif
		}


exit:
	FreeLineBuf();
	if (tess)
		gluDeleteTessProc(tess);
	// UnloadGLUTesselator();
	FreeVertBuf();
	return status;
	}



/*****************************************************************************
 * LoadGLUTesselator
 *
 * Maps the glu32.dll module and gets function pointers for the 
 * tesselator functions.
 *****************************************************************************/

static BOOL
LoadGLUTesselator(void)
	{
	if (gluModuleHandle != NULL)
		return TRUE;

	{
		extern HINSTANCE hInstanceOpenGL;
		char *gluName = "GLU32.DLL";
//		char name[256];
//		char *ptr;
//		int len;

/*
		len = GetModuleFileName(hInstanceOpenGL, name, 255);
		if (len != 0)
			{
			ptr = name+len-1;
			while (ptr > name && *ptr != '\\')
				ptr--;
			if (*ptr == '\\')
				ptr++;
			if (!stricmp(ptr, "cosmogl.dll"))
				{
				gluName = "COSMOGLU.DLL";
				}
			else if (!stricmp(ptr, "opengl32.dll"))
				{
				gluName = "GLU32.DLL";
				}
			}
*/
		if ((gluModuleHandle = LoadLibrary(gluName)) == NULL)
			return FALSE;
	}

	if ((gluNewTessProc = (gluNewTessProto)
		GetProcAddress(gluModuleHandle, "gluNewTess")) == NULL)
		return FALSE;
	
	if ((gluDeleteTessProc = (gluDeleteTessProto)
		GetProcAddress(gluModuleHandle, "gluDeleteTess")) == NULL)
		return FALSE;
	
	if ((gluTessBeginPolygonProc = (gluTessBeginPolygonProto)
		GetProcAddress(gluModuleHandle, "gluTessBeginPolygon")) == NULL)
		return FALSE;
	
	if ((gluTessBeginContourProc = (gluTessBeginContourProto)
		GetProcAddress(gluModuleHandle, "gluTessBeginContour")) == NULL)
		return FALSE;
	
	if ((gluTessVertexProc = (gluTessVertexProto)
		GetProcAddress(gluModuleHandle, "gluTessVertex")) == NULL)
		return FALSE;
	
	if ((gluTessEndContourProc = (gluTessEndContourProto)
		GetProcAddress(gluModuleHandle, "gl

⌨️ 快捷键说明

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