30 #if defined(_DEBUG) && defined(_WINDOWS)
31 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
41 Vertex_Buffer_Renderer::Vertex_Buffer_Renderer(
Vertex_Buffer &vertex_buffer)
42 : m_vbo(vertex_buffer)
54 : m_align_normals(
false),
59 get_vbos().insert(
this);
62 template <
typename VERTEX>
64 for(
typename std::vector<
Triangle<VERTEX> *>::iterator it = triangles.begin(), iend = triangles.end(); it != iend; ++it)
68 for(std::vector<Vertex_Buffer::Vertex_Buffer_Range *>::iterator it = descriptors.begin(), iend = descriptors.end(); it != iend; ++it)
78 delete m_macrorenderer;
80 get_vbos().erase(
this);
84 std::auto_ptr<Renderable> to_delete(triangle);
105 std::auto_ptr<Renderable> to_delete(triangle);
126 std::auto_ptr<Renderable> to_delete(quad);
139 std::auto_ptr<Renderable> to_delete(quad);
158 m_triangles_cm.push_back(triangle);
181 m_triangles_t.push_back(triangle);
198 std::auto_ptr<Renderable> to_delete(quad);
211 std::auto_ptr<Renderable> to_delete(quad);
224 for(
unsigned int i = 0;
i < m_triangles_cm.size(); ++
i)
226 for(
unsigned int i = 0; i < m_triangles_t.size(); ++
i)
231 delete m_macrorenderer;
232 m_macrorenderer = macrorenderer;
235 template <
typename VERTEX>
261 void Vertex_Buffer::prerender() {
266 align_similar_normals();
268 m_prerendered =
true;
272 void Vertex_Buffer::sort_triangles() {
273 std::stable_sort(m_triangles_cm.begin(), m_triangles_cm.end(), SORTER<Vertex3f_Color>());
274 std::stable_sort(m_triangles_t.begin(), m_triangles_t.end(), SORTER<Vertex3f_Texture>());
277 template <
typename VERTEX>
279 bool operator()(std::vector<Triangle<VERTEX> *> &triangles,
280 std::vector<Vertex_Buffer::Vertex_Buffer_Range *> &descriptors,
281 const size_t &triangles_done)
const {
284 if(!triangles.empty()) {
285 Material * material_ptr = triangles[0]->get_Material() ?
286 new Material(*triangles[0]->get_Material()) :
288 descriptors.push_back(
new Vertex_Buffer::Vertex_Buffer_Range(material_ptr, triangles_done, 1
u));
290 material_ptr->clear_optimization();
291 for(
size_t i = 1;
i < triangles.size(); ++
i) {
292 const Material * material_ptr1 = triangles[
i]->get_Material();
294 material_ptr1 = &mat;
296 if(material_ptr && *material_ptr == *material_ptr1)
297 ++descriptors[last]->num_elements;
299 Material *
const material_ptr2 =
new Material(*material_ptr1);
300 descriptors.push_back(
new Vertex_Buffer::Vertex_Buffer_Range(material_ptr2, triangles_done+
i, 1
u));
302 material_ptr2->clear_optimization();
304 material_ptr2->optimize_to_follow(*material_ptr);
305 material_ptr->optimize_to_precede(*material_ptr2);
307 material_ptr = material_ptr2;
311 return triangles.size() != 0
u;
315 template<
typename VERTEX>
317 Vertex_Ref() :
t(0), which(-1) {}
318 Vertex_Ref(Triangle<VERTEX> *
const &t_,
const int &which_) :
t(t_), which(which_) {}
324 bool operator()(
const Vertex_Ref<VERTEX> &lhs,
const Vertex_Ref<VERTEX> &rhs)
const {
325 return lhs.t->get_vertex(lhs.which).position.x <
326 rhs.t->get_vertex(rhs.which).position.x;
331 bool operator()(
const Vertex_Ref<VERTEX> &lhs,
const Vertex_Ref<VERTEX> &rhs)
const {
332 return lhs.t->get_vertex(lhs.which).position.y <
333 rhs.t->get_vertex(rhs.which).position.y;
338 bool operator()(
const Vertex_Ref<VERTEX> &lhs,
const Vertex_Ref<VERTEX> &rhs)
const {
339 return (*lhs.t)[lhs.which].position.z <
340 (*rhs.t)[rhs.which].position.z;
345 template<
typename VERTEX>
353 const VERTEX &
v1 = t1[which];
355 if((v0.position - v1.position).magnitude2() < closeness_threshold_squared &&
359 next.normal = v0.normal;
364 template<
typename VERTEX>
366 std::vector<Vertex_Buffer::Vertex_Buffer_Range *> &descriptors)
370 for(std::vector<Vertex_Buffer::Vertex_Buffer_Range *>::iterator it = descriptors.begin();
371 it != descriptors.end();
374 std::vector< Vertex_Ref<VERTEX> > verts;
376 verts.reserve(3
u * (*it)->num_elements);
377 for(
size_t i = (*it)->start, iend = (*it)->start + (*it)->num_elements;
381 verts.push_back(Vertex_Ref<VERTEX>(triangles[
i], 0
u));
382 verts.push_back(Vertex_Ref<VERTEX>(triangles[i], 1
u));
383 verts.push_back(Vertex_Ref<VERTEX>(triangles[i], 2
u));
386 std::stable_sort(verts.begin(), verts.end(),
typename Vertex_Ref<VERTEX>::Z_Sorter());
388 typename std::vector< Vertex_Ref<VERTEX> >::iterator kend = verts.begin();
390 for(
typename std::vector< Vertex_Ref<VERTEX> >::iterator jt = verts.begin();
394 for(; kend != verts.end(); ++kend)
396 if((*kend->t)[kend->which].position.z -
397 (*jt->t)[jt->which].position.z > closeness_threshold)
403 for(
typename std::vector< Vertex_Ref<VERTEX> >::iterator kt = jt + 1;
415 void Vertex_Buffer::align_similar_normals() {
420 void Vertex_Buffer::set_descriptors() {
421 DESCRIBER<Vertex3f_Color>()(m_triangles_cm, m_descriptors_cm, 0
u);
422 DESCRIBER<Vertex3f_Texture>()(m_triangles_t, m_descriptors_t, 0
u);
426 std::set<Vertex_Buffer *> &vbos = get_vbos();
428 for(std::set<Vertex_Buffer *>::iterator it = vbos.begin();
436 std::set<Vertex_Buffer *> & Vertex_Buffer::get_vbos() {
437 static std::set<Vertex_Buffer *> vbos;
441 #ifndef DISABLE_GL_FIXED
443 Vertex_Buffer_Renderer_GL_Fixed::Vertex_Buffer_Renderer_GL_Fixed(
Vertex_Buffer &vbo)
446 memset(m_vbuf, 0,
sizeof(VBO_GL) * 6);
450 const size_t v_size = vertex_size();
451 const size_t n_size = normal_size();
452 const size_t c_size = color_size();
453 const size_t t_size = texel_size();
455 const size_t vbuf_c_size = v_size * (vbo.num_vertices_cm());
456 const size_t nbuf_c_size = n_size * (vbo.num_vertices_cm());
457 const size_t cbuf_size = c_size * (vbo.num_vertices_cm());
458 const size_t vbuf_t_size = v_size * (vbo.num_vertices_t());
459 const size_t nbuf_t_size = n_size * (vbo.num_vertices_t());
460 const size_t tbuf_size = t_size * (vbo.num_vertices_t());
463 unsigned char *p_verts =
new unsigned char [vbuf_c_size];
464 unsigned char *p_normals =
new unsigned char [nbuf_c_size];
465 unsigned char *p_colors =
new unsigned char [cbuf_size];
467 unsigned char *buffered_verts = p_verts;
468 unsigned char *buffered_normals = p_normals;
469 unsigned char *buffered_colors = p_colors;
471 for(
unsigned int i = 0;
i < vbo.m_triangles_cm.size(); ++
i)
472 for(
int j = 0;
j < 3; ++
j) {
473 memcpy(buffered_verts, (*vbo.m_triangles_cm[
i])[
j].get_address(), v_size);
474 buffered_verts += v_size;
476 memcpy(buffered_normals, reinterpret_cast<float *>((*vbo.m_triangles_cm[
i])[
j].get_address())+3, n_size);
477 buffered_normals += n_size;
479 memcpy(buffered_colors, reinterpret_cast<float *>((*vbo.m_triangles_cm[
i])[
j].get_address())+6, c_size);
480 std::swap(buffered_colors[0], buffered_colors[2]);
481 buffered_colors += c_size;
484 if(buffers_supported(vgl)) {
485 for(
int i = 0;
i < 3; ++
i)
500 m_vbuf[0].alt = p_verts;
501 m_vbuf[1].alt = p_normals;
502 m_vbuf[2].alt = p_colors;
507 unsigned char *p_verts =
new unsigned char [vbuf_t_size];
508 unsigned char *p_normals =
new unsigned char [nbuf_t_size];
509 unsigned char *p_texels =
new unsigned char [tbuf_size];
511 unsigned char *buffered_verts = p_verts;
512 unsigned char *buffered_normals = p_normals;
513 unsigned char *buffered_texels = p_texels;
515 for(
unsigned int i = 0;
i < vbo.m_triangles_t.size(); ++
i)
516 for(
int j = 0;
j < 3; ++
j) {
517 memcpy(buffered_verts, (*vbo.m_triangles_t[
i])[
j].get_address(), v_size);
518 buffered_verts += v_size;
520 memcpy(buffered_normals, reinterpret_cast<float *>((*vbo.m_triangles_t[
i])[
j].get_address())+3, n_size);
521 buffered_normals += n_size;
523 memcpy(buffered_texels, reinterpret_cast<float *>((*vbo.m_triangles_t[
i])[
j].get_address())+6, t_size);
524 buffered_texels += t_size;
527 if(buffers_supported(vgl)) {
528 for(
int i = 3;
i < 6; ++
i)
543 m_vbuf[3].alt = p_verts;
544 m_vbuf[4].alt = p_normals;
545 m_vbuf[5].alt = p_texels;
553 if(buffers_supported(vgl)) {
554 for(
int i = 0;
i < 6; ++
i)
559 for(
int i = 0;
i < 6; ++
i)
560 delete [] m_vbuf[
i].alt;
566 VB_Renderer_GL(
const GLint &first_,
const GLsizei &count_)
573 void operator()()
const {
584 for(
size_t i = 0
u;
i < descriptors.size(); ++
i) {
585 if(descriptors[
i]->material.get())
588 VB_Renderer_GL microrenderer(
int(3
u*descriptors[i]->
start),
int(3
u*descriptors[i]->num_elements));
589 macrorenderer(microrenderer);
591 if(descriptors[i]->material.get())
598 const bool buffers_supported_ = buffers_supported(vgl);
603 if(!
m_vbo.m_descriptors_cm.empty()) {
605 if(buffers_supported_)
609 if(buffers_supported_)
614 if(buffers_supported_)
623 if(!
m_vbo.m_descriptors_t.empty()) {
625 if(buffers_supported_)
629 if(buffers_supported_)
634 if(buffers_supported_)
645 if(buffers_supported_)
650 #ifndef DISABLE_GL_SHADER
652 Vertex_Buffer_Renderer_GL_Shader::Vertex_Buffer_Renderer_GL_Shader(
Vertex_Buffer &vbo)
655 memset(m_vbuf, 0,
sizeof(VBO_GL) * 6);
657 const size_t v_size = vertex_size();
658 const size_t n_size = normal_size();
659 const size_t c_size = color_size();
660 const size_t t_size = texel_size();
662 const size_t vbuf_c_size = v_size * (vbo.num_vertices_cm());
663 const size_t nbuf_c_size = n_size * (vbo.num_vertices_cm());
664 const size_t cbuf_size = c_size * (vbo.num_vertices_cm());
665 const size_t vbuf_t_size = v_size * (vbo.num_vertices_t());
666 const size_t nbuf_t_size = n_size * (vbo.num_vertices_t());
667 const size_t tbuf_size = t_size * (vbo.num_vertices_t());
670 unsigned char *p_verts =
new unsigned char [vbuf_c_size];
671 unsigned char *p_normals =
new unsigned char [nbuf_c_size];
672 unsigned char *p_colors =
new unsigned char [cbuf_size];
674 unsigned char *buffered_verts = p_verts;
675 unsigned char *buffered_normals = p_normals;
676 unsigned char *buffered_colors = p_colors;
678 for(
unsigned int i = 0;
i < vbo.m_triangles_cm.size(); ++
i)
679 for(
int j = 0;
j < 3; ++
j) {
680 memcpy(buffered_verts, (*vbo.m_triangles_cm[
i])[
j].get_address(), v_size);
681 buffered_verts += v_size;
683 memcpy(buffered_normals, reinterpret_cast<float *>((*vbo.m_triangles_cm[
i])[
j].get_address())+3, n_size);
684 buffered_normals += n_size;
686 memcpy(buffered_colors, reinterpret_cast<float *>((*vbo.m_triangles_cm[
i])[
j].get_address())+6, c_size);
687 std::swap(buffered_colors[0], buffered_colors[2]);
688 buffered_colors += c_size;
691 for(
int i = 0;
i < 3; ++
i)
707 unsigned char *p_verts =
new unsigned char [vbuf_t_size];
708 unsigned char *p_normals =
new unsigned char [nbuf_t_size];
709 unsigned char *p_texels =
new unsigned char [tbuf_size];
711 unsigned char *buffered_verts = p_verts;
712 unsigned char *buffered_normals = p_normals;
713 unsigned char *buffered_texels = p_texels;
715 for(
unsigned int i = 0;
i < vbo.m_triangles_t.size(); ++
i)
716 for(
int j = 0;
j < 3; ++
j) {
717 memcpy(buffered_verts, (*vbo.m_triangles_t[
i])[
j].get_address(), v_size);
718 buffered_verts += v_size;
720 memcpy(buffered_normals, reinterpret_cast<float *>((*vbo.m_triangles_t[
i])[
j].get_address())+3, n_size);
721 buffered_normals += n_size;
723 memcpy(buffered_texels, reinterpret_cast<float *>((*vbo.m_triangles_t[
i])[
j].get_address())+6, t_size);
724 buffered_texels += t_size;
727 for(
int i = 3;
i < 6; ++
i)
744 for(
int i = 0;
i < 6; ++
i)
753 if(!
m_vbo.m_descriptors_cm.empty()) {
770 if(!
m_vbo.m_descriptors_t.empty()) {
805 if(!vbo.m_triangles_cm.empty()) {
806 const size_t buf_size = vertex_c_size() * vbo.num_vertices_cm();
826 vertex_size = vertex_c_size();
830 if(FAILED(
m_buf_c.
data.
vbo->Lock(0, 0, reinterpret_cast<void **>(&buffered), 0))) {
838 for(
size_t i = 0
u;
i != vbo.m_triangles_cm.size(); ++
i)
839 for(
int j = 0;
j != 3; ++
j) {
840 memcpy(buffered, (*vbo.m_triangles_cm[
i])[
j].get_address(), vertex_size);
841 buffered += vertex_size;
848 if(!vbo.m_triangles_t.empty()) {
849 const size_t buf_size = vertex_t_size() * vbo.num_vertices_t();
869 vertex_size = vertex_t_size();
873 if(FAILED(
m_buf_t.
data.
vbo->Lock(0, 0, reinterpret_cast<void **>(&buffered), 0))) {
881 for(
size_t i = 0
u;
i != vbo.m_triangles_t.size(); ++
i)
882 for(
int j = 0;
j != 3; ++
j) {
883 memcpy(buffered, (*vbo.m_triangles_t[
i])[
j].get_address(), vertex_size);
884 buffered += vertex_size;
910 VB_Renderer_DX9VBO(
Video_DX9 &vdx,
const size_t &StartVertex_,
const size_t &PrimitiveCount_)
911 : d3d_device(vdx.get_d3d_device()),
912 StartVertex(StartVertex_),
913 PrimitiveCount(PrimitiveCount_)
918 void operator()()
const {
921 UINT(PrimitiveCount));
926 size_t PrimitiveCount;
929 class VB_Renderer_DX9 :
public Vertex_Buffer_Microrenderer {
931 VB_Renderer_DX9(Video_DX9 &vdx,
const size_t &PrimitiveCount_,
const void *
const &pVertexStreamZeroData_,
const size_t &VertexStreamZeroStride_)
932 : d3d_device(vdx.get_d3d_device()),
933 PrimitiveCount(PrimitiveCount_),
934 pVertexStreamZeroData(pVertexStreamZeroData_),
935 VertexStreamZeroStride(VertexStreamZeroStride_)
940 void operator()()
const {
942 UINT(PrimitiveCount),
943 pVertexStreamZeroData,
944 UINT(VertexStreamZeroStride));
948 size_t PrimitiveCount;
949 const void * pVertexStreamZeroData;
950 size_t VertexStreamZeroStride;
954 std::vector<Vertex_Buffer::Vertex_Buffer_Range *> &descriptors,
956 const unsigned int &
stride,
959 for(
unsigned int i = 0;
i < descriptors.size(); ++
i) {
960 if(descriptors[
i]->material.get())
964 VB_Renderer_DX9VBO microrenderer(vdx, 3
u * descriptors[i]->
start, descriptors[i]->num_elements);
965 macrorenderer(microrenderer);
968 VB_Renderer_DX9 microrenderer(vdx, descriptors[i]->num_elements, vbo_dx9.
data.
alt + 3
u * descriptors[i]->start, stride);
969 macrorenderer(microrenderer);
972 if(descriptors[i]->material.get())
996 Vertex_Buffer::Uninit Vertex_Buffer::g_uninit;
#define GL_STATIC_DRAW_ARB
void give_Quadrilateral(Quadrilateral< Vertex2f_Color > *const &quadrilateral)
Give the Vertex_Buffer a Quadrilateral (which it will delete later)
void debug_render()
Render all Triangles in the Vertex_Buffer individually; Will fail if prerender has been called...
const Material * get_Material() const
Get the Material.
virtual void set_Material(const Material &material)=0
Set a Material.
void pglBufferDataARB(const GLenum target, const int size, const GLvoid *const data, const GLenum usage) const
The glBufferDataARB OpenGL function as provided by an extension; Will segfault if has_vertex_buffers(...
The Direct3D9 Rendering System.
#define CLOSENESS_THRESHOLD
struct IDirect3DDevice9 * LPDIRECT3DDEVICE9
LPDIRECT3DDEVICE9 & get_d3d_device()
See DirectX Documentation for details.
The Video Rendering Singleton.
EGLImageKHR EGLint EGLint EGLint * stride
An Abstraction of a Vertex in 2-space, colored.
#define D3DUSAGE_WRITEONLY
#define ALIKENESS_THRESHOLD
An Abstraction of a Vertex in 3-space, colored.
void lose()
Lose the Vertex_Buffer.
static void render(const Vertex_Buffer_Macrorenderer ¯orenderer, std::vector< Vertex_Buffer::Vertex_Buffer_Range * > &descriptors)
An Abstraction of a Material.
An Abstraction of a Quadrilateral.
An Abstraction of a Vertex in 3-space, textured.
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
virtual Vertex_Buffer_Renderer * create_Vertex_Buffer_Renderer(Vertex_Buffer &vertex_buffer)=0
Function for creating a Vertex_Buffer_Renderer.
Triangle< VERTEX > * get_duplicate() const
Get a duplicate of the Triangle.
void lend_pre_uninit(Event::Handler *const &handler)
#define CLOSENESS_THRESHOLD_SQUARED
IDirect3DVertexBuffer9 * vbo
Triangle< VERTEX > * get_duplicate_t1() const
Get the second half of the Quadrilateral.
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
void set_Material(const Material &material)
Set a Material.
Vertex_Buffer_Range(Material *const &m, const size_t &s, const size_t &ne)
GL_APICALL void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
A Featureful 3-Space Vector Class.
void give_Macrorenderer(Vertex_Buffer_Macrorenderer *const ¯orenderer)
Wraps the final render call.
The OpenGL Rendering System.
virtual void operator()(const Vertex_Buffer_Microrenderer µrenderer) const
GL_APICALL void GL_APIENTRY glGenBuffers(GLsizei n, GLuint *buffers)
virtual void unset_Material(const Material &material)=0
Unset a Material.
virtual void render(const Renderable &renderable)=0
Render a Renderable.
void pglDeleteBuffersARB(const GLsizei n, GLuint *const buffers) const
The glDeleteBuffersARB OpenGL function as provided by an extension; Will segfault if has_vertex_buffe...
void align_similar_normals(const VERTEX v0, Triangle< VERTEX > &t1, const int &which)
void pglGenBuffersARB(const GLsizei n, GLuint *const buffers) const
The glGenBuffersARB OpenGL function as provided by an extension; Will segfault if has_vertex_buffers(...
void fax_Quadrilateral(const Quadrilateral< Vertex2f_Color > *const &quadrilateral)
Give the Vertex_Buffer a copy of a Quadrilateral.
#define GL_TEXTURE_COORD_ARRAY
virtual ~Vertex_Buffer_Renderer_DX9()
void unset_Material(const Material &material)
Unset a Material.
union Zeni::Vertex_Buffer_Renderer_DX9::VBO_DX9::VBO_DX9_impl data
#define glDisableClientState
A Vertex_Buffer that accepts Triangle and Quadrilaterals.
void give_Triangle(Triangle< Vertex2f_Color > *const &triangle)
Give the Vertex_Buffer a Triangle (which it will delete later)
#define glTexCoordPointer
virtual ~Vertex_Buffer_Renderer_GL_Shader()
void fax_Triangle(const Triangle< Vertex2f_Color > *const &triangle)
Give the Vertex_Buffer a copy of a Triangle.
An Abstraction of a Vertex in 2-space, textured.
Triangle< VERTEX > * get_duplicate_t0() const
Get the first half of the Quadrilateral.
void fax_Material(const Material *const &material)
Set the Material, giving the Renderable a copy.
void swap(Zeni::String &lhs, Zeni::String &rhs)
#define glEnableClientState
virtual ~Vertex_Buffer_Renderer_GL_Fixed()
struct Zeni::Vertex_Buffer_Renderer_DX9::VBO_DX9 m_buf_t
void render()
Render the Vertex_Buffer.
An Abstraction of a Triangle.
static void clear_triangles(std::vector< Triangle< VERTEX > * > &triangles, std::vector< Vertex_Buffer::Vertex_Buffer_Range * > &descriptors)
Video & get_Video()
Get access to the singleton.
void set_fvf(const bool &is_3d)
GL_APICALL void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint *buffers)
GL_APICALL void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
const Uint32 & get_Color() const
Get the current Color.
struct Zeni::Vertex_Buffer_Renderer_DX9::VBO_DX9 m_buf_c
Point2f texture_coordinate
#define GL_ARRAY_BUFFER_ARB
void pglBindBufferARB(const GLenum target, const GLuint buffer) const
The glBindBufferARB OpenGL function as provided by an extension; Will segfault if has_vertex_buffers(...
GLfloat GLfloat GLfloat v2