C#OpenTK GLSL在尝试渲染时崩溃

时间:2012-07-18 14:03:03

标签: c# opengl glsl opentk

我一直在尝试将GLSL应用到我的程序中,但考虑到我之前从未使用过GLSL,我决定尝试使用教程。不幸的是,下面的教程不是我的强项,当我调用'RenderTerrain()'时,我的程序崩溃了(在函数的第二行代码中(GL.DrawElements))

现在这显然是程序中的所有代码,还有很多,你没有机会通过20k行找到我的问题:P但是如果你需要问任何问题,请评论:)

所以我的问题就是,这段代码有什么问题吗?为什么会崩溃?

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK.Graphics.OpenGL;
using OpenTK;

namespace HoardOfUpgrades
{
    public class Shaders
    {
        private static string TerrainVertexShaderText = @"

            #version 140

            // object space to camera space transformation
            uniform mat4 modelview_matrix;            

            // camera space to clip coordinates
            uniform mat4 projection_matrix;


            // incoming vertex position
            in vec3 vertex_position;

            // incoming vertex normal
            in vec3 vertex_normal;

            // incoming vertex_color
            in vec3 vertex_color

            // transformed vertex normal
            out vec3 normal;

            void main(void)
            {
              //not a proper transformation if modelview_matrix involves non-uniform scaling
              normal = ( modelview_matrix * vec4( vertex_normal, 0 ) ).xyz;

              // transforming the incoming vertex position
              gl_Position = projection_matrix * modelview_matrix * vec4( vertex_position, 1 );
            }

        ";

        private static string TerrainFragmentShaderText = @"

            #version 140

            precision highp float;

            const vec3 ambient = vec3( 0.1, 0.1, 0.1 );
            const vec3 lightVecNormalized = normalize( vec3( 0.5, 0.5, 2 ) );
            const vec3 lightColor = vec3( 1.0, 0.8, 0.2 );

            in vec3 normal;

            out vec4 out_frag_color;

            void main(void)
            {
              float diffuse = clamp( dot( lightVecNormalized, normalize( normal ) ), 0.0, 1.0 );
              out_frag_color = vec4( ambient + diffuse * lightColor, 1.0 );
            }

        ";

        public static int TerrainFragmentShaderHandle, TerrainVertexShaderHandle, TerrainProgramHandle, ProjectionMatrixLocation, ModelviewMatrixLocation, TerrainNormHandle, TerrainPosHandle, TerrainColorHandle, TerrainIndicesHandle, TerrainIndiceCount;

        public static void Load(Vector3[] position, Vector3[] normals, Vector3[] colors, int[] indices)
        {
            LoadShaders();
            LoadProgram();

            LoadVertexPositions(position);
            LoadVertexNormals(normals);
            LoadVertexColors(colors);
            LoadIndexer(indices);
        }

        static void LoadProgram()
        {
            TerrainProgramHandle = GL.CreateProgram();

            GL.AttachShader(TerrainProgramHandle, TerrainVertexShaderHandle);
            GL.AttachShader(TerrainProgramHandle, TerrainVertexShaderHandle);

            GL.LinkProgram(TerrainProgramHandle);
        }

        static void LoadShaders()
        {
            TerrainVertexShaderHandle = GL.CreateShader( ShaderType.VertexShader );
            TerrainFragmentShaderHandle = GL.CreateShader( ShaderType.FragmentShader );

            GL.ShaderSource(TerrainVertexShaderHandle, TerrainVertexShaderText);
            GL.ShaderSource(TerrainFragmentShaderHandle, TerrainFragmentShaderText);

            GL.CompileShader(TerrainVertexShaderHandle);
            GL.CompileShader(TerrainFragmentShaderHandle);
        }

        private static void QueryMatrixLocations()
        {
            ProjectionMatrixLocation = GL.GetUniformLocation(TerrainProgramHandle, "projection_matrix");
            ModelviewMatrixLocation = GL.GetUniformLocation(TerrainProgramHandle, "modelview_matrix");
        }

        public static void SetModelviewMatrix(Matrix4 matrix)
        {
            GL.UniformMatrix4(ModelviewMatrixLocation, false, ref matrix);
        }

        public static void SetProjectionMatrix(Matrix4 matrix)
        {
            GL.UniformMatrix4(ProjectionMatrixLocation, false, ref matrix);
        }

        private static void LoadVertexPositions(Vector3[] data)
        {
            GL.GenBuffers(1, out TerrainPosHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, TerrainPosHandle);
            GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                new IntPtr(data.Length * Vector3.SizeInBytes),
                data, BufferUsageHint.StaticDraw);

            GL.EnableVertexAttribArray(0);
            GL.BindAttribLocation(TerrainProgramHandle, 0, "vertex_position");
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
        }

        private static void LoadVertexNormals(Vector3[] data)
        {
            GL.GenBuffers(1, out TerrainNormHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, TerrainNormHandle);
            GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                new IntPtr(data.Length * Vector3.SizeInBytes),
                data, BufferUsageHint.StaticDraw);

            GL.EnableVertexAttribArray(1);
            GL.BindAttribLocation(TerrainProgramHandle, 1, "vertex_normal");
            GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
        }

        private static void LoadVertexColors(Vector3[] data)
        {
            GL.GenBuffers(1, out TerrainColorHandle);
            GL.BindBuffer(BufferTarget.ArrayBuffer, TerrainColorHandle);
            GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,
                new IntPtr(data.Length * Vector3.SizeInBytes),
                data, BufferUsageHint.StaticDraw);

            GL.EnableVertexAttribArray(1);
            GL.BindAttribLocation(TerrainProgramHandle, 1, "vertex_color");
            GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, Vector3.SizeInBytes, 0);
        }

        private static void LoadIndexer(int[] data)
        {
            TerrainIndiceCount = data.Length;

            GL.GenBuffers(1, out TerrainIndicesHandle);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, TerrainIndicesHandle);
            GL.BufferData<int>(BufferTarget.ElementArrayBuffer,
                new IntPtr(data.Length * sizeof(int)),
                data, BufferUsageHint.StaticDraw);
        }

        public static void RenderTerrain()
        {
            GL.UseProgram(TerrainProgramHandle);

            GL.DrawElements(BeginMode.Triangles, TerrainIndiceCount,
                DrawElementsType.UnsignedInt, IntPtr.Zero);

            GL.UseProgram(0);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

必须包含以下代码行:

        GL.DisableClientState(ArrayCap.NormalArray);
        GL.DisableClientState(ArrayCap.VertexArray);
        GL.DisableClientState(ArrayCap.TextureCoordArray);

已启用数组,必须禁用它们才能使用GL.DrawElements()函数