protected virtual void Create() { LogManager.Log(LogLevel.Debug, "Texture.Create()"); // Not needed on newer OpenGL if (!GlHelper.HasExtension("GL_ARB_texture_non_power_of_two")) { if (!IsPowerOf2(width) || !IsPowerOf2(height)) { throw new Exception("Texture size must be power of 2"); } } GlUtil.Assert("before creating texture"); CreateTexture(); try { gl.BindTexture(gl.TEXTURE_2D, Handle); gl.TexImage2D(gl.TEXTURE_2D, 0, (int)glformat, (int)width, (int)height, 0, gl.RGBA, gl.UNSIGNED_BYTE, IntPtr.Zero); GlUtil.Assert("creating texture (too big?)"); SetTextureParams(); } catch (Exception) { uint[] handles = { Handle }; gl.DeleteTextures(1, handles); throw; } }
protected override void Create() { // Not needed on newer OpenGL if (!GlHelper.HasExtension("GL_ARB_texture_non_power_of_two")) { if (!IsPowerOf2(width) || !IsPowerOf2(height)) { throw new Exception("Texture size must be power of 2"); } } GlUtil.Assert("before creating texture"); CreateTexture(); try { gl.BindTexture(gl.TEXTURE_2D, Handle); gl.TexImage2D(gl.TEXTURE_2D, 0, (int)gl.RGBA, (int)width, (int)height, 0, (pixbuf.HasAlpha ? gl.RGBA : gl.RGB), gl.UNSIGNED_BYTE, pixbuf.Pixels); GlUtil.Assert("creating texture (too big?)"); SetTextureParams(); this.pixbuf = null; //gc can take it now } catch (Exception) { uint[] handles = { Handle }; gl.DeleteTextures(1, handles); throw; } }
public ImageTexture(Stream input) { Gdk.Pixbuf pixbuf = new Gdk.Pixbuf(input); uint width = (uint)pixbuf.Width; uint height = (uint)pixbuf.Height; // Round to next power-of-two isn't needed with newer OpenGL versions if (!GlHelper.HasExtension("GL_ARB_texture_non_power_of_two")) { width = NextPowerOfTwo((uint)width); height = NextPowerOfTwo((uint)height); } Gdk.Pixbuf target = new Gdk.Pixbuf(Gdk.Colorspace.Rgb, true, 8, (int)width, (int)height); pixbuf.CopyArea(0, 0, pixbuf.Width, pixbuf.Height, target, 0, 0); ImageWidth = (float)pixbuf.Width; ImageHeight = (float)pixbuf.Height; this.width = (uint)target.Width; this.height = (uint)target.Height; this.pixbuf = target; }
public void Apply() { if (body.IsFrozen) { GlHelper.GlColor3(0, 0, 1); } else { GlHelper.GlColor3(1, 1, 1); } }
/// <summary> /// Push the modelview matrix, load the identity and load a new matrix at the origin and looking the same way as the player. /// After rendering the skybox, enable blending and render the sun and moon. /// </summary> /// <remarks> /// A future optimization would be to draw all opaque world objects first and then render the skybox followed by transparent world objects. /// This prevents the pixel shader from drawing many of the same pixels twice. However is more complicated for a small benefit. /// </remarks> public void Render(FrameEventArgs e) { GL.PushMatrix(); GL.LoadIdentity(); var sky = Matrix4d.LookAt(0, 0, 0, (float)Math.Cos(Game.Player.Coords.Direction) * (float)Math.Cos(Game.Player.Coords.Pitch), (float)Math.Sin(Game.Player.Coords.Pitch), (float)Math.Sin(Game.Player.Coords.Direction) * (float)Math.Cos(Game.Player.Coords.Pitch), 0, 1, 0); GL.LoadMatrix(ref sky); GL.PushAttrib(AttribMask.EnableBit); GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.Texture2D); const float TOP = 0.3f; const float BOTTOM = 0.04f; //make bottom color at the horizon so we can always set the fog color to the same and have nice blending const float SIDE = 0.5f; const float SIDE_OUT = SIDE + SIDE / 2; //where the sides stick out to create 8 faces //draw skybox as a triangle fan with a center top point and 8 bottom points, cuts down on the noticeable gradient corners //drawn clockwise because we are "inside" the skybox, not in a display list because the colors change on every render (could make a dynamic vbo) GL.Begin(BeginMode.TriangleFan); GL.Color3(SkyTopCurrentColor.ToFloatArray()); GL.Vertex3(0, TOP, 0); //center top point GL.Color3(SkyBottomCurrentColor.ToFloatArray()); GL.Vertex3(SIDE, BOTTOM, SIDE); GL.Vertex3(0, BOTTOM, SIDE_OUT); GL.Vertex3(-SIDE, BOTTOM, SIDE); GL.Vertex3(-SIDE_OUT, BOTTOM, 0); GL.Vertex3(-SIDE, BOTTOM, -SIDE); GL.Vertex3(0, BOTTOM, -SIDE_OUT); GL.Vertex3(SIDE, BOTTOM, -SIDE); GL.Vertex3(SIDE_OUT, BOTTOM, 0); GL.Vertex3(SIDE, BOTTOM, SIDE); GL.End(); GlHelper.ResetColor(); //render sun/moon GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); DisplayList.RenderDisplayList(DisplayList.SunId, SunPosition.X, SunPosition.Y, 0, Textures.EnvironmentTextureType.Sun); DisplayList.RenderDisplayList(DisplayList.MoonId, -SunPosition.X, -SunPosition.Y, 0, Textures.EnvironmentTextureType.Moon); GL.PopAttrib(); GL.PopMatrix(); }
internal override void Render(FrameEventArgs e) { base.Render(e); //sets light color, the color assigned will be the block the lower body is on GlHelper.ResetTexture(); //note that these rotations might seem counterintuitive - use the right-hand-rule -bm //render lower body GL.PushMatrix(); GL.Translate(Coords.Xf, Coords.Yf, Coords.Zf); GL.Rotate(MathHelper.RadiansToDegrees(Coords.Direction), -Vector3.UnitY); GL.CallList(DisplayList.TorsoId); //render upper body GL.Translate(Vector3.UnitY * Constants.PLAYER_EYE_LEVEL); //moves to eye level and render head GL.Rotate(Math.Max(MathHelper.RadiansToDegrees(Coords.Pitch), -40), Vector3.UnitZ); //pitch head up and down, doesnt need to be turned because the body already turned. cap at -40degrees or it looks weird GL.CallList(DisplayList.HeadId); GL.PopMatrix(); }
/// <summary> /// Renders this face. /// </summary> public void Render(int offsetX, int offsetY) { renderingStack.Push(this); try { if (this.Background.Color.HasValue && Size.Width.HasValue && Size.Height.HasValue) { Rectangle DrawArea = new Rectangle(offsetX, offsetY, Size.Width.Value, Size.Height.Value); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glPushMatrix(); Gl.glLoadIdentity(); Gl.glScalef(Game.Scale, Game.Scale, 1); Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA); GlHelper.SetColor(this.Background.Color.Value); Gl.glBegin(Gl.GL_QUADS); Gl.glVertex3f(DrawArea.Left, DrawArea.Top, 0); Gl.glVertex3f(DrawArea.Right, DrawArea.Top, 0); Gl.glVertex3f(DrawArea.Right, DrawArea.Bottom, 0); Gl.glVertex3f(DrawArea.Left, DrawArea.Bottom, 0); Gl.glEnd(); Gl.glColor3f(1, 1, 1); Gl.glPopMatrix(); } if (this.Background.Image.HasValue) { string currentImageId = this.Background.Image.Value; if (string.IsNullOrEmpty(lastImageId) || currentImageId != lastImageId) { if (lastTexture != null) { lastTexture.RemoveUser(); } lastImageId = currentImageId; lastTexture = Game.TextureManager.GetTexture(this.Background.Image.Value); } lastTexture.Draw(offsetX, offsetY); } // TODO: Implement background repeat, preferably by cleverly using texture coordinates on the image rendering quad. // This is probably impossible for images in tile-sets (and any with custom DrawArea) without the use of shaders. // We can either split it in multiple quads (one tile each) - that's quite wasteful, or we can make the TextureManagerItem // split the original tile-set into multiple autonomous textures (tile-sets aren't implemented yet anyway) if (this.Background.Repeat.GetValueOrDefault(GuiRepeatStyle.NoRepeat) != GuiRepeatStyle.NoRepeat) { throw new NotSupportedException("Background repeat not supported yet."); } foreach (var control in Controls) { control.Render(offsetX, offsetY); } } finally { renderingStack.Pop(); } }