Beispiel #1
0
		private static void GetSortedPoints(ref Vertex vertexA,
											ref Vertex vertexB,
											ref Vertex vertexC,
											ref TextureCoordinate textureA,
											ref TextureCoordinate textureB,
											ref TextureCoordinate textureC)
		{
			var point1 = vertexA;
			var point2 = vertexB;
			var point3 = vertexC;

			if (point2.TranslatedScreenCoordinates.Y < point1.TranslatedScreenCoordinates.Y)
			{
				var p = point1;
				point1 = point2;
				point2 = p;

				var t = textureA;
				textureA = textureB;
				textureB = t;
			}

			if (point3.TranslatedScreenCoordinates.Y < point2.TranslatedScreenCoordinates.Y)
			{
				var p = point2;
				point2 = point3;
				point3 = p;

				var t = textureB;
				textureB = textureC;
				textureC = t;
			}


			if (point2.TranslatedScreenCoordinates.Y < point1.TranslatedScreenCoordinates.Y)
			{
				var p = point1;
				point1 = point2;
				point2 = p;

				var t = textureA;
				textureA = textureB;
				textureB = t;
			}

			vertexA = point1;
			vertexB = point2;
			vertexC = point3;
		}
Beispiel #2
0
        unsafe void InitializeFont(GDIFont font)
        {
            IntPtr hdc = myTempGraphics.GetHdc();
            IntPtr hfont = font.ToHfont();
            SelectObject(hdc, hfont);

            if (!GetCharWidth32(hdc, 0, 255, CharacterWidths))
                throw new SystemException("Unable to measure character widths.");

            tagTEXTMETRIC metrics = new tagTEXTMETRIC();
            GetTextMetrics(hdc, ref metrics);
            myLeadingSpace = metrics.tmInternalLeading;
            myTrailingSpace = metrics.tmExternalLeading;

            myTempGraphics.ReleaseHdc(hdc);

            int width = 0;
            for (int i = myFirstCharacterOfInterest; i <= myLastCharacterOfInterest; i++)
            {
                CharacterWidths[i] += myLeadingSpace + myTrailingSpace;
                width += CharacterWidths[i];
            }
            myHeight = (int)Math.Round(myTempGraphics.MeasureString(myCharactersOfInterest, font).Height);

            int squareDim = (int)Math.Ceiling(Math.Sqrt(width * myHeight));
            squareDim = BitmapSource.GetValidTextureDimensionFromSize(squareDim);
            int squareWidth = squareDim;
            int squareHeight = squareDim;
            float fSquareWidth = squareWidth;
            float fSquareHeight = squareHeight;
            Bitmap bitmap;

            bool fit;
            do
            {
                bitmap = new Bitmap(squareWidth, squareHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb565);

                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    int x = 0;
                    int y = 0;

                    for (char i = myFirstCharacterOfInterest; i <= myLastCharacterOfInterest; i++)
                    {
                        if (x + CharacterWidths[i] >= fSquareWidth)
                        {
                            y += myHeight;
                            x = 0;
                        }
                        CharacterLocations[i] = new Point(x, y);

                        float uStart = x / fSquareWidth;
                        float uEnd = (x + CharacterWidths[i]) / fSquareWidth;
                        float vStart = y / fSquareHeight;
                        float vEnd = (y + myHeight) / fSquareHeight;

                        int offset = i * 4;
                        TextureCoordinates[offset] = new TextureCoordinate(uStart, vEnd);
                        TextureCoordinates[offset+ 1] = new TextureCoordinate(uStart, vStart);
                        TextureCoordinates[offset + 2] = new TextureCoordinate(uEnd, vEnd);
                        TextureCoordinates[offset + 3] = new TextureCoordinate(uEnd, vStart);

                        g.DrawString(i.ToString(), font, myWhiteBrush, x, y);
                        // adding a 1 pixel extra margin on the left seems to clear up some artifacting
                        // that occurs as a result of glyphs being too close together.
                        x += CharacterWidths[i] + 1;
                    }

                    fit = y + myHeight < fSquareHeight;
                    if (!fit)
                    {
                        squareWidth <<= 1;
                        fSquareWidth = squareWidth;
                    }
                }
            }
            while (!fit);

            byte[] alphaBytes = new byte[bitmap.Width * bitmap.Height];
            BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format16bppRgb565);

            int pixCount = 0;
            for (int y = 0; y < bitmap.Height; y++)
            {
                short* yp = (short*)((int)data.Scan0 + data.Stride * y);
                for (int x = 0; x < bitmap.Width; x++, pixCount++)
                {
                    short* p = (short*)(yp + x);
                    short pixel = *p;
                    byte b = (byte)((pixel & 0x1F) << 3);
                    byte g = (byte)(((pixel >> 5) & 0x3F) << 2);
                    byte r = (byte)(((pixel >> 11) & 0x1F) << 3);
                    byte totalAlpha = (byte)((r + g + b) / 3);
                    alphaBytes[pixCount] = totalAlpha;
                }
            }
            bitmap.UnlockBits(data);
            bitmap.Dispose();

            uint tex = 0;
            gl.GenTextures(1, &tex);
            gl.BindTexture(gl.GL_TEXTURE_2D, tex);

            fixed (byte* alphaBytesPointer = alphaBytes)
            {
                gl.TexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_ALPHA, squareWidth, squareHeight, 0, gl.GL_ALPHA, gl.GL_UNSIGNED_BYTE, (IntPtr)alphaBytesPointer);
            }

            gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR);
            gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR);
            gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE);
            gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE);

            mySource = new BitmapSource();
            mySource.myWidth = squareWidth;
            mySource.myHeight = squareHeight;
            mySource.myName = tex;
            mySource.myIsTransparent = true;
        }
Beispiel #3
0
		public static void Draw(IBuffers buffers, ISpanRenderer renderer, TriangleShade shade, Face face, Vertex[] vertices, TextureCoordinate[] textureCoordinates)
		{
			var vertexA = vertices[face.A];
			var vertexB = vertices[face.B];
			var vertexC = vertices[face.C];
			var textureA = ZeroTextureCoordinate;
			var textureB = ZeroTextureCoordinate;
			var textureC = ZeroTextureCoordinate;
			Image image = null;
			ImageContext texture = null;

			var useTexture = false;
			if( null != face.Material && null != face.Material.DiffuseMap)
			{
				useTexture = true;
				image = face.Material.DiffuseMap;
				texture = face.Material.DiffuseMap.ImageContext as ImageContext;
				textureA = textureCoordinates[face.DiffuseA];
				textureB = textureCoordinates[face.DiffuseB];
				textureC = textureCoordinates[face.DiffuseC];
			}

			
			/*
			SetSphericalEnvironmentMapTextureCoordinate(ref vertexA, ref textureA);
			SetSphericalEnvironmentMapTextureCoordinate(ref vertexB, ref textureB);
			SetSphericalEnvironmentMapTextureCoordinate(ref vertexC, ref textureC);
			*/

			GetSortedPoints(ref vertexA, ref vertexB, ref vertexC, ref textureA, ref textureB, ref textureC);

			var interpolator = GetInterpolatorForFace(face, shade);

			var secondaryStartY = (int)(vertexB.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y);
			var spreadCount = ((int)(vertexC.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y)) + 1;

			interpolator.SetPoint(0, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X);
			interpolator.SetPoint(1, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X, secondaryStartY);
			interpolator.SetPoint(2, vertexA.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ);
			interpolator.SetPoint(3, vertexA.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ, secondaryStartY);

			if (useTexture)
			{
				interpolator.SetPoint(4, textureA.U, textureC.U);
				interpolator.SetPoint(5, textureA.U, textureB.U, textureB.U, textureC.U, secondaryStartY);
				interpolator.SetPoint(6, textureA.V, textureC.V);
				interpolator.SetPoint(7, textureA.V, textureB.V, textureB.V, textureC.V, secondaryStartY);
			}

			var color = Color.FromArgb(0xff, 0xff, 0xff, 0xff);

			if (shade == TriangleShade.Gouraud && !useTexture)
			{
				var vertexAColor = vertexA.Color.ToVector();
				var vertexBColor = vertexB.Color.ToVector();
				var vertexCColor = vertexC.Color.ToVector();

				interpolator.SetPoint(4, vertexAColor.Red, vertexCColor.Red);
				interpolator.SetPoint(5, vertexAColor.Red, vertexBColor.Red, vertexBColor.Red, vertexCColor.Red, secondaryStartY);

				interpolator.SetPoint(6, vertexAColor.Green, vertexCColor.Green);
				interpolator.SetPoint(7, vertexAColor.Green, vertexBColor.Green, vertexBColor.Green, vertexCColor.Green, secondaryStartY);

				interpolator.SetPoint(8, vertexAColor.Blue, vertexCColor.Blue);
				interpolator.SetPoint(9, vertexAColor.Blue, vertexBColor.Blue, vertexBColor.Blue, vertexCColor.Blue, secondaryStartY);

				interpolator.SetPoint(10, vertexAColor.Alpha, vertexCColor.Alpha);
				interpolator.SetPoint(11, vertexAColor.Alpha, vertexBColor.Alpha, vertexBColor.Alpha, vertexCColor.Alpha, secondaryStartY);
			}
			else
			{
				color = face.Color;
			}

			
			interpolator.Interpolate(spreadCount);



			var yPosition = vertexA.TranslatedScreenCoordinates.Y;
			var clip = false;

			if( null == buffers )
			{
				return;
			}


			for (var index = 0; index < spreadCount; index++)
			{

				if( yPosition < 0 || yPosition >= buffers.Height )
				{
					clip = true;
				} else
				{
					clip = false;
				}

				

				var span = GetSpan(index, interpolator, vertexA, useTexture);
				if (null != span && !clip )
				{
					var actualSpan = (Span)span;
					var swapIndex = ((Span)span).Swap ? 1 : 0;

					actualSpan.ZStart = interpolator.Points[2 + swapIndex].InterpolatedValues[index];
					actualSpan.ZEnd = interpolator.Points[3 - swapIndex].InterpolatedValues[index];
					switch (shade)
					{
						case TriangleShade.Flat:
							{
								if (useTexture)
								{
									renderer.Texture(buffers, actualSpan, image, texture);
								}
								else
								{
									renderer.Flat(buffers, actualSpan, color);
								}
							}
							break;

						case TriangleShade.Gouraud:
							{
								if (useTexture)
								{
									renderer.Texture(buffers, actualSpan, image, texture);
								}
								else
								{
									actualSpan.ColorStart.Red = interpolator.Points[4 + swapIndex].InterpolatedValues[index];
									actualSpan.ColorEnd.Red = interpolator.Points[5 - swapIndex].InterpolatedValues[index];
									actualSpan.ColorStart.Green = interpolator.Points[6 + swapIndex].InterpolatedValues[index];
									actualSpan.ColorEnd.Green = interpolator.Points[7 - swapIndex].InterpolatedValues[index];
									actualSpan.ColorStart.Blue = interpolator.Points[8 + swapIndex].InterpolatedValues[index];
									actualSpan.ColorEnd.Blue = interpolator.Points[9 - swapIndex].InterpolatedValues[index];
									actualSpan.ColorStart.Alpha = interpolator.Points[10 + swapIndex].InterpolatedValues[index];
									actualSpan.ColorEnd.Alpha = interpolator.Points[11 - swapIndex].InterpolatedValues[index];
									renderer.Gouraud(buffers, actualSpan);
								}
							}
							break;
					}
				}
				yPosition++;
			}
		}
Beispiel #4
0
		private static void SetSphericalEnvironmentMapTextureCoordinate(ref Vertex vertex, ref TextureCoordinate textureCoordinate)
		{
			var u = vertex.TransformedVectorNormalized;
			var n = vertex.TransformedNormal;
			var r = Vector.Reflect(n, u);
			var m = Math.Core.Sqrt((r.X * r.X) + (r.Y * r.Y) +
									 ((r.Z + 1f) * (r.Z + 1f)));
			var s = (r.X / m) + 0.5f;
			var t = (r.Y / m) + 0.5f;
			textureCoordinate.U = s;
			textureCoordinate.V = t;
		}