public FrameBuffer(Size size) { this.size = size; if (!Exts.IsPowerOf2(size.Width) || !Exts.IsPowerOf2(size.Height)) { throw new InvalidDataException(string.Format("Frame buffer size ({0}x{1}) must be a power of two", size.Width, size.Height)); } GL.GenFramebuffers(1, out framebuffer); GraphicsExtensions.CheckGLError(); GL.BindFramebuffer(FramebufferTarget.FramebufferExt, framebuffer); GraphicsExtensions.CheckGLError(); //Color texture = new Graphics.Texture(); texture.SetEmpty(size.Width, size.Height); GL.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, texture.ID, 0); GraphicsExtensions.CheckGLError(); //Depth GL.GenRenderbuffers(1, out depth); GraphicsExtensions.CheckGLError(); GL.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, depth); GraphicsExtensions.CheckGLError(); GL.RenderbufferStorage(RenderbufferTarget.RenderbufferExt, RenderbufferStorage.DepthComponent24Oes, size.Width, size.Height); GraphicsExtensions.CheckGLError(); GL.FramebufferRenderbuffer(FramebufferTarget.FramebufferExt, FramebufferAttachment.DepthAttachment, RenderbufferTarget.RenderbufferExt, depth); GraphicsExtensions.CheckGLError(); //Test for completeness var status = GL.CheckFramebufferStatus(FramebufferTarget.FramebufferExt); if (status != FramebufferErrorCode.FramebufferCompleteExt) { throw new InvalidOperationException("OpenGL Error:" + status); } //Restore default buffer GL.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); GraphicsExtensions.CheckGLError(); }
public void SetData(T[] data, int start, int length) { Bind(); var ptr = GCHandle.Alloc(data, GCHandleType.Pinned); try { GL.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(VertexSize * start), new IntPtr(VertexSize * length), ptr.AddrOfPinnedObject()); } finally { ptr.Free(); } GraphicsExtensions.CheckGLError(); }
private int CompileShaderObject(ShaderType type, string name) { //var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); var ext = type == ShaderType.VertexShader ? "vert" : "frag"; var filename = Path.Combine("Content", "glsl", name + "." + ext); //var filePath = Path.Combine(documentsPath, filename); var code = string.Empty; using (var reader = new StreamReader(Android.App.Application.Context.Assets.Open(filename))) { code = reader.ReadToEnd(); } //System.Text.Encoding.ASCII.GetString(Android.App.Application.Context.Assets.Open(filename)); var shader = GL.CreateShader(type); GraphicsExtensions.CheckGLError(); unsafe { var length = code.Length; GL.ShaderSource2(shader, 1, new string[] { code }, new IntPtr(&length)); } GraphicsExtensions.CheckGLError(); GL.CompileShader(shader); GraphicsExtensions.CheckGLError(); int compiled; GL.GetShader(shader, ShaderParameter.CompileStatus, out compiled); GraphicsExtensions.CheckGLError(); if (compiled == 0) { var log = GL.GetShaderInfoLog(shader); GraphicsExtensions.CheckGLError(); shader = -1; throw new InvalidOperationException("Shader Compilation Failed"); } return(shader); }
public void SetMatrix(string name, float[] mtx) { Threading.EnsureUIThread(); if (mtx.Length != 16) { throw new InvalidDataException("Invalid 4x4 matrix"); } GL.UseProgram(program); GraphicsExtensions.CheckGLError(); var param = GL.GetUniformLocation(program, name); GraphicsExtensions.CheckGLError(); unsafe { fixed(float *pMtx = mtx) GL.UniformMatrix4fv(param, 1, false, new IntPtr(pMtx)); } GraphicsExtensions.CheckGLError(); }
public void EnableScissor(int left, int top, int width, int height) { Threading.EnsureUIThread(); if (width < 0) { width = 0; } if (height < 0) { height = 0; } var bottom = PresentationParameters.BackBufferHeight - (top + height); GL.Scissor(left, bottom, width, height); GraphicsExtensions.CheckGLError(); GL.Enable(EnableCap.ScissorTest); GraphicsExtensions.CheckGLError(); }
public byte[] GetData() { Threading.EnsureUIThread(); var data = new byte[4 * Size.Width * Size.Height]; GraphicsExtensions.CheckGLError(); GL.BindTexture(TextureTarget.Texture2D, texture); //unsafe //{ // fixed(byte*ptr = &data[0]) // { // var intPtr = new IntPtr((void*)ptr); // GL.GetTexImageInternal(TextureTarget.Texture2D, 0, PixelFormat.BGRA_EXT, PixelType.UnsignedByte, intPtr); // } //} GL.GetTexImage(TextureTarget.Texture2D, 0, PixelFormat.BGRA_EXT, PixelType.UnsignedByte, data); GraphicsExtensions.CheckGLError(); return(data); }
public VertexBuffer(int size) { GL.GenBuffers(1, out buffer); GraphicsExtensions.CheckGLError(); Bind(); //Generates a buffer with uninitialized memory. GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(VertexSize * size), IntPtr.Zero, BufferUsageHint.DynamicDraw); GraphicsExtensions.CheckGLError(); //We need to zero all the memory,Let's generate a smallish array and copy that over the whole buffer. var zeroedArrayElementSize = Math.Min(size, 2048); var ptr = GCHandle.Alloc(new T[zeroedArrayElementSize], GCHandleType.Pinned); try { for (var offset = 0; offset < size; offset += zeroedArrayElementSize) { var length = Math.Min(zeroedArrayElementSize, size - offset); GL.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(VertexSize * offset), new IntPtr(VertexSize * length), ptr.AddrOfPinnedObject()); GraphicsExtensions.CheckGLError(); } //GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(VertexSize * size), ptr.AddrOfPinnedObject(), BufferUsageHint.DynamicDraw); } finally { ptr.Free(); } //GraphicsExtensions.CheckGLError(); }
public Shader(string name) { var vertexShader = CompileShaderObject(ShaderType.VertexShader, name); var fragmentShader = CompileShaderObject(ShaderType.FragmentShader, name); program = GL.CreateProgram(); GraphicsExtensions.CheckGLError(); GL.BindAttribLocation(program, VertexPosAttributeIndex, "aVertexPosition"); GraphicsExtensions.CheckGLError(); GL.BindAttribLocation(program, TexCoordAttributeIndex, "aVertexTexCoord"); GraphicsExtensions.CheckGLError(); GL.BindAttribLocation(program, TexMetadataAttributeIndex, "aVertexTexMetadata"); GraphicsExtensions.CheckGLError(); GL.AttachShader(program, vertexShader); GraphicsExtensions.CheckGLError(); GL.AttachShader(program, fragmentShader); GraphicsExtensions.CheckGLError(); GL.LinkProgram(program); GraphicsExtensions.CheckGLError(); int success; GL.GetProgram(program, GetProgramParameterName.LinkStatus, out success); GraphicsExtensions.CheckGLError(); if (success == 0) { var log = GL.GetProgramInfoLog(program); GraphicsExtensions.CheckGLError(); GL.DetachShader(program, vertexShader); GraphicsExtensions.CheckGLError(); GL.DetachShader(program, fragmentShader); GraphicsExtensions.CheckGLError(); throw new InvalidOperationException("Unable to link effect program."); } GL.UseProgram(program); GraphicsExtensions.CheckGLError(); int numUniforms; //GL.GetProgram(program, GetProgramParameterName.LogLength, out numUniforms); GL.GetProgram(program, GetProgramParameterName.ActiveUniforms, out numUniforms); GraphicsExtensions.CheckGLError(); var nextTexUnit = 0; for (var i = 0; i < numUniforms; i++) { int length, size; int type; var sb = new StringBuilder(128); GL.GetActiveUniform(program, i, 128, out length, out size, out type, sb); GraphicsExtensions.CheckGLError(); var sampler = sb.ToString(); if (type == 35678) { samplers.Add(sampler, nextTexUnit); var loc = GL.GetUniformLocation(program, sampler); GraphicsExtensions.CheckGLError(); GL.Uniform1(loc, nextTexUnit); GraphicsExtensions.CheckGLError(); nextTexUnit++; } } }
private void PlatformInitialize(GraphicsDevice device) { #if GLES SupportsNonPowerOfTwo = GL.Extensions.Contains("GL_OES_texture_npot") || GL.Extensions.Contains("GL_ARB_texture_non_power_of_two") || GL.Extensions.Contains("GL_IMG_texture_npot") || GL.Extensions.Contains("GL_NV_texture_npot_2D_mipmap"); #else // Unfortunately non PoT texture support is patchy even on desktop systems and we can't // rely on the fact that GL2.0+ supposedly supports npot in the core. // Reference: http://aras-p.info/blog/2012/10/17/non-power-of-two-textures/ SupportsNonPowerOfTwo = device._maxTextureSize >= 8192; #endif SupportsTextureFilterAnisotropic = GL.Extensions.Contains("GL_EXT_texture_filter_anisotropic"); #if GLES SupportsDepth24 = GL.Extensions.Contains("GL_OES_depth24"); SupportsPackedDepthStencil = GL.Extensions.Contains("GL_OES_packed_depth_stencil"); SupportsDepthNonLinear = GL.Extensions.Contains("GL_NV_depth_nonlinear"); SupportsTextureMaxLevel = GL.Extensions.Contains("GL_APPLE_texture_max_level"); #else SupportsDepth24 = true; SupportsPackedDepthStencil = true; SupportsDepthNonLinear = false; SupportsTextureMaxLevel = true; #endif // Texture compression SupportsS3tc = GL.Extensions.Contains("GL_EXT_texture_compression_s3tc") || GL.Extensions.Contains("GL_OES_texture_compression_S3TC") || GL.Extensions.Contains("GL_EXT_texture_compression_dxt3") || GL.Extensions.Contains("GL_EXT_texture_compression_dxt5"); SupportsDxt1 = SupportsS3tc || GL.Extensions.Contains("GL_EXT_texture_compression_dxt1"); SupportsPvrtc = GL.Extensions.Contains("GL_IMG_texture_compression_pvrtc"); SupportsEtc1 = GL.Extensions.Contains("GL_OES_compressed_ETC1_RGB8_texture"); SupportsAtitc = GL.Extensions.Contains("GL_ATI_texture_compression_atitc") || GL.Extensions.Contains("GL_AMD_compressed_ATC_texture"); // Framebuffer objects #if GLES SupportsFramebufferObjectARB = GL.BoundApi == GL.RenderApi.ES && (device.glMajorVersion >= 2 || GL.Extensions.Contains("GL_ARB_framebuffer_object")); // always supported on GLES 2.0+ SupportsFramebufferObjectEXT = GL.Extensions.Contains("GL_EXT_framebuffer_object");; SupportsFramebufferObjectIMG = GL.Extensions.Contains("GL_IMG_multisampled_render_to_texture") | GL.Extensions.Contains("GL_APPLE_framebuffer_multisample") | GL.Extensions.Contains("GL_EXT_multisampled_render_to_texture") | GL.Extensions.Contains("GL_NV_framebuffer_multisample"); #else // if we're on GL 3.0+, frame buffer extensions are guaranteed to be present, but extensions may be missing // it is then safe to assume that GL_ARB_framebuffer_object is present so that the standard function are loaded SupportsFramebufferObjectARB = device.glMajorVersion >= 3 || GL.Extensions.Contains("GL_ARB_framebuffer_object"); SupportsFramebufferObjectEXT = GL.Extensions.Contains("GL_EXT_framebuffer_object"); #endif // Anisotropic filtering int anisotropy = 0; if (SupportsTextureFilterAnisotropic) { GL.GetInteger((GetPName)GetParamName.MaxTextureMaxAnisotropyExt, out anisotropy); GraphicsExtensions.CheckGLError(); } MaxTextureAnisotropy = anisotropy; // sRGB #if GLES SupportsSRgb = GL.Extensions.Contains("GL_EXT_sRGB"); #else SupportsSRgb = GL.Extensions.Contains("GL_EXT_texture_sRGB") && GL.Extensions.Contains("GL_EXT_framebuffer_sRGB"); #endif // TODO: Implement OpenGL support for texture arrays // once we can author shaders that use texture arrays. SupportsTextureArrays = false; SupportsDepthClamp = GL.Extensions.Contains("GL_ARB_depth_clamp"); SupportsVertexTextures = false; // For now, until we implement vertex textures in OpenGL. GL.GetInteger((GetPName)GetParamName.MaxSamples, out _maxMultiSampleCount); #if GLES SupportsInstancing = false; #else SupportsInstancing = GL.VertexAttribDivisor != null; #endif }
public void DisableScissor() { Threading.EnsureUIThread(); GL.Disable(EnableCap.ScissorTest); GraphicsExtensions.CheckGLError(); }
public void ClearDepthBuffer() { Threading.EnsureUIThread(); GL.Clear(ClearBufferMask.DepthBufferBit); GraphicsExtensions.CheckGLError(); }
public void DisableDepthBuffer() { Threading.EnsureUIThread(); GL.Disable(EnableCap.DepthTest); GraphicsExtensions.CheckGLError(); }
public void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices) { GL.DrawArrays(ModelFromPrimitiveType(pt), firstVertex, numVertices); GraphicsExtensions.CheckGLError(); }
public Texture() { GL.GenTextures(1, out texture); GraphicsExtensions.CheckGLError(); }