Merge revisions r5604 through r5621 from trunk to ogl-es.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5622 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2018-06-17 20:01:00 +00:00
parent 67d3ffbc1f
commit bdb412cd44
29 changed files with 2040 additions and 292 deletions

View File

@ -9,6 +9,22 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
--------------------------
Changes in 1.9 (not yet released)
- CGUIComboBox uses now EGDS_SCROLLBAR_SIZE instead of EGDS_WINDOW_BUTTON_WIDTH for the width of the listbox button to allow changing that without changing window topbar height.
Thanks @LunaRebirth for reporting. (Forum: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=52297&p=303682#p303682)
- CGUIListbox, CGUITreeView and CGUITable now resize scrollbars when EGDS_SCROLLBAR_SIZE in the skin changes without having to re-create the elements.
This also fixes the problem that drawing looked wrong when this value got changed after the elements were created.
Thanks @LunaRebirth for reporting. (Forum: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=52297&p=303682#p303682)
- Scrollbar buttons can no longer get larger than half the ScrollBar element to avoid them overlapping.
- Add IVideoDriver::swapMaterialRenderers to allow swapping the renderer used to render a certain material.
- IMeshManipulator functions createMeshWith1TCoords, createMeshWith2TCoords and createMeshWithTangents no longer weld vertices while converting meshes. Use IMeshManipulator::createMeshWelded if you need that welding.
- Add ITerrainSceneNode::setFixedBorderLOD to handle connecting terrain nodes without gaps. Thanks @diho for the bugreport, testcase and a patch proposal (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=51220).
- PLY loader now works with files which use "st" instead of "uv" for texture coordinates (like generated from Blender or Assimp). Thanks @JLouisB for patch (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=52261).
- STL writer does now also write binary files when EMWF_WRITE_BINARY flag is used. Based on patch from JLouisB (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=52261).
(EMWF_WRITE_COMPRESSED also still works for downward compatibility)
- Improved PLY exporter. Thanks for Patch from JLouisB. (Forum: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=52261):
- Support for UV and vertex colors.
- Support for binary PLY files export with the EMWF_WRITE_BINARY flag
- Fix for the meshes with 32 bits index
- Fix wrong colors on big endian platforms with burnings renders. Thx @kas1e for reporting and @curaga for the patch (#318). Forum bug discussion at http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=52177.
- Fix bug #440 where OpenGL driver enabled second texture for single-texture materials when setMaterial was called twice. Thx@ "number Zero" for bugreport and test-case.
- Irrlicht icon now loaded with LR_DEFAULTSIZE to better support larger icon requests. Thx@ luthyr for report and bugfix.

View File

@ -29,7 +29,7 @@ using namespace gui;
Some global variables used later on
*/
IrrlichtDevice *Device = 0;
core::stringc StartUpModelFile;
io::path StartUpModelFile;
core::stringw MessageText;
core::stringw Caption;
scene::ISceneNode* Model = 0;
@ -166,10 +166,8 @@ Function loadModel() loads a model and displays it using an
addAnimatedMeshSceneNode and the scene manager. Nothing difficult. It also
displays a short message box, if the model could not be loaded.
*/
void loadModel(const c8* fn)
void loadModel(const io::path& filename)
{
io::path filename(fn);
io::path extension;
core::getFileNameExtension(extension, filename);
extension.make_lower();
@ -440,7 +438,7 @@ public:
// load the model file, selected in the file open dialog
IGUIFileOpenDialog* dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
loadModel(core::stringc(dialog->getFileName()).c_str());
loadModel(dialog->getFileNameP());
}
break;

View File

@ -45,9 +45,12 @@ namespace scene
EMWF_NONE = 0,
//! write lightmap textures out if possible
//! Currently not used by any Irrlicht mesh-writer
// (Note: User meshwriters can still use it)
EMWF_WRITE_LIGHTMAPS = 0x1,
//! write in a way that consumes less disk space
// (Note: Mainly there for user meshwriters)
EMWF_WRITE_COMPRESSED = 0x2,
//! write in binary format rather than text

View File

@ -149,11 +149,11 @@ namespace gui
//! Enumeration for default sizes.
enum EGUI_DEFAULT_SIZE
{
//! default with / height of scrollbar
//! default with / height of scrollbar. Also width of drop-down button in comboboxes.
EGDS_SCROLLBAR_SIZE = 0,
//! height of menu
EGDS_MENU_HEIGHT,
//! width of a window button
//! width and height of a window titlebar button (like minimize/maximize/close buttons). The titlebar height is also calculated from that.
EGDS_WINDOW_BUTTON_WIDTH,
//! width of a checkbox check
EGDS_CHECK_BOX_WIDTH,
@ -163,7 +163,7 @@ namespace gui
EGDS_MESSAGE_BOX_HEIGHT,
//! width of a default button
EGDS_BUTTON_WIDTH,
//! height of a default button
//! height of a default button (OK and cancel buttons)
EGDS_BUTTON_HEIGHT,
//! distance for text from background
EGDS_TEXT_DISTANCE_X,

View File

@ -100,7 +100,9 @@ namespace scene
virtual s32 getCurrentLODOfPatches(core::array<s32>& LODs) const =0;
//! Manually sets the LOD of a patch
/** \param patchX Patch x coordinate.
/** NOTE: Any values set here are overwritten again in the automatic
recalculations when the camera changes.
\param patchX Patch x coordinate.
\param patchZ Patch z coordinate.
\param LOD The level of detail to set the patch to. */
virtual void setLODOfPatch(s32 patchX, s32 patchZ, s32 LOD=0) =0;
@ -172,6 +174,12 @@ namespace scene
video::SColor vertexColor=video::SColor(255,255,255,255),
s32 smoothFactor=0) =0;
//! Force node to use a fixed LOD level at the borders of the terrain.
/** This can be useful when several TerrainSceneNodes are connected.
\param borderLOD When >= 0 all patches at the 4 borders will use the
given LOD. When < 0 borders are just regular patches (that's default). */
virtual void setFixedBorderLOD(irr::s32 borderLOD=0) = 0;
};
} // end namespace scene

View File

@ -501,11 +501,15 @@ namespace video
bool zeroTexels = false) const =0;
//! Creates a normal map from a height map texture.
/** If the target texture has 32 bit, the height value is
stored in the alpha component of the texture as addition. This
value is used by the video::EMT_PARALLAX_MAP_SOLID material and
similar materials.
\param texture Texture whose alpha channel is modified.
/** As input is considered to be a height map the texture is read like:
- For a 32-bit texture only the red channel is regarded
- For a 16-bit texture the rgb-values are averaged.
Output channels red/green for X/Y and blue for up (Z).
For a 32-bit texture we store additionally the height value in the
alpha channel. This value is used by the video::EMT_PARALLAX_MAP_SOLID
material and similar materials.
On the borders the texture is considered to repeat.
\param texture Height map texture which is converted to a normal map.
\param amplitude Constant value by which the height
information is multiplied.*/
virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const =0;
@ -1327,6 +1331,16 @@ namespace video
\param name: New name of the material renderer. */
virtual void setMaterialRendererName(s32 idx, const c8* name) =0;
//! Swap the material renderers used for certain id's
/** Swap the IMaterialRenderers responsible for rendering specific
material-id's. This means every SMaterial using a MaterialType
with one of the indices involved here will now render differently.
\param idx1 First material index to swap. It must already exist or nothing happens.
\param idx2 Second material index to swap. It must already exist or nothing happens.
\param swapNames When true the renderer names also swap
When false the names will stay at the original index */
virtual void swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames=true) = 0;
//! Creates material attributes list from a material
/** This method is useful for serialization and more.
Please note that the video driver will use the material

View File

@ -25,7 +25,9 @@ enum E_VERTEX_TYPE
EVT_2TCOORDS,
//! Vertex with a tangent and binormal vector, video::S3DVertexTangents.
/** Usually used for tangent space normal mapping. */
/** Usually used for tangent space normal mapping.
Usually tangent and binormal get send to shaders as texture coordinate sets 1 and 2.
*/
EVT_TANGENTS
};
@ -181,7 +183,9 @@ struct S3DVertex2TCoords : public S3DVertex
//! Vertex with a tangent and binormal vector.
/** Usually used for tangent space normal mapping. */
/** Usually used for tangent space normal mapping.
Usually tangent and binormal get send to shaders as texture coordinate sets 1 and 2.
*/
struct S3DVertexTangents : public S3DVertex
{
//! default constructor

View File

@ -440,7 +440,7 @@ namespace video
f32 BlendFactor;
//! Factor specifying how far the polygon offset should be made
/** Specifying 0 disables the polygon offset. The direction is specified spearately.
/** Specifying 0 disables the polygon offset. The direction is specified separately.
The factor can be from 0 to 7.*/
u8 PolygonOffsetFactor:3;

View File

@ -236,22 +236,24 @@ namespace irr
if (!Surface[i] && Texture[i])
{
IDirect3DTexture9* currentTexture = static_cast<CD3D9Texture*>(Texture[i])->getDX9Texture();
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
Surface[i] = currentSurface;
if ( currentTexture )
{
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
Surface[i] = currentSurface;
}
}
}
if (!DepthStencilSurface && DepthStencil)
{
IDirect3DTexture9* currentTexture = static_cast<CD3D9Texture*>(DepthStencil)->getDX9Texture();
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
DepthStencilSurface = currentSurface;
if ( currentTexture )
{
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
DepthStencilSurface = currentSurface;
}
}
}
}

View File

@ -353,13 +353,13 @@ void CD3D9Texture::generateRenderTarget()
if (FAILED(hr))
{
if (D3DERR_INVALIDCALL == hr)
os::Printer::log("Could not create render target texture", "Invalid Call");
os::Printer::log("Could not create render target texture", "Invalid Call", irr::ELL_ERROR);
else if (D3DERR_OUTOFVIDEOMEMORY == hr)
os::Printer::log("Could not create render target texture", "Out of Video Memory");
os::Printer::log("Could not create render target texture", "Out of Video Memory", irr::ELL_ERROR);
else if (E_OUTOFMEMORY == hr)
os::Printer::log("Could not create render target texture", "Out of Memory");
os::Printer::log("Could not create render target texture", "Out of Memory", irr::ELL_ERROR);
else
os::Printer::log("Could not create render target texture");
os::Printer::log("Could not create render target texture", irr::ELL_ERROR);
}
}
}

View File

@ -33,18 +33,7 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
IGUISkin* skin = Environment->getSkin();
s32 width = 15;
if (skin)
width = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
core::rect<s32> r;
r.UpperLeftCorner.X = rectangle.getWidth() - width - 2;
r.LowerRightCorner.X = rectangle.getWidth() - 2;
r.UpperLeftCorner.Y = 2;
r.LowerRightCorner.Y = rectangle.getHeight() - 2;
ListButton = Environment->addButton(r, this, -1, L"");
ListButton = Environment->addButton(core::recti(0,0,1,1), this, -1, L"");
if (skin && skin->getSpriteBank())
{
ListButton->setSpriteBank(skin->getSpriteBank());
@ -55,12 +44,7 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
ListButton->setSubElement(true);
ListButton->setTabStop(false);
r.UpperLeftCorner.X = 2;
r.UpperLeftCorner.Y = 2;
r.LowerRightCorner.X = RelativeRect.getWidth() - (ListButton->getAbsolutePosition().getWidth() + 2);
r.LowerRightCorner.Y = RelativeRect.getHeight() - 2;
SelectedText = Environment->addStaticText(L"", r, false, false, this, -1, false);
SelectedText = Environment->addStaticText(L"", core::recti(0,0,1,1), false, false, this, -1, false);
SelectedText->setSubElement(true);
SelectedText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
SelectedText->setTextAlignment(EGUIA_UPPERLEFT, EGUIA_CENTER);
@ -68,6 +52,8 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
SelectedText->setOverrideColor(skin->getColor(EGDC_BUTTON_TEXT));
SelectedText->enableOverrideColor(true);
updateListButtonWidth(skin ? skin->getSize(EGDS_SCROLLBAR_SIZE) : 15);
// this element can be tabbed to
setTabStop(true);
setTabOrder(-1);
@ -377,6 +363,24 @@ void CGUIComboBox::sendSelectionChangedEvent()
}
}
void CGUIComboBox::updateListButtonWidth(s32 width)
{
if (ListButton->getRelativePosition().getWidth() != width)
{
core::rect<s32> r;
r.UpperLeftCorner.X = RelativeRect.getWidth() - width - 2;
r.LowerRightCorner.X = RelativeRect.getWidth() - 2;
r.UpperLeftCorner.Y = 2;
r.LowerRightCorner.Y = RelativeRect.getHeight() - 2;
ListButton->setRelativePosition(r);
r.UpperLeftCorner.X = 2;
r.UpperLeftCorner.Y = 2;
r.LowerRightCorner.X = RelativeRect.getWidth() - (width + 2);
r.LowerRightCorner.Y = RelativeRect.getHeight() - 2;
SelectedText->setRelativePosition(r);
}
}
//! draws the element and its children
void CGUIComboBox::draw()
@ -386,6 +390,8 @@ void CGUIComboBox::draw()
IGUISkin* skin = Environment->getSkin();
updateListButtonWidth(skin->getSize(EGDS_SCROLLBAR_SIZE));
// font changed while the listbox is open?
if ( ActiveFont != skin->getFont() && ListBox )
{

View File

@ -84,6 +84,7 @@ namespace gui
void openCloseMenu();
void sendSelectionChangedEvent();
void updateListButtonWidth(s32 width);
IGUIButton* ListButton;
IGUIStaticText* SelectedText;

View File

@ -34,10 +34,9 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
#endif
IGUISkin* skin = Environment->getSkin();
const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE);
ScrollBar = new CGUIScrollBar(false, Environment, this, -1,
core::rect<s32>(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()),
ScrollBar = new CGUIScrollBar(false, Environment, this, -1,
core::recti(0, 0, 1, 1),
!clip);
ScrollBar->setSubElement(true);
ScrollBar->setTabStop(false);
@ -45,6 +44,8 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
ScrollBar->setVisible(false);
ScrollBar->setPos(0);
updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE));
setNotClipped(!clip);
// this element can be tabbed to
@ -149,8 +150,7 @@ void CGUIListBox::clear()
ItemsIconWidth = 0;
Selected = -1;
if (ScrollBar)
ScrollBar->setPos(0);
ScrollBar->setPos(0);
recalculateItemHeight();
}
@ -190,7 +190,6 @@ void CGUIListBox::recalculateItemHeight()
ScrollBar->setVisible(true);
}
//! returns id of selected item. returns -1 if no item is selected.
s32 CGUIListBox::getSelected() const
{
@ -495,6 +494,7 @@ void CGUIListBox::draw()
recalculateItemHeight(); // if the font changed
IGUISkin* skin = Environment->getSkin();
updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE));
core::rect<s32>* clipRect = 0;
@ -507,7 +507,7 @@ void CGUIListBox::draw()
clientClip.UpperLeftCorner.Y += 1;
clientClip.UpperLeftCorner.X += 1;
if (ScrollBar->isVisible())
clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
clientClip.LowerRightCorner.X -= ScrollBar->getRelativePosition().getWidth();
clientClip.LowerRightCorner.Y -= 1;
clientClip.clipAgainst(AbsoluteClippingRect);
@ -520,7 +520,7 @@ void CGUIListBox::draw()
frameRect = AbsoluteRect;
frameRect.UpperLeftCorner.X += 1;
if (ScrollBar->isVisible())
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
frameRect.LowerRightCorner.X -= ScrollBar->getRelativePosition().getWidth();
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
@ -637,6 +637,14 @@ void CGUIListBox::recalculateScrollPos()
}
}
void CGUIListBox::updateScrollBarSize(s32 size)
{
if ( size != ScrollBar->getRelativePosition().getWidth() )
{
core::recti r(RelativeRect.getWidth() - size, 0, RelativeRect.getWidth(), RelativeRect.getHeight());
ScrollBar->setRelativePosition(r);
}
}
void CGUIListBox::setAutoScrollEnabled(bool scroll)
{

View File

@ -157,6 +157,7 @@ namespace gui
void recalculateItemHeight();
void selectNew(s32 ypos, bool onlyHover=false);
void recalculateScrollPos();
void updateScrollBarSize(s32 size);
// extracted that function to avoid copy&paste code
void recalculateItemWidth(s32 icon);

View File

@ -466,10 +466,11 @@ void CGUIScrollBar::refreshControls()
if (Horizontal)
{
s32 h = RelativeRect.getHeight();
const s32 h = RelativeRect.getHeight();
const s32 w = (h < RelativeRect.getWidth() / 2) ? h : RelativeRect.getWidth() / 2;
if (!UpButton)
{
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, h, h), NoClip);
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, h), NoClip);
UpButton->setSubElement(true);
UpButton->setTabStop(false);
}
@ -479,11 +480,11 @@ void CGUIScrollBar::refreshControls()
UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor);
UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor);
}
UpButton->setRelativePosition(core::rect<s32>(0,0, h, h));
UpButton->setRelativePosition(core::rect<s32>(0,0, w, h));
UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
if (!DownButton)
{
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h), NoClip);
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(RelativeRect.getWidth()-w, 0, RelativeRect.getWidth(), h), NoClip);
DownButton->setSubElement(true);
DownButton->setTabStop(false);
}
@ -493,15 +494,16 @@ void CGUIScrollBar::refreshControls()
DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor);
DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor);
}
DownButton->setRelativePosition(core::rect<s32>(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h));
DownButton->setRelativePosition(core::rect<s32>(RelativeRect.getWidth()-w, 0, RelativeRect.getWidth(), h));
DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
}
else
{
s32 w = RelativeRect.getWidth();
const s32 w = RelativeRect.getWidth();
const s32 h = (w < RelativeRect.getHeight() / 2) ? w : RelativeRect.getHeight() / 2;
if (!UpButton)
{
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, w), NoClip);
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, h), NoClip);
UpButton->setSubElement(true);
UpButton->setTabStop(false);
}
@ -511,11 +513,11 @@ void CGUIScrollBar::refreshControls()
UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor);
UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor);
}
UpButton->setRelativePosition(core::rect<s32>(0,0, w, w));
UpButton->setRelativePosition(core::rect<s32>(0,0, w, h));
UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
if (!DownButton)
{
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()), NoClip);
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,RelativeRect.getHeight()-h, w, RelativeRect.getHeight()), NoClip);
DownButton->setSubElement(true);
DownButton->setTabStop(false);
}
@ -525,7 +527,7 @@ void CGUIScrollBar::refreshControls()
DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor);
DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor);
}
DownButton->setRelativePosition(core::rect<s32>(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()));
DownButton->setRelativePosition(core::rect<s32>(0,RelativeRect.getHeight()-h, w, RelativeRect.getHeight()));
DownButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT);
}
}

View File

@ -33,6 +33,7 @@ CGUITable::CGUITable(IGUIEnvironment* environment, IGUIElement* parent,
ItemHeight(0), TotalItemHeight(0), TotalItemWidth(0), Selected(-1),
CellHeightPadding(2), CellWidthPadding(5), ActiveTab(-1),
CurrentOrdering(EGOM_NONE), DrawFlags(EGTDF_ROWS | EGTDF_COLUMNS | EGTDF_ACTIVE_ROW ),
ScrollBarSize(0),
OverrideFont(0)
{
#ifdef _DEBUG
@ -436,7 +437,8 @@ void CGUITable::checkScrollbars()
if ( !HorizontalScrollBar || !VerticalScrollBar || !skin)
return;
s32 scrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE);
ScrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE);
bool wasHorizontalScrollBarVisible = HorizontalScrollBar->isVisible();
bool wasVerticalScrollBarVisible = VerticalScrollBar->isVisible();
HorizontalScrollBar->setVisible(false);
@ -456,7 +458,7 @@ void CGUITable::checkScrollbars()
// needs horizontal scroll be visible?
if( TotalItemWidth > clientClip.getWidth() )
{
clientClip.LowerRightCorner.Y -= scrollBarSize;
clientClip.LowerRightCorner.Y -= ScrollBarSize;
HorizontalScrollBar->setVisible(true);
HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth()));
}
@ -464,7 +466,7 @@ void CGUITable::checkScrollbars()
// needs vertical scroll be visible?
if( TotalItemHeight > clientClip.getHeight() )
{
clientClip.LowerRightCorner.X -= scrollBarSize;
clientClip.LowerRightCorner.X -= ScrollBarSize;
VerticalScrollBar->setVisible(true);
VerticalScrollBar->setMax(core::max_(0,TotalItemHeight - clientClip.getHeight()));
@ -473,7 +475,7 @@ void CGUITable::checkScrollbars()
{
if( TotalItemWidth > clientClip.getWidth() )
{
clientClip.LowerRightCorner.Y -= scrollBarSize;
clientClip.LowerRightCorner.Y -= ScrollBarSize;
HorizontalScrollBar->setVisible(true);
HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth()));
}
@ -489,13 +491,13 @@ void CGUITable::checkScrollbars()
if ( HorizontalScrollBar->isVisible() )
{
VerticalScrollBar->setRelativePosition(
core::rect<s32>(RelativeRect.getWidth() - scrollBarSize, 1,
RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+scrollBarSize) ) );
core::rect<s32>(RelativeRect.getWidth() - ScrollBarSize, 1,
RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+ScrollBarSize) ) );
}
else
{
VerticalScrollBar->setRelativePosition(
core::rect<s32>(RelativeRect.getWidth() - scrollBarSize, 1,
core::rect<s32>(RelativeRect.getWidth() - ScrollBarSize, 1,
RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) );
}
}
@ -508,11 +510,11 @@ void CGUITable::checkScrollbars()
if ( VerticalScrollBar->isVisible() )
{
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-(1+scrollBarSize), RelativeRect.getHeight()-1) );
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - ScrollBarSize, RelativeRect.getWidth()-(1+ScrollBarSize), RelativeRect.getHeight()-1) );
}
else
{
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) );
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - ScrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) );
}
}
}
@ -864,15 +866,18 @@ void CGUITable::draw()
if (!font)
return;
if ( ScrollBarSize != skin->getSize(EGDS_SCROLLBAR_SIZE) )
checkScrollbars();
// CAREFUL: near identical calculations for tableRect and clientClip are also done in checkScrollbars and selectColumnHeader
// Area of table used for drawing without scrollbars
core::rect<s32> tableRect(AbsoluteRect);
tableRect.UpperLeftCorner.X += 1;
tableRect.UpperLeftCorner.Y += 1;
if ( VerticalScrollBar && VerticalScrollBar->isVisible() )
tableRect.LowerRightCorner.X -= skin->getSize(EGDS_SCROLLBAR_SIZE);
tableRect.LowerRightCorner.X -= ScrollBarSize;
if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() )
tableRect.LowerRightCorner.Y -= skin->getSize(EGDS_SCROLLBAR_SIZE);
tableRect.LowerRightCorner.Y -= ScrollBarSize;
s32 headerBottom = tableRect.UpperLeftCorner.Y + ItemHeight;
@ -910,7 +915,7 @@ void CGUITable::draw()
if (rowRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y &&
rowRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y)
{
// draw row seperator
// draw row separator
if ( DrawFlags & EGTDF_ROWS )
{
core::rect<s32> lineRect(rowRect);
@ -966,7 +971,7 @@ void CGUITable::draw()
// draw column background
skin->draw3DButtonPaneStandard(this, columnrect, &tableClip);
// draw column seperator
// draw column separator
if ( DrawFlags & EGTDF_COLUMNS )
{
columnSeparator.UpperLeftCorner.X = pos;

View File

@ -179,8 +179,8 @@ namespace gui
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;
protected:
virtual void refreshControls();
virtual void checkScrollbars();
void refreshControls();
void checkScrollbars();
private:
@ -240,6 +240,7 @@ namespace gui
s32 ActiveTab;
EGUI_ORDERING_MODE CurrentOrdering;
s32 DrawFlags;
s32 ScrollBarSize;
gui::IGUIFont* OverrideFont;
};

View File

@ -432,6 +432,7 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
IndentWidth( 0 ),
TotalItemHeight( 0 ),
TotalItemWidth ( 0 ),
ScrollBarSize( 0 ),
Font( 0 ),
OverrideFont( 0 ),
IconFont( 0 ),
@ -450,15 +451,15 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
#endif
IGUISkin* skin = Environment->getSkin();
s32 s = skin->getSize( EGDS_SCROLLBAR_SIZE );
ScrollBarSize = skin->getSize( EGDS_SCROLLBAR_SIZE );
if ( scrollBarVertical )
{
ScrollBarV = new CGUIScrollBar( false, Environment, this, -1,
core::rect<s32>( RelativeRect.getWidth() - s,
core::rect<s32>( RelativeRect.getWidth() - ScrollBarSize,
0,
RelativeRect.getWidth(),
RelativeRect.getHeight() - s
RelativeRect.getHeight() - ScrollBarSize
), !clip );
ScrollBarV->drop();
@ -471,8 +472,8 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
{
ScrollBarH = new CGUIScrollBar( true, Environment, this, -1,
core::rect<s32>( 0,
RelativeRect.getHeight() - s,
RelativeRect.getWidth() - s,
RelativeRect.getHeight() - ScrollBarSize,
RelativeRect.getWidth() - ScrollBarSize,
RelativeRect.getHeight()
), !clip );
ScrollBarH->drop();
@ -640,6 +641,28 @@ void CGUITreeView::recalculateItemHeight()
}
void CGUITreeView::updateScrollBarSize(s32 size)
{
if ( size != ScrollBarSize )
{
ScrollBarSize = size;
if ( ScrollBarV )
{
core::recti r(RelativeRect.getWidth() - ScrollBarSize, 0,
RelativeRect.getWidth(), RelativeRect.getHeight() - ScrollBarSize);
ScrollBarV->setRelativePosition(r);
}
if ( ScrollBarH )
{
core::recti r(0, RelativeRect.getHeight() - ScrollBarSize,
RelativeRect.getWidth() - ScrollBarSize, RelativeRect.getHeight());
ScrollBarH->setRelativePosition(r);
}
}
}
//! called if an event happened.
bool CGUITreeView::OnEvent( const SEvent &event )
{
@ -829,9 +852,11 @@ void CGUITreeView::draw()
return;
}
IGUISkin* skin = Environment->getSkin();
updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE));
recalculateItemHeight(); // if the font changed
IGUISkin* skin = Environment->getSkin();
irr::video::IVideoDriver* driver = Environment->getVideoDriver();
core::rect<s32>* clipRect = 0;
@ -876,9 +901,9 @@ void CGUITreeView::draw()
clientClip.LowerRightCorner.Y -= 1;
if ( ScrollBarV )
clientClip.LowerRightCorner.X -= skin->getSize( EGDS_SCROLLBAR_SIZE );
clientClip.LowerRightCorner.X -= ScrollBarSize;
if ( ScrollBarH )
clientClip.LowerRightCorner.Y -= skin->getSize( EGDS_SCROLLBAR_SIZE );
clientClip.LowerRightCorner.Y -= ScrollBarSize;
if( clipRect )
{
@ -886,7 +911,7 @@ void CGUITreeView::draw()
}
frameRect = AbsoluteRect;
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize( EGDS_SCROLLBAR_SIZE );
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - ScrollBarSize;
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
if ( ScrollBarV )

View File

@ -320,6 +320,9 @@ namespace gui
//! calculates the heigth of an node and of all visible nodes.
void recalculateItemHeight();
//! Resize scrollbars when their size in the skin has changed
void updateScrollBarSize(s32 size);
//! executes an mouse action (like selectNew of CGUIListBox)
void mouseAction( s32 xpos, s32 ypos, bool onlyHover = false );
@ -329,6 +332,7 @@ namespace gui
s32 IndentWidth;
s32 TotalItemHeight;
s32 TotalItemWidth;
s32 ScrollBarSize;
IGUIFont* Font;
gui::IGUIFont* OverrideFont;
IGUIFont* IconFont;

View File

@ -951,75 +951,63 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
// not yet 32bit
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted, bool calculateTangents) const
{
using namespace video;
if (!mesh)
return 0;
// copy mesh and fill data into SMeshBufferTangents
SMesh* clone = new SMesh();
const u32 meshBufferCount = mesh->getMeshBufferCount();
for (u32 b=0; b<meshBufferCount; ++b)
{
const IMeshBuffer* const original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount();
const u16* idx = original->getIndices();
SMeshBufferTangents* buffer = new SMeshBufferTangents();
// copy material
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertexTangents, int> vertMap;
int vertLocation;
// copy indices
const u32 idxCnt = original->getIndexCount();
const u16* indices = original->getIndices();
buffer->Indices.reallocate(idxCnt);
for (u32 i=0; i < idxCnt; ++i)
buffer->Indices.push_back(indices[i]);
// copy vertices
const u32 vtxCnt = original->getVertexCount();
buffer->Vertices.reallocate(vtxCnt);
const video::E_VERTEX_TYPE vType = original->getVertexType();
video::S3DVertexTangents vNew;
for (u32 i=0; i<idxCnt; ++i)
const E_VERTEX_TYPE vType = original->getVertexType();
switch(vType)
{
switch(vType)
case video::EVT_STANDARD:
{
case video::EVT_STANDARD:
{
const video::S3DVertex* v =
(const video::S3DVertex*)original->getVertices();
vNew = video::S3DVertexTangents(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
}
break;
case video::EVT_2TCOORDS:
{
const video::S3DVertex2TCoords* v =
(const video::S3DVertex2TCoords*)original->getVertices();
vNew = video::S3DVertexTangents(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
}
break;
case video::EVT_TANGENTS:
{
const video::S3DVertexTangents* v =
(const video::S3DVertexTangents*)original->getVertices();
vNew = v[idx[i]];
}
break;
}
core::map<video::S3DVertexTangents, int>::Node* n = vertMap.find(vNew);
if (n)
{
vertLocation = n->getValue();
}
else
{
vertLocation = buffer->Vertices.size();
buffer->Vertices.push_back(vNew);
vertMap.insert(vNew, vertLocation);
}
const S3DVertex* v = (const S3DVertex*)original->getVertices();
// create new indices
buffer->Indices.push_back(vertLocation);
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back( S3DVertexTangents(
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
}
break;
case video::EVT_2TCOORDS:
{
const S3DVertex2TCoords* v =(const S3DVertex2TCoords*)original->getVertices();
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back( S3DVertexTangents(
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
}
break;
case video::EVT_TANGENTS:
{
const S3DVertexTangents* v =(const S3DVertexTangents*)original->getVertices();
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back(v[i]);
}
break;
}
buffer->recalculateBoundingBox();
@ -1347,11 +1335,12 @@ donehere:
free(accel);
}
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoords vertices.
// not yet 32bit
IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
{
using namespace video;
if (!mesh)
return 0;
@ -1363,63 +1352,50 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
for (u32 b=0; b<meshBufferCount; ++b)
{
const IMeshBuffer* const original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount();
const u16* idx = original->getIndices();
SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertex2TCoords, int> vertMap;
int vertLocation;
// copy material
buffer->Material = original->getMaterial();
// copy indices
const u32 idxCnt = original->getIndexCount();
const u16* indices = original->getIndices();
buffer->Indices.reallocate(idxCnt);
for (u32 i=0; i < idxCnt; ++i)
buffer->Indices.push_back(indices[i]);
// copy vertices
const u32 vtxCnt = original->getVertexCount();
buffer->Vertices.reallocate(vtxCnt);
const video::E_VERTEX_TYPE vType = original->getVertexType();
video::S3DVertex2TCoords vNew;
for (u32 i=0; i<idxCnt; ++i)
switch(vType)
{
switch(vType)
case video::EVT_STANDARD:
{
case video::EVT_STANDARD:
{
const video::S3DVertex* v =
(const video::S3DVertex*)original->getVertices();
vNew = video::S3DVertex2TCoords(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
}
break;
case video::EVT_2TCOORDS:
{
const video::S3DVertex2TCoords* v =
(const video::S3DVertex2TCoords*)original->getVertices();
vNew = v[idx[i]];
}
break;
case video::EVT_TANGENTS:
{
const video::S3DVertexTangents* v =
(const video::S3DVertexTangents*)original->getVertices();
vNew = video::S3DVertex2TCoords(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
}
break;
}
core::map<video::S3DVertex2TCoords, int>::Node* n = vertMap.find(vNew);
if (n)
{
vertLocation = n->getValue();
}
else
{
vertLocation = buffer->Vertices.size();
buffer->Vertices.push_back(vNew);
vertMap.insert(vNew, vertLocation);
}
const S3DVertex* v = (const S3DVertex*)original->getVertices();
// create new indices
buffer->Indices.push_back(vertLocation);
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back( video::S3DVertex2TCoords(
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords, v[i].TCoords));
}
break;
case video::EVT_2TCOORDS:
{
const S3DVertex2TCoords* v =(const S3DVertex2TCoords*)original->getVertices();
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back(v[i]);
}
break;
case video::EVT_TANGENTS:
{
const S3DVertexTangents* v =(const S3DVertexTangents*)original->getVertices();
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back( S3DVertex2TCoords(
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords, v[i].TCoords) );
}
break;
}
buffer->recalculateBoundingBox();
@ -1437,6 +1413,8 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
// not yet 32bit
IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
{
using namespace video;
if (!mesh)
return 0;
@ -1446,64 +1424,54 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
for (u32 b=0; b<meshBufferCount; ++b)
{
IMeshBuffer* original = mesh->getMeshBuffer(b);
const u32 idxCnt = original->getIndexCount();
const u16* idx = original->getIndices();
const IMeshBuffer* const original = mesh->getMeshBuffer(b);
SMeshBuffer* buffer = new SMeshBuffer();
buffer->Material = original->getMaterial();
buffer->Vertices.reallocate(idxCnt);
buffer->Indices.reallocate(idxCnt);
core::map<video::S3DVertex, int> vertMap;
int vertLocation;
// copy material
buffer->Material = original->getMaterial();
// copy indices
const u32 idxCnt = original->getIndexCount();
const u16* indices = original->getIndices();
buffer->Indices.reallocate(idxCnt);
for (u32 i=0; i < idxCnt; ++i)
buffer->Indices.push_back(indices[i]);
// copy vertices
const video::E_VERTEX_TYPE vType = original->getVertexType();
video::S3DVertex vNew;
for (u32 i=0; i<idxCnt; ++i)
{
switch(vType)
{
case video::EVT_STANDARD:
{
video::S3DVertex* v =
(video::S3DVertex*)original->getVertices();
vNew = v[idx[i]];
}
break;
case video::EVT_2TCOORDS:
{
video::S3DVertex2TCoords* v =
(video::S3DVertex2TCoords*)original->getVertices();
vNew = video::S3DVertex(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
}
break;
case video::EVT_TANGENTS:
{
video::S3DVertexTangents* v =
(video::S3DVertexTangents*)original->getVertices();
vNew = video::S3DVertex(
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
}
break;
}
core::map<video::S3DVertex, int>::Node* n = vertMap.find(vNew);
if (n)
{
vertLocation = n->getValue();
}
else
{
vertLocation = buffer->Vertices.size();
buffer->Vertices.push_back(vNew);
vertMap.insert(vNew, vertLocation);
}
const u32 vtxCnt = original->getVertexCount();
buffer->Vertices.reallocate(vtxCnt);
// create new indices
buffer->Indices.push_back(vertLocation);
const video::E_VERTEX_TYPE vType = original->getVertexType();
switch(vType)
{
case video::EVT_STANDARD:
{
const S3DVertex* v = (const S3DVertex*)original->getVertices();
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back( v[i] );
}
break;
case video::EVT_2TCOORDS:
{
const S3DVertex2TCoords* v =(const S3DVertex2TCoords*)original->getVertices();
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back( S3DVertex(
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
}
break;
case video::EVT_TANGENTS:
{
const S3DVertexTangents* v =(const S3DVertexTangents*)original->getVertices();
for (u32 i=0; i < vtxCnt; ++i)
buffer->Vertices.push_back( S3DVertex(
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
}
break;
}
buffer->recalculateBoundingBox();
// add new buffer
clone->addMeshBuffer(buffer);

View File

@ -2087,6 +2087,15 @@ void CNullDriver::setMaterialRendererName(s32 idx, const char* name)
MaterialRenderers[idx].Name = name;
}
void CNullDriver::swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames)
{
if ( idx1 < MaterialRenderers.size() && idx2 < MaterialRenderers.size() )
{
irr::core::swap(MaterialRenderers[idx1].Renderer, MaterialRenderers[idx2].Renderer);
if ( swapNames )
irr::core::swap(MaterialRenderers[idx1].Name, MaterialRenderers[idx2].Name);
}
}
//! Creates material attributes list from a material, usable for serialization and more.
io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMaterial& material,

View File

@ -612,6 +612,9 @@ namespace video
//! Sets the name of a material renderer.
virtual void setMaterialRendererName(s32 idx, const char* name) _IRR_OVERRIDE_;
//! Swap the material renderers used for certain id's
virtual void swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames) _IRR_OVERRIDE_;
//! Creates material attributes list from a material, usable for serialization and more.
virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material,
io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;

View File

@ -571,7 +571,7 @@ public:
//! Compare material to current cache and update it when there are differences
// Some material renderers do change the cache beyond the original material settings
// This correct the material to represent the current cache state again.
// This corrects the material to represent the current cache state again.
void correctCacheMaterial(irr::video::SMaterial& material)
{
// Fix textures which got removed

View File

@ -324,9 +324,10 @@ bool CPLYMeshFileLoader::readVertex(const SPLYElement &Element, scene::CDynamicM
vert.Normal.Y = getFloat(t);
result=true;
}
else if (Element.Properties[i].Name == "u")
// there isn't a single convention for the UV, some software like Blender or Assimp uses "st" instead of "uv"
else if (Element.Properties[i].Name == "u" || Element.Properties[i].Name == "s")
vert.TCoords.X = getFloat(t);
else if (Element.Properties[i].Name == "v")
else if (Element.Properties[i].Name == "v" || Element.Properties[i].Name == "t")
vert.TCoords.Y = getFloat(t);
else if (Element.Properties[i].Name == "red")
{

View File

@ -39,11 +39,21 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
os::Printer::log("Writing mesh", file->getFileName());
// write PLY header
core::stringc header =
"ply\n"
"format ascii 1.0\n"
"comment Irrlicht Engine ";
// write PLY header
core::stringc header = "ply\n";
if (flags & scene::EMWF_WRITE_BINARY)
{
#ifdef __BIG_ENDIAN__
header += "format binary_big_endian 1.0\n";
#else
header += "format binary_little_endian 1.0\n";
#endif
}
else
header += "format ascii 1.0\n";
header += "comment Irrlicht Engine ";
header += IRRLICHT_SDK_VERSION;
// get vertex and triangle counts
@ -66,16 +76,12 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
"property float z\n"
"property float nx\n"
"property float ny\n"
"property float nz\n";
// todo: writer flags for extended (r,g,b,u,v) and non-standard (alpha,u1,uv,tx,ty,tz) properties
// "property uchar red\n"
// "property uchar green\n"
// "property uchar blue\n"
// "property uchar alpha\n"
// "property float u\n"
// "property float v\n";
// "property float u1\n
// "property float v1\n"
"property float nz\n"
"property float s\n"
"property float t\n"
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n";
// "property float tx\n"
// "property float ty\n"
// "property float tz\n"
@ -97,38 +103,61 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
for (u32 i=0; i < mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
const scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
u32 vertexSize = 0;
switch(mb->getVertexType())
{
case video::EVT_STANDARD:
vertexSize = sizeof(video::S3DVertex);
break;
case video::EVT_2TCOORDS:
vertexSize = sizeof(video::S3DVertex2TCoords);
break;
case video::EVT_TANGENTS:
vertexSize = sizeof(video::S3DVertexTangents);
break;
}
u8 *vertices = (u8*)mb->getVertices() ;
for (u32 j=0; j < mb->getVertexCount(); ++j)
{
const core::vector3df& pos = mb->getPosition(j);
const core::vector3df& n = mb->getNormal(j);
// const core::vector2df& tc = mb->getTCoords(j);
u8 *buf = vertices + j * vertexSize;
const video::S3DVertex* vertex = ( (video::S3DVertex*)buf );
const core::vector3df& pos = vertex->Pos;
const core::vector3df& n = vertex->Normal;
const core::vector2df& uv = vertex->TCoords;
const video::SColor& color = vertex->Color;
u8 *buf = (u8*)mb->getVertices();
switch(mb->getVertexType())
if (flags & scene::EMWF_WRITE_BINARY)
{
case video::EVT_STANDARD:
buf += sizeof(video::S3DVertex)*j;
break;
case video::EVT_2TCOORDS:
buf += sizeof(video::S3DVertex2TCoords)*j;
break;
case video::EVT_TANGENTS:
buf += sizeof(video::S3DVertexTangents)*j;
break;
// Y and Z are flipped
file->write(&pos.X, 4);
file->write(&pos.Z, 4);
file->write(&pos.Y, 4);
file->write(&n.X, 4);
file->write(&n.Z, 4);
file->write(&n.Y, 4);
file->write(&uv, 8);
const u32 r = color.getRed(), g = color.getGreen(), b = color.getBlue();
file->write(&r, 1);
file->write(&g, 1);
file->write(&b, 1);
}
// video::SColor &col = ( (video::S3DVertex*)buf )->Color;
else
{
// x y z nx ny nz u v red green blue [u1 v1 | tx ty tz]\n
snprintf_irr(outLine, 1024,
"%f %f %f %f %f %f %f %f %d %d %d\n",// %u %u %u %u %f %f\n",
pos.X, pos.Z, pos.Y, // Y and Z are flipped
n.X, n.Z, n.Y,
uv.X, uv.Y,
color.getRed(), color.getGreen(), color.getBlue());
// x y z nx ny nz red green blue alpha u v [u1 v1 | tx ty tz]\n
snprintf_irr(outLine, 1024,
"%f %f %f %f %f %f\n",// %u %u %u %u %f %f\n",
pos.X, pos.Z, pos.Y, // Y and Z are flipped
n.X, n.Z, n.Y);
/*col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha(),
tc.X, tc.Y);*/
// write the line
file->write(outLine, strlen(outLine));
file->write(outLine, strlen(outLine));
}
}
}
@ -136,6 +165,7 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
u32 StartOffset = 0;
// write triangles
const unsigned char nbIndicesParFace = 3;
for (u32 i=0; i < mesh->getMeshBufferCount(); ++i)
{
scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
@ -155,15 +185,24 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
break;
case video::EIT_32BIT:
a += ((u32*)mb->getIndices()) [j+0];
c += ((u32*)mb->getIndices()) [j+0];
b += ((u32*)mb->getIndices()) [j+0];
c += ((u32*)mb->getIndices()) [j+1];
b += ((u32*)mb->getIndices()) [j+2];
break;
}
// count a b c\n
snprintf_irr(outLine, 1024, "3 %u %u %u\n", a, b, c);
// write the line
file->write(outLine, strlen(outLine));
if (flags & scene::EMWF_WRITE_BINARY)
{
file->write(&nbIndicesParFace, 1);
file->write(&a, 4);
file->write(&b, 4);
file->write(&c, 4);
}
else
{
// count a b c\n
snprintf_irr(outLine, 1024, "3 %u %u %u\n", a, b, c);
file->write(outLine, strlen(outLine));
}
}
// increment offset

View File

@ -54,7 +54,7 @@ bool CSTLMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
os::Printer::log("Writing mesh", file->getFileName());
if (flags & scene::EMWF_WRITE_COMPRESSED)
if (flags & (scene::EMWF_WRITE_BINARY|scene::EMWF_WRITE_COMPRESSED) )
return writeMeshBinary(file, mesh, flags);
else
return writeMeshASCII(file, mesh, flags);

View File

@ -38,6 +38,7 @@ namespace scene
TerrainData(patchSize, maxLOD, position, rotation, scale), RenderBuffer(0),
VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false),
OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(true),
FixedBorderLOD(-1),
CameraMovementDelta(10.0f), CameraRotationDelta(1.0f),CameraFOVDelta(0.1f),
TCoordScale1(1.0f), TCoordScale2(1.0f), SmoothFactor(0), FileSystem(fs)
{
@ -640,7 +641,18 @@ namespace scene
{
const f32 distance = cameraPosition.getDistanceFromSQ(TerrainData.Patches[j].Center);
if ( FixedBorderLOD >= 0 )
{
TerrainData.Patches[j].CurrentLOD = FixedBorderLOD;
if (j < TerrainData.PatchCount
|| j >= (count - TerrainData.PatchCount)
|| (j % TerrainData.PatchCount) == 0
|| (j % TerrainData.PatchCount) == TerrainData.PatchCount-1)
continue;
}
TerrainData.Patches[j].CurrentLOD = 0;
for (s32 i = TerrainData.MaxLOD - 1; i>0; --i)
{
if (distance >= TerrainData.LODDistanceThreshold[i])

View File

@ -202,6 +202,12 @@ namespace scene
//! Scales the two textures
virtual void scaleTexture(f32 scale = 1.0f, f32 scale2 = 0.0f) _IRR_OVERRIDE_;
//! Force node to use a fixed LOD level at the borders of the terrain.
virtual void setFixedBorderLOD(irr::s32 borderLOD) _IRR_OVERRIDE_
{
FixedBorderLOD = borderLOD;
}
//! Returns type of the scene node
virtual ESCENE_NODE_TYPE getType() const _IRR_OVERRIDE_ {return ESNT_TERRAIN;}
@ -303,6 +309,7 @@ namespace scene
bool OverrideDistanceThreshold;
bool UseDefaultRotationPivot;
bool ForceRecalculation;
s32 FixedBorderLOD;
core::vector3df OldCameraPosition;
core::vector3df OldCameraRotation;

File diff suppressed because it is too large Load Diff