protected override void OnLoad(System.EventArgs e) { try { Console.WriteLine(ClientSize.Width + " " + ClientSize.Height); Console.WriteLine(GL.GetString(StringName.Version)); Console.WriteLine(GL.GetString(StringName.ShadingLanguageVersion)); GL.Viewport(0, 0, ClientSize.Width, ClientSize.Height); VSync = VSyncMode.On; GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.DepthTest); GL.DepthFunc(DepthFunction.Less); // Setup quad VAO quadVAO = GL.GenVertexArray(); int quadVBO = GL.GenBuffer(); GL.BindVertexArray(quadVAO); GL.BindBuffer(BufferTarget.ArrayBuffer, quadVBO); GL.BufferData(BufferTarget.ArrayBuffer, quadVertices.Length * sizeof(float), quadVertices, BufferUsageHint.StaticDraw); GL.EnableVertexAttribArray(0); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 5 * sizeof(float), 0); GL.EnableVertexAttribArray(1); GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); uchar4[] data = new uchar4[Width * Height]; textureID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, textureID); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Width, Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, data); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, Convert.ToInt32(TextureWrapMode.Repeat)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, Convert.ToInt32(TextureWrapMode.Repeat)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, Convert.ToInt32(TextureMinFilter.Linear)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, Convert.ToInt32(TextureMagFilter.Linear)); GL.BindTexture(TextureTarget.Texture2D, 0); string vsource = File.ReadAllText(@"vertex.glsl"); string fsource = File.ReadAllText(@"fragment.glsl"); shaderProgram = LoadShaderProgram(vsource, fsource); IntPtr resource; cuda.ERROR_CHECK(cuda.GraphicsGLRegisterImage(out resource, (uint)textureID, (uint)GL_TEXTURE_MODE.GL_TEXTURE_2D, (uint)cudaGraphicsRegisterFlags.SurfaceLoadStore)); cuda.ERROR_CHECK(cuda.GraphicsMapResources(1, new IntPtr[1] { resource }, cudaStream_t.NO_STREAM)); cudaArray_t array; cuda.ERROR_CHECK(cuda.GraphicsSubResourceGetMappedArray(out array, resource, 0, 0)); cudaChannelFormatDesc channelDescSurf = TextureHelpers.cudaCreateChannelDesc(32, 0, 0, 0, cudaChannelFormatKind.cudaChannelFormatKindUnsigned); cudaResourceDesc resDescSurf = TextureHelpers.CreateCudaResourceDesc(array); cuda.CreateSurfaceObject(out surface, ref resDescSurf); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
public void Render(cudaSurfaceObject_t surface, int cWidth, int cHeight, int iterations, float3 viewDirection, float3 nearFieldLocation, float3 eyeLocation, float3 lightDirection) { int cHalfWidth = cWidth / 2; float pixel = ((float)DEPTH_OF_FIELD) / (((cHeight + cWidth) / 2.0F)); float halfPixel = pixel / 2.0F; float smallStep = 0.01F; float bigStep = 0.02F; for (int y = threadIdx.y + blockIdx.y * blockDim.y; y < cHeight; y += blockDim.y * gridDim.y) { var ny = y - cHeight / 2; float3 tempViewDirectionY = viewDirection; float3 tempViewDirectionX1 = viewDirection; MathFunctions.turnOrthogonal(ref tempViewDirectionY); MathFunctions.crossProduct(ref tempViewDirectionY, viewDirection); tempViewDirectionY = tempViewDirectionY * (ny * pixel); MathFunctions.turnOrthogonal(ref tempViewDirectionX1); for (int x = threadIdx.x + blockDim.x * blockIdx.x; x < cWidth; x += blockDim.x * gridDim.x) { int nx = x - cHalfWidth; float3 pixelLocation = nearFieldLocation; float3 tempViewDirectionX2 = tempViewDirectionX1 * (nx * pixel); pixelLocation = pixelLocation + tempViewDirectionX2 + tempViewDirectionY; float3 rayLocation = pixelLocation; float3 rayDirection = rayLocation - eyeLocation; MathFunctions.normalize(ref rayDirection); var distanceFromCamera = 0.0; var d = Distance(rayLocation, iterations); int i = 0; for (; i < MAX_ITER; i++) { if (d < halfPixel) { break; } //Increase rayLocation with direction and d: rayDirection = rayDirection * d; rayLocation = rayLocation + rayDirection; //And reset ray direction: MathFunctions.normalize(ref rayDirection); //Move the pixel location: distanceFromCamera = MathFunctions.length(nearFieldLocation - rayLocation); if (distanceFromCamera > DEPTH_OF_FIELD) { break; } d = Distance(rayLocation, iterations); } if (distanceFromCamera < DEPTH_OF_FIELD && distanceFromCamera > 0) { rayLocation.x -= smallStep; var locationMinX = Distance(rayLocation, iterations); rayLocation.x += bigStep; var locationPlusX = Distance(rayLocation, iterations); rayLocation.x -= smallStep; rayLocation.y -= smallStep; var locationMinY = Distance(rayLocation, iterations); rayLocation.y += bigStep; var locationPlusY = Distance(rayLocation, iterations); rayLocation.y -= smallStep; rayLocation.z -= smallStep; var locationMinZ = Distance(rayLocation, iterations); rayLocation.z += bigStep; var locationPlusZ = Distance(rayLocation, iterations); rayLocation.z -= smallStep; float3 normal = new float3(); //Calculate the normal: normal.x = (locationMinX - locationPlusX); normal.y = (locationMinY - locationPlusY); normal.z = (locationMinZ - locationPlusZ); MathFunctions.normalize(ref normal); //Calculate the ambient light: var dotNL = MathFunctions.dotProduct(lightDirection, normal); var diff = MathFunctions.saturate(dotNL); //Calculate specular light: float3 halfway = rayDirection + lightDirection; MathFunctions.normalize(ref halfway); var dotNH = MathFunctions.dotProduct(halfway, normal); float s = MathFunctions.saturate(dotNH); float s2 = s * s; float s4 = s2 * s2; float s8 = s4 * s4; float s16 = s8 * s8; float s32 = s16 * s16; float spec = s * s2 * s32; // s^35 var shad = shadow(lightDirection, rayLocation, iterations, 1.0F, DEPTH_OF_FIELD, 16.0F) + 0.25F; var brightness = (10.0F + (200.0F + spec * 45.0F) * shad * diff) / 270.0F; var red = 10 + (380 * brightness); var green = 10 + (280 * brightness); var blue = (180 * brightness); red = MathFunctions.clamp(red, 0, 255.0F); green = MathFunctions.clamp(green, 0, 255.0F); blue = MathFunctions.clamp(blue, 0, 255.0F); uchar4 color = new uchar4(); color.x = (byte)red; color.y = (byte)green; color.z = (byte)blue; TextureHelpers.surf2Dwrite(color, surface, x * sizeof(int), y); } else { uchar4 color = new uchar4(); color.x = (byte)(155.0F + MathFunctions.clamp(i * 1.5F, 0.0F, 100.0F)); color.y = ((byte)(205.0F + MathFunctions.clamp(i * 1.5F, 0.0F, 50.0F))); color.z = 255; TextureHelpers.surf2Dwrite(color, surface, x * sizeof(int), y); } } } }