unit cubesidestest_min;
{$mode Delphi}
interface
uses
Classes, SysUtils, XIntVector, GR32, dglOpenGL;
type
PYCubeVertex = ^TYCubeVertex;
TYCubeVertex = packed record // 20 byte
Position : TXIntVector8;
Normal : TXIntVector8;
TexCoord : TXIntVector16;
Color : TColor32Entry; // BGRA
end;
PYCubeBlockDataIbo = ^TYCubeBlockDataIbo;
TYCubeBlockDataIbo = packed array[0..36] of GLuint;
type
TYCubeChunkMin = class
strict private
var
FData : PYCubeVertex;
FDataIbo : PYCubeBlockDataIbo;
FVisibleBlocks: GLint;
FVao : GLuint;
FVbo : GLuint;
FIbo : GLuint;
procedure InitVertexData;
procedure UpdateIbo;
public
constructor Create;
destructor Destroy; override;
procedure Draw;
end;
implementation
constructor TYCubeChunkMin.Create;
begin
glCreateVertexArrays(1, @FVao);
glCreateBuffers(1, @FVbo);
glCreateBuffers(1, @FIbo);
// bind vbo to vao
glVertexArrayVertexBuffer(FVao, 0, FVbo, 0, SizeOf(TYCubeVertex));
// map attributes to vbo
glVertexArrayAttribBinding(FVao, 0, 0);
glVertexArrayAttribBinding(FVao, 1, 0);
glVertexArrayAttribBinding(FVao, 2, 0);
glVertexArrayAttribBinding(FVao, 3, 0);
// enable attributes
glEnableVertexArrayAttrib(FVao, 0);
glEnableVertexArrayAttrib(FVao, 1);
glEnableVertexArrayAttrib(FVao, 2);
glEnableVertexArrayAttrib(FVao, 3);
// define attributes
glVertexArrayAttribFormat(FVao, 0, 4, GL_BYTE , GL_FALSE, GLuint(@TYCubeVertex(nil^).Position));
glVertexArrayAttribFormat(FVao, 1, 4, GL_BYTE , GL_FALSE, GLuint(@TYCubeVertex(nil^).Normal));
glVertexArrayAttribFormat(FVao, 2, 2, GL_SHORT , GL_TRUE , GLuint(@TYCubeVertex(nil^).TexCoord));
glVertexArrayAttribFormat(FVao, 3, 4, GL_UNSIGNED_BYTE, GL_TRUE , GLuint(@TYCubeVertex(nil^).Color));
// add ibo
glVertexArrayElementBuffer(FVao, FIbo);
InitVertexData;
UpdateIbo;
end;
destructor TYCubeChunkMin.Destroy;
begin
glUnmapNamedBuffer(FIbo);
glUnmapNamedBuffer(FVbo);
glDeleteBuffers (1, @FIbo);
glDeleteBuffers (1, @FVbo);
glDeleteVertexArrays(1, @FVao);
end;
procedure TYCubeChunkMin.InitVertexData;
var x, y, z, i: NativeInt;
p : PYCubeVertex;
begin
// allocate
glNamedBufferStorage(
FVbo,
SizeOf(TYCubeVertex) * 8,
nil,
GL_DYNAMIC_STORAGE_BIT or GL_MAP_WRITE_BIT or GL_MAP_READ_BIT or GL_MAP_PERSISTENT_BIT or GL_MAP_COHERENT_BIT
);
// map
FData:= PYCubeVertex(glMapNamedBufferRange(
FVbo,
0,
SizeOf(TYCubeVertex) * 8,
GL_MAP_WRITE_BIT or GL_MAP_READ_BIT or GL_MAP_PERSISTENT_BIT or GL_MAP_COHERENT_BIT
));
p:= FData;
// 0
p^.Position := TXIntVector8.Create( 0, 0, 0, 0);
p^.Normal := TXIntVector8.Create(-1, -1, -1, 0);
p^.TexCoord := TXIntVector16.Create(
High(Int16),
High(Int16),
High(Int16),
0);
p^.Color.ARGB := Color32(0, 0, 0);
Inc(p);
// 1
p^.Position := TXIntVector8.Create( 1, 0, 0, 0);
p^.Normal := TXIntVector8.Create( 1, -1, -1, 0);
p^.TexCoord := TXIntVector16.Create(
Low(Int16),
High(Int16),
High(Int16),
0);
p^.Color.ARGB := Color32(255, 0, 0);
Inc(p);
// 2
p^.Position := TXIntVector8.Create( 0, 1, 0, 0);
p^.Normal := TXIntVector8.Create(-1, 1, -1, 0);
p^.TexCoord := TXIntVector16.Create(
High(Int16),
Low(Int16),
High(Int16),
0);
p^.Color.ARGB := Color32(0, 255, 0);
Inc(p);
// 3
p^.Position := TXIntVector8.Create( 1, 1, 0, 0);
p^.Normal := TXIntVector8.Create( 1, 1, -1, 0);
p^.TexCoord := TXIntVector16.Create(
Low(Int16),
Low(Int16),
High(Int16),
0);
p^.Color.ARGB := Color32(255, 255, 0);
Inc(p);
// 4
p^.Position := TXIntVector8.Create( 0, 0, 1, 0);
p^.Normal := TXIntVector8.Create(-1, -1, 1, 0);
p^.TexCoord := TXIntVector16.Create(
High(Int16),
High(Int16),
Low(Int16),
0);
p^.Color.ARGB := Color32(0, 0, 255);
Inc(p);
// 5
p^.Position := TXIntVector8.Create( 1, 0, 1, 0);
p^.Normal := TXIntVector8.Create( 1, -1, 1, 0);
p^.TexCoord := TXIntVector16.Create(
Low(Int16),
High(Int16),
Low(Int16),
0);
p^.Color.ARGB := Color32(255, 0, 255);
Inc(p);
// 6
p^.Position := TXIntVector8.Create( 0, 1, 1, 0);
p^.Normal := TXIntVector8.Create(-1, 1, 1, 0);
p^.TexCoord := TXIntVector16.Create(
High(Int16),
Low(Int16),
Low(Int16),
0);
p^.Color.ARGB := Color32(0, 255, 255);
Inc(p);
// 7
p^.Position := TXIntVector8.Create( 1, 1, 1, 0);
p^.Normal := TXIntVector8.Create( 1, 1, 1, 0);
p^.TexCoord := TXIntVector16.Create(
Low(Int16),
Low(Int16),
Low(Int16),
0);
p^.Color.ARGB := Color32(255, 255, 255);
end;
procedure TYCubeChunkMin.UpdateIbo;
var x, y, z, o, s: NativeInt;
p : PYCubeVertex;
b : PGLuint;
begin
glNamedBufferStorage(
FIbo,
SizeOf(GLuint) * 36,
nil,
GL_DYNAMIC_STORAGE_BIT or GL_MAP_WRITE_BIT or GL_MAP_READ_BIT or GL_MAP_PERSISTENT_BIT or GL_MAP_COHERENT_BIT
);
FDataIbo:= PYCubeBlockDataIbo(glMapNamedBufferRange(
FIbo,
0,
SizeOf(GLuint) * 36,
GL_MAP_WRITE_BIT or GL_MAP_READ_BIT or GL_MAP_PERSISTENT_BIT or GL_MAP_COHERENT_BIT
));
FVisibleBlocks:= 0;
p:= @FData;
b:= @FDataIbo^[0];
// +X
b^:= 7;
Inc(b);
b^:= 5;
Inc(b);
b^:= 1;
Inc(b);
b^:= 1;
Inc(b);
b^:= 3;
Inc(b);
b^:= 7;
Inc(b);
Inc(FVisibleBlocks, 6);
// -X
b^:= 0;
Inc(b);
b^:= 4;
Inc(b);
b^:= 6;
Inc(b);
b^:= 6;
Inc(b);
b^:= 2;
Inc(b);
b^:= 0;
Inc(b);
Inc(FVisibleBlocks, 6);
// +Y
b^:= 2;
Inc(b);
b^:= 6;
Inc(b);
b^:= 7;
Inc(b);
b^:= 7;
Inc(b);
b^:= 3;
Inc(b);
b^:= 2;
Inc(b);
Inc(FVisibleBlocks, 6);
// -Y
b^:= 5;
Inc(b);
b^:= 4;
Inc(b);
b^:= 0;
Inc(b);
b^:= 0;
Inc(b);
b^:= 1;
Inc(b);
b^:= 5;
Inc(b);
Inc(FVisibleBlocks, 6);
// +Z
b^:= 6;
Inc(b);
b^:= 4;
Inc(b);
b^:= 5;
Inc(b);
b^:= 5;
Inc(b);
b^:= 7;
Inc(b);
b^:= 6;
Inc(b);
Inc(FVisibleBlocks, 6);
// -Z
b^:= 1;
Inc(b);
b^:= 0;
Inc(b);
b^:= 2;
Inc(b);
b^:= 2;
Inc(b);
b^:= 3;
Inc(b);
b^:= 1;
Inc(b);
Inc(FVisibleBlocks, 6);
end;
procedure TYCubeChunkMin.Draw;
begin
glBindVertexArray(FVao);
glDrawElements(GL_TRIANGLES, FVisibleBlocks, GL_UNSIGNED_INT, nil);
end;
end.