public OpenGLShape GetShape(ref OpenGLShapeInfo info) { // // Hopefully, we already have this shape // var ss = _shapesByType [(int)info.ShapeType]; foreach (var s in ss) { if (s.Info.Equals (ref info)) { return s; } } // // Uh oh, have to make it. // _needsSave = true; var shape = new OpenGLShape (info); ss.Add (shape); // // Find out its texture requirements // var r = shape.Info.GetTextureRequirements (); // // Try to find a texture that can meet those requirements // foreach (var t in _textures) { if (t.TryInsert (r)) { break; } } // // If we couldn't find a texture that could take this reference, // we better get another texture // if (r.Texture == null) { // // Discover the largest texture we can handle. // It is the smaller of that supported by OpenGL // and whatever the renderer can handle. // var maxSize = 0; GL.GetInteger (All.MaxTextureSize, ref maxSize); maxSize = Math.Min (MaxTextureSize, maxSize); // // Create that texture if this shape will fit in it // if (r.Frame.Width <= maxSize && r.Frame.Height <= maxSize) { var tex = CreateTexture (maxSize, maxSize); tex.NeedsSave = true; _textures.Add (tex); tex.TryInsert (r); } } shape.TextureReference = r; return shape; }
public void Open() { var path = ShapeStorePath; if (string.IsNullOrEmpty (path)) return; EnsurePathExists (path); // // Load textures // var ti = 0; var foundTexture = true; var textures = new List<OpenGLTexture> (); while (foundTexture) { try { var t = ReadTexture (ti); foundTexture = t != null; if (foundTexture) { textures.Insert (ti, t); } ti++; } catch (Exception) { foundTexture = false; } } // // Load the shapes // var shapesByType = CreateShapesByType (); using (var r = System.Xml.XmlReader.Create (System.IO.Path.Combine (path, "ShapeStore.xml"))) { while (r.Read ()) { if (r.IsStartElement ("Shape")) { try { var s = new OpenGLShape (r.ReadSubtree (), textures); if (s.TextureReference.Texture != null) { shapesByType[(int)s.Info.ShapeType].Add (s); } } catch (Exception) { } } } } // // Done! // _textures = textures; _shapesByType = shapesByType; }
void AddShape(OpenGLShape shape, float x, float y) { var tex = shape.TextureReference; if (tex != null && tex.Texture != null && _nextDrawCallIndex < MaxDrawCalls) { // // Remember which shapes we're drawing so that they // can be rendered into their textures // if (!_frameShapes.ContainsKey (shape)) { _frameShapes.Add (shape, shape); } // // Get a buffer with enough space // EnsureRoomForVertices (4); var b = _buffers[_currentBufferIndex]; var i = b.Length; // // The position must be computed such that the point // ShapeOffset is aligned to x, y // var tx = x - tex.ShapeOffset.X; var ty = y - tex.ShapeOffset.Y; b.Positions[i] = new Vector2 (tx, ty); b.Positions[i + 1] = new Vector2 (tx, ty + tex.Height); b.Positions[i + 2] = new Vector2 (tx + tex.Width, ty + tex.Height); b.Positions[i + 3] = new Vector2 (tx + tex.Width, ty); // // TexCoords and Color are simple, you should be able to understand them ;-) // b.TexCoords[i] = new Vector2 (tex.U, tex.V); b.TexCoords[i + 1] = new Vector2 (tex.U, tex.V + tex.TexHeight); b.TexCoords[i + 2] = new Vector2 (tex.U + tex.TexWidth, tex.V + tex.TexHeight); b.TexCoords[i + 3] = new Vector2 (tex.U + tex.TexWidth, tex.V); b.Colors[i] = _color; b.Colors[i + 1] = _color; b.Colors[i + 2] = _color; b.Colors[i + 3] = _color; b.Length += 4; // // Record the draw call // var call = new OpenGLDrawArrayCall { Operation = All.TriangleFan, BufferIndex = (byte)_currentBufferIndex, Offset = (ushort)i, NumVertices = 4, Texture = tex.Texture, }; _calls[_nextDrawCallIndex] = call; _nextDrawCallIndex++; } }