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);
            }
        }
Example #2
0
        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);
                    }
                }
            }
        }