我正在使用 SharpGL 在 WPF 中编写一个程序来绘制一些立方体。在我的软件中,需要绘制大量的立方体。最初,我使用即时模式渲染方法,这使得应用程序太慢。之后我使用了VAO方法,应用程序的速度提高了很多。唯一的问题是所有的立方体都是用白色绘制的。我认为问题在于着色器部分。请帮我解决这个问题。
private void openGLControl_OpenGLInitialized(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
{
OpenGL gL = openGLControl.OpenGL;
gL.Enable(OpenGL.GL_DEPTH_TEST);
gL.ClearColor(0, 0, 0, 0);
gL.MatrixMode(OpenGL.GL_PROJECTION);
gL.LoadIdentity();
myShader = new MyShader(gL);
}
public void SetUpCamera(OpenGL gL)
{
gL.Viewport(0, 0, (int)openGLControl.ActualWidth, (int)openGLControl.ActualHeight);
gL.MatrixMode(OpenGL.GL_PROJECTION);
gL.LoadIdentity();
gL.Perspective(45.0, openGLControl.ActualWidth / openGLControl.ActualHeight, 0.1, 10000.0);
gL.LookAt(0.0, 0.0, 0.1,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
}
private void openGLControl_OpenGLDraw(object sender, SharpGL.WPF.OpenGLRoutedEventArgs args)
{
if (Camera.IsDrawSkip)
{
return;
}
Camera.IsDrawSkip = true;
OpenGL gL = openGLControl.OpenGL;
gL.ClearColor(Colors.DarkGray.ScR, Colors.DarkGray.ScG , Colors.DarkGray.ScB, 0);
gL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
SetUpCamera(gL);
gL.MatrixMode(OpenGL.GL_MODELVIEW);
gL.LoadIdentity();
gL.Translate(Camera.XTransition, Camera.YTransition, Camera.Zoom);
gL.Rotate(Camera.XRotationAngle, 1, 0, 0);
gL.Rotate(Camera.YRotationAngle, 0, 1, 0);
myShader.Bind();
if (Camera.DrawState == DrawState.Draw)
{
drawObjects(gL);
}
VBOManager.Render(gL);
myShader.Unbind();
gL.EnableVertexAttribArray(1);
gL.Flush();
}
private void drawObjects(OpenGL gL)
{
if(int.TryParse(txtCount.Text, out int count))
{
VBOManager.Vertices.Clear();
int index = cbxShape.SelectedIndex;
if (index == 0)
{
for (int z = 0; z < count; z++)
{
for (int y = 0; y < count; y++)
{
for (int x = 0; x < count; x++)
{
VBOManager.AddCubeValues(x * 5, y * 5, z * 5, Colors.OrangeRed);
}
}
}
}
VBOManager.GenerateGeometry(gL);
}
}
public class MyShader
{
public MyShader(OpenGL gl)
{
gL = gl;
init();
}
#region Property
public OpenGL gL { get; set; }
public uint shader_id;
public uint shader_vp;
public uint shader_fp;
#endregion
public void init()
{
shader_vp = gL.CreateShader(OpenGL.GL_VERTEX_SHADER);
shader_fp = gL.CreateShader(OpenGL.GL_FRAGMENT_SHADER);
gL.ShaderSource(shader_vp, Shader_VERTEX_Text());
gL.ShaderSource(shader_fp, Shader_FRAGMENT_Text());
gL.CompileShader(shader_vp);
gL.CompileShader(shader_fp);
shader_id = gL.CreateProgram();
gL.AttachShader(shader_id, shader_fp);
gL.AttachShader(shader_id, shader_vp);
gL.LinkProgram(shader_id);
gL.BindAttribLocation(shader_id, 0, "in_Position"); // Bind a constant attribute location for positions of vertices
gL.BindAttribLocation(shader_id, 1, "in_Color"); // Bind another constant attribute location, this time for color
}
public void Bind()
{
gL.UseProgram(shader_id);
}
public void Unbind()
{
gL.UseProgram(0);
}
private string Shader_FRAGMENT_Text()
{
return @"#version 150 core
in vec3 pass_Color;
out vec4 out_Color;
void main(void)
{
out_Color = vec4(pass_Color, 1.0);
}";
}
private string Shader_VERTEX_Text()
{
return @"##version 150 core
in vec3 in_Position;
in vec3 in_Color;
out vec3 pass_Color;
void main(void)
{
gl_Position = vec4(in_Position, 1.0);
pass_Color = in_Color;
}";
}
}
public static class VBOManager
{
private static VertexBufferArray m_vertexBuffer = new VertexBufferArray();
public static List<float> Vertices = new List<float>();
public static List<float> Colores = new List<float>();
public static void GenerateGeometry(SharpGL.OpenGL gl)
{
m_vertexBuffer.Create(gl);
m_vertexBuffer.Bind(gl);
GenerateVertexBuffer(gl);
GenerateColourBuffer(gl);
m_vertexBuffer.Unbind(gl);
}
private static void GenerateColourBuffer(SharpGL.OpenGL gl)
{
var vertexDataBuffer = new VertexBuffer();
vertexDataBuffer.Create(gl);
vertexDataBuffer.Bind(gl);
vertexDataBuffer.SetData(gl, 1, Colores.ToArray(), false, 3);
}
private static void GenerateVertexBuffer(SharpGL.OpenGL gl)
{
var vertexDataBuffer = new VertexBuffer();
vertexDataBuffer.Create(gl);
vertexDataBuffer.Bind(gl);
vertexDataBuffer.SetData(gl, 0, Vertices.ToArray(), true, 3);
}
public static void Render(SharpGL.OpenGL gl)
{
m_vertexBuffer.Bind(gl);
gl.DrawArrays(SharpGL.OpenGL.GL_QUADS, 0, Vertices.Count);
m_vertexBuffer.Unbind(gl);
}
#region Cube Part
public static List<VertexV2> Vertexs;
public static void GenerateVertex()
{
float value = 2 / 2.0f;
Vertexs = new List<VertexV2>();
Vertexs.Add(new VertexV2(-value, value, value)); //V1
Vertexs.Add(new VertexV2(value, value, value)); //V2
Vertexs.Add(new VertexV2(value, -value, value)); //V3
Vertexs.Add(new VertexV2(-value, -value, value)); //V4
Vertexs.Add(new VertexV2(-value, value, -value)); //V5
Vertexs.Add(new VertexV2(value, value, -value)); //V6
Vertexs.Add(new VertexV2(value, -value, -value)); //V7
Vertexs.Add(new VertexV2(-value, -value, -value)); //V8
}
public static void AddVertex(int i, float x_Trans, float y_Trans, float z_Trans, Color color)
{
Vertices.Add(Vertexs[i].X + x_Trans);
Vertices.Add(Vertexs[i].Y + y_Trans);
Vertices.Add(Vertexs[i].Z + z_Trans);
Colores.Add(color.ScR);
Colores.Add(color.ScG);
Colores.Add(color.ScB);
}
public static void AddCubeValues(float x_Trans, float y_Trans, float z_Trans, Color color)
{
AddVertex(0, x_Trans,y_Trans,z_Trans, color); //V1
AddVertex(1, x_Trans,y_Trans,z_Trans, color); //V2
AddVertex(2, x_Trans,y_Trans,z_Trans, color); //V3
AddVertex(3, x_Trans, y_Trans, z_Trans, color); //V4
AddVertex(4, x_Trans,y_Trans,z_Trans, color); //V5
AddVertex(5, x_Trans,y_Trans,z_Trans, color); //V6
AddVertex(6, x_Trans,y_Trans,z_Trans, color); //V7
AddVertex(7, x_Trans,y_Trans,z_Trans, color); //V8
AddVertex(0, x_Trans,y_Trans,z_Trans, color); //V1
AddVertex(3, x_Trans,y_Trans,z_Trans, color); //V4
AddVertex(7, x_Trans,y_Trans,z_Trans, color); //V5
AddVertex(4, x_Trans,y_Trans,z_Trans, color); //V8
AddVertex(0, x_Trans,y_Trans,z_Trans, color); //V1
AddVertex(1, x_Trans,y_Trans,z_Trans, color); //V4
AddVertex(5, x_Trans,y_Trans,z_Trans, color); //V5
AddVertex(4, x_Trans,y_Trans,z_Trans, color); //V8
AddVertex(1, x_Trans,y_Trans,z_Trans, color); //V1
AddVertex(2, x_Trans,y_Trans,z_Trans, color); //V4
AddVertex(6, x_Trans,y_Trans,z_Trans, color); //V5
AddVertex(5, x_Trans,y_Trans,z_Trans, color); //V8
AddVertex(2, x_Trans,y_Trans,z_Trans, color); //V3
AddVertex(3, x_Trans,y_Trans,z_Trans, color); //V4
AddVertex(7, x_Trans,y_Trans,z_Trans, color); //V8
AddVertex(6, x_Trans, y_Trans, z_Trans, color); //V7
}
}