public void DrawArrays(OpenTK.Graphics.OpenGL.PrimitiveType pt, int st, int len) { int sf = sizeof(float); float[] ab = buffers[activeBuffer]; bool ev = enables.ContainsKey(ArrayCap.VertexArray); bool ec = enables.ContainsKey(ArrayCap.ColorArray); bool et = enables.ContainsKey(ArrayCap.TextureCoordArray); int vi = ev ? pointers[ArrayCap.VertexArray].offset / sf : 0; int ci = ec ? pointers[ArrayCap.ColorArray].offset / sf : 0; int ti = et ? pointers[ArrayCap.TextureCoordArray].offset / sf : 0; int vs = ev ? pointers[ArrayCap.VertexArray].stride / sf : 0; int cs = ec ? pointers[ArrayCap.ColorArray].stride / sf : 0; int ts = et ? pointers[ArrayCap.TextureCoordArray].stride / sf : 0; vi += vs * st; ci += cs * st; ti += ts * st; List <rend> data = new List <rend>(); for (int i = 0; i < len; i++) // index only for counting loop. { ver v = null; col c = null; tex t = null; if (ev) { v = new ver() { x = ab[vi], y = ab[vi + 1] }; vi += vs; } if (ec) { c = new col() { a = ab[ci], r = ab[ci + 1], g = ab[ci + 2], b = ab[ci + 3] }; ci += cs; } if (et) { t = new tex() { u = ab[ti], v = ab[ti + 1] }; ti += ts; } data.Add(new rend() { v = v, c = c, t = t }); } renderlist.Add(new pol() { pt = pt, data = data.ToArray() }); }
public unsafe void DrawArrays(gl.PrimitiveType mode, int first, int count) { PrimitiveType pt = PrimitiveType.TriangleStrip; if (mode != gl.PrimitiveType.TriangleStrip) { throw new NotSupportedException(); } //for tristrip int primCount = (count - 2); var pw = _CurrPipeline.Opaque as PipelineWrapper; int stride = pw.VertexStride; byte *ptr = (byte *)_pVertexData.ToPointer() + first * stride; dev.DrawUserPrimitives(pt, primCount, (void *)ptr, (uint)stride); }
/// <summary> /// Constructor to set primitive drawing mode & graphics card BufferUsage Hint /// </summary> /// <param name="drawingMode"></param> /// <param name="graphicsCardBufferUsageHint"></param> public SingleMaterialVBO(OpenTK.Graphics.OpenGL.PrimitiveType drawingMode, OpenTK.Graphics.OpenGL.BufferUsageHint graphicsCardBufferUsageHint) : base(drawingMode, graphicsCardBufferUsageHint) { }
/// <summary> /// Constructor to set primitive drawing mode /// </summary> /// <param name="drawingMode"></param> public SingleMaterialVBO(OpenTK.Graphics.OpenGL.PrimitiveType drawingMode) : base(drawingMode) { }
/// <summary> /// Constructor to set primitive drawing mode & graphics card BufferUsage Hint /// </summary> /// <param name="drawingMode"></param> /// <param name="graphicsCardBufferUsageHint"></param> public AbstractMesh(OpenTK.Graphics.OpenGL.PrimitiveType drawingMode, OpenTK.Graphics.OpenGL.BufferUsageHint graphicsCardBufferUsageHint = BufferUsageHint.StaticDraw) { DrawingMode = drawingMode; GraphicsCardBufferUsageHint = graphicsCardBufferUsageHint; }
public PolygonCollection(string name, Color color, float pointsize, OpenTK.Graphics.OpenGL.PrimitiveType ptype) : base(name, color, pointsize) { Primative = ptype; }
/// <summary> /// constructor to set the drawing mode /// </summary> public ColorVBO(OpenTK.Graphics.OpenGL.PrimitiveType drawingMode) : base(drawingMode) { }
public void DrawArrays(gl.PrimitiveType mode, int first, int count) { }
/// <summary> /// Constructor to set primitive drawing mode & graphics card BufferUsage Hint /// </summary> /// <param name="drawingMode"></param> /// <param name="graphicsCardBufferUsageHint"></param> public CompleteVBO(OpenTK.Graphics.OpenGL.PrimitiveType drawingMode, OpenTK.Graphics.OpenGL.BufferUsageHint graphicsCardBufferUsageHint) : base(drawingMode, graphicsCardBufferUsageHint) { }
/// <summary> /// drawingMode constructor instantiates the default materail & passed the drawingMode parameter to the base class AbstractMesh constructor /// </summary> /// <param name="drawingMode"></param> public AbstractSingleMaterialMesh(OpenTK.Graphics.OpenGL.PrimitiveType drawingMode) : base(drawingMode) { material = new Material(); }
/// <summary> /// default constructor = instantiate default material object & DrawingMode = Triangles /// </summary> public VertexArrayMesh(OpenTK.Graphics.OpenGL.PrimitiveType drawingMode) : base(drawingMode) { }
/// <summary> /// Render a frame. /// </summary> internal void Draw() { #if RENDERER_GL GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit | OpenTK.Graphics.OpenGL.ClearBufferMask.DepthBufferBit); #endif // Go through each of our commands that are for this frame. for (int commandIndex = 0; commandIndex < this._commandCount; commandIndex++) { // Next command to work with. Command command = this._nextFrameCommands[commandIndex]; // Default instructions if we're missing any if ((command.Instructions & CommandInstructions.SetBlendState) == CommandInstructions.None) { // Set default blend state for anything that doesn't have one explicitly set. command.SetBlendState(_defaultBlendState); } if ((command.Instructions & CommandInstructions.SetDepthState) == CommandInstructions.None) { // Set default blend state for anything that doesn't have one explicitly set. command.SetDepthState(_defaultDepthState); } if ((command.Instructions & CommandInstructions.SetRasteriserState) == CommandInstructions.None) { // Set default blend state for anything that doesn't have one explicitly set. command.SetRasteriserState(_defaultRasteriserState); } // Default shaders in case someone decided to pass us empty shaders if (String.IsNullOrEmpty(command.ShaderProgram.VertexShader.Data)) { command.ShaderProgram.VertexShader.Data = DefaultVertexShaderCode; } if (String.IsNullOrEmpty(command.ShaderProgram.FragmentShader.Data)) { command.ShaderProgram.FragmentShader.Data = DefaultFragmentShaderCode; } #if RENDERER_GL bool viewChanged = false; View view = null; if (command.ViewId != this._currentState.ViewId) { viewChanged = true; this._currentState.ViewId = command.ViewId; if (!_views.TryGetValue(command.ViewId, out view)) { //TODO: Logging to say we failed loading a command specific view view = _defaultView; } ResetViewPort(view); } if (!((command.Instructions & CommandInstructions.SetShaderProgram) != CommandInstructions.None)) { //TODO: Debug log that we dont have any program set so skipping the command instruction. continue; } GLShader vertexShader; GLShader fragmentShader; GLShaderProgram program; if (!command.ShaderProgram.VertexShader.Created) { // Build a OpenGL shader from our commands vertex shader data. vertexShader = new GLShader(command.ShaderProgram.VertexShader); this._glShaderCache.Add(command.ShaderProgram.VertexShader, vertexShader); } else { vertexShader = this._glShaderCache[command.ShaderProgram.VertexShader.ResourceIndex]; } if (!command.ShaderProgram.FragmentShader.Created) { // Build a OpenGL shader from our commands vertex shader data. fragmentShader = new GLShader(command.ShaderProgram.FragmentShader); this._glShaderCache.Add(command.ShaderProgram.FragmentShader, fragmentShader); } else { fragmentShader = this._glShaderCache[command.ShaderProgram.FragmentShader.ResourceIndex]; } // Build Shader Program as appropriate // Have we already loaded and cached a shader program. if (!command.ShaderProgram.Created) { // Build a OpenGL shader program from our commands ShaderProgram data. program = new GLShaderProgram(new GLShader[] { vertexShader, fragmentShader }); this._glProgramCache.Add(command.ShaderProgram, program); } else { program = this._glProgramCache[command.ShaderProgram.ResourceIndex]; } if ((command.Instructions & CommandInstructions.SetBlendState) != CommandInstructions.None) { // Is the blend state different if so we need to set it. if (command.BlendState != this._currentState.BlendState) { this._currentState.BlendState = command.BlendState; var bs = command.BlendState; if (bs.EnableBlending) { GL.Enable(EnableCap.Blend); var colourOp = glBlendOperationMapping[bs.ColourOperation]; var alphaOp = glBlendOperationMapping[bs.AlphaOperation]; GL.BlendEquationSeparate(colourOp, alphaOp); var sourceColour = glSrcBlendFactorMapping[bs.SourceBlendColour]; var destColour = glDstBlendFactorMapping[bs.DestinationBlendColour]; var sourceAlpha = glSrcBlendFactorMapping[bs.SourceBlendAlpha]; var destAlpha = glDstBlendFactorMapping[bs.SourceBlendAlpha]; GL.BlendFuncSeparate(sourceColour, destColour, sourceAlpha, destAlpha); if (bs.SourceBlendColour == BlendFactor.ConstantColour | bs.DestinationBlendColour == BlendFactor.ConstantColour && bs.BlendConstant != this._currentState.BlendState.BlendConstant) { GL.BlendColor(bs.BlendConstant.Red, bs.BlendConstant.Green, bs.BlendConstant.Blue, bs.BlendConstant.Alpha); } } else { GL.Disable(EnableCap.Blend); } } } if ((command.Instructions & CommandInstructions.SetDepthState) != CommandInstructions.None) { // Is the depth state different if so we need to set it. if (command.DepthState != this._currentState.DepthState) { this._currentState.DepthState = command.DepthState; var ds = command.DepthState; // Depth Test if (ds.EnableDepthTest) { GL.Enable(EnableCap.DepthTest); var df = glDepthFuncMapping[ds.DepthFunc]; GL.DepthFunc(df); } else { GL.Disable(EnableCap.DepthTest); } // Depth write if (ds.EnableDepthWrite) { GL.DepthMask(true); } else { GL.DepthMask(false); } } } if ((command.Instructions & CommandInstructions.SetRasteriserState) != CommandInstructions.None) { // Is the rasteriser state different if so we need to set it. if (command.RasteriserState != this._currentState.RasteriserState) { this._currentState.RasteriserState = command.RasteriserState; var rs = command.RasteriserState; // Cull mode if (rs.CullMode == CullMode.Clockwise) { GL.Enable(EnableCap.CullFace); GL.CullFace(OpenTK.Graphics.OpenGL.CullFaceMode.Back); } else if (rs.CullMode == CullMode.CounterClockwise) { GL.Enable(EnableCap.CullFace); GL.CullFace(OpenTK.Graphics.OpenGL.CullFaceMode.Front); } else { GL.Disable(EnableCap.CullFace); } // Multisampling if (rs.EnableMultisampling) { GL.Enable(EnableCap.Multisample); } else { GL.Disable(EnableCap.Multisample); } } } bool programChanged = false; // Do we need to change the state for the current active program. if (command.ShaderProgram != this._currentState.ShaderProgram) { this._currentState.ShaderProgram = command.ShaderProgram; GL.UseProgram(program.ProgramRef); // Predefined locations int uniformLocation; // Model transform if (program.Uniforms.TryGetValue("_model", out uniformLocation)) { this.predefinedModelUniformLocation = uniformLocation; } // View transform if (program.Uniforms.TryGetValue("_view", out uniformLocation)) { this.predefinedViewUniformLocation = uniformLocation; } // Projection transform if (program.Uniforms.TryGetValue("_projection", out uniformLocation)) { this.predefinedProjectionUniformLocation = uniformLocation; } // Program changed, so we'll need to change the uniforms. programChanged = true; } // Build Vertex Buffer as appropriate GLBuffer vb = null; if ((command.Instructions & CommandInstructions.SetVertexBuffer) != CommandInstructions.None) { if (command.VertexBuffer != null) { // Have we already loaded and cached a vertex buffer if (!command.VertexBuffer.Created) { vb = new GLBuffer(OpenTK.Graphics.OpenGL.BufferTarget.ArrayBuffer); vb.Create(command.VertexBuffer.DataType, command.VertexBuffer.Size, command.VertexBuffer.Data, command.VertexBuffer.Dynamic); this._glVBCache.Add(command.VertexBuffer, vb); } else { vb = this._glVBCache[command.VertexBuffer.ResourceIndex]; } // Do we need to update the vertex buffer data if (command.VertexBuffer.Changed) { vb.Update(command.VertexBuffer.Data, 0); command.VertexBuffer.Changed = false; } } } // Build Index Buffer as appropriate GLBuffer ib = null; if ((command.Instructions & CommandInstructions.SetIndexBuffer) != CommandInstructions.None) { if (command.IndexBuffer != null) { // Have we already loaded and cached a vertex buffer if (!command.IndexBuffer.Created) { ib = new GLBuffer(OpenTK.Graphics.OpenGL.BufferTarget.ElementArrayBuffer); ib.Create(typeof(uint), command.IndexBuffer.Size, command.IndexBuffer.Data, command.IndexBuffer.Dynamic); this._glIBCache.Add(command.IndexBuffer, ib); } else { ib = this._glIBCache[command.IndexBuffer.ResourceIndex]; } // Do we need to update the index buffer data if (command.IndexBuffer.Changed) { ib.Update(command.IndexBuffer.Data, 0); command.IndexBuffer.Changed = false; } } } if ((command.Instructions & (CommandInstructions.SetVertexBuffer | CommandInstructions.SetIndexBuffer)) != CommandInstructions.None) { if (programChanged || command.VertexBuffer != _currentState.VertexBuffer || command.IndexBuffer != _currentState.IndexBuffer) { _currentState.VertexBuffer = command.VertexBuffer; _currentState.IndexBuffer = command.IndexBuffer; // Bind the vertex buffer if (vb != null) { GL.BindBuffer(OpenTK.Graphics.OpenGL.BufferTarget.ArrayBuffer, vb.BufferId); uint index = 0; // Bind attributes that are defined for the vertex buffer var type = Activator.CreateInstance(command.VertexBuffer.DataType) as IVertex; foreach (var attribute in type.VertexDeclaration.Attributes) { VertexAttribPointerType glAttribType; Renderer.glAttribMapping.TryGetValue(attribute.Type, out glAttribType); GL.EnableVertexAttribArray(index); GL.VertexAttribPointer(index, attribute.Size, glAttribType, attribute.Normalised, type.VertexDeclaration.Stride, new IntPtr(type.VertexDeclaration.Offsets[attribute.Name])); index += 1; } } // Bind the Index Buffer if (ib != null) { GL.BindBuffer(BufferTarget.ElementArrayBuffer, ib.BufferId); } } } // For view changes we need to set view/projection matrices again if (viewChanged) { // View transform if (predefinedViewUniformLocation != -1) { unsafe { var viewMatrix = view.ViewMatrix; fixed(float *matrix_ptr = &viewMatrix[0]) { GL.UniformMatrix4(predefinedViewUniformLocation, 1, false, matrix_ptr); } } } // Projection transform if (predefinedProjectionUniformLocation != -1) { unsafe { var projectionMatrix = view.ProjectionMatrix; fixed(float *matrix_ptr = &projectionMatrix[0]) { GL.UniformMatrix4(predefinedProjectionUniformLocation, 1, false, matrix_ptr); } } } } if ((command.Instructions & CommandInstructions.SetSharedUniforms) != CommandInstructions.None) { // If we have a uniform buffer in the command and we've said we need to change them, then rebind them all to the current program. if (command.SharedUniforms != null) { int uniformLocation; foreach (var uniform in command.SharedUniforms._uniforms) { if (program.Uniforms.TryGetValue(uniform.Key.Name, out uniformLocation)) { if (uniform.Key.Type == UniformType.Matrix4x4f) { var matrix = (float[])uniform.Value; unsafe { fixed(float *matrix_ptr = &matrix[0]) { GL.UniformMatrix4(uniformLocation, 1, false, matrix_ptr); } } } else if (uniform.Key.Type == UniformType.Uniform1f) { GL.Uniform1(uniformLocation, (float)uniform.Value); } else if (uniform.Key.Type == UniformType.Uniform2f) { float[] value = uniform.Value as float[]; GL.Uniform2(uniformLocation, value[0], value[1]); } else if (uniform.Key.Type == UniformType.Uniform3f) { float[] value = uniform.Value as float[]; GL.Uniform3(uniformLocation, value[0], value[1], value[2]); } else if (uniform.Key.Type == UniformType.Uniform4f) { float[] value = uniform.Value as float[]; GL.Uniform4(uniformLocation, value[0], value[1], value[2], value[3]); } } } } } // Per command transform if ((command.Instructions & CommandInstructions.SetTransform) != CommandInstructions.None) { if (this.predefinedModelUniformLocation != -1) { { unsafe { fixed(float *matrix_ptr = &command.Transform[0]) { GL.UniformMatrix4(this.predefinedModelUniformLocation, 1, false, matrix_ptr); } } } } } // Texture bindings GLTexture glTexture; GLSampler glSampler; if ((command.Instructions & CommandInstructions.SetTextureAll) != CommandInstructions.None) { for (int stage = 0; stage < MaxTextureStages; stage++) { var textureStageEnum = (CommandInstructions)Enum.Parse(typeof(CommandInstructions), $"SetTexture{stage}"); if (command.Instructions.HasFlag(textureStageEnum)) { var currentTextureStage = _currentState.TextureStages[stage]; // Has a texture or a uniform changed, if so we need to potentially rebuild / rebind if (programChanged || command.TextureStages[stage].Texture != currentTextureStage.Texture || command.TextureStages[stage].TextureUniform != currentTextureStage.TextureUniform) { // Build Textures if required glTexture = null; if (command.TextureStages[stage].Texture != null) { // Have we already loaded and cached a texture if (!command.TextureStages[stage].Texture.Created) { glTexture = new GLTexture(); glTexture.Create(command.TextureStages[stage].Texture); this._glTextureCache.Add(command.TextureStages[stage].Texture, glTexture); } else { glTexture = this._glTextureCache[command.TextureStages[stage].Texture.ResourceIndex]; } // If a texture has changed re-create it. if (command.TextureStages[stage].Texture.Changed) { glTexture.Build(command.TextureStages[stage].Texture); } } // We must have a valid gl texture and a texture uniform defined before we can continue. if (glTexture != null && command.TextureStages[stage].TextureUniform != null) { // Activate the texture based upon which texture stage we're in. GL.ActiveTexture((TextureUnit)Enum.Parse(typeof(TextureUnit), $"Texture{stage}")); glTexture.Bind(); // Bind the texture sample uniform to the correct stage int uniformLocation; if (program.Uniforms.TryGetValue(command.TextureStages[stage].TextureUniform.Name, out uniformLocation)) { GL.Uniform1(uniformLocation, stage); } } } // Always ensure we have a texture sampler. if (command.TextureStages[stage].TextureSampler == null) { command.TextureStages[stage].TextureSampler = _defaultTextureSampler; } // If a texture sampler has changed then we are free to rebind this at any time regardless of what texture currently bound. if (programChanged || command.TextureStages[stage].TextureSampler != currentTextureStage.TextureSampler) { // Build a texture sample object if we need to glSampler = null; if (command.TextureStages[stage].TextureSampler != null) { // Have we already loaded and cached a texture if (!command.TextureStages[stage].TextureSampler.Created) { glSampler = new GLSampler(); glSampler.Create(command.TextureStages[stage].TextureSampler); this._glSamplerCache.Add(command.TextureStages[stage].TextureSampler, glSampler); } else { glSampler = this._glSamplerCache[command.TextureStages[stage].TextureSampler.ResourceIndex]; } // Did the texture sampler say it's change, if so then we need to rebuild. if (command.TextureStages[stage].TextureSampler.Changed) { glSampler.Build(command.TextureStages[stage].TextureSampler); } } // Bind the sampler to the texture stage we're working with. if (glSampler != null) { GL.BindSampler(stage, glSampler.SamplerRef); } } _currentState.TextureStages[stage] = command.TextureStages[stage]; } } } // Work out what primitive topology we should be using OpenTK.Graphics.OpenGL.PrimitiveType primType = OpenTK.Graphics.OpenGL.PrimitiveType.Triangles; if ((command.Instructions & CommandInstructions.SetPrimitiveType) != CommandInstructions.None) { if (command.PrimitiveType != _currentState.PrimitiveType) { _currentState.PrimitiveType = command.PrimitiveType; primType = glPrimitiveTypeMapping[command.PrimitiveType]; } } // Lets draw! if (ib != null) { GL.DrawElements(primType, ib.Size, OpenTK.Graphics.OpenGL.DrawElementsType.UnsignedInt, IntPtr.Zero); } else { if (vb != null) { GL.DrawArrays(primType, 0, vb.Size); } } #endif } // End of command list #if RENDERER_GL _context.SwapBuffers(); #endif }