Back to index

nux  3.0.0
GLTemplatePrimitiveBuffer.cpp
Go to the documentation of this file.
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 (unsigned int 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, "[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, "[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, "[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, "[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 }