我正在使用OpenTK編寫我自己的引擎(基本上只是C#的OpenGL綁定,gl *變成了GL。*),而且我將要存儲大量的頂點緩衝區每個頂點有數千個頂點。因此我需要自己的自定義頂點格式,因爲帶有浮點數的Vec3會佔用太多空間。 (我說的是數以百萬計的頂點位置)如何使用OpenGL製作自定義頂點格式
我想要做的就是創建自己的頂點格式用這個佈局:
Byte 0: Position X
Byte 1: Position Y
Byte 2: Position Z
Byte 3: Texture Coordinate X
Byte 4: Color R
Byte 5: Color G
Byte 6: Color B
Byte 7: Texture Coordinate Y
這裏是頂點在C#代碼:
public struct SmallBlockVertex
{
public byte PositionX;
public byte PositionY;
public byte PositionZ;
public byte TextureX;
public byte ColorR;
public byte ColorG;
public byte ColorB;
public byte TextureY;
}
作爲每個軸的位置的字節是很多,因爲我只需要32^3個獨特的位置。
我已經寫了我自己的頂點着色器,它需要兩個vec4作爲輸入,對每組字節。 我的頂點着色器是這樣的:
attribute vec4 pos_data;
attribute vec4 col_data;
uniform mat4 projection_mat;
uniform mat4 view_mat;
uniform mat4 world_mat;
void main()
{
vec4 position = pos_data * vec4(1.0, 1.0, 1.0, 0.0);
gl_Position = projection_mat * view_mat * world_mat * position;
}
要嘗試找出問題,我已經做了我的頂點着色器儘可能簡單。 編譯着色器的代碼使用即時模式繪圖進行測試,並且它可以工作,所以它不可能如此。
這裏是我的函數,它生成,設置和填充頂點緩衝區的數據,並建立一個指向屬性的指針。
public void SetData<VertexType>(VertexType[] vertices, int vertexSize) where VertexType : struct
{
GL.GenVertexArrays(1, out ArrayID);
GL.BindVertexArray(ArrayID);
GL.GenBuffers(1, out ID);
GL.BindBuffer(BufferTarget.ArrayBuffer, ID);
GL.BufferData<VertexType>(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * vertexSize), vertices, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(Shaders.PositionDataID, 4, VertexAttribPointerType.UnsignedByte, false, 4, 0);
GL.VertexAttribPointer(Shaders.ColorDataID, 4, VertexAttribPointerType.UnsignedByte, false, 4, 4);
}
據我瞭解,這是正確的步驟: 生成一個頂點數組對象,並將其綁定 生成頂點緩存,並將其綁定 填寫頂點緩衝帶設置屬性指針
數據着色器*在編譯和使用着色器後,使用此代碼設置DataID。
PositionDataID = GL.GetAttribLocation(shaderProgram, "pos_data");
ColorDataID = GL.GetAttribLocation(shaderProgram, "col_data");
這是我的渲染功能:
void Render()
{
GL.UseProgram(Shaders.ChunkShaderProgram);
Matrix4 view = Constants.Engine_Physics.Player.ViewMatrix;
GL.UniformMatrix4(Shaders.ViewMatrixID, false, ref view);
//GL.Enable(EnableCap.DepthTest);
//GL.Enable(EnableCap.CullFace);
GL.EnableClientState(ArrayCap.VertexArray);
{
Matrix4 world = Matrix4.CreateTranslation(offset.Position);
GL.UniformMatrix4(Shaders.WorldMatrixID, false, ref world);
GL.BindVertexArray(ArrayID);
GL.BindBuffer(OpenTK.Graphics.OpenGL.BufferTarget.ArrayBuffer, ID);
GL.DrawArrays(OpenTK.Graphics.OpenGL.BeginMode.Quads, 0, Count/4);
}
//GL.Disable(EnableCap.DepthTest);
//GL.Disable(EnableCap.CullFace);
GL.DisableClientState(ArrayCap.VertexArray);
GL.Flush();
}
誰能這麼好心給我一些指點(沒有雙關語意)?我是以錯誤的順序來做這件事還是有一些我需要調用的功能?
我在網上搜索了所有內容,但找不到一個很好的教程或指導,解釋如何實現自定義頂點。 如果您需要更多信息,請說明。
那麼...當你運行它會發生什麼?無論如何,你應該做的是讓系統處於工作狀態。如果你知道如何使它與浮點數據一起工作,那就使用它。讓它工作。一旦你的東西渲染正確,那麼你可以慢慢優化數據。在每一步中,驗證它是否有效。然後,當你達到破發點時,你知道哪裏出了問題。 –
如果我運行它,沒有任何反應。也就是說,它是_runs_,但沒有顯示。我也會嘗試使用浮點數據並從那裏開發,但問題是我不知道我應該怎麼做才能獲得我自己的頂點格式(因此標題)。這是一個重大的關鍵步驟(可能不能分成更小的步驟),因爲很多事情都可能出錯。所以這基本上只是試驗和錯誤。如果你知道如何,你能發現我的代碼中有任何錯誤嗎? – Azzi777