예제 #1
0
    /// <summary>
    /// OnRenderFrame is called on every frame for rendering
    /// </summary>
    /// <param name="e">event arguments</param>
    protected override void OnRenderFrame(FrameEventArgs e)
    {
        base.OnRenderFrame(e);

        // Clear the color & depth buffer
        gl.Clear(ClearBufferMask.ColorBufferBit |
                 ClearBufferMask.DepthBufferBit);

        // Start with identity every frame
        _viewMatrix.Identity();

        // View transform: move the coordinate system away from the camera
        _viewMatrix.Translate(0, 0, _camZ);

        // View transform: rotate the coordinate system increasingly
        _viewMatrix.Rotate(_rotX + _deltaX, 1, 0, 0);
        _viewMatrix.Rotate(_rotY + _deltaY, 0, 1, 0);

        // Transform light position & direction into view space
        SLVec3f lightPosVS = _viewMatrix * _lightPos;

        // The light dir is not a position. We only take the rotation of the mv matrix.
        SLMat3f viewRot    = _viewMatrix.Mat3();
        SLVec3f lightDirVS = viewRot * _lightDir;

        // Rotate the model so that we see it
        _modelMatrix.Identity();
        _modelMatrix.Rotate(90, -1, 0, 0);

        // Build the combined modelview-projection matrix
        SLMat4f mvp = new SLMat4f(_projectionMatrix);
        SLMat4f mv  = new SLMat4f(_viewMatrix);

        mv.Multiply(_modelMatrix);
        mvp.Multiply(mv);

        // Build normal matrix
        SLMat3f nm = mv.InverseTransposed();

        // Pass the matrix uniform variables
        unsafe
        { gl.UniformMatrix4(_mvMatrixLoc, 1, false, mv.m);
          gl.UniformMatrix3(_nMatrixLoc, 1, false, nm.m);
          gl.UniformMatrix4(_mvpMatrixLoc, 1, false, mvp.m);

          // Pass lighting uniforms variables
          gl.Uniform4(_globalAmbiLoc, 1, (float[])_globalAmbi);
          gl.Uniform3(_lightPosVSLoc, 1, (float[])lightPosVS);
          gl.Uniform3(_lightSpotDirVSLoc, 1, (float[])lightDirVS);
          gl.Uniform4(_lightAmbientLoc, 1, (float[])_lightAmbient);
          gl.Uniform4(_lightDiffuseLoc, 1, (float[])_lightDiffuse);
          gl.Uniform4(_lightSpecularLoc, 1, (float[])_lightSpecular);
          gl.Uniform4(_matAmbientLoc, 1, (float[])_matAmbient);
          gl.Uniform4(_matDiffuseLoc, 1, (float[])_matDiffuse);
          gl.Uniform4(_matSpecularLoc, 1, (float[])_matSpecular);
          gl.Uniform4(_matEmissiveLoc, 1, (float[])_matEmissive); }
        gl.Uniform1(_matShininessLoc, _matShininess);
        gl.Uniform1(_texture0Loc, 0);

        //////////////////////
        // Draw with 2 VBOs //
        //////////////////////

        // Enable all of the vertex attribute arrays
        gl.EnableVertexAttribArray(_pLoc);
        gl.EnableVertexAttribArray(_nLoc);
        gl.EnableVertexAttribArray(_tLoc);

        // Activate VBOs
        gl.BindBuffer(BufferTarget.ArrayBuffer, _vboV);
        gl.BindBuffer(BufferTarget.ElementArrayBuffer, _vboI);

        // Activate Texture
        gl.BindTexture(TextureTarget.Texture2D, _textureID);

        // For VBO only offset instead of data pointer
        int stride  = 32;
        int offsetN = 3 * sizeof(float);
        int offsetT = 6 * sizeof(float);

        gl.VertexAttribPointer(_pLoc, 3, VertexAttribPointerType.Float, false, stride, 0);
        gl.VertexAttribPointer(_nLoc, 3, VertexAttribPointerType.Float, false, stride, offsetN);
        gl.VertexAttribPointer(_tLoc, 2, VertexAttribPointerType.Float, false, stride, offsetT);

        /////////////////////////////////////////////////////////////////////////////
        // Draw cube model triangles by indexes
        gl.DrawElements(BeginMode.Triangles, _numI, DrawElementsType.UnsignedInt, 0);
        /////////////////////////////////////////////////////////////////////////////

        // Deactivate buffers
        gl.BindBuffer(BufferTarget.ArrayBuffer, 0);
        gl.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

        // Disable the vertex arrays
        gl.DisableVertexAttribArray(_pLoc);
        gl.DisableVertexAttribArray(_nLoc);
        gl.DisableVertexAttribArray(_tLoc);

        // Fast copy the back buffer to the front buffer. This is OS dependent.
        SwapBuffers();

        // Check for errors
        glUtils.GetGLError("OnRenderFrame", true);
    }