Merge branch 'master' into move

This commit is contained in:
Marc Zinnschlag 2016-03-11 12:47:33 +01:00
commit 6a2fe564ef
26 changed files with 304 additions and 82 deletions

View file

@ -94,6 +94,7 @@ Programmers
Nolan Poe (nopoe) Nolan Poe (nopoe)
Paul Cercueil (pcercuei) Paul Cercueil (pcercuei)
Paul McElroy (Greendogo) Paul McElroy (Greendogo)
Pi03k
Pieter van der Kloet (pvdk) Pieter van der Kloet (pvdk)
pkubik pkubik
Radu-Marius Popovici (rpopovici) Radu-Marius Popovici (rpopovici)

View file

@ -90,7 +90,7 @@ opencs_units (view/render
opencs_units_noqt (view/render opencs_units_noqt (view/render
lighting lightingday lightingnight lighting lightingday lightingnight
lightingbright object cell terrainstorage tagbase cellarrow cellmarker lightingbright object cell terrainstorage tagbase cellarrow cellmarker cellborder
) )
opencs_hdrs_noqt (view/render opencs_hdrs_noqt (view/render

View file

@ -47,7 +47,7 @@ void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
void CSVDoc::SubView::closeEvent (QCloseEvent *event) void CSVDoc::SubView::closeEvent (QCloseEvent *event)
{ {
emit updateSubViewIndicies (this); emit updateSubViewIndices (this);
} }
std::string CSVDoc::SubView::getTitle() const std::string CSVDoc::SubView::getTitle() const

View file

@ -64,7 +64,7 @@ namespace CSVDoc
void updateTitle(); void updateTitle();
void updateSubViewIndicies (SubView *view = 0); void updateSubViewIndices (SubView *view = NULL);
void universalIdChanged (const CSMWorld::UniversalId& universalId); void universalIdChanged (const CSMWorld::UniversalId& universalId);

View file

@ -343,7 +343,7 @@ void CSVDoc::View::updateTitle()
setWindowTitle (QString::fromUtf8(stream.str().c_str())); setWindowTitle (QString::fromUtf8(stream.str().c_str()));
} }
void CSVDoc::View::updateSubViewIndicies(SubView *view) void CSVDoc::View::updateSubViewIndices(SubView *view)
{ {
CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"]; CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
@ -373,7 +373,7 @@ void CSVDoc::View::updateSubViewIndicies(SubView *view)
else else
{ {
delete subView->titleBarWidget(); delete subView->titleBarWidget();
subView->setTitleBarWidget (0); subView->setTitleBarWidget (NULL);
} }
} }
} }
@ -402,7 +402,7 @@ void CSVDoc::View::updateActions()
CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews)
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
mViewTotal (totalViews), mScroll(0), mScrollbarOnly(false) mViewTotal (totalViews), mScroll(NULL), mScrollbarOnly(false)
{ {
CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"]; CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
@ -419,10 +419,7 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
} }
else else
{ {
mScroll = new QScrollArea(this); createScrollArea();
mScroll->setWidgetResizable(true);
mScroll->setWidget(&mSubViewWindow);
setCentralWidget(mScroll);
} }
mOperations = new Operations; mOperations = new Operations;
@ -570,36 +567,11 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
// //
mScrollbarOnly = windows["mainwindow-scrollbar"].toString() == "Scrollbar Only"; mScrollbarOnly = windows["mainwindow-scrollbar"].toString() == "Scrollbar Only";
QDesktopWidget *dw = QApplication::desktop(); updateWidth(windows["grow-limit"].isTrue(), minWidth);
QRect rect;
if (windows["grow-limit"].isTrue())
rect = dw->screenGeometry(this);
else
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
if (!mScrollbarOnly && mScroll && mSubViews.size() > 1)
{
int newWidth = width()+minWidth;
int frameWidth = frameGeometry().width() - width();
if (newWidth+frameWidth <= rect.width())
{
resize(newWidth, height());
// WARNING: below code assumes that new subviews are added to the right
if (x() > rect.width()-(newWidth+frameWidth))
move(rect.width()-(newWidth+frameWidth), y()); // shift left to stay within the screen
}
else
{
// full width
resize(rect.width()-frameWidth, height());
mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minWidth);
move(0, y());
}
}
mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view); mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view);
updateSubViewIndicies(); updateSubViewIndices();
connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this, connect (view, SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&)), this,
SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&))); SLOT (addSubView (const CSMWorld::UniversalId&, const std::string&)));
@ -608,8 +580,8 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
connect (view, SIGNAL (updateTitle()), this, SLOT (updateTitle())); connect (view, SIGNAL (updateTitle()), this, SLOT (updateTitle()));
connect (view, SIGNAL (updateSubViewIndicies (SubView *)), connect (view, SIGNAL (updateSubViewIndices (SubView *)),
this, SLOT (updateSubViewIndicies (SubView *))); this, SLOT (updateSubViewIndices (SubView *)));
view->show(); view->show();
@ -631,7 +603,7 @@ void CSVDoc::View::moveScrollBarToEnd(int min, int max)
void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting) void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
{ {
if (*setting=="Windows/hide-subview") if (*setting=="Windows/hide-subview")
updateSubViewIndicies (0); updateSubViewIndices (NULL);
else if (*setting=="Windows/mainwindow-scrollbar") else if (*setting=="Windows/mainwindow-scrollbar")
{ {
if (setting->toString()!="Grow Only") if (setting->toString()!="Grow Only")
@ -651,10 +623,7 @@ void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
} }
else else
{ {
mScroll = new QScrollArea(this); createScrollArea();
mScroll->setWidgetResizable(true);
mScroll->setWidget(&mSubViewWindow);
setCentralWidget(mScroll);
} }
} }
else if (mScroll) else if (mScroll)
@ -662,7 +631,7 @@ void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
mScroll->takeWidget(); mScroll->takeWidget();
setCentralWidget (&mSubViewWindow); setCentralWidget (&mSubViewWindow);
mScroll->deleteLater(); mScroll->deleteLater();
mScroll = 0; mScroll = NULL;
} }
} }
} }
@ -959,3 +928,41 @@ void CSVDoc::View::merge()
{ {
emit mergeDocument (mDocument); emit mergeDocument (mDocument);
} }
void CSVDoc::View::updateWidth(bool isGrowLimit, int minSubViewWidth)
{
QDesktopWidget *dw = QApplication::desktop();
QRect rect;
if (isGrowLimit)
rect = dw->screenGeometry(this);
else
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
if (!mScrollbarOnly && mScroll && mSubViews.size() > 1)
{
int newWidth = width()+minSubViewWidth;
int frameWidth = frameGeometry().width() - width();
if (newWidth+frameWidth <= rect.width())
{
resize(newWidth, height());
// WARNING: below code assumes that new subviews are added to the right
if (x() > rect.width()-(newWidth+frameWidth))
move(rect.width()-(newWidth+frameWidth), y()); // shift left to stay within the screen
}
else
{
// full width
resize(rect.width()-frameWidth, height());
mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minSubViewWidth);
move(0, y());
}
}
}
void CSVDoc::View::createScrollArea()
{
mScroll = new QScrollArea(this);
mScroll->setWidgetResizable(true);
mScroll->setWidget(&mSubViewWindow);
setCentralWidget(mScroll);
}

View file

@ -95,7 +95,8 @@ namespace CSVDoc
void resizeViewHeight (int height); void resizeViewHeight (int height);
void updateScrollbar(); void updateScrollbar();
void updateWidth(bool isGrowLimit, int minSubViewWidth);
void createScrollArea();
public: public:
View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews);
@ -143,7 +144,7 @@ namespace CSVDoc
void updateTitle(); void updateTitle();
// called when subviews are added or removed // called when subviews are added or removed
void updateSubViewIndicies (SubView *view = 0); void updateSubViewIndices (SubView *view = NULL);
private slots: private slots:

View file

@ -99,6 +99,9 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st
mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Mask_Terrain)); mTerrain.reset(new Terrain::TerrainGrid(mCellNode, data.getResourceSystem().get(), NULL, new TerrainStorage(mData), Mask_Terrain));
mTerrain->loadCell(esmLand.mX, mTerrain->loadCell(esmLand.mX,
esmLand.mY); esmLand.mY);
mCellBorder.reset(new CellBorder(mCellNode, mCoordinates));
mCellBorder->buildShape(esmLand);
} }
} }
} }

View file

@ -16,6 +16,7 @@
#include "object.hpp" #include "object.hpp"
#include "cellarrow.hpp" #include "cellarrow.hpp"
#include "cellmarker.hpp" #include "cellmarker.hpp"
#include "cellborder.hpp"
class QModelIndex; class QModelIndex;
@ -44,6 +45,7 @@ namespace CSVRender
CSMWorld::CellCoordinates mCoordinates; CSMWorld::CellCoordinates mCoordinates;
std::auto_ptr<CellArrow> mCellArrows[4]; std::auto_ptr<CellArrow> mCellArrows[4];
std::auto_ptr<CellMarker> mCellMarker; std::auto_ptr<CellMarker> mCellMarker;
std::auto_ptr<CellBorder> mCellBorder;
bool mDeleted; bool mDeleted;
int mSubMode; int mSubMode;
unsigned int mSubModeElementMask; unsigned int mSubModeElementMask;

View file

@ -0,0 +1,96 @@
#include "cellborder.hpp"
#include <osg/Group>
#include <osg/PositionAttitudeTransform>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/PrimitiveSet>
#include <components/esm/loadland.hpp>
#include "mask.hpp"
#include "../../model/world/cellcoordinates.hpp"
const int CSVRender::CellBorder::CellSize = ESM::Land::REAL_SIZE;
const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 3;
CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords)
: mParentNode(cellNode)
{
mBaseNode = new osg::PositionAttitudeTransform();
mBaseNode->setNodeMask(Mask_CellBorder);
mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10));
mParentNode->addChild(mBaseNode);
}
CSVRender::CellBorder::~CellBorder()
{
mParentNode->removeChild(mBaseNode);
}
void CSVRender::CellBorder::buildShape(const ESM::Land& esmLand)
{
const ESM::Land::LandData* landData = esmLand.getLandData(ESM::Land::DATA_VHGT);
if (!landData)
return;
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();
// Vertices
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
int x = 0, y = 0;
for (; x < ESM::Land::LAND_SIZE; ++x)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
x = ESM::Land::LAND_SIZE - 1;
for (; y < ESM::Land::LAND_SIZE; ++y)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
y = ESM::Land::LAND_SIZE - 1;
for (; x >= 0; --x)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
x = 0;
for (; y >= 0; --y)
vertices->push_back(osg::Vec3f(scaleToWorld(x), scaleToWorld(y), landData->mHeights[landIndex(x, y)]));
geometry->setVertexArray(vertices);
// Color
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array();
colors->push_back(osg::Vec4f(0.f, 0.5f, 0.f, 1.f));
geometry->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);
// Primitive
osg::ref_ptr<osg::DrawElementsUShort> primitives =
new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount+1);
for (size_t i = 0; i < VertexCount; ++i)
primitives->setElement(i, i);
primitives->setElement(VertexCount, 0);
geometry->addPrimitiveSet(primitives);
geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
geode->addDrawable(geometry);
mBaseNode->addChild(geode);
}
size_t CSVRender::CellBorder::landIndex(int x, int y)
{
return y * ESM::Land::LAND_SIZE + x;
}
float CSVRender::CellBorder::scaleToWorld(int value)
{
return (CellSize + 128) * (float)value / ESM::Land::LAND_SIZE;
}

View file

@ -0,0 +1,54 @@
#ifndef OPENCS_VIEW_CELLBORDER_H
#define OPENCS_VIEW_CELLBORDER_H
#include <cstddef>
#include <osg/ref_ptr>
namespace osg
{
class Group;
class PositionAttitudeTransform;
}
namespace ESM
{
struct Land;
}
namespace CSMWorld
{
class CellCoordinates;
}
namespace CSVRender
{
class CellBorder
{
public:
CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords);
~CellBorder();
void buildShape(const ESM::Land& esmLand);
private:
static const int CellSize;
static const int VertexCount;
size_t landIndex(int x, int y);
float scaleToWorld(int val);
// unimplemented
CellBorder(const CellBorder&);
CellBorder& operator=(const CellBorder&);
osg::Group* mParentNode;
osg::ref_ptr<osg::PositionAttitudeTransform> mBaseNode;
};
}
#endif

View file

@ -598,7 +598,7 @@ CSVWidget::SceneToolToggle *CSVRender::PagedWorldspaceWidget::makeControlVisibil
mControlElements->addButton (":placeholder", Mask_CellMarker, ":placeholder", mControlElements->addButton (":placeholder", Mask_CellMarker, ":placeholder",
"Cell marker"); "Cell marker");
mControlElements->addButton (":placeholder", Mask_CellArrow, ":placeholder", "Cell arrows"); mControlElements->addButton (":placeholder", Mask_CellArrow, ":placeholder", "Cell arrows");
mControlElements->addButton (":placeholder", Mask_CellBorder, ":placeholder", "Cell border"); mControlElements->addButton (":scenetoolbar/grid", Mask_CellBorder, ":scenetoolbar/grid-small", "Cell border");
mControlElements->setSelectionMask (0xffffffff); mControlElements->setSelectionMask (0xffffffff);

View file

@ -1363,6 +1363,7 @@ namespace MWRender
foundKeyframeCtrl = true; foundKeyframeCtrl = true;
break; break;
} }
cb = cb->getNestedCallback();
} }
if (foundKeyframeCtrl) if (foundKeyframeCtrl)

View file

@ -182,23 +182,30 @@ void WeaponAnimation::deleteControllers()
void WeaponAnimation::configureControllers(float characterPitchRadians) void WeaponAnimation::configureControllers(float characterPitchRadians)
{ {
if (!mSpineControllers[0])
return;
if (mPitchFactor == 0.f || characterPitchRadians == 0.f) if (mPitchFactor == 0.f || characterPitchRadians == 0.f)
{ {
for (int i=0; i<2; ++i) setControllerEnabled(false);
mSpineControllers[i]->setEnabled(false);
return; return;
} }
float pitch = characterPitchRadians * mPitchFactor; float pitch = characterPitchRadians * mPitchFactor;
osg::Quat rotate (pitch/2, osg::Vec3f(-1,0,0)); osg::Quat rotate (pitch/2, osg::Vec3f(-1,0,0));
for (int i=0; i<2; ++i) setControllerRotate(rotate);
{ setControllerEnabled(true);
mSpineControllers[i]->setRotate(rotate);
mSpineControllers[i]->setEnabled(true);
} }
void WeaponAnimation::setControllerRotate(const osg::Quat& rotate)
{
for (int i=0; i<2; ++i)
if (mSpineControllers[i])
mSpineControllers[i]->setRotate(rotate);
}
void WeaponAnimation::setControllerEnabled(bool enabled)
{
for (int i=0; i<2; ++i)
if (mSpineControllers[i])
mSpineControllers[i]->setEnabled(enabled);
} }
} }

View file

@ -52,6 +52,9 @@ namespace MWRender
osg::ref_ptr<RotateController> mSpineControllers[2]; osg::ref_ptr<RotateController> mSpineControllers[2];
void setControllerRotate(const osg::Quat& rotate);
void setControllerEnabled(bool enabled);
virtual osg::Group* getArrowBone() = 0; virtual osg::Group* getArrowBone() = 0;
virtual osg::Node* getWeaponNode() = 0; virtual osg::Node* getWeaponNode() = 0;
virtual Resource::ResourceSystem* getResourceSystem() = 0; virtual Resource::ResourceSystem* getResourceSystem() = 0;

View file

@ -2039,7 +2039,7 @@ namespace MWWorld
bool World::isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const bool World::isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const
{ {
if (!(cell->getCell()->mData.mFlags & ESM::Cell::HasWater)) { if (!(cell->getCell()->hasWater())) {
return false; return false;
} }
return pos.z() < cell->getWaterLevel(); return pos.z() < cell->getWaterLevel();

View file

@ -141,7 +141,7 @@ struct Cell
bool hasWater() const bool hasWater() const
{ {
return (mData.mFlags&HasWater) != 0; return ((mData.mFlags&HasWater) != 0) || isExterior();
} }
// Restore the given reader to the stored position. Will try to open // Restore the given reader to the stored position. Will try to open

View file

@ -470,7 +470,7 @@ namespace NifOsg
const Nif::NiTextureEffect* textureEffect = static_cast<const Nif::NiTextureEffect*>(nifNode); const Nif::NiTextureEffect* textureEffect = static_cast<const Nif::NiTextureEffect*>(nifNode);
if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map) if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map)
{ {
std::cerr << "Unhandled NiTextureEffect type " << textureEffect->textureType << std::endl; std::cerr << "Unhandled NiTextureEffect type " << textureEffect->textureType << " in " << mFilename << std::endl;
return; return;
} }
@ -487,7 +487,7 @@ namespace NifOsg
texGen->setMode(osg::TexGen::SPHERE_MAP); texGen->setMode(osg::TexGen::SPHERE_MAP);
break; break;
default: default:
std::cerr << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << std::endl; std::cerr << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << " in " << mFilename << std::endl;
return; return;
} }
@ -1374,17 +1374,15 @@ namespace NifOsg
case Nif::NiTexturingProperty::DarkTexture: case Nif::NiTexturingProperty::DarkTexture:
case Nif::NiTexturingProperty::BumpTexture: case Nif::NiTexturingProperty::BumpTexture:
case Nif::NiTexturingProperty::DetailTexture: case Nif::NiTexturingProperty::DetailTexture:
case Nif::NiTexturingProperty::DecalTexture:
break; break;
case Nif::NiTexturingProperty::GlossTexture: case Nif::NiTexturingProperty::GlossTexture:
{ {
// Not used by the vanilla engine. MCP (Morrowind Code Patch) adds an option to use Gloss maps:
// "- Gloss map fix. Morrowind removed gloss map entries from model files after loading them. This stops Morrowind from removing them."
std::cerr << "NiTexturingProperty::GlossTexture in " << mFilename << " not currently used." << std::endl; std::cerr << "NiTexturingProperty::GlossTexture in " << mFilename << " not currently used." << std::endl;
continue; continue;
} }
case Nif::NiTexturingProperty::DecalTexture:
{
std::cerr << "NiTexturingProperty::DecalTexture in " << mFilename << " not currently used." << std::endl;
continue;
}
default: default:
{ {
std::cerr << "Warning: unhandled texture stage " << i << " in " << mFilename << std::endl; std::cerr << "Warning: unhandled texture stage " << i << " in " << mFilename << std::endl;
@ -1435,16 +1433,16 @@ namespace NifOsg
{ {
osg::TexEnvCombine* texEnv = new osg::TexEnvCombine; osg::TexEnvCombine* texEnv = new osg::TexEnvCombine;
texEnv->setScale_RGB(2.f); texEnv->setScale_RGB(2.f);
texEnv->setCombine_Alpha(GL_MODULATE); texEnv->setCombine_Alpha(osg::TexEnvCombine::MODULATE);
texEnv->setOperand0_Alpha(GL_SRC_ALPHA); texEnv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA);
texEnv->setOperand1_Alpha(GL_SRC_ALPHA); texEnv->setOperand1_Alpha(osg::TexEnvCombine::SRC_ALPHA);
texEnv->setSource0_Alpha(GL_PREVIOUS_ARB); texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
texEnv->setSource1_Alpha(GL_TEXTURE); texEnv->setSource1_Alpha(osg::TexEnvCombine::TEXTURE);
texEnv->setCombine_RGB(GL_MODULATE); texEnv->setCombine_RGB(osg::TexEnvCombine::MODULATE);
texEnv->setOperand0_RGB(GL_SRC_COLOR); texEnv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
texEnv->setOperand1_RGB(GL_SRC_COLOR); texEnv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
texEnv->setSource0_RGB(GL_PREVIOUS_ARB); texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
texEnv->setSource1_RGB(GL_TEXTURE); texEnv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON); stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
} }
else if (i == Nif::NiTexturingProperty::BumpTexture) else if (i == Nif::NiTexturingProperty::BumpTexture)
@ -1452,6 +1450,21 @@ namespace NifOsg
// Set this texture to Off by default since we can't render it with the fixed-function pipeline // Set this texture to Off by default since we can't render it with the fixed-function pipeline
stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF); stateset->setTextureMode(texUnit, GL_TEXTURE_2D, osg::StateAttribute::OFF);
} }
else if (i == Nif::NiTexturingProperty::DecalTexture)
{
osg::TexEnvCombine* texEnv = new osg::TexEnvCombine;
texEnv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
texEnv->setSource0_RGB(osg::TexEnvCombine::TEXTURE);
texEnv->setOperand0_RGB(osg::TexEnvCombine::SRC_COLOR);
texEnv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS);
texEnv->setOperand1_RGB(osg::TexEnvCombine::SRC_COLOR);
texEnv->setSource2_RGB(osg::TexEnvCombine::TEXTURE);
texEnv->setOperand2_RGB(osg::TexEnvCombine::SRC_ALPHA);
texEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);
texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
texEnv->setOperand0_Alpha(osg::TexEnvCombine::SRC_ALPHA);
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
}
switch (i) switch (i)
{ {
@ -1470,6 +1483,9 @@ namespace NifOsg
case Nif::NiTexturingProperty::DetailTexture: case Nif::NiTexturingProperty::DetailTexture:
texture2d->setName("detailMap"); texture2d->setName("detailMap");
break; break;
case Nif::NiTexturingProperty::DecalTexture:
texture2d->setName("decalMap");
break;
default: default:
break; break;
} }

View file

@ -13,6 +13,10 @@ namespace Resource
} }
ResourceManager::~ResourceManager()
{
}
void ResourceManager::updateCache(double referenceTime) void ResourceManager::updateCache(double referenceTime)
{ {
mCache->updateTimeStampOfObjectsInCacheWithExternalReferences(referenceTime); mCache->updateTimeStampOfObjectsInCacheWithExternalReferences(referenceTime);

View file

@ -18,6 +18,7 @@ namespace Resource
{ {
public: public:
ResourceManager(const VFS::Manager* vfs); ResourceManager(const VFS::Manager* vfs);
virtual ~ResourceManager();
/// Clear cache entries that have not been referenced for longer than expiryDelay. /// Clear cache entries that have not been referenced for longer than expiryDelay.
virtual void updateCache(double referenceTime); virtual void updateCache(double referenceTime);

View file

@ -102,9 +102,15 @@ namespace SceneUtil
// Need to invert culling because of the negative scale // Need to invert culling because of the negative scale
// Note: for absolute correctness we would need to check the current front face for every mesh then invert it // Note: for absolute correctness we would need to check the current front face for every mesh then invert it
// However MW isn't doing this either, so don't. Assuming all meshes are using backface culling is more efficient. // However MW isn't doing this either, so don't. Assuming all meshes are using backface culling is more efficient.
static osg::ref_ptr<osg::StateSet> frontFaceStateSet;
if (!frontFaceStateSet)
{
frontFaceStateSet = new osg::StateSet;
osg::FrontFace* frontFace = new osg::FrontFace; osg::FrontFace* frontFace = new osg::FrontFace;
frontFace->setMode(osg::FrontFace::CLOCKWISE); frontFace->setMode(osg::FrontFace::CLOCKWISE);
trans->getOrCreateStateSet()->setAttributeAndModes(frontFace, osg::StateAttribute::ON); frontFaceStateSet->setAttributeAndModes(frontFace, osg::StateAttribute::ON);
}
trans->setStateSet(frontFaceStateSet);
} }
if (trans) if (trans)

View file

@ -88,11 +88,11 @@ namespace Shader
return newStateSet.get(); return newStateSet.get();
} }
const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap" }; const char* defaultTextures[] = { "diffuseMap", "normalMap", "emissiveMap", "darkMap", "detailMap", "envMap", "specularMap", "decalMap" };
bool isTextureNameRecognized(const std::string& name) bool isTextureNameRecognized(const std::string& name)
{ {
for (unsigned int i=0; i<sizeof(defaultTextures)/sizeof(defaultTextures[0]); ++i) for (unsigned int i=0; i<sizeof(defaultTextures)/sizeof(defaultTextures[0]); ++i)
if (name.c_str() == defaultTextures[i]) if (name == defaultTextures[i])
return true; return true;
return false; return false;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 B

BIN
files/opencs/grid-view.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

View file

@ -80,6 +80,8 @@
<file alias="free-camera">flying eye.png</file> <file alias="free-camera">flying eye.png</file>
<file alias="orbiting-camera">orbit2.png</file> <file alias="orbiting-camera">orbit2.png</file>
<file alias="play">scene-play.png</file> <file alias="play">scene-play.png</file>
<file alias="grid">grid-view.png</file>
<file alias="grid-small">grid-view-small.png</file>
<file alias="scene-view-1">scene-view-references.png</file> <file alias="scene-view-1">scene-view-references.png</file>
<file alias="scene-view-16">scene-view-terrain.png</file> <file alias="scene-view-16">scene-view-terrain.png</file>
<file alias="scene-view-4">scene-view-water.png</file> <file alias="scene-view-4">scene-view-water.png</file>

View file

@ -15,6 +15,11 @@ uniform sampler2D detailMap;
varying vec2 detailMapUV; varying vec2 detailMapUV;
#endif #endif
#if @decalMap
uniform sampler2D decalMap;
varying vec2 decalMapUV;
#endif
#if @emissiveMap #if @emissiveMap
uniform sampler2D emissiveMap; uniform sampler2D emissiveMap;
varying vec2 emissiveMapUV; varying vec2 emissiveMapUV;
@ -67,6 +72,11 @@ void main()
gl_FragData[0].xyz *= texture2D(darkMap, darkMapUV).xyz; gl_FragData[0].xyz *= texture2D(darkMap, darkMapUV).xyz;
#endif #endif
#if @decalMap
vec4 decalTex = texture2D(decalMap, decalMapUV);
gl_FragData[0].xyz = mix(gl_FragData[0].xyz, decalTex.xyz, decalTex.a);
#endif
vec3 viewNormal = passViewNormal; vec3 viewNormal = passViewNormal;
#if @normalMap #if @normalMap

View file

@ -12,6 +12,10 @@ varying vec2 darkMapUV;
varying vec2 detailMapUV; varying vec2 detailMapUV;
#endif #endif
#if @decalMap
varying vec2 decalMapUV;
#endif
#if @emissiveMap #if @emissiveMap
varying vec2 emissiveMapUV; varying vec2 emissiveMapUV;
#endif #endif
@ -68,7 +72,11 @@ void main(void)
#endif #endif
#if @detailMap #if @detailMap
detailMapUV = (gl_TextureMatrix[@detailMap] * gl_MultiTexCoord@detailMap).xy; detailMapUV = (gl_TextureMatrix[@detailMapUV] * gl_MultiTexCoord@detailMapUV).xy;
#endif
#if @decalMap
decalMapUV = (gl_TextureMatrix[@decalMapUV] * gl_MultiTexCoord@decalMapUV).xy;
#endif #endif
#if @emissiveMap #if @emissiveMap