protected override void DoRender(RenderEventArgs arg) { float deltaTime = (float)random.NextDouble() * 5; time += (float)random.NextDouble() * 5; IntPtr attractors = this.attractorBuffer.MapBufferRange( 0, 64 * Marshal.SizeOf(typeof(vec4)), MapBufferRangeAccess.MapWriteBit | MapBufferRangeAccess.MapInvalidateBufferBit); unsafe { var array = (vec4 *)attractors.ToPointer(); for (int i = 0; i < 64; i++) { array[i] = new vec4( (float)(Math.Sin(time)) * 50.0f, (float)(Math.Cos(time)) * 50.0f, (float)(Math.Cos(time)) * (float)(Math.Sin(time)) * 5.0f, ParticleModel.attractor_masses[i]); } } this.attractorBuffer.UnmapBuffer(); // Activate the compute program and bind the position and velocity buffers computeProgram.Bind(); OpenGL.BindImageTexture(0, this.velocityTexture.Id, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_RGBA32F); OpenGL.BindImageTexture(1, this.positionTexture.Id, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_RGBA32F); // Set delta time computeProgram.SetUniform("dt", deltaTime); // Dispatch OpenGL.GetDelegateFor <OpenGL.glDispatchCompute>()(ParticleModel.particleGroupCount, 1, 1); }
protected override void DoRender(RenderEventArgs arg) { this.depthTestState.On(); this.cullFaceState.On(); // Reset atomic counter IntPtr data = this.atomicCountBuffer.MapBuffer(MapBufferAccess.WriteOnly); unsafe { var array = (uint *)data.ToPointer(); array[0] = 0; } this.atomicCountBuffer.UnmapBuffer(); // Clear head-pointer image this.headClearBuffer.Bind(); this.headTexture.Bind(); OpenGL.TexSubImage2D(TexSubImage2DTarget.Texture2D, 0, 0, 0, arg.CanvasRect.Width, arg.CanvasRect.Height, TexSubImage2DFormats.RedInteger, TexSubImage2DType.UnsignedByte, IntPtr.Zero); this.headTexture.Unbind(); this.headClearBuffer.Unbind(); // // Bind head-pointer image for read-write OpenGL.BindImageTexture(0, this.headTexture.Id, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_R32UI); // Bind linked-list buffer for write OpenGL.BindImageTexture(1, this.linkedListTexture.Id, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA32UI); mat4 projection = arg.Camera.GetProjectionMatrix(); mat4 view = arg.Camera.GetViewMatrix(); this.buildListsRenderer.SetUniform("projection_matrix", projection); this.buildListsRenderer.SetUniform("view_matrix", view); this.resolve_lists.SetUniform("projection_matrix", projection); this.resolve_lists.SetUniform("view_matrix", view); MarkableStruct <mat4> model = this.GetModelMatrix(); if (this.modelTicks != model.UpdateTicks) { this.buildListsRenderer.SetUniform("model_matrix", model.Value); this.resolve_lists.SetUniform("model_matrix", model.Value); this.modelTicks = model.UpdateTicks; } // first pass this.buildListsRenderer.Render(arg); // second pass this.resolve_lists.Render(arg); OpenGL.BindImageTexture(1, 0, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA32UI); OpenGL.BindImageTexture(0, 0, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_R32UI); this.cullFaceState.Off(); this.depthTestState.Off(); }
protected override void DoInitialize() { this.buildListsRenderer.Initialize(); this.resolve_lists.Initialize(); { var texture = new Texture(TextureTarget.Texture2D, new NullImageFiller(MAX_FRAMEBUFFER_WIDTH, MAX_FRAMEBUFFER_HEIGHT, OpenGL.GL_R32UI, OpenGL.GL_RED_INTEGER, OpenGL.GL_UNSIGNED_BYTE), new SamplerParameters(TextureWrapping.Repeat, TextureWrapping.Repeat, TextureWrapping.Repeat, TextureFilter.Nearest, TextureFilter.Nearest)); texture.Initialize(); this.headTexture = texture; OpenGL.BindImageTexture(0, this.headTexture.Id, 0, true, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_R32UI); } // Create buffer for clearing the head pointer texture //var buffer = new IndependentBuffer<uint>(BufferTarget.PixelUnpackBuffer, BufferUsage.StaticDraw, false); using (var buffer = new PixelUnpackBuffer <uint>(BufferUsage.StaticDraw, false)) { buffer.Create(MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT); // NOTE: not all initial values are zero in this unmanged array. //unsafe //{ // var array = (uint*)buffer.Header.ToPointer(); // for (int i = 0; i < MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT; i++) // { // array[i] = 0; // } //} this.headClearBufferPtr = buffer.GetBufferPtr() as PixelUnpackBufferPtr; } // Create the atomic counter buffer using (var buffer = new AtomicCounterBuffer <uint>(BufferUsage.DynamicCopy, false)) { buffer.Create(1); this.atomicCountBufferPtr = buffer.GetBufferPtr() as AtomicCounterBufferPtr; } // Bind it to a texture (for use as a TBO) using (var buffer = new TextureBuffer <vec4>(BufferUsage.DynamicCopy, noDataCopyed: false)) { buffer.Create(elementCount: MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * 3); IndependentBufferPtr bufferPtr = buffer.GetBufferPtr(); Texture texture = bufferPtr.DumpBufferTexture(OpenGL.GL_RGBA32UI, autoDispose: true); texture.Initialize(); bufferPtr.Dispose();// dispose it ASAP. this.linkedListTexture = texture; } { OpenGL.BindImageTexture(1, this.linkedListTexture.Id, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA32UI); } OpenGL.ClearDepth(1.0f); }
protected override void DoRender(RenderEventArgs arg) { // Activate the compute program and bind the output texture image computeProgram.Bind(); OpenGL.BindImageTexture((uint)computeProgram.GetUniformLocation("input_image"), this.innerRenderer.InputTexture.Id, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_RGBA32F); OpenGL.BindImageTexture((uint)computeProgram.GetUniformLocation("output_image"), this.innerRenderer.IntermediateTexture.Id, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_RGBA32F); // Dispatch OpenGL.GetDelegateFor <OpenGL.glDispatchCompute>()(1, 512, 1); OpenGL.GetDelegateFor <OpenGL.glMemoryBarrier>()(OpenGL.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); computeProgram.Unbind(); computeProgram.Bind(); OpenGL.BindImageTexture((uint)computeProgram.GetUniformLocation("input_image"), this.innerRenderer.IntermediateTexture.Id, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_RGBA32F); OpenGL.BindImageTexture((uint)computeProgram.GetUniformLocation("output_image"), this.innerRenderer.OutputTexture.Id, 0, false, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_RGBA32F); // Dispatch OpenGL.GetDelegateFor <OpenGL.glDispatchCompute>()(1, 512, 1); OpenGL.GetDelegateFor <OpenGL.glMemoryBarrier>()(OpenGL.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); computeProgram.Unbind(); }
protected override void DoRender(RenderEventArgs arg) { { this.computeProgram.Bind(); // Also bind created texture ... this.texture.Bind(); // ... and bind this texture as an image, as we will write to it. see binding = 0 in shader. //glBindImageTexture(0, g_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); OpenGL.BindImageTexture(0, this.texture.Id, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA8); //glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, g_directionSSBO); OpenGL.BindBufferBase(BindBufferBaseTarget.ShaderStorageBuffer, 1, this.g_directionSSBO.BufferId); //glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, g_positionSSBO); OpenGL.BindBufferBase(BindBufferBaseTarget.ShaderStorageBuffer, 2, this.g_positionSSBO.BufferId); //glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, g_stackSSBO); OpenGL.BindBufferBase(BindBufferBaseTarget.ShaderStorageBuffer, 3, this.g_stackSSBO.BufferId); //glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, g_sphereSSBO); OpenGL.BindBufferBase(BindBufferBaseTarget.ShaderStorageBuffer, 4, this.g_sphereSSBO.BufferId); //glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, g_pointLightSSBO); OpenGL.BindBufferBase(BindBufferBaseTarget.ShaderStorageBuffer, 3, this.g_pointLightSSBO.BufferId); } { //mat4 mvp = arg.Camera.GetProjectionMatrix() * arg.Camera.GetViewMatrix(); this.computeProgram.Bind(); OpenGL.GetDelegateFor <OpenGL.glDispatchCompute>()(WIDTH / g_localSize, HEIGHT / g_localSize, 1); this.computeProgram.Unbind(); this.Program.Bind(); this.texture.Bind(); // ... and bind this texture as an image, as we will write to it. see binding = 0 in shader. //glBindImageTexture(0, g_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); OpenGL.BindImageTexture(0, this.texture.Id, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA8); mat4 mvp = arg.Camera.GetProjectionMatrix() * arg.Camera.GetViewMatrix(); this.SetUniform("mvp", mvp); base.DoRender(arg); } }
protected override void DoRender(RenderEventArgs arg) { // reset image computeResetProgram.Bind(); OpenGL.BindImageTexture(0, outputImage.Id, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA32F); OpenGL.GetDelegateFor <OpenGL.glDispatchCompute>()(maxX, maxY, maxZ); computeResetProgram.Unbind(); // Activate the compute program and bind the output texture image computeProgram.Bind(); OpenGL.BindImageTexture(0, outputImage.Id, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA32F); OpenGL.GetDelegateFor <OpenGL.glDispatchCompute>()(GroupX, GroupY, GroupZ); computeProgram.Unbind(); mat4 model = mat4.identity(); mat4 view = arg.Camera.GetViewMatrix(); mat4 projection = arg.Camera.GetProjectionMatrix(); this.SetUniform("modelMatrix", model); this.SetUniform("viewMatrix", view); this.SetUniform("projectionMatrix", projection); base.DoRender(arg); }
protected override void DoInitialize() { this.buildListsRenderer.Initialize(); this.resolve_lists.Initialize(); { var texture = new Texture(TextureTarget.Texture2D, new NullImageFiller(MAX_FRAMEBUFFER_WIDTH, MAX_FRAMEBUFFER_HEIGHT, OpenGL.GL_R32UI, OpenGL.GL_RED_INTEGER, OpenGL.GL_UNSIGNED_BYTE), new SamplerParameters(TextureWrapping.Repeat, TextureWrapping.Repeat, TextureWrapping.Repeat, TextureFilter.Nearest, TextureFilter.Nearest)); texture.Initialize(); this.headTexture = texture; OpenGL.BindImageTexture(0, this.headTexture.Id, 0, true, 0, OpenGL.GL_READ_WRITE, OpenGL.GL_R32UI); } // Create buffer for clearing the head pointer texture { const int length = MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT; PixelUnpackBuffer buffer = PixelUnpackBuffer.Create(typeof(uint), length, BufferUsage.StaticDraw); // NOTE: not all initial values are zero in this unmanged array. // initialize buffer's value to 0. //unsafe //{ // IntPtr pointer = ptr.MapBuffer(MapBufferAccess.WriteOnly); // var array = (uint*)pointer.ToPointer(); // for (int i = 0; i < MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT; i++) // { // array[i] = 0; // } //} // another way to initialize buffer's value to 0. //using (var data = new UnmanagedArray<uint>(1)) //{ // data[0] = 0; // ptr.ClearBufferData(OpenGL.GL_UNSIGNED_INT, OpenGL.GL_RED, OpenGL.GL_UNSIGNED_INT, data); //} this.headClearBuffer = buffer; } // Create the atomic counter buffer { const int length = 1; AtomicCounterBuffer buffer = AtomicCounterBuffer.Create(typeof(uint), length, BufferUsage.DynamicCopy); // another way to do this: //uint data = 1; //AtomicCounterBuffer buffer = data.GenAtomicCounterBuffer(BufferUsage.DynamicCopy); this.atomicCountBuffer = buffer; } // Bind it to a texture (for use as a TBO) { const int length = MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * 3; TextureBuffer buffer = TextureBuffer.Create(typeof(vec4), length, BufferUsage.DynamicCopy); Texture texture = buffer.DumpBufferTexture(OpenGL.GL_RGBA32UI, autoDispose: true); texture.Initialize(); buffer.Dispose();// dispose it ASAP. this.linkedListTexture = texture; } { //TextureBuffer buffer = TextureBuffer.Create() } { OpenGL.BindImageTexture(1, this.linkedListTexture.Id, 0, false, 0, OpenGL.GL_WRITE_ONLY, OpenGL.GL_RGBA32UI); } OpenGL.ClearDepth(1.0f); }