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

📄 dglwgl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 5 页
字号:
	/*	 * 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 HFONTCreateHighResolutionFont(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 intMakeDisplayListFromGlyph(	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 intDrawGlyph(	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 BOOLLoadGLUTesselator(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, "gluTessEndContour")) == NULL)		return FALSE;		if ((gluTessEndPolygonProc = (gluTessEndPolygonProto)		GetProcAddress(gluModuleHandle, "gluTessEndPolygon")) == NULL)		return FALSE;		if ((gluTessPropertyProc = (gluTessPropertyProto)		GetProcAddress(gluModuleHandle, "gluTessProperty")) == NULL)		return FALSE;	if ((gluTessNormalProc = (gluTessNormalProto)		GetProcAddress(gluModuleHandle, "gluTessNormal")) == NULL)		return FALSE;		if ((gluTessCallbackProc = (gluTessCallbackProto)		GetProcAddress(gluModuleHandle, "gluTessCallback")) == NULL)		return FALSE;	return TRUE;	}/***************************************************************************** * UnloadGLUTesselator * * Unmaps the glu32.dll module. *****************************************************************************/static BOOLUnloadGLUTesselator(void)	{	if (gluModuleHandle != NULL)	    if (FreeLibrary(gluModuleHandle) == FALSE)		return FALSE;	gluModuleHandle = NULL;	}/***************************************************************************** * TessVertexOut * * Used by tessellator to handle output vertexes. *****************************************************************************/ static void CALLBACKTessVertexOut(FLOAT	p[3])	{	    GLfloat v[2];	    v[0] = p[0] * ScaleFactor;	    v[1] = p[1] * ScaleFactor;	    _GLD_glVertex2fv(v);	}static void CALLBACKTessVertexOutData(FLOAT	p[3], GLfloat z){    GLfloat v[3];    v[0] = (GLfloat) p[0];    v[1] = (GLfloat) p[1];    v[2] = z;    _GLD_glVertex3fv(v);}/***************************************************************************** * TessCombine * * Used by tessellator to handle self-intersecting contours and degenerate * geometry. *****************************************************************************/ static void CALLBACKTessCombine(double	coords[3],	    void*	vertex_data[4],	    FLOAT	weight[4],	    void**	outData)	{	if (!AppendToVertBuf((FLOAT) coords[0])	 || !AppendToVertBuf((FLOAT) coords[1])	 || !AppendToVertBuf((FLOAT) coords[2]))		TessErrorOccurred = GL_OUT_OF_MEMORY;	*outData = VertBuf + (VertBufIndex - 3);	}/***************************************************************************** * TessError * * Saves the last tessellator error code in the global TessErrorOccurred. *****************************

⌨️ 快捷键说明

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