* some small cleanup
[LazOpenGLCore.git] / uglcArrayBuffer.pas
1 unit uglcArrayBuffer;
2
3 { Package:      OpenGLCore
4   Prefix:       glc - OpenGL Core
5   Beschreibung: diese Unit enthält eine Klassen-Kapselung für OpenGL Array Buffer
6   Beispiel:
7     type
8       TVertex = packed record
9         pos: TgluVector3f; // vertex position
10         tex: TgluVector2f; // texture coordinates
11         nor: TgluVector3f; // normal
12       end;
13       PVertex = ^TVertex;
14
15     var
16       vBuffer: TglcArrayBuffer;
17       iBuffer: TglcArrayBuffer;
18       p: Pointer;
19
20     vBuffer := TglcArrayBuffer.Create(TglcBufferTarget.btArrayBuffer);
21     iBuffer := TglcArrayBuffer.Create(TglcBufferTarget.btElementArrayBuffer);
22     try
23       // write vertex data to vertex buffer
24       vBuffer.Bind;
25       vBuffer.BufferData(4, SizeOf(TresMeshVertex), TglcBufferUsage.buStaticDraw, nil);
26       p := vBuffer.MapBuffer(TglcBufferAccess.baWriteOnly);
27       try
28         PVertex(p).pos := gluVertex3f(0.0, 0.0, 0.0);
29         PVertex(p).tex := gluVertex2f(0.0, 0.5);
30         PVertex(p).nor := gluVertex3f(0.0, 1.0, 0.0);
31         inc(p, SizeOf(TVertex));
32         // ... 
33       finally
34         vBuffer.UnmapBuffer;
35         vBuffer.Unbind;
36       end;
37
38       // write indices to index buffer 
39       iBuffer.Bind;
40       iBuffer.BufferData(4, SizeOf(GLuint), TglcBufferUsage.buStaticDraw, nil);
41       p := iBuffer.MapBuffer(TglcBufferAccess.baWriteOnly);
42       try
43         PGLuint(p) := 0;
44         //  ...
45       finally
46         iBuffer.UnmapBuffer;
47         iBuffer.Unbind;
48       end;
49
50       // use array buffers to draw primitive
51       vBuffer.Bind;
52       iBuffer.Bind;
53
54       glEnableClientState(GL_VERTEX_ARRAY);
55       glVertexPointer(3, GL_FLOAT, 8, Pointer(0));
56
57       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
58       glTexCoordPointer(2, GL_FLOAT, 8, Pointer(3));
59
60       glEnableClientState(GL_NORMAL_ARRAY);
61       glNormalPointer(GL_FLOAT, 8, Pointer(5));
62
63       glEnableClientState(GL_INDEX_ARRAY);
64       glIndexPointer(GL_INT, 0, nil);
65
66       glDrawElements(GL_QUADS, iBuffer.DataCount, GL_UNSIGNED_INT, nil);
67
68       glDisableClientState(GL_INDEX_ARRAY);
69       glDisableClientState(GL_VERTEX_ARRAY);
70       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
71       glDisableClientState(GL_NORMAL_ARRAY);
72
73       fIndexBuffer.Unbind;
74       fVertexBuffer.Unbind;
75     finally
76       FreeAndNil(vBuffer);
77       FreeAndNil(iBuffer);
78     end; }
79
80 {$mode objfpc}{$H+}
81
82 interface
83
84 uses
85   dglOpenGL, sysutils, uglcTypes;
86
87 type
88   EglcArrayBuffer = class(Exception);
89   TglcArrayBuffer = class(TObject)
90   private
91     fID: GLuint;
92     fTarget: TglcBufferTarget;
93     fUsage: TglcBufferUsage;
94   protected
95     fDataCount: Integer;
96     fDataSize: Integer;
97   public
98     property ID:        gluInt           read fID;
99     property Target:    TglcBufferTarget read fTarget;
100     property Usage:     TglcBufferUsage  read fUsage;
101     property DataCount: Integer          read fDataCount;
102     property DataSize:  Integer          read fDataSize;
103
104     procedure BufferData(const aDataCount, aDataSize: Cardinal; const aUsage: TglcBufferUsage; const aData: Pointer);
105     function MapBuffer(const aAccess: TglcBufferAccess): Pointer;
106     procedure UnmapBuffer;
107     procedure Bind;
108     procedure Unbind;
109     constructor Create(const aTarget: TglcBufferTarget);
110     destructor Destroy; override;
111   end;
112
113 implementation
114
115 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 //TglcArrayBuffer///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
117 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
118 procedure TglcArrayBuffer.BufferData(const aDataCount, aDataSize: Cardinal; const aUsage: TglcBufferUsage; const aData: Pointer);
119 begin
120   glGetError(); //clear Errors
121   Bind;
122   fDataCount := aDataCount;
123   fDataSize  := aDataSize;
124   fUsage     := aUsage;
125   glBufferData(GLenum(fTarget), fDataCount * fDataSize, aData, GLenum(fUsage));
126   glcCheckAndRaiseError;
127 end;
128
129 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
130 function TglcArrayBuffer.MapBuffer(const aAccess: TglcBufferAccess): Pointer;
131 begin
132   glGetError();
133   result := nil;
134   if (fDataCount * fDataSize) <= 0 then
135     exit;
136   result := glMapBuffer(GLenum(fTarget), GLenum(aAccess));
137   glcCheckAndRaiseError;
138 end;
139
140 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
141 procedure TglcArrayBuffer.UnmapBuffer;
142 begin
143   glUnmapBuffer(GLenum(fTarget));
144 end;
145
146 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
147 procedure TglcArrayBuffer.Bind;
148 begin
149   glBindBuffer(GLenum(fTarget), fID);
150 end;
151
152 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
153 procedure TglcArrayBuffer.Unbind;
154 begin
155   glBindBuffer(GLenum(fTarget), 0);
156 end;
157
158 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
159 constructor TglcArrayBuffer.Create(const aTarget: TglcBufferTarget);
160 begin
161   if not GL_ARB_Vertex_Buffer_Object then
162     raise EglcArrayBuffer.Create('Create - VertexBuffer: not supported');
163   inherited Create;
164   glGenBuffers(1, @fID);
165   fDataCount   := 0;
166   fDataSize    := 0;
167   fTarget      := aTarget;
168 end;
169
170 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////[c]
171 destructor TglcArrayBuffer.Destroy;
172 begin
173   glDeleteBuffers(1, @fID);
174   inherited Destroy;
175 end;
176
177 end.
178