From f7e202a7c8a9146d59fd47b191fff3982ee18346 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 14 Apr 2012 18:28:15 +0000 Subject: [PATCH] gpu: implement vertex buffer streams for Direct3D. OpenGL is missing for now. --- src/core.h | 2 +- src/gpu/shader.cpp | 14 +- src/gpu/shader.h | 15 +- src/gpu/vertexbuffer.cpp | 286 ++++++++++++++++++++++++++++----------- src/gpu/vertexbuffer.h | 35 ++++- test/tutorial/tut01.cpp | 56 ++------ test/tutorial/tut02.cpp | 61 ++++----- 7 files changed, 291 insertions(+), 178 deletions(-) diff --git a/src/core.h b/src/core.h index f4848f94..c3e7cf8f 100644 --- a/src/core.h +++ b/src/core.h @@ -98,8 +98,8 @@ static inline int isnan(float f) #include "map.h" #include "layer.h" #include "gpu/shader.h" -#include "gpu/vbo.h" #include "gpu/vertexbuffer.h" +#include "gpu/vbo.h" #include "image/image.h" #include "application/application.h" diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp index b10befe6..6136e955 100644 --- a/src/gpu/shader.cpp +++ b/src/gpu/shader.cpp @@ -231,17 +231,19 @@ Shader::Shader(char const *vert, char const *frag) #endif } -int Shader::GetAttribLocation(char const *attr) const +ShaderAttrib Shader::GetAttribLocation(char const *attr, + VertexUsage usage, int index) const { + ShaderAttrib ret; #if defined USE_D3D9 || defined _XBOX - /* FIXME: do we have attribs on these platforms? */ - return 0; + ret.m_flags = (uint32_t)index << 16; + ret.m_flags |= (uint32_t)usage; #elif !defined __CELLOS_LV2__ - return glGetAttribLocation(data->prog_id, attr); + ret.m_flags = glGetAttribLocation(data->prog_id, attr); #else - /* FIXME: need to differentiate between vertex and fragment program */ - return 0; + /* FIXME: can we do this at all? */ #endif + return ret; } ShaderUniform Shader::GetUniformLocation(char const *uni) const diff --git a/src/gpu/shader.h b/src/gpu/shader.h index 9b70b3af..cef975dc 100644 --- a/src/gpu/shader.h +++ b/src/gpu/shader.h @@ -34,6 +34,18 @@ private: uint32_t flags; }; +struct ShaderAttrib +{ + friend class Shader; + friend class VertexDeclaration; + +public: + ShaderAttrib(int flags = 0xffffffff) : m_flags(flags) {} + +private: + uint32_t m_flags; +}; + class ShaderData; class Shader @@ -42,7 +54,8 @@ public: static Shader *Create(char const *vert, char const *frag); static void Destroy(Shader *shader); - int GetAttribLocation(char const *attr) const; + ShaderAttrib GetAttribLocation(char const *attr, struct VertexUsage usage, + int index) const; ShaderUniform GetUniformLocation(char const *uni) const; void SetUniform(ShaderUniform const &uni, int i); diff --git a/src/gpu/vertexbuffer.cpp b/src/gpu/vertexbuffer.cpp index 54be30fc..a8a98294 100644 --- a/src/gpu/vertexbuffer.cpp +++ b/src/gpu/vertexbuffer.cpp @@ -32,14 +32,145 @@ extern D3DDevice *g_d3ddevice; namespace lol { +// +// The VertexBufferData class +// -------------------------- +// + +class VertexBufferData +{ + friend class VertexBuffer; + friend class VertexDeclaration; + +#if defined USE_D3D9 + IDirect3DVertexBuffer9 *m_vbo; +#elif defined _XBOX + D3DVertexBuffer *m_vbo; +#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ + GLuint m_vbo; + uint8_t *m_memory; + size_t m_size; +#endif +}; + +// +// The VertexDeclaration class +// --------------------------- +// + VertexStreamBase const VertexStreamBase::Empty; +VertexDeclaration::VertexDeclaration(VertexStreamBase const &s1, + VertexStreamBase const &s2, + VertexStreamBase const &s3, + VertexStreamBase const &s4, + VertexStreamBase const &s5, + VertexStreamBase const &s6, + VertexStreamBase const &s7, + VertexStreamBase const &s8, + VertexStreamBase const &s9, + VertexStreamBase const &s10, + VertexStreamBase const &s11, + VertexStreamBase const &s12) : m_count(0) +{ + if (&s1 != &VertexStreamBase::Empty) AddStream(s1); + if (&s2 != &VertexStreamBase::Empty) AddStream(s2); + if (&s3 != &VertexStreamBase::Empty) AddStream(s3); + if (&s4 != &VertexStreamBase::Empty) AddStream(s4); + if (&s5 != &VertexStreamBase::Empty) AddStream(s5); + if (&s6 != &VertexStreamBase::Empty) AddStream(s6); + if (&s7 != &VertexStreamBase::Empty) AddStream(s7); + if (&s8 != &VertexStreamBase::Empty) AddStream(s8); + if (&s9 != &VertexStreamBase::Empty) AddStream(s9); + if (&s10 != &VertexStreamBase::Empty) AddStream(s10); + if (&s11 != &VertexStreamBase::Empty) AddStream(s11); + if (&s12 != &VertexStreamBase::Empty) AddStream(s12); + Initialize(); +} + +VertexDeclaration::~VertexDeclaration() +{ +#if defined _XBOX || defined USE_D3D9 +# if defined USE_D3D9 + IDirect3DVertexDeclaration9 *vdecl = (IDirect3DVertexDeclaration9 *)m_data; +# elif defined _XBOX + D3DVertexDeclaration *vdecl = (D3DVertexDeclaration *)m_data; +# endif + + vdecl->Release(); +#else + +#endif +} + +void VertexDeclaration::Bind() +{ +#if defined _XBOX || defined USE_D3D9 +# if defined USE_D3D9 + IDirect3DVertexDeclaration9 *vdecl = (IDirect3DVertexDeclaration9 *)m_data; +# elif defined _XBOX + D3DVertexDeclaration *vdecl = (D3DVertexDeclaration *)m_data; +# endif + + g_d3ddevice->SetVertexDeclaration(vdecl); +#else + +#endif +} + +void VertexDeclaration::SetStream(VertexBuffer *vb, ShaderAttrib attr1, + ShaderAttrib attr2, + ShaderAttrib attr3, + ShaderAttrib attr4, + ShaderAttrib attr5, + ShaderAttrib attr6, + ShaderAttrib attr7, + ShaderAttrib attr8, + ShaderAttrib attr9, + ShaderAttrib attr10, + ShaderAttrib attr11, + ShaderAttrib attr12) +{ +#if defined _XBOX || defined USE_D3D9 + /* Only the first item is required to know which stream this + * is about; the rest of the information is stored in the + * vertex declaration already. */ + uint32_t usage = attr1.m_flags >> 16; + uint32_t index = attr1.m_flags & 0xffff; + int usage_index = 0, stream = -1, stride = 0; + for (int i = 0; i < m_count; i++) + { + if (m_streams[i].usage == usage) + if (usage_index++ == index) + stream = m_streams[i].index; + if (stream == m_streams[i].index) + stride += m_streams[i].size; + } + + /* Now we know the stream index and the element stride */ + /* FIXME: precompute most of the crap above! */ + if (stream >= 0) + g_d3ddevice->SetStreamSource(stream, vb->m_data->m_vbo, 0, stride); +#else + glBindBuffer(GL_ARRAY_BUFFER, vb); + ShaderAttrib l[12] = { attr1, attr2, attr3, attr4, attr5, attr6, + attr7, attr8, attr9, attr10, attr11, attr12 }; + for (int i = 0; i < 12 && l[i].m_flags != 0xffffffff; i++) + { + uint32_t usage = l[i].m_flags >> 16; + uint32_t index = l[i].m_flags & 0xffff; + glEnableVertexAttribArray((GLint)attr.flags); + /* FIXME: Hardcoded!! Where to get that from? */ + glVertexAttribPointer((GLint)attr.flags, 3, GL_FLOAT, GL_FALSE, 0, 0); +#endif +} + void VertexDeclaration::Initialize() { #if defined _XBOX || defined USE_D3D9 static D3DVERTEXELEMENT9 const end_element[] = { D3DDECL_END() }; - static D3DECLTYPE const X = D3DDECLTYPE_UNUSED; - static D3DECLTYPE const tlut[] = + static D3DDECLTYPE const X = D3DDECLTYPE_UNUSED; + static D3DDECLTYPE const tlut[] = { D3DDECLTYPE_UNUSED, X, D3DDECLTYPE_FLOAT16_2, X, D3DDECLTYPE_FLOAT16_4, /* half */ @@ -72,37 +203,34 @@ void VertexDeclaration::Initialize() }; D3DVERTEXELEMENT9 elements[12 + 1]; - int nstreams = 0; - while (m_streams[nstreams].size) + for (int n = 0; n < m_count; n++) { - elements[nstreams].Stream = m_streams[nstreams].index; - elements[nstreams].Offset = 0; - for (int i = 0; i < nstreams; i++) - elements[nstreams].Offset += m_streams[nstreams].size; - - if (m_streams[nstreams].type >= 0 - && m_streams[nstreams].type < sizeof(tlut) / sizeof(*tlut)) - elements[nstreams].Type = tlut[m_streams[nstreams].type]; + elements[n].Stream = m_streams[n].index; + elements[n].Offset = 0; + for (int i = 0; i < n; i++) + elements[n].Offset += m_streams[n].size; + + if (m_streams[n].stream_type >= 0 + && m_streams[n].stream_type < sizeof(tlut) / sizeof(*tlut)) + elements[n].Type = tlut[m_streams[n].stream_type]; else - elements[nstreams].Type = D3DDECLTYPE_UNUSED; + elements[n].Type = D3DDECLTYPE_UNUSED; - elements[nstreams].Method = D3DDECLMETHOD_DEFAULT; + elements[n].Method = D3DDECLMETHOD_DEFAULT; - if (m_streams[nstreams].usage >= 0 - && m_streams[nstreams].usage < sizeof(ulut) / sizeof(*ulut)) - elements[nstreams].Type = ulut[m_streams[nstreams].usage]; + if (m_streams[n].usage >= 0 + && m_streams[n].usage < sizeof(ulut) / sizeof(*ulut)) + elements[n].Usage = ulut[m_streams[n].usage]; else - elements[nstreams].Type = D3DDECLUSAGE_POSITION; + elements[n].Usage = D3DDECLUSAGE_POSITION; - elements[nstreams].UsageIndex = 0; - for (int i = 0; i < nstreams; i++) - if (elements[i].Stream == elements[nstreams].Stream - && elements[i].Usage == elements[nstreams].Usage) - elements[nstreams].UsageIndex++; - - nstreams++; + elements[n].UsageIndex = 0; + for (int i = 0; i < n; i++) + if (elements[i].Stream == elements[n].Stream + && elements[i].Usage == elements[n].Usage) + elements[n].UsageIndex++; } - elements[nstreams] = end_element[0]; + elements[m_count] = end_element[0]; # if defined USE_D3D9 IDirect3DVertexDeclaration9 *vdecl; @@ -118,76 +246,70 @@ void VertexDeclaration::Initialize() #endif } -VertexDeclaration::~VertexDeclaration() +void VertexDeclaration::AddStream(VertexStreamBase const &s) { -#if defined _XBOX || defined USE_D3D9 -# if defined USE_D3D9 - IDirect3DVertexDeclaration9 *vdecl = (IDirect3DVertexDeclaration9 *)m_data; -# elif defined _XBOX - D3DVertexDeclaration *vdecl = (D3DVertexDeclaration *)m_data; -# endif + int index = m_count ? m_streams[m_count - 1].index + 1 : 0; - vdecl->Release(); -#else + for (int i = 0; s.m_streams[i].size; i++) + { + m_streams[m_count].stream_type = s.m_streams[i].stream_type; + m_streams[m_count].usage = s.m_streams[i].usage; + m_streams[m_count].size = s.m_streams[i].size; + m_streams[m_count].index = index; + m_count++; + } +} + +// +// The VertexBuffer class +// ---------------------- +// +VertexBuffer::VertexBuffer(size_t size) + : m_data(new VertexBufferData) +{ +#if defined USE_D3D9 || defined _XBOX + g_d3ddevice->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, NULL, + D3DPOOL_MANAGED, &m_data->m_vbo, NULL); + new uint8_t[size]; +#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ + glGenBuffers(1, &m_data->m_vbo); + m_data->m_memory = new uint8_t[size]; + m_data->m_size = size; #endif } -void VertexDeclaration::Bind() +VertexBuffer::~VertexBuffer() { -#if defined _XBOX || defined USE_D3D9 -# if defined USE_D3D9 - IDirect3DVertexDeclaration9 *vdecl = (IDirect3DVertexDeclaration9 *)m_data; -# elif defined _XBOX - D3DVertexDeclaration *vdecl = (D3DVertexDeclaration *)m_data; -# endif - - g_d3ddevice->SetVertexDeclaration(vdecl); -#else - +#if defined USE_D3D9 || defined _XBOX + m_data->m_vbo->Release(); +#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ + glDeleteBuffers(1, &m_data->m_vbo); + delete[] m_data->m_memory; #endif } -VertexDeclaration::VertexDeclaration(VertexStreamBase const &s1, - VertexStreamBase const &s2, - VertexStreamBase const &s3, - VertexStreamBase const &s4, - VertexStreamBase const &s5, - VertexStreamBase const &s6, - VertexStreamBase const &s7, - VertexStreamBase const &s8, - VertexStreamBase const &s9, - VertexStreamBase const &s10, - VertexStreamBase const &s11, - VertexStreamBase const &s12) : m_count(0) +void *VertexBuffer::Lock(size_t offset, size_t size) { - if (&s1 != &VertexStreamBase::Empty) AddStream(s1); - if (&s2 != &VertexStreamBase::Empty) AddStream(s2); - if (&s3 != &VertexStreamBase::Empty) AddStream(s3); - if (&s4 != &VertexStreamBase::Empty) AddStream(s4); - if (&s5 != &VertexStreamBase::Empty) AddStream(s5); - if (&s6 != &VertexStreamBase::Empty) AddStream(s6); - if (&s7 != &VertexStreamBase::Empty) AddStream(s7); - if (&s8 != &VertexStreamBase::Empty) AddStream(s8); - if (&s9 != &VertexStreamBase::Empty) AddStream(s9); - if (&s10 != &VertexStreamBase::Empty) AddStream(s10); - if (&s11 != &VertexStreamBase::Empty) AddStream(s11); - if (&s12 != &VertexStreamBase::Empty) AddStream(s12); - Initialize(); +#if defined USE_D3D9 || defined _XBOX + void *ret; + if (FAILED(m_data->m_vbo->Lock(offset, size, (void **)&ret, 0))) + exit(0); + return ret; +#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ + return m_data->m_memory + offset; +#endif } -void VertexDeclaration::AddStream(VertexStreamBase const &s) +void VertexBuffer::Unlock() { - int index = m_count ? m_streams[m_count - 1].index + 1 : 0; - - for (int i = 0; s.m_streams[i].size; i++) - { - m_streams[m_count].stream_type = s.m_streams[i].stream_type; - m_streams[m_count].usage = s.m_streams[i].usage; - m_streams[m_count].size = s.m_streams[i].size; - m_streams[m_count].index = index; - m_count++; - } +#if defined USE_D3D9 || defined _XBOX + m_data->m_vbo->Unlock(); +#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glBufferData(GL_ARRAY_BUFFER, m_data->m_size, m_data->m_memory, + GL_STATIC_DRAW); +#endif } } /* namespace lol */ diff --git a/src/gpu/vertexbuffer.h b/src/gpu/vertexbuffer.h index b7038d56..679e3eba 100644 --- a/src/gpu/vertexbuffer.h +++ b/src/gpu/vertexbuffer.h @@ -9,8 +9,8 @@ // // -// The VertexBuffer class -// ---------------------- +// The VertexBuffer and VertexDeclaration classes +// ---------------------------------------------- // #if !defined __LOL_VERTEXBUFFER_H__ @@ -21,6 +21,21 @@ namespace lol { +class VertexBuffer +{ + friend class VertexDeclaration; + +public: + VertexBuffer(size_t size); + ~VertexBuffer(); + + void *Lock(size_t offset, size_t size); + void Unlock(); + +private: + class VertexBufferData *m_data; +}; + struct VertexUsage { enum Value @@ -80,7 +95,7 @@ protected: LOL_TYPE(int32_t) LOL_TYPE(ivec2) LOL_TYPE(ivec3) LOL_TYPE(ivec4) #undef LOL_TYPE - template inline void AddStream(int n, int usage) + template inline void AddStream(int n, VertexUsage usage) { m_streams[n].stream_type = GetType((T *)NULL); m_streams[n].usage = usage; @@ -96,7 +111,7 @@ private: }; template<> -inline void VertexStreamBase::AddStream(int n, int usage) +inline void VertexStreamBase::AddStream(int n, VertexUsage usage) { (void)usage; m_streams[n].size = 0; @@ -149,6 +164,18 @@ public: ~VertexDeclaration(); void Bind(); + void SetStream(VertexBuffer *vb, ShaderAttrib attr1, + ShaderAttrib attr2 = ShaderAttrib(), + ShaderAttrib attr3 = ShaderAttrib(), + ShaderAttrib attr4 = ShaderAttrib(), + ShaderAttrib attr5 = ShaderAttrib(), + ShaderAttrib attr6 = ShaderAttrib(), + ShaderAttrib attr7 = ShaderAttrib(), + ShaderAttrib attr8 = ShaderAttrib(), + ShaderAttrib attr9 = ShaderAttrib(), + ShaderAttrib attr10 = ShaderAttrib(), + ShaderAttrib attr11 = ShaderAttrib(), + ShaderAttrib attr12 = ShaderAttrib()); private: void Initialize(); diff --git a/test/tutorial/tut01.cpp b/test/tutorial/tut01.cpp index 49080983..373c8976 100644 --- a/test/tutorial/tut01.cpp +++ b/test/tutorial/tut01.cpp @@ -99,53 +99,25 @@ public: "}" #endif ); -#if !defined _XBOX && !defined USE_D3D9 - m_attrib = m_shader->GetAttribLocation("in_Position"); -#endif - m_ready = true; + m_coord = m_shader->GetAttribLocation("in_Position", VertexUsage::Position, 0); -#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ && !defined _XBOX && !defined USE_D3D9 - /* Method 1: store vertex buffer on the GPU memory */ - glGenBuffers(1, &m_vbo); - glBindBuffer(GL_ARRAY_BUFFER, m_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, - GL_STATIC_DRAW); -#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ && !defined _XBOX && !defined USE_D3D9 - /* Method 2: upload vertex information at each frame */ -#elif defined _XBOX || defined USE_D3D9 - m_vdecl = - new VertexDeclaration(VertexStream(VertexUsage::Position)); - - if (FAILED(g_d3ddevice->CreateVertexBuffer(sizeof(m_vertices), D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &m_vbo, NULL))) - exit(0); - - vec2 *vertices; - if (FAILED(m_vbo->Lock(0, 0, (void **)&vertices, 0))) - exit(0); + m_vdecl = new VertexDeclaration(VertexStream(VertexUsage::Position)); + + m_vbo = new VertexBuffer(sizeof(m_vertices)); + void *vertices = m_vbo->Lock(0, 0); memcpy(vertices, m_vertices, sizeof(m_vertices)); m_vbo->Unlock(); -#else -#endif + + m_ready = true; /* FIXME: this object never cleans up */ } m_shader->Bind(); m_vdecl->Bind(); + m_vdecl->SetStream(m_vbo, m_coord); #if defined _XBOX || defined USE_D3D9 g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); - g_d3ddevice->SetStreamSource(0, m_vbo, 0, sizeof(*m_vertices)); -#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ - glBindBuffer(GL_ARRAY_BUFFER, m_vbo); - glEnableVertexAttribArray(m_attrib); - glVertexAttribPointer(m_attrib, 2, GL_FLOAT, GL_FALSE, 0, 0); -#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ - /* Never used for now */ - glEnableVertexAttribArray(m_attrib); - glVertexAttribPointer(m_attrib, 2, GL_FLOAT, GL_FALSE, 0, m_vertices); -#else - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, m_vertices); #endif #if defined _XBOX || defined USE_D3D9 @@ -171,16 +143,8 @@ private: vec2 m_vertices[3]; Shader *m_shader; VertexDeclaration *m_vdecl; -#if defined USE_D3D9 - IDirect3DVertexBuffer9 *m_vbo; -#elif defined _XBOX - D3DVertexBuffer *m_vbo; -#else - int m_attrib; -# if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ - GLuint m_vbo; -# endif -#endif + VertexBuffer *m_vbo; + ShaderAttrib m_coord; bool m_ready; }; diff --git a/test/tutorial/tut02.cpp b/test/tutorial/tut02.cpp index 6499fff7..2a2c9886 100644 --- a/test/tutorial/tut02.cpp +++ b/test/tutorial/tut02.cpp @@ -138,49 +138,33 @@ public: "}" #endif ); -#if !defined _XBOX && !defined USE_D3D9 - m_coord = m_shader->GetAttribLocation("in_Vertex"); - m_color = m_shader->GetAttribLocation("in_Color"); -#endif m_mvp = m_shader->GetUniformLocation("in_Matrix"); - m_ready = true; + m_coord = m_shader->GetAttribLocation("in_Vertex", + VertexUsage::Position, 0); + m_color = m_shader->GetAttribLocation("in_Color", + VertexUsage::Color, 0); m_vdecl = new VertexDeclaration(VertexStream(VertexUsage::Position), VertexStream(VertexUsage::Color)); -#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ && !defined _XBOX && !defined USE_D3D9 - /* Method 1: store vertex buffer on the GPU memory */ - glGenBuffers(1, &m_vbo); - glBindBuffer(GL_ARRAY_BUFFER, m_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertices), m_vertices, - GL_STATIC_DRAW); - glGenBuffers(1, &m_cbo); - glBindBuffer(GL_ARRAY_BUFFER, m_cbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(m_colors), m_colors, - GL_STATIC_DRAW); - glGenBuffers(1, &m_ibo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_indices), m_indices, - GL_STATIC_DRAW); -#elif defined _XBOX || defined USE_D3D9 - if (FAILED(g_d3ddevice->CreateVertexBuffer(sizeof(m_vertices), D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &m_vbo, NULL))) - exit(0); - vec3 *vertices; - if (FAILED(m_vbo->Lock(0, 0, (void **)&vertices, 0))) - exit(0); + m_vbo = new VertexBuffer(sizeof(m_vertices)); + void *vertices = m_vbo->Lock(0, 0); memcpy(vertices, m_vertices, sizeof(m_vertices)); m_vbo->Unlock(); - if (FAILED(g_d3ddevice->CreateVertexBuffer(sizeof(m_colors), D3DUSAGE_WRITEONLY, NULL, D3DPOOL_MANAGED, &m_cbo, NULL))) - exit(0); - - vec3 *colors; - if (FAILED(m_cbo->Lock(0, 0, (void **)&colors, 0))) - exit(0); + m_cbo = new VertexBuffer(sizeof(m_colors)); + void *colors = m_cbo->Lock(0, 0); memcpy(colors, m_colors, sizeof(m_colors)); m_cbo->Unlock(); +#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ && !defined _XBOX && !defined USE_D3D9 + /* Method 1: store vertex buffer on the GPU memory */ + glGenBuffers(1, &m_ibo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m_indices), m_indices, + GL_STATIC_DRAW); +#elif defined _XBOX || defined USE_D3D9 int16_t *indices; if (FAILED(g_d3ddevice->CreateIndexBuffer(sizeof(m_indices), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_ibo, NULL))) exit(0); @@ -193,15 +177,17 @@ public: #endif /* FIXME: this object never cleans up */ + m_ready = true; } m_shader->Bind(); m_shader->SetUniform(m_mvp, m_matrix); m_vdecl->Bind(); + m_vdecl->SetStream(m_vbo, m_coord); + m_vdecl->SetStream(m_cbo, m_color); + #if defined _XBOX || defined USE_D3D9 g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); - g_d3ddevice->SetStreamSource(0, m_vbo, 0, sizeof(*m_vertices)); - g_d3ddevice->SetStreamSource(1, m_cbo, 0, sizeof(*m_colors)); g_d3ddevice->SetIndices(m_ibo); g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, sizeof(m_indices) / sizeof(*m_indices)); #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ @@ -237,20 +223,19 @@ private: vec3 m_colors[8]; i16vec3 m_indices[12]; Shader *m_shader; + ShaderAttrib m_coord, m_color; + ShaderUniform m_mvp; VertexDeclaration *m_vdecl; + VertexBuffer *m_vbo, *m_cbo; #if defined USE_D3D9 - IDirect3DVertexBuffer9 *m_vbo, *m_cbo; IDirect3DIndexBuffer9 *m_ibo; #elif defined _XBOX - D3DVertexBuffer *m_vbo, *m_cbo; D3DIndexBuffer *m_ibo; #else - int m_coord, m_color; #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__ - GLuint m_vbo, m_cbo, m_ibo; + GLuint m_ibo; #endif #endif - ShaderUniform m_mvp; bool m_ready; };