public void RenderWithStruct(SharpGL.OpenGL gl, SharpGL.SceneGraph.Core.RenderMode renderMode) { //if (!this.IsRenderable()) //return; ShaderProgram shader = this.shader; //GetShader(gl, renderMode); shader.Bind(gl); // 用VAO+EBO进行渲染。 // Bind the out vertex array. //gl.BindVertexArray(vao[0]); gl.BindVertexArray(vertexArrayObject); // Draw the square. //gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, ebo[0]); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, this.triangleBufferObject); // 启用Primitive restart gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue);// 截断图元(四边形带、三角形带等)的索引值。 gl.DrawElements(this.primitiveMode, this.triangleIndexCount, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); // Unbind our vertex array and shader. gl.BindVertexArray(0); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); shader.Unbind(gl); }
void IRenderable.Render(OpenGL gl, RenderMode renderMode) { if (positionBuffer != null && colorBuffer != null && radiusBuffer != null) { if (this.shaderProgram == null) { this.shaderProgram = InitShader(gl, renderMode); } if (this.vertexArrayObject == null) { CreateVertexArrayObject(gl, renderMode); } BeforeRendering(gl, renderMode); if (this.RenderGrid && this.vertexArrayObject != null) { gl.Enable(OpenGL.GL_BLEND); gl.BlendFunc(SharpGL.Enumerations.BlendingSourceFactor.SourceAlpha, SharpGL.Enumerations.BlendingDestinationFactor.OneMinusSourceAlpha); gl.BindVertexArray(this.vertexArrayObject[0]); gl.DrawArrays(OpenGL.GL_POINTS, 0, count); gl.BindVertexArray(0); gl.Disable(OpenGL.GL_BLEND); } AfterRendering(gl, renderMode); } }
public void Render(SharpGL.OpenGL gl, SharpGL.SceneGraph.Core.RenderMode renderMode) { // update matrix and bind shader program mat4 projectionMatrix = camera.GetProjectionMat4(); mat4 viewMatrix = camera.GetViewMat4(); mat4 modelMatrix = glm.scale(mat4.identity(), new vec3(1, 1, this.ZAxisScale)); shaderProgram.Bind(gl); shaderProgram.SetUniformMatrix4(gl, strprojectionMatrix, projectionMatrix.to_array()); shaderProgram.SetUniformMatrix4(gl, strviewMatrix, viewMatrix.to_array()); shaderProgram.SetUniformMatrix4(gl, strmodelMatrix, modelMatrix.to_array()); gl.BindVertexArray(vao[0]); // 启用Primitive restart gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue);// 截断图元(四边形带、三角形带等)的索引值。 //GL.DrawArrays(primitiveMode, 0, vertexCount); gl.DrawElements((uint)primitiveMode, vertexCount + (this.pipe.Count - 1) * 2, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.BindVertexArray(0); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); // unbind shader program shaderProgram.Unbind(gl); }
public void Render(SharpGL.OpenGL gl, SharpGL.SceneGraph.Core.RenderMode renderMode) { gl.BindVertexArray(vao[0]); gl.DrawArrays((uint)primitiveMode, 0, vertexCount); gl.BindVertexArray(0); }
public void Render(SharpGL.OpenGL gl, SharpGL.SceneGraph.Core.RenderMode renderMode) { gl.BindVertexArray(vao[0]); //GL.DrawArrays(primitiveMode, 0, vertexCount); gl.DrawElements((uint)primitiveMode, faceCount * 2 + 2, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.BindVertexArray(0); }
/// <summary> /// 渲染此元素。 /// </summary> /// <param name="gl"></param> /// <param name="renderMode"></param> public virtual void Render(SharpGL.OpenGL gl, SharpGL.SceneGraph.Core.RenderMode renderMode) { BeforeRendering(gl, renderMode); ShaderProgram shader = this.shaderProgram;// GetShader(gl, renderMode); shader.Bind(gl); // 用VAO+EBO进行渲染。 // Bind the out vertex array. gl.BindVertexArray(vao[0]); gl.DrawArrays(this.primitiveMode, 0, this.primitiveCount); // Unbind our vertex array and shader. gl.BindVertexArray(0); shader.Unbind(gl); AfterRendering(gl, renderMode); }
public BackgroundRenderer(OpenGL gl) { _gl = gl; _program = new BackgroundShader(gl); _flat = new VAO(gl); _flatBuffer = new VBO(gl); using (new Bind(_flat)) using (new Bind(_flatBuffer)) { var flatData = new float[] { -1, -1, 1, -1, -1, 1, 1, 1, }; _flatBuffer.Update(flatData, flatData.Length * sizeof(float)); gl.EnableVertexAttribArray(0); gl.VertexAttribPointer(0, 2, OpenGL.GL_FLOAT, false, 0, new IntPtr(0)); gl.BindVertexArray(0); } }
public PostProcesser(OpenGL gl,int width,int height) { _gl = gl; _fbo = new FBO(gl, width, height); _flatProgram = new FlatShader(gl); _flat = new VAO(gl); _flatBuffer = new VBO(gl); using (new Bind(_flat)) using (new Bind(_flatBuffer)) { var flatData = new float[] { -1, -1, 1, -1, -1, 1, 1, 1, }; _flatBuffer.Update(flatData, flatData.Length * sizeof(float)); gl.EnableVertexAttribArray(0); gl.VertexAttribPointer(0, 2, OpenGL.GL_FLOAT, false, 0, new IntPtr(0)); gl.BindVertexArray(0); } }
public void BindAll(OpenGL gl) { UseProgram(gl, () => { // Update uniforms. foreach (var action in ChangedUniforms) { action.Invoke(gl); } ChangedUniforms.Clear(); foreach (var group in BufferGroups) { group.BindVAO(gl); gl.DrawElements(OpenGL.GL_TRIANGLES, group.IndicesCount, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.BindVertexArray(0); } }); }
private void CreateVertexArrayObject(OpenGL gl, RenderMode renderMode) { if (this.positionBuffer == null || this.colorBuffer == null) { return; } this.vertexArrayObject = new uint[1]; gl.GenVertexArrays(1, this.vertexArrayObject); gl.BindVertexArray(this.vertexArrayObject[0]); // prepare positions { int location = shaderProgram.GetAttributeLocation(gl, in_Position); ATTRIB_INDEX_POSITION = (uint)location; gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, positionBuffer[0]); gl.VertexAttribPointer(ATTRIB_INDEX_POSITION, 3, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero); gl.EnableVertexAttribArray(ATTRIB_INDEX_POSITION); } // prepare colors { int location = shaderProgram.GetAttributeLocation(gl, in_uv); ATTRIB_INDEX_UV = (uint)location; gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, colorBuffer[0]); gl.VertexAttribPointer(ATTRIB_INDEX_UV, 1, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero); gl.EnableVertexAttribArray(ATTRIB_INDEX_UV); } gl.BindVertexArray(0); }
void IRenderable.Render(OpenGL gl, RenderMode renderMode) { if (positionBuffer == null || colorBuffer == null) { return; } if (this.shaderProgram == null) { this.shaderProgram = InitShader(gl, renderMode); } if (this.vertexArrayObject == null) { CreateVertexArrayObject(gl, renderMode); } BeforeRendering(gl, renderMode); if (this.RenderGridWireframe && this.vertexArrayObject != null) { //if (wireframeIndexBuffer != null) if (positionBuffer != null && colorBuffer != null && indexBuffer != null) { shaderProgram.SetUniform1(gl, "renderingWireframe", 1.0f);// shader一律上白色。 gl.Disable(OpenGL.GL_LINE_STIPPLE); gl.Disable(OpenGL.GL_POLYGON_STIPPLE); gl.Enable(OpenGL.GL_LINE_SMOOTH); gl.Enable(OpenGL.GL_POLYGON_SMOOTH); gl.ShadeModel(SharpGL.Enumerations.ShadeModel.Smooth); gl.Hint(SharpGL.Enumerations.HintTarget.LineSmooth, SharpGL.Enumerations.HintMode.Nicest); gl.Hint(SharpGL.Enumerations.HintTarget.PolygonSmooth, SharpGL.Enumerations.HintMode.Nicest); gl.PolygonMode(SharpGL.Enumerations.FaceMode.FrontAndBack, SharpGL.Enumerations.PolygonMode.Lines); gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue); gl.Enable(OpenGL.GL_BLEND); gl.BlendFunc(SharpGL.Enumerations.BlendingSourceFactor.SourceAlpha, SharpGL.Enumerations.BlendingDestinationFactor.OneMinusSourceAlpha); gl.BindVertexArray(this.vertexArrayObject[0]); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer[0]); gl.DrawElements(OpenGL.GL_QUAD_STRIP, this.indexBufferLength, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.BindVertexArray(0); gl.Disable(OpenGL.GL_BLEND); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); gl.PolygonMode(SharpGL.Enumerations.FaceMode.FrontAndBack, SharpGL.Enumerations.PolygonMode.Filled); gl.Disable(OpenGL.GL_POLYGON_SMOOTH); } } if (this.RenderGrid && this.vertexArrayObject != null) { if (positionBuffer != null && colorBuffer != null && indexBuffer != null) { shaderProgram.SetUniform1(gl, "renderingWireframe", 0.0f);// shader根据uv buffer来上色。 gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue); gl.Enable(OpenGL.GL_BLEND); gl.BlendFunc(SharpGL.Enumerations.BlendingSourceFactor.SourceAlpha, SharpGL.Enumerations.BlendingDestinationFactor.OneMinusSourceAlpha); gl.BindVertexArray(this.vertexArrayObject[0]); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer[0]); gl.DrawElements(OpenGL.GL_QUAD_STRIP, this.indexBufferLength, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.BindVertexArray(0); gl.Disable(OpenGL.GL_BLEND); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); } } AfterRendering(gl, renderMode); }
public void PrepareNMVAO(OpenGL gl, NormalMaterialProgram program) { var vertArrIds = new uint[1]; gl.GenVertexArrays(1, vertArrIds); VaoNM = vertArrIds[0]; gl.BindVertexArray(VaoNM); BindNMVBOs(gl, program); gl.EnableVertexAttribArray(0); gl.BindVertexArray(0); }
public void BindHTVAO(OpenGL gl) { gl.BindVertexArray(VaoHT); }
public void BindNMVAO(OpenGL gl) { gl.BindVertexArray(VaoNM); }
public void PrepareHTVAO(OpenGL gl, HitTestProgram program) { var vertArrIds = new uint[1]; gl.GenVertexArrays(1, vertArrIds); VaoHT = vertArrIds[0]; gl.BindVertexArray(VaoHT); BindHTVBOs(gl, program); gl.EnableVertexAttribArray(0); gl.BindVertexArray(0); }
private void DoRenderFraction(OpenGL gl, RenderMode renderMode) { if (this.fractionPositionBuffer == null || this.fractionUVBuffer == null) { return; } if (this.RenderFraction && this.fractionVertexArrayObject != null) { shaderProgram.SetUniform1(gl, "renderingWireframe", 0.0f); gl.Enable(OpenGL.GL_POLYGON_OFFSET_FILL); gl.PolygonOffset(1.0f, 1.0f); gl.BindVertexArray(fractionVertexArrayObject[0]); switch (this.FractionType) { case FractureFormat.Line: float[] originalWidth = new float[1]; gl.GetFloat(SharpGL.Enumerations.GetTarget.LineWidth, originalWidth); gl.LineWidth(this.FractionLineWidth); gl.DrawArrays(OpenGL.GL_LINES, 0, this.FractionVertexCount); gl.LineWidth(originalWidth[0]); break; case FractureFormat.Triange: gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, this.FractionVertexCount); break; case FractureFormat.Quad: gl.DrawArrays(OpenGL.GL_QUADS, 0, this.FractionVertexCount); break; default: throw new NotImplementedException(); //break; } gl.BindVertexArray(0); gl.Disable(OpenGL.GL_POLYGON_OFFSET_FILL); } if (this.renderFractionWireframe && this.fractionVertexArrayObject != null) { shaderProgram.SetUniform1(gl, "renderingWireframe", 1.0f); gl.BindVertexArray(fractionVertexArrayObject[0]); { gl.PolygonMode(SharpGL.Enumerations.FaceMode.FrontAndBack, SharpGL.Enumerations.PolygonMode.Lines); switch (this.FractionType) { case FractureFormat.Line: gl.DrawArrays(OpenGL.GL_LINES, 0, this.FractionVertexCount); break; case FractureFormat.Triange: gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, this.FractionVertexCount); break; case FractureFormat.Quad: gl.DrawArrays(OpenGL.GL_QUADS, 0, this.FractionVertexCount); break; default: break; } gl.PolygonMode(SharpGL.Enumerations.FaceMode.FrontAndBack, SharpGL.Enumerations.PolygonMode.Filled); } gl.BindVertexArray(0); } }
/// <summary> /// 渲染基质 /// </summary> /// <param name="gl"></param> /// <param name="renderMode"></param> private void DoRenderMatrix(OpenGL gl, RenderMode renderMode) { if (this.positionBuffer == null || this.colorBuffer == null) { return; } if (this.RenderGrid && this.matrixVertexArrayObject != null) { shaderProgram.SetUniform1(gl, "renderingWireframe", 0.0f); shaderProgram.SetUniform1(gl, "opacity", this.Opacity); gl.Enable(OpenGL.GL_POLYGON_OFFSET_FILL); gl.PolygonOffset(1.0f, 1.0f); gl.Enable(OpenGL.GL_BLEND); gl.BlendFunc(SharpGL.Enumerations.BlendingSourceFactor.SourceAlpha, SharpGL.Enumerations.BlendingDestinationFactor.OneMinusSourceAlpha); gl.BindVertexArray(matrixVertexArrayObject[0]); switch (this.MatrixType) { case MatrixFormat.Triangle: gl.DrawArrays(this.matrixRenderMode, 0, this.MatrixVertexOrIndexCount); break; case MatrixFormat.Tetrahedron: gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, this.matrixIndexBuffer[0]); gl.DrawElements(this.matrixRenderMode, this.MatrixVertexOrIndexCount, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); break; case MatrixFormat.TriangularPrism: // 先渲染三棱柱的上下三角形 gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, this.MatrixVertexOrIndexCount); // 再渲染三棱柱的三个侧面 gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, this.matrixIndexBuffer[0]); gl.DrawElements(this.matrixRenderMode, this.MatrixVertexOrIndexCount, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); break; default: break; } gl.BindVertexArray(0); gl.Disable(OpenGL.GL_BLEND); gl.Disable(OpenGL.GL_POLYGON_OFFSET_FILL); } if (this.RenderGridWireframe && this.matrixVertexArrayObject != null) { shaderProgram.SetUniform1(gl, "renderingWireframe", 1.0f); shaderProgram.SetUniform1(gl, "opacity", this.Opacity); gl.PolygonMode(SharpGL.Enumerations.FaceMode.FrontAndBack, SharpGL.Enumerations.PolygonMode.Lines); gl.Enable(OpenGL.GL_BLEND); gl.BlendFunc(SharpGL.Enumerations.BlendingSourceFactor.SourceAlpha, SharpGL.Enumerations.BlendingDestinationFactor.OneMinusSourceAlpha); gl.BindVertexArray(matrixVertexArrayObject[0]); switch (this.MatrixType) { case MatrixFormat.Triangle: gl.DrawArrays(this.matrixRenderMode, 0, this.MatrixVertexOrIndexCount); break; case MatrixFormat.Tetrahedron: gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, this.matrixIndexBuffer[0]); gl.DrawElements(this.matrixRenderMode, this.MatrixVertexOrIndexCount, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); break; case MatrixFormat.TriangularPrism: // 先渲染三棱柱的上下三角形 gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, this.MatrixVertexOrIndexCount / 9 * 6); // 再渲染三棱柱的三个侧面 gl.Enable(OpenGL.GL_PRIMITIVE_RESTART); gl.PrimitiveRestartIndex(uint.MaxValue); gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, this.matrixIndexBuffer[0]); gl.DrawElements(this.matrixRenderMode, this.MatrixVertexOrIndexCount, OpenGL.GL_UNSIGNED_INT, IntPtr.Zero); gl.Disable(OpenGL.GL_PRIMITIVE_RESTART); break; default: break; } gl.PolygonMode(SharpGL.Enumerations.FaceMode.FrontAndBack, SharpGL.Enumerations.PolygonMode.Filled); gl.BindVertexArray(0); gl.Disable(OpenGL.GL_BLEND); } }
private void PlaySound() { try { gl.GenVertexArrays(1, vao); gl.BindVertexArray(vao[0]); gl.GenBuffers(1, vbo); float[] vertices = new float[] { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f }; gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, vbo[0]); unsafe { fixed(float *verts = vertices) { var ptr = new IntPtr(verts); // fill the buffer to the currently binded buffer gl.BufferData(OpenGL.GL_ARRAY_BUFFER, vertices.Length * sizeof(float), ptr, OpenGL.GL_STATIC_DRAW); } } // Create the shader program. var vertexShaderSource = ManifestResourceLoader.LoadTextFile("SoundShader.vert"); var fragmentShaderSource = ManifestResourceLoader.LoadTextFile("SoundShader.frag"); vertexShader = gl.CreateShader(OpenGL.GL_VERTEX_SHADER); gl.ShaderSource(vertexShader, vertexShaderSource); gl.CompileShader(vertexShader); // Create and compile the fragment shader fragmentShader = gl.CreateShader(OpenGL.GL_FRAGMENT_SHADER); gl.ShaderSource(fragmentShader, fragmentShaderSource); gl.CompileShader(fragmentShader); // Link the vertex and fragment shader into a shader program shaderProgram = gl.CreateProgram(); gl.AttachShader(shaderProgram, vertexShader); gl.AttachShader(shaderProgram, fragmentShader); gl.BindFragDataLocation(shaderProgram, (uint)0, "gl_FragColor"); gl.LinkProgram(shaderProgram); int[] infoLength = new int[] { 0 }; int bufSize = infoLength[0]; // Get the compile info. StringBuilder il = new StringBuilder(bufSize); gl.GetProgramInfoLog(shaderProgram, bufSize, IntPtr.Zero, il); gl.UseProgram(shaderProgram); posAttrib = gl.GetAttribLocation(shaderProgram, "position"); gl.EnableVertexAttribArray((uint)posAttrib); gl.VertexAttribPointer((uint)posAttrib, 2, OpenGL.GL_FLOAT, false, 0, new IntPtr(0)); timeLoc = gl.GetUniformLocation(shaderProgram, "iGlobalTime"); sampleLoc = gl.GetUniformLocation(shaderProgram, "Spectrum"); waveLoc = gl.GetUniformLocation(shaderProgram, "Wavedata"); int resLoc = gl.GetUniformLocation(shaderProgram, "iResolution"); gl.Uniform3(resLoc, (float)this.openGLControl1.Width, (float)this.openGLControl1.Height, (float)(this.openGLControl1.Width * this.openGLControl1.Height)); Thread thread = new Thread(() => PlaySoundT(((USound)selectedObject).SoundBuffer)); thread.Start(); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace.ToString()); } }
public void PrepareVAO(OpenGL gl, LinesProgram program) { var vertArrIds = new uint[1]; gl.GenVertexArrays(1, vertArrIds); Vao = vertArrIds[0]; gl.BindVertexArray(Vao); BindVBOs(gl, program); gl.EnableVertexAttribArray(0); gl.BindVertexArray(0); }
public void BindVAO(OpenGL gl) { var isBuffer = new bool[] { gl.IsBuffer(Vao), gl.IsBuffer(Ibo), gl.IsBuffer(Position), gl.IsBuffer(Normal), gl.IsBuffer(Vao), gl.IsBuffer(Vao), gl.IsBuffer(Vao), gl.IsBuffer(Vao), }; gl.BindVertexArray(Vao); }
public OctreeRenderer(OctreeModel model, OpenGL gl) { _gl = gl; _octreeProgram = new OctreeShader(gl); _cubes = new VAO(gl); _cubeBuffer = new VBO(gl); var filled = model.Node.Flatten().Where(o => o.State == NodeState.Filled).ToArray(); _count = filled.Length; var list = new List<float>(); foreach (var octreeNode in filled) { list.AddRange(octreeNode.Center.ToArray().Select(d => (float)d)); list.AddRange(new[] { (float)MathsHelper.Map(octreeNode.Color.R, 0, 255, 0, 1), (float)MathsHelper.Map(octreeNode.Color.G, 0, 255, 0, 1), (float)MathsHelper.Map(octreeNode.Color.B, 0, 255, 0, 1), (float)MathsHelper.Map(octreeNode.Color.A, 0, 255, 0, 1), (float)octreeNode.Size }); } var vertices = list.ToArray(); using (new Bind(_cubes)) using (new Bind(_cubeBuffer)) { _cubeBuffer.Update(vertices, vertices.Length * sizeof(float)); const int stride = sizeof(float) * 8; gl.EnableVertexAttribArray(0); gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, stride, new IntPtr(0)); gl.EnableVertexAttribArray(1); gl.VertexAttribPointer(1, 4, OpenGL.GL_FLOAT, false, stride, new IntPtr(sizeof(float) * 3)); gl.EnableVertexAttribArray(2); gl.VertexAttribPointer(2, 1, OpenGL.GL_FLOAT, false, stride, new IntPtr(sizeof(float) * 7)); gl.BindVertexArray(0); } }
private void runGlThread(object args) { var inputs = (Tuple<CancellationToken>) args; var cancelToken = inputs.Item1; var gl = new OpenGL(); int localRenderWidth = 1; int localRenderHeight = 1; if (!createRenderContext(gl, localRenderWidth, localRenderHeight)) { //TODO better error handling here Console.WriteLine("*** Unable to create OpenGL Render Context"); return; } uint activeVaoHandle; uint activeGlProgramHandle; initGLObjects(gl, out activeVaoHandle, out activeGlProgramHandle); ActiveProgramValues localActiveProgramValues = null; while (!cancelToken.IsCancellationRequested) { bool resizeRenderContext; lock (this) { if (!ReferenceEquals(localActiveProgramValues, activeProgramValues)) { localActiveProgramValues = activeProgramValues; if (localActiveProgramValues.Valid) { linkProgram(gl, localActiveProgramValues, activeGlProgramHandle); } else { // Leave the old program running. This prevents the user from seeing // a black screen while they are in the process of modifying a shader. } } resizeRenderContext = localRenderWidth != renderWidth || localRenderHeight != renderHeight; localRenderWidth = renderWidth; localRenderHeight = renderHeight; } if (resizeRenderContext) { localActiveProgramValues = null; deleteGlObjects(gl, activeVaoHandle, activeGlProgramHandle); if (!createRenderContext(gl, localRenderWidth, localRenderHeight)) { //TODO better error handling here Console.WriteLine("*** Unable to resize OpenGL Render Context"); return; } initGLObjects(gl, out activeVaoHandle, out activeGlProgramHandle); } gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT); gl.BindVertexArray(activeVaoHandle); gl.UseProgram(activeGlProgramHandle); gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 3); // do some other stuff while the image is rendering, to give it a chance to finish ShaderCompiler.ValidateShaders(gl); var provider = gl.RenderContextProvider as FBORenderContextProvider; Debug.Assert(provider != null, "Render context provider is not an FBO renderer"); //TODO this call to blit will probably block. Find a better way to copy the image to CPU memory. gl.Blit(IntPtr.Zero); var hBitmap = provider.InternalDIBSection.HBitmap; if (hBitmap != IntPtr.Zero) { var bitmap = GetFormattedBitmapSource(hBitmap); // the bitmap needs to be frozen in order to share it between threads bitmap.Freeze(); ImageRendered(bitmap); } } deleteGlObjects(gl, activeVaoHandle, activeGlProgramHandle); }