- Updated automake file with celmodel changes
- Added geometry and modelgeometry filessensor-dev
parent
c76d2b0fb7
commit
b92930b79d
|
@ -38,10 +38,8 @@ libcelengine_a_SOURCES = \
|
|||
location.cpp \
|
||||
lodspheremesh.cpp \
|
||||
marker.cpp \
|
||||
mesh.cpp \
|
||||
meshmanager.cpp \
|
||||
model.cpp \
|
||||
modelfile.cpp \
|
||||
modelgeometry.cpp \
|
||||
multitexture.cpp \
|
||||
nebula.cpp \
|
||||
observer.cpp \
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
// geometry.h
|
||||
//
|
||||
// Copyright (C) 2004-2010, Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef _CELENGINE_GEOMETRY_H_
|
||||
#define _CELENGINE_GEOMETRY_H_
|
||||
|
||||
#include <celmodel/material.h>
|
||||
#include <celmath/ray.h>
|
||||
|
||||
class RenderContext;
|
||||
|
||||
|
||||
class Geometry
|
||||
{
|
||||
public:
|
||||
Geometry() {};
|
||||
virtual ~Geometry() {};
|
||||
|
||||
//! Render the geometry in the specified OpenGL context
|
||||
virtual void render(RenderContext& rc, double t = 0.0) = 0;
|
||||
|
||||
/*! Find the closest intersection between the ray and the
|
||||
* model. If the ray intersects the model, return true
|
||||
* and set distance; otherwise return false and leave
|
||||
* distance unmodified.
|
||||
*/
|
||||
virtual bool pick(const Ray3d& r, double& distance) const = 0;
|
||||
|
||||
virtual bool isOpaque() const = 0;
|
||||
|
||||
virtual bool isNormalized() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! Return true if the specified texture map type is used at
|
||||
* all within this geometry object. This information is used
|
||||
* to decide whether multiple rendering passes are required.
|
||||
*/
|
||||
virtual bool usesTextureType(cmod::Material::TextureSemantic) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Load all textures used by the model. */
|
||||
virtual void loadTextures()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _CELENGINE_GEOMETRY_H_
|
|
@ -0,0 +1,247 @@
|
|||
// modelgeometry.cpp
|
||||
//
|
||||
// Copyright (C) 2004-2010, Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include "modelgeometry.h"
|
||||
#include "rendcontext.h"
|
||||
#include "texmanager.h"
|
||||
#include <Eigen/Core>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
using namespace cmod;
|
||||
using namespace Eigen;
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
// Vertex buffer object support
|
||||
|
||||
// VBO optimization is only worthwhile for large enough vertex lists
|
||||
static const unsigned int MinVBOSize = 4096;
|
||||
static bool VBOSupportTested = false;
|
||||
static bool VBOSupported = false;
|
||||
|
||||
static bool isVBOSupported()
|
||||
{
|
||||
if (!VBOSupportTested)
|
||||
{
|
||||
VBOSupportTested = true;
|
||||
VBOSupported = (GLEW_ARB_vertex_buffer_object == GL_TRUE);
|
||||
}
|
||||
|
||||
return VBOSupported;
|
||||
}
|
||||
|
||||
|
||||
class ModelOpenGLData
|
||||
{
|
||||
public:
|
||||
ModelOpenGLData()
|
||||
{
|
||||
}
|
||||
|
||||
~ModelOpenGLData()
|
||||
{
|
||||
for (vector<GLuint>::iterator iter = vbos.begin(); iter != vbos.end(); ++iter)
|
||||
{
|
||||
GLuint vboId = *iter;
|
||||
if (vboId != 0)
|
||||
{
|
||||
glDeleteBuffersARB(1, &vboId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<GLuint> vbos; // vertex buffer objects
|
||||
};
|
||||
|
||||
|
||||
/** Create a new ModelGeometry wrapping the specified model.
|
||||
* The ModelGeoemtry takes ownership of the model.
|
||||
*/
|
||||
ModelGeometry::ModelGeometry(Model* model) :
|
||||
m_model(model),
|
||||
m_vbInitialized(false),
|
||||
m_glData(NULL)
|
||||
{
|
||||
m_glData = new ModelOpenGLData();
|
||||
}
|
||||
|
||||
|
||||
ModelGeometry::~ModelGeometry()
|
||||
{
|
||||
delete m_model;
|
||||
delete m_glData;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ModelGeometry::pick(const Ray3d& r, double& distance) const
|
||||
{
|
||||
return m_model->pick(r.origin, r.direction, distance);
|
||||
}
|
||||
|
||||
|
||||
/*! Render the model; the time parameter is ignored right now
|
||||
* since this class doesn't currently support animation.
|
||||
*/
|
||||
void
|
||||
ModelGeometry::render(RenderContext& rc, double /* t */)
|
||||
{
|
||||
// The first time the mesh is rendered, we will try and place the
|
||||
// vertex data in a vertex buffer object and potentially get a huge
|
||||
// rendering performance boost. This can consume a great deal of
|
||||
// memory, since we're duplicating the vertex data. TODO: investigate
|
||||
// the possibility of deleting the original data. We can always map
|
||||
// read-only later on for things like picking, but this could be a low
|
||||
// performance path.
|
||||
if (!m_vbInitialized && isVBOSupported())
|
||||
{
|
||||
m_vbInitialized = true;
|
||||
|
||||
for (unsigned int i = 0; i < m_model->getMeshCount(); ++i)
|
||||
{
|
||||
Mesh* mesh = m_model->getMesh(i);
|
||||
const Mesh::VertexDescription& vertexDesc = mesh->getVertexDescription();
|
||||
|
||||
GLuint vboId = 0;
|
||||
if (mesh->getVertexCount() * vertexDesc.stride > MinVBOSize)
|
||||
{
|
||||
glGenBuffersARB(1, &vboId);
|
||||
if (vboId != 0)
|
||||
{
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB,
|
||||
mesh->getVertexCount() * vertexDesc.stride,
|
||||
mesh->getVertexData(),
|
||||
GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
}
|
||||
|
||||
m_glData->vbos.push_back(vboId);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int lastMaterial = ~0u;
|
||||
unsigned int materialCount = m_model->getMaterialCount();
|
||||
|
||||
// Iterate over all meshes in the model
|
||||
for (unsigned int meshIndex = 0; meshIndex < m_model->getMeshCount(); ++meshIndex)
|
||||
{
|
||||
Mesh* mesh = m_model->getMesh(meshIndex);
|
||||
GLuint vboId = 0;
|
||||
|
||||
if (m_glData && meshIndex < m_glData->vbos.size())
|
||||
{
|
||||
vboId = m_glData->vbos[meshIndex];
|
||||
}
|
||||
|
||||
if (vboId != 0)
|
||||
{
|
||||
// Bind the vertex buffer object.
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
|
||||
rc.setVertexArrays(mesh->getVertexDescription(), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No vertex buffer object; just use normal vertex arrays
|
||||
rc.setVertexArrays(mesh->getVertexDescription(), mesh->getVertexData());
|
||||
}
|
||||
|
||||
// Iterate over all primitive groups in the mesh
|
||||
for (unsigned int groupIndex = 0; groupIndex < mesh->getGroupCount(); ++groupIndex)
|
||||
{
|
||||
const Mesh::PrimitiveGroup* group = mesh->getGroup(groupIndex);
|
||||
|
||||
// Set up the material
|
||||
const Material* material = NULL;
|
||||
unsigned int materialIndex = group->materialIndex;
|
||||
if (materialIndex != lastMaterial && materialIndex < materialCount)
|
||||
{
|
||||
material = m_model->getMaterial(materialIndex);
|
||||
}
|
||||
|
||||
rc.setMaterial(material);
|
||||
rc.drawGroup(*group);
|
||||
}
|
||||
|
||||
// If we set a VBO, unbind it.
|
||||
if (vboId != 0)
|
||||
{
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ModelGeometry::isOpaque() const
|
||||
{
|
||||
return m_model->isOpaque();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ModelGeometry::isNormalized() const
|
||||
{
|
||||
return m_model->isNormalized();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ModelGeometry::usesTextureType(Material::TextureSemantic t) const
|
||||
{
|
||||
return m_model->usesTextureType(t);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelGeometry::loadTextures()
|
||||
{
|
||||
#if 0
|
||||
for (vector<const Material*>::const_iterator iter = materials.begin();
|
||||
iter != materials.end(); iter++)
|
||||
{
|
||||
const Mesh::Material* m = *iter;
|
||||
|
||||
if (m->maps[Mesh::DiffuseMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Mesh::DiffuseMap]);
|
||||
if (m->maps[Mesh::NormalMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Mesh::NormalMap]);
|
||||
if (m->maps[Mesh::SpecularMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Mesh::SpecularMap]);
|
||||
if (m->maps[Mesh::EmissiveMap] != InvalidResource)
|
||||
GetTextureManager()->find(m->maps[Mesh::EmissiveMap]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
string
|
||||
CelestiaTextureResource::source() const
|
||||
{
|
||||
if (m_textureHandle == InvalidResource)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
const TextureInfo* t = GetTextureManager()->getResourceInfo(textureHandle());
|
||||
if (!t)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
return t->source;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
// modelgeometry.h
|
||||
//
|
||||
// Copyright (C) 2010, Celestia Development Team
|
||||
// Original version by Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef _CELENGINE_MODEL_GEOMETRY_H_
|
||||
#define _CELENGINE_MODEL_GEOMETRY_H_
|
||||
|
||||
#include "geometry.h"
|
||||
#include <celmodel/model.h>
|
||||
#include <celutil/resmanager.h>
|
||||
|
||||
|
||||
class CelestiaTextureResource : public cmod::Material::TextureResource
|
||||
{
|
||||
public:
|
||||
CelestiaTextureResource(ResourceHandle textureHandle) :
|
||||
m_textureHandle(textureHandle)
|
||||
{
|
||||
}
|
||||
|
||||
ResourceHandle textureHandle() const
|
||||
{
|
||||
return m_textureHandle;
|
||||
}
|
||||
|
||||
std::string source() const;
|
||||
|
||||
private:
|
||||
ResourceHandle m_textureHandle;
|
||||
};
|
||||
|
||||
class ModelOpenGLData;
|
||||
|
||||
class ModelGeometry : public Geometry
|
||||
{
|
||||
public:
|
||||
ModelGeometry(cmod::Model* model);
|
||||
~ModelGeometry();
|
||||
|
||||
/*! Find the closest intersection between the ray and the
|
||||
* model. If the ray intersects the model, return true
|
||||
* and set distance; otherwise return false and leave
|
||||
* distance unmodified.
|
||||
*/
|
||||
virtual bool pick(const Ray3d& r, double& distance) const;
|
||||
|
||||
//! Render the model in the current OpenGL context
|
||||
virtual void render(RenderContext&, double t = 0.0);
|
||||
|
||||
virtual bool usesTextureType(cmod::Material::TextureSemantic) const;
|
||||
virtual bool isOpaque() const;
|
||||
virtual bool isNormalized() const;
|
||||
|
||||
void loadTextures();
|
||||
|
||||
private:
|
||||
cmod::Model* m_model;
|
||||
bool m_vbInitialized;
|
||||
ModelOpenGLData* m_glData;
|
||||
};
|
||||
|
||||
#endif // !_CELENGINE_MODEL_H_
|
Loading…
Reference in New Issue