
This file was automatically generated from diguyOglGraphicsMesh.cpp. Do not edit this file directly; the changes will be lost.
| Introduction |
Meshes contain the visual geometry of a DI-Guy character. They are attached to shapes, and are associated with materials and textures.
The class diguyOglGraphicsMesh is an example of a diguyGraphicsMesh subclass for an immediate mode renderer using the DI-Guy Loader. The example subclass shows how to use the accessors of the diguyGraphicsMesh class and which virtual functions should be overridden for an immediate mode renderer such as OpenGL.
| Header files and forward declarations |
#include "diguyOglGraphicsMesh.h" #include "diguyOglGraphicsShaderProgram.h" #include "diguyOglGraphicsShaderInstance.h" #include <diguyGraphicsState.h> #include <stdlib.h> #include <libbdilog.h> #define BUFFER_OFFSET(i) ((char*) NULL + (i))
| Constructor |
Initialize data members of the class to a known state.
Base class data will not be fully initialized until during the Build Stage, so base class accessors should not be called here.
diguyOglGraphicsMesh::diguyOglGraphicsMesh(void* internal_data) : diguyGraphicsMesh(internal_data), m_is_skinned_mesh(false), m_has_tangents(false), m_vertex_buffer(0), m_index_buffer(0), m_gl_index_type(GL_UNSIGNED_SHORT) { /* * Nothing else to do after calling base class constructor and * initializing data members. */ }
| build |
Build Stage
Description:
Override of diguyGraphicsMesh::build().
The build() function should create objects necessary to render the visible geometry of this mesh in the Draw Stage.
This implementation creates OpenGL vertex buffer objects (VBOs) for drawing the visible geometry of the mesh. The contents of the VBO are set based on vertex, normal, and texture index data read using object accessors.
No objects are created if this mesh has no vertices or indices.
void diguyOglGraphicsMesh::build() { /* * Don't try to build if there aren't any vertices or indices. */ if (get_vertex_buffer_size() == 0) return; if (get_index_buffer_size() == 0) return; /* * See if this mesh is skinned. */ m_is_skinned_mesh = get_is_skinned_mesh(); /* * See if this mesh has vertex tangents for normal mapping. */ int vf = get_vertex_format(); if ((vf == DIGUY_GRAPHICS_VERTEX_FORMAT_V3_N3_T2_T4) || (vf == DIGUY_GRAPHICS_VERTEX_FORMAT_V3_N3_T2_T4_I4F_W4)) { m_has_tangents = true; } /* * Determine the index type, and from that the OpenGL index type. * Index types are listed in diguyGraphicsVertexFormats.h, in * the diguyGraphicsIndexType enumeration. */ switch (get_index_type()) { case DIGUY_GRAPHICS_INDEX_TYPE_UINT: m_gl_index_type = GL_UNSIGNED_INT; break; case DIGUY_GRAPHICS_INDEX_TYPE_USHORT: case DIGUY_GRAPHICS_INDEX_TYPE_D3D_WORD: m_gl_index_type = GL_UNSIGNED_SHORT; break; case DIGUY_GRAPHICS_INDEX_TYPE_UNKNOWN: default: break; } /* * Allocate a vertex buffer object (VBO) for vertex data. * * Bind the new VBO so that subsequent commands are applied to it. * * If calling this function fails, make sure the glew library is * initialized. */ if (glGenBuffers == NULL) { static bool s_printed_glew_warning = false; if (!s_printed_glew_warning) { bdi_log_printf(BDI_LOG_ERROR, "\n" "ERROR: glGenBuffers function is NULL. Make sure the glew library\n" " is initialized after OpenGL is initialized, but before DI-Guy\n" " is initialized.\n" "\n"); s_printed_glew_warning = true; } return; } glGenBuffers(1, &m_vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); glBufferData(GL_ARRAY_BUFFER, get_vertex_buffer_size(), get_vertex_buffer_data(), GL_STATIC_DRAW); /* * Make sure the buffer was created successfully. */ int n_param_array_object_size; glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &n_param_array_object_size); if (n_param_array_object_size <= 0) { bdi_log_printf(BDI_LOG_ERROR, "WARNING: Failed to allocate Vertex Buffer Object of %d bytes for mesh '%s'.\n", get_vertex_buffer_size(), get_name()); return; } glBindBuffer(GL_ARRAY_BUFFER, 0); /* * Allocate a VBO for index data. * * Bind the new VBO so that subsequent commands are applied to it. */ glGenBuffers(1, &m_index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, get_index_buffer_size(), get_index_buffer_data(), GL_STATIC_DRAW); glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &n_param_array_object_size); /* * Make sure the buffer was created successfully. */ if (n_param_array_object_size <= 0) { bdi_log_printf(BDI_LOG_ERROR, "WARNING: Failed to allocate Index Buffer Object of %d bytes for mesh '%s'.\n", get_index_buffer_size(), get_name()); return; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
| unbuild |
Unbuild Stage
Description:
Override of diguyGraphicsMesh::unbuild().
The unbuild() function should delete the objects created in the build() function.
void diguyOglGraphicsMesh::unbuild() { if (m_vertex_buffer) glDeleteBuffers(1, &m_vertex_buffer); if (m_index_buffer) glDeleteBuffers(1, &m_index_buffer); }
| draw |
Draw Stage
Description:
Override of diguyGraphicsMesh::draw().
The draw() function should perform the steps necessary to draw the visible geometry of this link.
In this implementation the VBOs created in build() are bound, and other OpenGL state is set up so that the mesh can be drawn.
void diguyOglGraphicsMesh::draw() { if (!m_vertex_buffer || !m_index_buffer) return; /* * Bind the vertex data and index buffers. */ glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer); diguyOglGraphicsShaderProgram* shader_program = (diguyOglGraphicsShaderProgram*) get_shader_program(); diguyOglGraphicsShaderInstance* shader_instance = (diguyOglGraphicsShaderInstance*) get_shader_instance(); diguyGraphicsState* state = get_current_graphics_state(); if (state && shader_program) { int textures_available = state->get_textures_available(); if (shader_program->m_bind_location_ufrm_bump_map_enabled != -1) { glUniform1i(shader_program->m_bind_location_ufrm_bump_map_enabled, !!(textures_available & DIGUY_TEXTURE_MAP_MASK_BUMP)); } if (shader_program->m_bind_location_ufrm_specular_map_enabled != -1) { glUniform1i(shader_program->m_bind_location_ufrm_specular_map_enabled, !!(textures_available & DIGUY_TEXTURE_MAP_MASK_SPECULAR)); } if (shader_program->m_bind_location_ufrm_component_map_enabled != -1) { glUniform1i(shader_program->m_bind_location_ufrm_component_map_enabled, !!(textures_available & DIGUY_TEXTURE_MAP_MASK_COMPONENTS)); } if (shader_program->m_bind_location_ufrm_misc_1_map_enabled != -1) { glUniform1i(shader_program->m_bind_location_ufrm_misc_1_map_enabled, !!(textures_available & DIGUY_TEXTURE_MAP_MASK_MISC_1)); } if (shader_program->m_bind_location_ufrm_misc_2_map_enabled != -1) { glUniform1i(shader_program->m_bind_location_ufrm_misc_2_map_enabled, !!(textures_available & DIGUY_TEXTURE_MAP_MASK_MISC_2)); } } /* * Set base geometry pointers. */ glNormalPointer( GL_FLOAT, get_normal_stride(), BUFFER_OFFSET(get_normal_offset())); glTexCoordPointer( 2, GL_FLOAT, get_texture_indices_stride(), BUFFER_OFFSET(get_texture_indices_offset())); glVertexPointer( 3, GL_FLOAT, get_vertex_stride(), BUFFER_OFFSET(get_vertex_offset())); /* * If this is a skinned mesh, we need to set some OpenGL state. */ if (m_is_skinned_mesh) { if (!shader_program ) { static bool printed_shader_warning = false; if (!printed_shader_warning) { bdi_log_printf(BDI_LOG_WARN, "WARNING: Attempt to draw skinned mesh '%s',\n" " but mesh has no shader. This can happen if DI-Guy Graphics shader\n" " program or shader instance subclasses have not been registered.\n", get_name()); printed_shader_warning = true; } return; } shader_program->set_apply_matrices_flag(1); /* * Set shader attribute pointers. */ if (shader_program->m_bind_location_attr_weight_array != -1) { /* * From glVertexAttribPointer() doc: * * "If a non-zero named buffer object is bound to the * GL_ARRAY_BUFFER target (see glBindBufferARB) while a * generic vertex attribute array is specified, pointer * is treated as a byte offset into the buffer object's * data store." */ glVertexAttribPointer(shader_program->m_bind_location_attr_weight_array, 4, // size GL_FLOAT, // type GL_FALSE, // normalized get_vertex_stride(), // stride BUFFER_OFFSET(get_link_weight_offset())); // pointer/offset glEnableVertexAttribArray(shader_program->m_bind_location_attr_weight_array); } if (shader_program->m_bind_location_attr_index_array != -1) { glVertexAttribPointer(shader_program->m_bind_location_attr_index_array, 4, // size GL_FLOAT, // type GL_FALSE, // normalized get_vertex_stride(), // stride BUFFER_OFFSET(get_link_index_offset())); // pointer/offset glEnableVertexAttribArray(shader_program->m_bind_location_attr_index_array); } } else { if (shader_program) shader_program->set_apply_matrices_flag(0); } if (m_has_tangents && shader_program->m_bind_location_attr_tangent != -1) { glVertexAttribPointer(shader_program->m_bind_location_attr_tangent, 4, // size GL_FLOAT, // type GL_TRUE, // normalized?? get_vertex_stride(), // stride BUFFER_OFFSET(get_tangent_offset())); // pointer/offset glEnableVertexAttribArray(shader_program->m_bind_location_attr_tangent); } // (don't know if we need to do this every time, or just once per frame...) glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); /* * DI-Guy's binary format has good sharing of vertices, which means * the number of vertices isn't necessarily the same as the number of * indices. */ //glDrawElements(GL_TRIANGLES, get_vertex_count(), m_gl_index_type, BUFFER_OFFSET(0)); glDrawElements(GL_TRIANGLES, get_index_count(), m_gl_index_type, BUFFER_OFFSET(0)); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); /* * Disable attribute arrays if necessary. */ if (shader_program) { if (m_is_skinned_mesh) { if (shader_program->m_bind_location_attr_index_array != -1) glDisableVertexAttribArray(shader_program->m_bind_location_attr_index_array); if (shader_program->m_bind_location_attr_weight_array != -1) glDisableVertexAttribArray(shader_program->m_bind_location_attr_weight_array); } if (m_has_tangents && (shader_program->m_bind_location_attr_tangent != -1)) { glDisableVertexAttribArray(shader_program->m_bind_location_attr_tangent); } } /* * Unbind the vertex data and index buffers. */ glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
| Create function definition |
Create and return an object of a subclass of diguyGraphicsMesh. This function will be called whenever DI-Guy requires a mesh object.
diguyGraphicsMesh* diguyOglGraphicsMesh_create_func(void* internal_data) { return new diguyOglGraphicsMesh(internal_data); }
ALL RIGHTS RESERVED.
These coded instructions, statements, and computer programs contain unpublished proprietary information of Boston Dynamics and are protected by Copyright Laws of the United States. They may not be used, duplicated, or disclosed in any form, in whole or in part, without the prior written consent from Boston Dynamics.
RESTRICTED RIGHTS LEGEND
Use, duplication, or disclosure by the government is subject to restrictions as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Sofware clause at DFARS 252.227-7013 and/or in similar or successor clauses in the FAR, or the DOD or NASA FAR Supplement, or to subparagraphs (c)(1) and (c)(2) of the Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19, as applicable. Unpublished-rights reserved under the Copyright Laws of the United States.
Contractor/Manufacturer is:
Boston Dynamics/78 Fourth Avenue/Waltham MA 02451.