Skip to content

Commit

Permalink
Model Renderer|Fixed: Dynamically enlarge vertex buffers to accommoda…
Browse files Browse the repository at this point in the history
…te model vertices

Previously Doomsday used fixed-size vertex buffers (and normals,
etc...) while rendering models. However, as there now appears to be
DMD files in the wild which use many more vertices than those which
may be created using the original md2tool; we must now dynamically
resize the vertex render buffers. Failure to do so results in the
engine writing past the end of the static buffers and trashing
memory.

Vertex buffers are now dynamically resized according to the maximum
number of vertices needed to render the densest model among those
presently loaded.

There however remains a fixed limit of 16192 vertices, primarily to
prevent model authors from going completey OTT. If a model contains
more than this number, a warning will be logged and the model will
simply not be rendered.
  • Loading branch information
danij-deng committed Feb 8, 2012
1 parent cb4d44e commit 98b2fcb
Show file tree
Hide file tree
Showing 4 changed files with 309 additions and 123 deletions.
88 changes: 59 additions & 29 deletions doomsday/engine/portable/include/rend_model.h
@@ -1,34 +1,32 @@
/**\file
*\section License
* License: GPL
* Online License Link: http://www.gnu.org/licenses/gpl.html
*
*\author Copyright © 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
*\author Copyright © 2007-2012 Daniel Swanson <danij@dengine.net>
/**
* @file rend_model.h
* 3D Model Renderer (v2.1). @ingroup gl
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* @authors Copyright &copy; 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright &copy; 2007-2012 Daniel Swanson <danij@dengine.net>
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

/**
* rend_model.h: 3D Models
*/
#ifndef LIBDENG_RENDER_MODEL_H
#define LIBDENG_RENDER_MODEL_H

#ifndef __DOOMSDAY_RENDER_MODEL_H__
#define __DOOMSDAY_RENDER_MODEL_H__
/// Absolute maximum number of vertices per submodel supported by this module.
#define RENDER_MAX_MODEL_VERTS 16192

/// @todo Split this large inflexible structure into logical subcomponent pieces.
typedef struct rendmodelparams_s {
// Animation, frame interpolation.
struct modeldef_s *mf, *nextMF;
Expand All @@ -41,7 +39,7 @@ typedef struct rendmodelparams_s {
float center[3], gzt; // The real center point and global top z for silhouette clipping.
float srvo[3]; // Short-range visual offset.
float distance; // Distance from viewer.
float yaw, extraYawAngle, yawAngleOffset; // \todo we don't need three sets of angles, update users of this struct instead.
float yaw, extraYawAngle, yawAngleOffset; ///< @todo We do not need three sets of angles...
float pitch, extraPitchAngle, pitchAngleOffset;

float extraScale;
Expand All @@ -57,7 +55,7 @@ typedef struct rendmodelparams_s {
float ambientColor[4];
uint vLightListIdx;

// Shinemaping:
// Shiney texture mapping:
float shineYawOffset;
float shinePitchOffset;
boolean shineTranslateWithViewerPos;
Expand All @@ -70,11 +68,43 @@ extern int mirrorHudModels;
extern int modelShinyMultitex;
extern float rendModelLOD;

/**
* Registers the console commands and variables used by this module.
*/
void Rend_ModelRegister(void);

/// Initialize this module.
/**
* Initialize this module.
*/
void Rend_ModelInit(void);

void Rend_RenderModel(const rendmodelparams_t *params);
/**
* Shuts down this module.
*/
void Rend_ModelShutdown(void);

/**
* Expand the render buffer to accommodate rendering models containing at most
* this number of vertices.
*
* @note It is not actually necessary to call this. The vertex buffer will be
* enlarged automatically at render time to accommodate a given model so
* long as it contains less than RENDER_MAX_MODEL_VERTS. If not the model
* will simply not be rendered at all.
*
* @note Buffer reallocation is deferred until necessary, so repeatedly calling
* this routine during initialization is OK.
*
* @param numVertices New maximum number of vertices we'll be required to handle.
*
* @return @c true= successfully expanded. May fail if @a numVertices is larger
* than RENDER_MAX_MODEL_VERTS.
*/
boolean Rend_ModelExpandVertexBuffers(uint numVertices);

/**
* Render a submodel according to paramaters.
*/
void Rend_RenderModel(const rendmodelparams_t* params);

#endif
#endif /// LIBDENG_RENDER_MODEL_H
1 change: 1 addition & 0 deletions doomsday/engine/portable/src/gl_main.c
Expand Up @@ -549,6 +549,7 @@ void GL_Shutdown(void)
}
GL_ShutdownDeferredTask();
FR_Shutdown();
Rend_ModelShutdown();
Rend_SkyShutdown();
Rend_Reset();
GL_ShutdownRefresh();
Expand Down
7 changes: 7 additions & 0 deletions doomsday/engine/portable/src/r_model.c
Expand Up @@ -523,6 +523,13 @@ static int R_LoadModel(const Uri* uri)
registerModelSkin(mdl, i);
}

// Enlarge the vertex buffers to enable drawing of this model.
if(!Rend_ModelExpandVertexBuffers(mdl->info.numVertices))
{
Con_Message("Warning: Model \"%s\" contains more than %u vertices (%u), it will not be rendered.\n",
Str_Text(&foundPath), (uint)RENDER_MAX_MODEL_VERTS, (uint)mdl->info.numVertices);
}

Str_Free(&foundPath);
return index;
}
Expand Down

0 comments on commit 98b2fcb

Please sign in to comment.