我一直在尝试在我的程序中实现 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);
}
}
}