这是我第一次使用OpenGL / OpenTK,并且在尝试渲染两个对象时,其中一个对象无法正确渲染。我已经尝试过代码,似乎无法弄清楚正在发生什么。我坚持认为我错误地使用了mVAO / mVBO数组。
The object on top of the cylinder is the one that isn't rendering properly
and this is how that object should look
第二个物体只是一个圆柱体,它不会像第一个物体那样变形。
这是我的代码:
private int[] mVBO_IDs = new int[4];
private int[] mVAO_IDs = new int[3];
private ShaderUtility mShader;
private ModelUtility mSphereModelUtility;
private ModelUtility mCylinderModelUtility;
private Matrix4 mView, mSphereModel, mGroundModel, mCylinderModel;
protected override void OnLoad(EventArgs e)
{
// Set some GL state
GL.ClearColor(Color4.LightBlue);
GL.Enable(EnableCap.DepthTest);
GL.Enable(EnableCap.CullFace);
mShader = new ShaderUtility(@"Lab3/Shaders/vPassThrough.vert", @"Lab3/Shaders/fLighting.frag");
GL.UseProgram(mShader.ShaderProgramID);
int vPositionLocation = GL.GetAttribLocation(mShader.ShaderProgramID, "vPosition");
int vNormalLocation = GL.GetAttribLocation(mShader.ShaderProgramID, "vNormal");
GL.GenVertexArrays(mVAO_IDs.Length, mVAO_IDs);
GL.GenBuffers(mVBO_IDs.Length, mVBO_IDs);
float[] squareVertices = new float[] {-10, 0, -10,0,1,0,
-10, 0, 10,0,1,0,
10, 0, 10,0,1,0,
10, 0, -10,0,1,0,};
/// Floor
GL.BindVertexArray(mVAO_IDs[0]);
GL.BindBuffer(BufferTarget.ArrayBuffer, mVBO_IDs[0]);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(squareVertices.Length * sizeof(float)), squareVertices, BufferUsageHint.StaticDraw);
int size;
GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
if (squareVertices.Length * sizeof(float) != size)
{
throw new ApplicationException("Vertex data not loaded onto graphics card correctly");
}
GL.EnableVertexAttribArray(vPositionLocation);
GL.VertexAttribPointer(vPositionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
GL.EnableVertexAttribArray(vNormalLocation);
GL.VertexAttribPointer(vNormalLocation, 3, VertexAttribPointerType.Float, true, 6 * sizeof(float), 3);
/// Model 1
mSphereModelUtility = ModelUtility.LoadModel(@"Utility/Models/model.bin");
GL.BindVertexArray(mVAO_IDs[1]);
GL.BindBuffer(BufferTarget.ArrayBuffer, mVBO_IDs[1]);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(mSphereModelUtility.squareVertices.Length * sizeof(float)), mSphereModelUtility.squareVertices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, mVBO_IDs[2]);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(mSphereModelUtility.Indices.Length * sizeof(float)), mSphereModelUtility.Indices, BufferUsageHint.StaticDraw);
GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
if (mSphereModelUtility.squareVertices.Length * sizeof(float) != size)
{
throw new ApplicationException("Vertex data not loaded onto graphics card correctly");
}
GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out size);
if (mSphereModelUtility.Indices.Length * sizeof(float) != size)
{
throw new ApplicationException("Index data not loaded onto graphics card correctly");
}
GL.EnableVertexAttribArray(vPositionLocation);
GL.VertexAttribPointer(vPositionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
GL.EnableVertexAttribArray(vNormalLocation);
GL.VertexAttribPointer(vNormalLocation, 3, VertexAttribPointerType.Float, true, 6 * sizeof(float), 0);
GL.BindVertexArray(0);
/// Model 2
mCylinderModelUtility = ModelUtility.LoadModel(@"Utility/Models/cylinder.bin");
GL.BindVertexArray(mVAO_IDs[2]);
GL.BindBuffer(BufferTarget.ArrayBuffer, mVBO_IDs[2]);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(mCylinderModelUtility.squareVertices.Length * sizeof(float)), mCylinderModelUtility.squareVertices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, mVBO_IDs[3]);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(mCylinderModelUtility.Indices.Length * sizeof(float)), mCylinderModelUtility.Indices, BufferUsageHint.StaticDraw);
GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
if (mCylinderModelUtility.squareVertices.Length * sizeof(float) != size)
{
throw new ApplicationException("Vertex data not loaded onto graphics card correctly");
}
GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out size);
if (mCylinderModelUtility.Indices.Length * sizeof(float) != size)
{
throw new ApplicationException("Index data not loaded onto graphics card correctly");
}
GL.EnableVertexAttribArray(vPositionLocation);
GL.VertexAttribPointer(vPositionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);
GL.EnableVertexAttribArray(vNormalLocation);
GL.VertexAttribPointer(vNormalLocation, 3, VertexAttribPointerType.Float, true, 6 * sizeof(float), 0);
GL.BindVertexArray(0);
/// Positions
mView = Matrix4.CreateTranslation(0, -1.5f, 0);
int uView = GL.GetUniformLocation(mShader.ShaderProgramID, "uView");
GL.UniformMatrix4(uView, true, ref mView);
mGroundModel = Matrix4.CreateTranslation(0, 0, -5f);
mSphereModel = Matrix4.CreateTranslation(0, 3f, -5f);
mCylinderModel = Matrix4.CreateTranslation(0, 1f, -5f);
Vector3 t = mSphereModel.ExtractTranslation();
Matrix4 translation = Matrix4.CreateTranslation(t);
Matrix4 inverseTranslation = Matrix4.CreateTranslation(-t);
mSphereModel = mSphereModel * inverseTranslation * Matrix4.CreateRotationY((float)(Math.PI * -90 / 180.0)) *
translation;
t = mCylinderModel.ExtractTranslation();
translation = Matrix4.CreateTranslation(t);
inverseTranslation = Matrix4.CreateTranslation(-t);
mCylinderModel = mCylinderModel * inverseTranslation * Matrix4.CreateRotationY((float)(Math.PI * -90 / 180.0)) *
translation;
/// Lighting
int uLightPositionLocation = GL.GetUniformLocation(mShader.ShaderProgramID, "uLightPosition");
Vector4 lightPosition = Vector4.Transform(new Vector4(3, 5, -5f, 1), mView);
GL.Uniform4(uLightPositionLocation, lightPosition);
base.OnLoad(e);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
int uModel = GL.GetUniformLocation(mShader.ShaderProgramID, "uModel");
GL.UniformMatrix4(uModel, true, ref mGroundModel);
GL.BindVertexArray(mVAO_IDs[0]);
GL.DrawArrays(PrimitiveType.TriangleFan, 0, 4);
Matrix4 m = mSphereModel * mGroundModel;
uModel = GL.GetUniformLocation(mShader.ShaderProgramID, "uModel");
GL.UniformMatrix4(uModel, true, ref m);
GL.BindVertexArray(mVAO_IDs[1]);
GL.DrawElements(PrimitiveType.Triangles, mSphereModelUtility.Indices.Length, DrawElementsType.UnsignedInt, 0);
m = mCylinderModel * mGroundModel;
uModel = GL.GetUniformLocation(mShader.ShaderProgramID, "uModel");
GL.UniformMatrix4(uModel, true, ref m);
GL.BindVertexArray(mVAO_IDs[2]);
GL.DrawElements(PrimitiveType.Triangles, mCylinderModelUtility.Indices.Length, DrawElementsType.UnsignedInt, 0);
GL.BindVertexArray(0);
this.SwapBuffers();
}
答案 0 :(得分:0)
事实证明,我怀疑是错误地绑定了mVAO / mVBO阵列。我只需要增加mVBO数组大小,然后将缓冲区绑定到正确的数组索引。