nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "GpuDevice.h" 00024 #include "GLTemplatePrimitiveBuffer.h" 00025 00026 namespace nux 00027 { 00028 00029 TemplateQuadBuffer::TemplateQuadBuffer (GpuDevice *pDeviceFactory, ShaderType Type, int NumQuads) 00030 : m_ShaderType (Type) 00031 { 00032 Memset (VertexAttributeBuffer, 0, 16); 00033 00034 nuxAssert (pDeviceFactory); 00035 m_pDeviceFactory = pDeviceFactory; 00036 m_NumQuad = NumQuads; 00037 nuxAssert (m_NumQuad > 0); 00038 00039 if (m_NumQuad < 0) 00040 m_NumQuad = 256; 00041 00042 m_NumVertex = m_NumQuad * 6; 00043 00044 FormatQuads(); 00045 } 00046 00047 TemplateQuadBuffer::~TemplateQuadBuffer() 00048 { 00049 m_IB.Release(); 00050 00051 for (t_u32 i = 0; i < 16; i++) 00052 { 00053 VertexAttributeBuffer[i].Release(); 00054 } 00055 } 00056 00057 void TemplateQuadBuffer::FormatQuads() 00058 { 00059 // create vertex buffers for quad rendering 00060 // NumQuads * (4 vertices per Quad) * (4 Bytes per vertices) 00061 VertexAttributeBuffer[0] = m_pDeviceFactory->CreateVertexBuffer (m_NumQuad * 4 * 16, VBO_USAGE_DYNAMIC); 00062 00063 // fill quad vertex buffer 00064 unsigned idx = 0; 00065 //BYTE* data0; 00066 float *data0; 00067 VertexAttributeBuffer[0]->Lock (0, m_NumQuad * 4 * 16, (void **) &data0); 00068 00069 for (INT i = 0; i < m_NumQuad; ++i) 00070 { 00071 // (0, 0) _________ (1, 0) 00072 // | /| 00073 // | / | 00074 // | / | 00075 // | / | 00076 // | / | 00077 // | / | 00078 // |/ | 00079 // (0, 1) --------- (1, 1) 00080 00081 00082 ( (float *) data0) [idx++] = 0; // x 00083 ( (float *) data0) [idx++] = 0; // y 00084 ( (float *) data0) [idx++] = 0; // z 00085 ( (float *) data0) [idx++] = 1.0f; // w 00086 00087 00088 ( (float *) data0) [idx++] = 0; // x 00089 ( (float *) data0) [idx++] = 1.0f; // y 00090 ( (float *) data0) [idx++] = 0; // z 00091 ( (float *) data0) [idx++] = 1; // w 00092 00093 ( (float *) data0) [idx++] = 1.0f; // x 00094 ( (float *) data0) [idx++] = 1.0f; // y 00095 ( (float *) data0) [idx++] = 0; // z 00096 ( (float *) data0) [idx++] = 1; // w 00097 00098 00099 ( (float *) data0) [idx++] = 1.0f; // x 00100 ( (float *) data0) [idx++] = 0; // y 00101 ( (float *) data0) [idx++] = 0; // z 00102 ( (float *) data0) [idx++] = 1; // w 00103 00104 00105 // ((DWORD*)data0)[idx++]=((255*(0&1)))|((255*((0&2)>>1))<<8)|(0<<16)|(255<<24); 00106 // ((DWORD*)data0)[idx++]=((255*(1&1)))|((255*((1&2)>>1))<<8)|(0<<16)|(255<<24); 00107 // ((DWORD*)data0)[idx++]=((255*(3&1)))|((255*((3&2)>>1))<<8)|(0<<16)|(255<<24); 00108 // ((DWORD*)data0)[idx++]=((255*(2&1)))|((255*((2&2)>>1))<<8)|(0<<16)|(255<<24); 00109 } 00110 00111 VertexAttributeBuffer[0]->Unlock(); 00112 00113 // create index buffers for quad rendering 00114 // NumQuads * (6 index per Quad) * (2 Bytes per index) : each quad is 2 triangles => 6 indices. 00115 m_IB = m_pDeviceFactory->CreateIndexBuffer (m_NumQuad * 6 * 2, VBO_USAGE_DYNAMIC, INDEX_FORMAT_USHORT); 00116 00117 // Fill quad index buffer 00118 // The index buffers defines 2 triangles for each quad. 00119 // Triangles are arranged as strips (that is 6 triangle index for a quad). 00120 WORD *data1; 00121 m_IB->Lock (0, m_NumQuad * 6 * 2, (void **) &data1); 00122 00123 for (INT i = 0; i < m_NumQuad; ++i) 00124 { 00125 // 00126 // (0) _________ (1) 00127 // | /| 00128 // | / | 00129 // | / | 00130 // | / | 00131 // | / | 00132 // | / | 00133 // |/ | 00134 // (3) --------- (2) 00135 // 00136 ( (WORD *) data1) [i*6+0] = i * 4 + 0; 00137 ( (WORD *) data1) [i*6+1] = i * 4 + 1; 00138 ( (WORD *) data1) [i*6+2] = i * 4 + 3; 00139 ( (WORD *) data1) [i*6+3] = i * 4 + 3; 00140 ( (WORD *) data1) [i*6+4] = i * 4 + 1; 00141 ( (WORD *) data1) [i*6+5] = i * 4 + 2; 00142 00143 } 00144 00145 m_IB->Unlock(); 00146 } 00147 00148 void TemplateQuadBuffer::SetNumQuads (int NumQuads) 00149 { 00150 m_NumQuad = NumQuads; 00151 nuxAssert (m_NumQuad > 0); 00152 00153 if (m_NumQuad < 0) 00154 m_NumQuad = 256; 00155 00156 m_NumVertex = m_NumQuad * 6; 00157 00158 m_IB = ObjectPtr<IOpenGLIndexBuffer> (0);; 00159 00160 for (int i = 0; i < 16; i++) 00161 VertexAttributeBuffer[i] = ObjectPtr<IOpenGLVertexBuffer> (0); 00162 00163 FormatQuads(); 00164 } 00165 00166 int TemplateQuadBuffer::GetNumQuads() const 00167 { 00168 return m_NumQuad; 00169 } 00170 00171 void TemplateQuadBuffer::UnBind() 00172 { 00173 m_pDeviceFactory->InvalidateIndexBuffer(); 00174 m_pDeviceFactory->InvalidateVertexBuffer(); 00175 } 00176 00177 void TemplateQuadBuffer::BindAttribute (INT AttributeLocation, UINT AttributeIndex) 00178 { 00179 if (AttributeLocation < 0) 00180 { 00181 // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! 00182 return; 00183 } 00184 00185 nuxAssert (AttributeIndex >= 0); // Index 0 is the vertex position attribute. This on is set in the constructor. 00186 nuxAssert (AttributeIndex < 16); 00187 nuxAssert (AttributeLocation >= 0); 00188 00189 00190 if (VertexAttributeBuffer[AttributeIndex].IsNull() ) 00191 return; 00192 00193 if (m_ShaderType == SHADER_TYPE_GLSL) 00194 { 00195 if (AttributeIndex == 0) 00196 { 00197 VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); 00198 CHECKGL ( glEnableVertexAttribArrayARB (AttributeLocation) ); 00199 CHECKGL ( glVertexAttribPointerARB ( (GLuint) AttributeLocation, 4, GL_FLOAT, GL_FALSE, 0, NUX_BUFFER_OFFSET (0) ) ); 00200 } 00201 else 00202 { 00203 VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); 00204 CHECKGL ( glEnableVertexAttribArrayARB (AttributeLocation) ); 00205 CHECKGL ( glVertexAttribPointerARB ( (GLuint) AttributeLocation, 4, GL_FLOAT, GL_FALSE, 0, NUX_BUFFER_OFFSET (0) ) ); 00206 } 00207 } 00208 else 00209 { 00210 nuxAssertMsg (0, TEXT ("[TemplateQuadBuffer::BindCgAttribute] Use BindCGAttribute for CG attributes.") ); 00211 } 00212 } 00213 00214 #if (NUX_ENABLE_CG_SHADERS) 00215 void TemplateQuadBuffer::BindCGAttribute (CGparameter AttributeLocation, UINT AttributeIndex) 00216 { 00217 if (AttributeLocation < 0) 00218 { 00219 // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! 00220 return; 00221 } 00222 00223 nuxAssert (AttributeIndex >= 0); // Index 0 is the vertex position attribute. This on is set in the constructor. 00224 nuxAssert (AttributeIndex < 16); 00225 nuxAssert (AttributeLocation >= 0); 00226 00227 00228 if (VertexAttributeBuffer[AttributeIndex].IsNull() ) 00229 return; 00230 00231 if (m_ShaderType == SHADER_TYPE_CG) 00232 { 00233 if (AttributeIndex == 0) 00234 { 00235 VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); 00236 CHECKGL ( cgGLEnableClientState ( (CGparameter) AttributeLocation) ); 00237 CHECKGL ( cgGLSetParameterPointer ( (CGparameter) AttributeLocation, 4, GL_FLOAT, 0, NUX_BUFFER_OFFSET (0) ) ); 00238 } 00239 else 00240 { 00241 VertexAttributeBuffer[AttributeIndex]->BindVertexBuffer(); 00242 CHECKGL ( cgGLEnableClientState ( (CGparameter) AttributeLocation) ); 00243 CHECKGL ( cgGLSetParameterPointer ( (CGparameter) AttributeLocation, 4, GL_FLOAT, 0, NUX_BUFFER_OFFSET (0) ) ); 00244 } 00245 } 00246 else 00247 { 00248 nuxAssertMsg (0, TEXT ("[TemplateQuadBuffer::BindCGAttribute] Use BindAttribute for GLSL attributes.") ); 00249 } 00250 } 00251 #endif 00252 00253 void TemplateQuadBuffer::UnBindAttribute (INT AttributeLocation) 00254 { 00255 if (AttributeLocation < 0) 00256 { 00257 // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! 00258 return; 00259 } 00260 00261 if (m_ShaderType == SHADER_TYPE_GLSL) 00262 { 00263 CHECKGL ( glDisableVertexAttribArrayARB (AttributeLocation) ); 00264 } 00265 else 00266 { 00267 nuxAssertMsg (0, TEXT ("[TemplateQuadBuffer::UnBindAttribute] Use UnBindCGAttribute for CG attributes.") ); 00268 } 00269 } 00270 00271 #if (NUX_ENABLE_CG_SHADERS) 00272 void TemplateQuadBuffer::UnBindCGAttribute (CGparameter AttributeLocation) 00273 { 00274 if (AttributeLocation < 0) 00275 { 00276 // Exclude Attribute Location that are not valid. Not valid does not mean the program is wrong! 00277 return; 00278 } 00279 00280 if (m_ShaderType == SHADER_TYPE_CG) 00281 { 00282 CHECKGL ( cgGLDisableClientState ( (CGparameter) AttributeLocation) ); 00283 } 00284 else 00285 { 00286 nuxAssertMsg (0, TEXT ("[TemplateQuadBuffer::UnBindCGAttribute] Use UnBindAttribute for GLSL attributes.") ); 00287 } 00288 } 00289 #endif 00290 00291 void TemplateQuadBuffer::Render (INT NumPrimitives) 00292 { 00293 INT NumVertex = NumPrimitives * 6; // each quad is 2 triangles = 6 indices 00294 00295 if (NumVertex > m_NumVertex) 00296 { 00297 NumVertex = m_NumVertex; 00298 } 00299 00300 m_IB->BindIndexBuffer(); 00301 CHECKGL ( glDrawElements ( GL_TRIANGLES, NumVertex, GL_UNSIGNED_SHORT, NUX_BUFFER_OFFSET (0) ) ); 00302 m_pDeviceFactory->InvalidateIndexBuffer(); 00303 } 00304 00305 void TemplateQuadBuffer::SetPerQuadAttribute (UINT AttributeIndex, INT Num, Vector4 *pVector) 00306 { 00307 nuxAssert (AttributeIndex > 0); // Index 0 is the vertex position attribute. This on is set in the constructor. 00308 nuxAssert (AttributeIndex < 16); 00309 00310 // Destroy the vertex buffer by setting it to NULL; 00311 VertexAttributeBuffer[AttributeIndex] = ObjectPtr<IOpenGLVertexBuffer> (0);; 00312 00313 VertexAttributeBuffer[AttributeIndex] = m_pDeviceFactory->CreateVertexBuffer (m_NumQuad * 4 * sizeof (Vector4), VBO_USAGE_DYNAMIC); 00314 00315 FLOAT *data; 00316 VertexAttributeBuffer[AttributeIndex]->Lock (0, m_NumQuad * 4 * sizeof (Vector4), (void **) &data); 00317 00318 INT i; 00319 00320 for (i = 0; (i < m_NumQuad) && (i < Num); i++) 00321 { 00322 for (INT j = 0; j < 4; j++) 00323 { 00324 data[16*i + 4*j + 0] = pVector[i].x; 00325 data[16*i + 4*j + 1] = pVector[i].y; 00326 data[16*i + 4*j + 2] = pVector[i].z; 00327 data[16*i + 4*j + 3] = pVector[i].w; 00328 } 00329 } 00330 00331 while (i < m_NumQuad) 00332 { 00333 // this happens if Num < m_NumQuad. 00334 // Fill the rest with the last element of the parameter array passed as argument of the function. 00335 for (INT j = 0; j < 4; j++) 00336 { 00337 data[16*i + 4*j + 0] = pVector[Num-1].x; 00338 data[16*i + 4*j + 1] = pVector[Num-1].y; 00339 data[16*i + 4*j + 2] = pVector[Num-1].z; 00340 data[16*i + 4*j + 3] = pVector[Num-1].w; 00341 } 00342 00343 i++; 00344 } 00345 00346 VertexAttributeBuffer[AttributeIndex]->Unlock(); 00347 } 00348 00349 void TemplateQuadBuffer::SetPerVertexAttribute (UINT AttributeIndex, INT Num, Vector4 *pVector) 00350 { 00351 nuxAssert (AttributeIndex > 0); // Index 0 is the vertex position attribute. This on is set in the constructor. 00352 nuxAssert (AttributeIndex < 16); 00353 00354 // Destroy the vertex buffer by setting it to NULL; 00355 VertexAttributeBuffer[AttributeIndex] = ObjectPtr<IOpenGLVertexBuffer> (0);; 00356 00357 VertexAttributeBuffer[AttributeIndex] = m_pDeviceFactory->CreateVertexBuffer (m_NumQuad * 4 * sizeof (Vector4), VBO_USAGE_DYNAMIC); 00358 00359 FLOAT *data; 00360 VertexAttributeBuffer[AttributeIndex]->Lock (0, m_NumQuad * 4 * sizeof (Vector4), (void **) &data); 00361 00362 INT i; 00363 00364 for (i = 0; (i < m_NumQuad * 4) && (i < Num); i++) 00365 { 00366 data[4*i+0] = pVector[i].x; 00367 data[4*i+1] = pVector[i].y; 00368 data[4*i+2] = pVector[i].z; 00369 data[4*i+3] = pVector[i].w; 00370 } 00371 00372 while (i < m_NumQuad * 4) 00373 { 00374 // this happens if Num < m_NumQuad. 00375 // Fill the rest with the last element of the parameter array passed as argument of the function. 00376 data[4*i+0] = pVector[Num-1].x; 00377 data[4*i+1] = pVector[Num-1].y; 00378 data[4*i+2] = pVector[Num-1].z; 00379 data[4*i+3] = pVector[Num-1].w; 00380 i++; 00381 } 00382 00383 VertexAttributeBuffer[AttributeIndex]->Unlock(); 00384 } 00385 00386 void TemplateQuadBuffer::UnSetQuadAttribute (UINT AttributeIndex) 00387 { 00388 00389 } 00390 }