Cleaned up some old code

actorid
Nicolay Korslund 15 years ago
parent 6b6f5b95ec
commit 782a90066d

@ -296,6 +296,22 @@ static void createOgreMesh(Mesh *mesh, NiTriShape *shape, const String &material
// Set material if one was given
if(!material.empty()) sub->setMaterialName(material);
/* Old commented D code. Might be useful when reimplementing
animation.
// Assign this submesh to the given bone
VertexBoneAssignment v;
v.boneIndex = ((Bone*)bone)->getHandle();
v.weight = 1.0;
std::cerr << "+ Assigning bone index " << v.boneIndex << "\n";
for(int i=0; i < numVerts; i++)
{
v.vertexIndex = i;
sub->addBoneAssignment(v);
}
*/
}
// Helper math functions. Reinventing linear algebra for the win!
@ -632,3 +648,109 @@ MeshPtr NIFLoader::load(const std::string &name,
// Nope, create a new one.
return MeshManager::getSingleton().createManual(name, group, &g_sing);
}
/* More code currently not in use, from the old D source. This was
used in the first attempt at loading NIF meshes, where each submesh
in the file was given a separate bone in a skeleton. Unfortunately
the OGRE skeletons can't hold more than 256 bones, and some NIFs go
way beyond that. The code might be of use if we implement animated
submeshes like this (the part of the NIF that is animated is
usually much less than the entire file, but the method might still
not be water tight.)
// Insert a raw RGBA image into the texture system.
extern "C" void ogre_insertTexture(char* name, uint32_t width, uint32_t height, void *data)
{
TexturePtr texture = TextureManager::getSingleton().createManual(
name, // name
"General", // group
TEX_TYPE_2D, // type
width, height, // width & height
0, // number of mipmaps
PF_BYTE_RGBA, // pixel format
TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for
// textures updated very often (e.g. each frame)
// Get the pixel buffer
HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
// Lock the pixel buffer and get a pixel box
pixelBuffer->lock(HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD!
const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
void *dest = pixelBox.data;
// Copy the data
memcpy(dest, data, width*height*4);
// Unlock the pixel buffer
pixelBuffer->unlock();
}
// We need this later for animated meshes.
extern "C" void* ogre_setupSkeleton(char* name)
{
SkeletonPtr skel = SkeletonManager::getSingleton().create(
name, "Closet", true);
skel->load();
// Create all bones at the origin and unrotated. This is necessary
// since our submeshes each have their own model space. We must
// move the bones after creating an entity, then copy this entity.
return (void*)skel->createBone();
}
extern "C" void *ogre_insertBone(char* name, void* rootBone, int32_t index)
{
return (void*) ( ((Bone*)rootBone)->createChild(index) );
}
*/
/* This was the D part:
// Create a skeleton and get the root bone (index 0)
BonePtr bone = ogre_setupSkeleton(name);
// Reset the bone index. The next bone to be created has index 1.
boneIndex = 1;
// Create a mesh and assign the skeleton to it
MeshPtr mesh = ogre_setupMesh(name);
// Loop through the nodes, creating submeshes, materials and
// skeleton bones in the process.
handleNode(node, bone, mesh);
// Create the "template" entity
EntityPtr entity = ogre_createEntity(name);
// Loop through once again, this time to set the right
// transformations on the entity's SkeletonInstance. The order of
// children will be the same, allowing us to reference bones using
// their boneIndex.
int lastBone = boneIndex;
boneIndex = 1;
transformBones(node, entity);
if(lastBone != boneIndex) writefln("WARNING: Bone number doesn't match");
if(!hasBBox)
ogre_setMeshBoundingBox(mesh, minX, minY, minZ, maxX, maxY, maxZ);
return entity;
}
void handleNode(Node node, BonePtr root, MeshPtr mesh)
{
// Insert a new bone for this node
BonePtr bone = ogre_insertBone(node.name, root, boneIndex++);
}
void transformBones(Node node, EntityPtr entity)
{
ogre_transformBone(entity, &node.trafo, boneIndex++);
NiNode n = cast(NiNode)node;
if(n !is null)
foreach(Node nd; n.children)
transformBones(nd, entity);
}
*/

@ -1,272 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (keys.d) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
/*
* This module handles keyboard and mouse button configuration
*/
module input.keys;
import std.string;
import std.stdio;
import input.ois;
// List of all functions we need to map to keys. If you add new keys,
// REMEMBER to add strings for them below as well. TODO: We should
// redo this entire section so that we insert actual functions into
// the system instead. That way, if we do not insert a function, the
// key gets treated as a "non-event" key. Then we will also force the
// definition of strings and function call to be in the same
// place. The Keys enum can be eliminated, really. Default keysyms can
// be added when the functions are inserted. But don't do anything
// until you know how this will interact with script code.
enum Keys
{
None = 0,
// Movement
MoveLeft, MoveRight,
TurnLeft, TurnRight,
MoveForward, MoveBackward,
// Used eg. when flying or swimming
MoveUp, MoveDown,
// These are handled as events, while the above are not.
FirstEvent,
// Sound control
MainVolUp, MainVolDown,
MusVolUp, MusVolDown,
SfxVolUp, SfxVolDown,
Mute,
// These will not be part of the finished product
Fullscreen,
ToggleBattleMusic,
PhysMode, // Toggle physics mode between walking, flying and ghost
Nighteye, // Full ambient lighting
ToggleGui,// Turn the GUI on/off
Console, // Turn console on/off
Debug,
// Misc
Pause,
ScreenShot,
Exit,
Length
}
// List of keyboard-bound functions
char[][] keyToString;
// Lookup for keyboard key names. TODO: This is currently case
// sensitive, we should use my own AA to fix that.
int[char[]] stringToKeysym;
// Represents a key binding for a single function. Each function can
// have any number keys bound to it, including mouse buttons. This
// might be extended later to allow joystick buttons and other input
// devices.
struct KeyBind
{
int syms[];
// Does the given keysym match this binding?
bool isMatch(int sym, char ch = 0)
{
assert(sym != 0, "don't send empty syms to isMatch");
// We don't match characters yet
if(sym == KC.CharOnly)
return false;
foreach(s; syms)
if(sym == s) return true;
return false;
}
// Does any of the given syms match this binding?
bool isMatchArray(int arr[] ...)
{
foreach(i; arr)
if(i!=0 && isMatch(i)) return true;
return false;
}
// Assign key bindings to this structure. Can be called multiple
// times or with multiple paramters (or an array) to bind multiple
// keys.
void bind(int symlist[] ...)
{
syms ~= symlist;
}
// Remove all bindings to this function
void clear()
{
syms = null;
}
// Remove the given syms from this binding, if found.
void remove(int symlist[] ...)
{
foreach(rs; symlist)
// Just loop though all the syms and set matching values to
// zero. isMatch() will ignore zeros.
foreach(ref s; syms)
if(s == rs) s = 0;
}
// Turn the keysym list into a comma separated list of key names
char[] getString()
{
char[] res = null;
bool notFirst = false;
foreach(int k; syms)
if(k != 0) // Ignore empty keysyms
{
if(notFirst) res ~= ",";
else notFirst = true;
res ~= keysymToString[k];
}
//writefln("getString returned %s", res);
return res;
}
}
KeyBindings keyBindings;
// This structure holds the bindings of all the functions
struct KeyBindings
{
KeyBind[] bindings;
// Bind the given function to the given key(s)
void bind(Keys func, char[] key1, char[] key2 = "")
{
bind(func, getSym(key1), getSym(key2));
}
void bind(Keys func, int syms[] ...)
{
// Find other bindings that match this key
foreach(int i, ref KeyBind kb; bindings)
if(kb.isMatchArray(syms))
kb.remove(syms);
bindings[func].bind(syms);
}
// Find the function that matches the given keysym. We could
// optimize this, but I'm not sure it's worth it.
Keys findMatch(KC keysym, dchar ch)
{
int start=cast(int)Keys.FirstEvent + 1;
foreach(int i, ref KeyBind kb; bindings[start..$])
if( kb.isMatch(keysym, ch) )
return cast(Keys)(i+start);
return cast(Keys)0; // No match
}
static int getSym(char[] key)
{
key = strip(key);
if(key.length)
{
int *p = key in stringToKeysym;
if(p) return *p;
else writefln("Warning: unknown key '%s'", key);
}
return 0;
}
// Bind a function to a comma-separated key list (intended to be
// used directly with the ini file reader.)
void bindComma(Keys func, char[] keys)
{
int index = keys.find(',');
if(index != -1)
{
// Bind the first in the list
bind(func, keys[0..index]);
// Recurse on the rest
bindComma(func, keys[index+1..$]);
}
// Last or only element in the list
else bind(func, keys);
}
// Remove all key bindings
void clear()
{
foreach(ref kb; bindings)
kb.clear();
}
void initKeys()
{
// Keyboard functions
keyToString.length = Keys.Length;
keyToString[Keys.MoveLeft] = "Move Left";
keyToString[Keys.MoveRight] = "Move Right";
keyToString[Keys.TurnLeft] = "Turn Left";
keyToString[Keys.TurnRight] = "Turn Right";
keyToString[Keys.MoveForward] = "Move Forward";
keyToString[Keys.MoveBackward] = "Move Backward";
keyToString[Keys.MoveUp] = "Move Up";
keyToString[Keys.MoveDown] = "Move Down";
keyToString[Keys.MainVolUp] = "Increase Main Volume";
keyToString[Keys.MainVolDown] = "Decrease Main Volume";
keyToString[Keys.MusVolUp] = "Increase Music Volume";
keyToString[Keys.MusVolDown] = "Decrease Music Volume";
keyToString[Keys.SfxVolUp] = "Increase SFX Volume";
keyToString[Keys.SfxVolDown] = "Decrease SFX Volume";
keyToString[Keys.Mute] = "Mute Sound";
keyToString[Keys.Fullscreen] = "Toggle Fullscreen Mode";
keyToString[Keys.ToggleBattleMusic] = "Toggle Battle Music";
keyToString[Keys.PhysMode] = "Toggle Physics Mode";
keyToString[Keys.Nighteye] = "Toggle Nighteye";
keyToString[Keys.ToggleGui] = "Toggle GUI";
keyToString[Keys.Console] = "Console";
keyToString[Keys.Debug] = "OGRE Test Action";
keyToString[Keys.Pause] = "Pause";
keyToString[Keys.ScreenShot] = "Screen Shot";
keyToString[Keys.Exit] = "Quick Exit";
//keyToString[Keys.] = "";
bindings.length = Keys.Length;
// Store all the key strings in a lookup-table
foreach(int k, ref char[] s; keysymToString)
if(s.length) stringToKeysym[s] = k;
}
}

@ -1,166 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (bindings.d) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
module ogre.bindings;
import nif.misc; // for Transformation
import ogre.ogre; // for Placement
import core.resource;
/*
* This module is the interface to OGRE from D. Since OGRE is written
* in C++, all the code that deals directly with the graphics engine
* is packaged in a bunch of C++ functions. These functions are
* exported from C++ through the C calling convention, and imported
* here.
*
* Note that the C calling convension is not in any way type
* safe. This is convenient, as it allows us to send pointers as one
* type and recieve them as another, without casting, but also
* dangerous since it opens for some nasty bugs.
*/
// Represents a pointer to a Node in the OGRE engine. We never use
// these directly in D code, only pass them back to the C++ code.
typedef void* NodePtr;
extern(C):
// Do engine configuration. Returns 0 if we should continue, 1 if
// not.
int ogre_configure(int showConfig, // Do we show the config dialogue?
char *plugincfg,// Name of 'plugin.cfg' file
int debutOut); // Enable or disable debug output
// Sets up the window
void ogre_initWindow();
// Set up an empty scene.
void ogre_makeScene();
// Set the ambient light and "sunlight"
void ogre_setAmbient(float r, float g, float b,
float rs, float gs, float bs);
// Set fog color and view distance
void ogre_setFog(float rf, float gf, float bf,
float flow, float fhigh);
// Create a simple sky dome
int ogre_makeSky();
// Toggle full ambient lighting on and off
void ogre_toggleLight();
// Enter main rendering loop
void ogre_startRendering();
// Cleans up after ogre
void ogre_cleanup();
// Gets a child SceneNode from the root node, then detatches it to
// hide it from view. Used for creating the "template" node associated
// with a NIF mesh.
NodePtr ogre_getDetachedNode();
// Convert a Morrowind rotation (3 floats) to a quaternion (4 floats)
void ogre_mwToQuaternion(float *mw, float *quat);
// Create a copy of the given scene node, with the given coordinates
// and rotation (as a quaternion.)
NodePtr ogre_insertNode(NodePtr base, char* name,
float *pos, float *quat, float scale);
// Get the world transformation of a node, returned as a translation
// and a matrix. The matrix includes both rotation and scaling. The
// buffers given must be large enough to store the result (3 and 9
// floats respectively.)
void ogre_getWorldTransform(NodePtr node, float *trans, float *matrix);
// Create a (very crappy looking) plane to simulate the water level
void ogre_createWater(float level);
// Creates a scene node as a child of 'parent', then translates and
// rotates it according to the data in 'trafo'.
NodePtr ogre_createNode(
char *name, // Name to give the node
Transformation *trafo, // Transformation
NodePtr parent, // Parent node
int noRot); // If 1, don't rotate node
// Create a light with the given diffuse color. Attach it to SceneNode
// 'parent'.
NodePtr ogre_attachLight(char* name, NodePtr parent,
float r, float g, float b,
float radius);
// Create the specified material
void ogre_createMaterial(char *name, // Name to give resource
float *ambient, // Ambient RBG value
float *diffuse,
float *specular,
float *emissive, // Self illumination
float glossiness,// Same as shininess?
float alpha, // Reflection alpha?
char *texture, // Texture name
int alphaFlags, // Alpha settings (see
ubyte alphaTest);// NiAlphaProperty in nif/)
// Creates a mesh and gives it a bounding box. Also creates an entity
// and attached it to the given SceneNode 'owner'.
void ogre_createMesh(
char* name, // Name of the mesh
int numVerts, // Number of vertices
float* vertices, // Vertex list
float* normals, // Normal list
float* colors, // Vertex colors
float* uvs, // Texture coordinates
int numFaces, // Number of faces*3
short* faces, // Faces
float radius, // Bounding sphere
char* material, // Material name, if any
// Bounding box
float minX,float minY,float minZ,
float maxX,float maxY,float maxZ,
NodePtr owner // Scene node to attach to.
);
// Toggle fullscreen mode
void ogre_toggleFullscreen();
// Save a screen shot to the given file name
void ogre_screenshot(char *filename);
// Camera control and information
void ogre_rotateCamera(float x, float y);
void ogre_moveCamera(float x, float y, float z);
void ogre_setCameraRotation(float r1, float r2, float r3);
void ogre_getCameraPos(float *x, float *y, float *z);
void ogre_getCameraOrientation(float *fx, float *fy, float *fz, float *ux, float *uy, float *uz);
void ogre_moveCameraRel(float x, float y, float z);
// Insert a raw RGBA image into the texture system.
//void ogre_insertTexture(char *name, int width, int height, void *data);

@ -1,39 +1,3 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (cpp_framelistener.cpp) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
#include <stdint.h>
// Callbacks to D code.
// Called once each frame
extern "C" int32_t d_frameStarted(float time);
// Handle events
extern "C" void d_handleKey(int keycode, uint32_t text);
extern "C" void d_handleMouseMove(const OIS::MouseState *state);
extern "C" void d_handleMouseButton(const OIS::MouseState *state,
int32_t button);
// Frame listener, passed to Ogre. The only thing we use this for is
// to capture input and pass control to D code.
class MorroFrameListener: public FrameListener
@ -134,10 +98,6 @@ InputListener mInput;
extern "C" void ogre_screenshot(char* filename)
{
mWindow->writeContentsToFile(filename);
//This doesn't work, I think I have to set up an overlay or
//something first and display the text manually.
//mWindow->setDebugText(String("Wrote ") + filename);
}
// Rotate camera as result of mouse movement
@ -177,8 +137,6 @@ extern "C" void ogre_moveCamera(float x, float y, float z)
// is not affected by the rotation of the root node, so we must
// transform this manually.
mCamera->setPosition(Vector3(x,z+90,-y));
//g_light->setPosition(mCamera->getPosition());
}
// Rotate camera using Morrowind rotation specifiers

@ -1,96 +1,3 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (cpp_interface.cpp) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
extern "C" Light* ogre_attachLight(char *name, SceneNode* base,
float r, float g, float b,
float radius)
{
Light *l = mSceneMgr->createLight(name);
l->setDiffuseColour(r,g,b);
radius /= 4.0f;
float cval=0.0f, lval=0.0f, qval=0.0f;
if(lightConst)
cval = lightConstValue;
if(!lightOutQuadInLin)
{
if(lightLinear)
radius *= lightLinearRadiusMult;
if(lightQuadratic)
radius *= lightQuadraticRadiusMult;
if(lightLinear)
lval = lightLinearValue / pow(radius, lightLinearMethod);
if(lightQuadratic)
qval = lightQuadraticValue / pow(radius, lightQuadraticMethod);
}
else
{
// FIXME:
// Do quadratic or linear, depending if we're in an exterior or interior
// cell, respectively. Ignore lightLinear and lightQuadratic.
}
// The first parameter is a cutoff value on which meshes to
// light. If it's set to small, some meshes will end up 'flashing'
// in and out of light depending on the camera distance from the
// light.
l->setAttenuation(10*radius, cval, lval, qval);
// base might be null, sometimes lights don't have meshes
if(base) base->attachObject(l);
return l;
}
extern "C" void ogre_setAmbient(float r, float g, float b, // Ambient light
float rs, float gs, float bs) // "Sunlight"
{
g_ambient = ColourValue(r, g, b);
mSceneMgr->setAmbientLight(g_ambient);
// Create a "sun" that shines light downwards. It doesn't look
// completely right, but leave it for now.
Light *l = mSceneMgr->createLight("Sun");
l->setDiffuseColour(rs, gs, bs);
l->setType(Light::LT_DIRECTIONAL);
l->setDirection(0,-1,0);
}
extern "C" void ogre_setFog(float rf, float gf, float bf, // Fog color
float flow, float fhigh) // Fog distance
{
ColourValue fogColor( rf, gf, bf );
mSceneMgr->setFog( FOG_LINEAR, fogColor, 0.0, flow, fhigh );
// Don't render what you can't see anyway
mCamera->setFarClipDistance(fhigh + 10);
// Leave this out for now
vp->setBackgroundColour(fogColor);
}
// Copy a scene node and all its children
void cloneNode(SceneNode *from, SceneNode *to, char* name)
{
@ -185,246 +92,6 @@ extern "C" void ogre_createWater(float level)
ent->setCastShadows(false);
}
// Manual loader for meshes. Reloading individual meshes is too
// difficult, and not worth the trouble. Later I should make one
// loader for each NIF file, and whenever it is invoked it should
// somehow reload the entire file. How this is to be done when some of
// the meshes might be loaded and in use already, I have no
// idea. Let's just ignore it for now.
class MeshLoader : public ManualResourceLoader
{
public:
void loadResource(Resource *resource)
{
}
} dummyLoader;
// Load the contents of a mesh
extern "C" void ogre_createMesh(
char* name, // Name of the mesh
int32_t numVerts, // Number of vertices
float* vertices, // Vertex list
float* normals, // Normal list
float* colors, // Vertex colors
float* uvs, // Texture coordinates
int32_t numFaces, // Number of faces*3
uint16_t* faces, // Faces
float radius, // Bounding sphere
char* material, // Material
// Bounding box
float minX,float minY,float minZ,
float maxX,float maxY,float maxZ,
SceneNode *owner
)
{
//std::cerr << "Creating mesh " << name << "\n";
MeshPtr msh = MeshManager::getSingleton().createManual(name, "Meshes",
&dummyLoader);
Entity *e = mSceneMgr->createEntity(name, name);
owner->attachObject(e);
//msh->setSkeletonName(name);
// Create vertex data structure
msh->sharedVertexData = new VertexData();
msh->sharedVertexData->vertexCount = numVerts;
/// Create declaration (memory format) of vertex data
VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
int nextBuf = 0;
// 1st buffer
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION);
/// Allocate vertex buffer of the requested number of vertices (vertexCount)
/// and bytes per vertex (offset)
HardwareVertexBufferSharedPtr vbuf =
HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
/// Upload the vertex data to the card
vbuf->writeData(0, vbuf->getSizeInBytes(), vertices, true);
/// Set vertex buffer binding so buffer 0 is bound to our vertex buffer
VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
bind->setBinding(nextBuf++, vbuf);
// The lists are read in the same order that they appear in NIF
// files, and likely in memory. Sequential reads might possibly
// avert an occational cache miss.
// normals
if(normals)
{
//std::cerr << "+ Adding normals\n";
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL);
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
vbuf->writeData(0, vbuf->getSizeInBytes(), normals, true);
bind->setBinding(nextBuf++, vbuf);
}
// vertex colors
if(colors)
{
//std::cerr << "+ Adding vertex colors\n";
// Use render system to convert colour value since colour packing varies
RenderSystem* rs = Root::getSingleton().getRenderSystem();
RGBA colorsRGB[numVerts];
RGBA *pColour = colorsRGB;
for(int i=0; i<numVerts; i++)
{
rs->convertColourValue(ColourValue(colors[0],colors[1],colors[2], colors[3]),
pColour++);
colors += 4;
}
decl->addElement(nextBuf, 0, VET_COLOUR, VES_DIFFUSE);
/// Allocate vertex buffer of the requested number of vertices (vertexCount)
/// and bytes per vertex (offset)
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_COLOUR),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
/// Upload the vertex data to the card
vbuf->writeData(0, vbuf->getSizeInBytes(), colorsRGB, true);
/// Set vertex buffer binding so buffer 1 is bound to our colour buffer
bind->setBinding(nextBuf++, vbuf);
}
if(uvs)
{
//std::cerr << "+ Adding texture coordinates\n";
decl->addElement(nextBuf, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT2),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
vbuf->writeData(0, vbuf->getSizeInBytes(), uvs, true);
bind->setBinding(nextBuf++, vbuf);
}
// Create the submesh that holds triangle data
SubMesh* sub = msh->createSubMesh(name);
sub->useSharedVertices = true;
if(numFaces)
{
//std::cerr << "+ Adding faces\n";
/// Allocate index buffer of the requested number of faces
HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
createIndexBuffer(
HardwareIndexBuffer::IT_16BIT,
numFaces,
HardwareBuffer::HBU_STATIC_WRITE_ONLY);
/// Upload the index data to the card
ibuf->writeData(0, ibuf->getSizeInBytes(), faces, true);
/// Set parameters of the submesh
sub->indexData->indexBuffer = ibuf;
sub->indexData->indexCount = numFaces;
sub->indexData->indexStart = 0;
}
// Create a material with the given texture, if any.
// If this mesh has a material, attach it.
if(material) sub->setMaterialName(name);
/*
// Assign this submesh to the given bone
VertexBoneAssignment v;
v.boneIndex = ((Bone*)bone)->getHandle();
v.weight = 1.0;
std::cerr << "+ Assigning bone index " << v.boneIndex << "\n";
for(int i=0; i < numVerts; i++)
{
v.vertexIndex = i;
sub->addBoneAssignment(v);
}
*/
/// Set bounding information (for culling)
msh->_setBounds(AxisAlignedBox(minX,minY,minZ,maxX,maxY,maxZ));
//std::cerr << "+ Radius: " << radius << "\n";
msh->_setBoundingSphereRadius(radius);
}
extern "C" void ogre_createMaterial(char *name, // Name to give
// resource
float *ambient, // Ambient RBG
// value
float *diffuse,
float *specular,
float *emissive, // Self
// illumination
float glossiness,// Same as
// shininess?
float alpha, // Use this in all
// alpha values?
char* texture, // Texture
int32_t alphaFlags,
uint8_t alphaTest) // Alpha settings
{
MaterialPtr material = MaterialManager::getSingleton().create(
name,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
// This assigns the texture to this material. If the texture
// name is a file name, and this file exists (in a resource
// directory), it will automatically be loaded when needed. If
// not, we should already have inserted a manual loader for the texture.
if(texture)
{
Pass *pass = material->getTechnique(0)->getPass(0);
TextureUnitState *txt = pass->createTextureUnitState(texture);
// Add transparencly.
if(alphaFlags != -1)
{
// The 237 alpha flags are by far the most common. Check
// NiAlphaProperty in nif/properties.d if you need to
// decode other values. 237 basically means normal
// transparencly.
if(alphaFlags == 237)
{
// Enable transparency
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
//pass->setDepthCheckEnabled(false);
pass->setDepthWriteEnabled(false);
}
else
std::cout << "UNHANDLED ALPHA FOR " << texture << ": " << alphaFlags << "\n";
}
}
// Set bells and whistles
material->setAmbient(ambient[0], ambient[1], ambient[2]);
material->setDiffuse(diffuse[0], diffuse[1], diffuse[2], alpha);
material->setSpecular(specular[0], specular[1], specular[2], alpha);
material->setSelfIllumination(emissive[0], emissive[1], emissive[2]);
material->setShininess(glossiness);
}
extern "C" SceneNode *ogre_getDetachedNode()
{
SceneNode *node = mwRoot->createChildSceneNode();
@ -466,54 +133,3 @@ extern "C" SceneNode* ogre_createNode(
return node;
}
/* Code currently not in use
// Insert a raw RGBA image into the texture system.
extern "C" void ogre_insertTexture(char* name, uint32_t width, uint32_t height, void *data)
{
TexturePtr texture = TextureManager::getSingleton().createManual(
name, // name
"General", // group
TEX_TYPE_2D, // type
width, height, // width & height
0, // number of mipmaps
PF_BYTE_RGBA, // pixel format
TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for
// textures updated very often (e.g. each frame)
// Get the pixel buffer
HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
// Lock the pixel buffer and get a pixel box
pixelBuffer->lock(HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD!
const PixelBox& pixelBox = pixelBuffer->getCurrentLock();
void *dest = pixelBox.data;
// Copy the data
memcpy(dest, data, width*height*4);
// Unlock the pixel buffer
pixelBuffer->unlock();
}
// We need this later for animated meshes.
extern "C" void* ogre_setupSkeleton(char* name)
{
SkeletonPtr skel = SkeletonManager::getSingleton().create(
name, "Closet", true);
skel->load();
// Create all bones at the origin and unrotated. This is necessary
// since our submeshes each have their own model space. We must
// move the bones after creating an entity, then copy this entity.
return (void*)skel->createBone();
}
extern "C" void *ogre_insertBone(char* name, void* rootBone, int32_t index)
{
return (void*) ( ((Bone*)rootBone)->createChild(index) );
}
*/

@ -1,48 +1,5 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (cpp_ogre.cpp) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
#include <Ogre.h>
#include <iostream>
#include <Ogre.h>
#include <OgreConfigFile.h>
#include <OgreStringConverter.h>
#include <OgreException.h>
#include <OgreArchive.h>
#include <OgreArchiveFactory.h>
#include <MyGUI.h>
#include "../util/dbg.h"
using namespace Ogre;
ColourValue g_ambient;
int g_lightOn = 0;
// Set to nonzero if debug mode is enabled
int g_isDebug = 0;
// The global GUI object
MyGUI::Gui *mGUI;
@ -51,11 +8,5 @@ MyGUI::Gui *mGUI;
// input into MyGUI.
int32_t guiMode = 0;
// Include the other parts of the code, and make one big happy object
// file. This is extremely against the grain of C++ "recomended
// practice", but I don't care.
#include "../gui/cpp_mygui.cpp"
#include "cpp_framelistener.cpp"
#include "cpp_bsaarchive.cpp"
#include "cpp_interface.cpp"
#include "../terrain/cpp_terrain.cpp"

@ -389,50 +389,3 @@ struct MeshLoader
}
}
}
/*
// Create a skeleton and get the root bone (index 0)
BonePtr bone = ogre_setupSkeleton(name);
// Reset the bone index. The next bone to be created has index 1.
boneIndex = 1;
// Create a mesh and assign the skeleton to it
MeshPtr mesh = ogre_setupMesh(name);
// Loop through the nodes, creating submeshes, materials and
// skeleton bones in the process.
handleNode(node, bone, mesh);
// Create the "template" entity
EntityPtr entity = ogre_createEntity(name);
// Loop through once again, this time to set the right
// transformations on the entity's SkeletonInstance. The order of
// children will be the same, allowing us to reference bones using
// their boneIndex.
int lastBone = boneIndex;
boneIndex = 1;
transformBones(node, entity);
if(lastBone != boneIndex) writefln("WARNING: Bone number doesn't match");
if(!hasBBox)
ogre_setMeshBoundingBox(mesh, minX, minY, minZ, maxX, maxY, maxZ);
return entity;
}
void handleNode(Node node, BonePtr root, MeshPtr mesh)
{
// Insert a new bone for this node
BonePtr bone = ogre_insertBone(node.name, root, boneIndex++);
}
void transformBones(Node node, EntityPtr entity)
{
ogre_transformBone(entity, &node.trafo, boneIndex++);
NiNode n = cast(NiNode)node;
if(n !is null)
foreach(Node nd; n.children)
transformBones(nd, entity);
}
*/

@ -30,19 +30,6 @@ NodePtr placeObject(MeshIndex mesh, Placement *pos, float scale,
return node;
}
void setAmbient(Color amb, Color sun, Color fog, float density)
{
ogre_setAmbient(amb.red/255.0, amb.green/255.0, amb.blue/255.0,
sun.red/255.0, sun.green/255.0, sun.blue/255.0);
// Calculate fog distance
// TODO: Mesh with absolute view distance later
float fhigh = 4500 + 9000*(1-density);
float flow = 200 + 2000*(1-density);
ogre_setFog(fog.red/255.0, fog.green/255.0, fog.blue/255.0, 200, fhigh);
}
// Gives the placement of an item in the scene (position and
// orientation). It must have this exact structure since we also use
// it when reading ES files.

Loading…
Cancel
Save