@@ -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" | |||
@@ -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 | |||
@@ -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); | |||
@@ -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 */ | |||
@@ -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<typename T> inline void AddStream(int n, int usage) | |||
template<typename T> 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<void>(int n, int usage) | |||
inline void VertexStreamBase::AddStream<void>(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(); | |||
@@ -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<vec2>(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<vec2>(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; | |||
}; | |||
@@ -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<vec3>(VertexUsage::Position), | |||
VertexStream<vec3>(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; | |||
}; | |||