1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-27 17:28:41 +00:00

Merge remote-tracking branch 'upstream/master' into Visuals-Vol-2

This commit is contained in:
Gefüllte Taubenbrust 2024-11-17 12:02:30 +01:00
commit 00ef9b14d0
1043 changed files with 44800 additions and 28934 deletions

View file

@ -36,6 +36,27 @@ We aim to support these platforms:
This doesn't mean other platforms don't work or won't be supported, if you find something that doesn't work contributions are welcome.
Compatibility matrix
--------------------
Driver (rows) vs Device (columns)
| | SDL [1] | Linux [2] | OSX [3] | Win32 [4] |
|---------------------------|----------|----------------|------------------|-----------------|
| OpenGL 1.2 (to 2.1) | Works | Works (GLX) | Works (NSOpenGL) | Works (WGL) |
| OpenGL 3.2+ | Works | Testing (GLX) | Not implemented | Testing (WGL) |
| OpenGL ES 2.x | Works | Untested (EGL) | Not implemented | Untested (EGL) |
| WebGL 1 | Untested | Untested (EGL) | Not implemented | Not implemented |
| Null (no graphics output) | Works | Works | Works | Works |
Notes:
* [1] `CIrrDeviceSDL`: supports Android, Linux, macOS, Windows
* [2] `CIrrDeviceLinux`: supports Linux
* [3] `CIrrDeviceOSX`: supports macOS
* [4] `CIrrDeviceWin32`: supports Windows
License
-------

View file

@ -4,8 +4,6 @@
#pragma once
#include "irrTypes.h"
namespace irr
{
namespace video

View file

@ -4,7 +4,6 @@
#pragma once
#include "aabbox3d.h"
#include "IMesh.h"
namespace irr

View file

@ -7,9 +7,6 @@
#include "IReferenceCounted.h"
#include "EAttributes.h"
// not needed here but I can't be bothered to clean the transitive includes up.
#include "quaternion.h"
namespace irr
{
namespace video

View file

@ -18,7 +18,7 @@ enum EEVENT_TYPE
to mouse or keyboard events. When a GUI element receives an event it will either
process it and return true, or pass the event to its parent. If an event is not absorbed
before it reaches the root element then it will then be passed to the user receiver. */
EET_GUI_EVENT = 0,
EET_GUI_EVENT = 1,
//! A mouse input event.
/** Mouse events are created by the device and passed to IrrlichtDevice::postEventFromUser
@ -332,6 +332,9 @@ struct SEvent
//! True if ctrl was also pressed
bool Control : 1;
//! Is this a simulated mouse event generated by the engine itself?
bool Simulated : 1;
//! A bitmap of button states. You can use isButtonPressed() to determine
//! if a button is pressed or not.
u32 ButtonStates;
@ -347,9 +350,6 @@ struct SEvent
//! Type of mouse event
EMOUSE_INPUT_EVENT Event;
//! Is this a simulated mouse event generated by Minetest itself?
bool Simulated;
};
//! Any kind of keyboard event.
@ -543,8 +543,9 @@ struct SEvent
};
SEvent() {
// would be left uninitialized in many places otherwise
MouseInput.Simulated = false;
EventType = static_cast<EEVENT_TYPE>(0);
// zero the biggest union member we have, which clears all others too
memset(&JoystickEvent, 0, sizeof(JoystickEvent));
}
};

View file

@ -10,10 +10,8 @@
#include "IEventReceiver.h"
#include "EGUIElementTypes.h"
#include "EGUIAlignment.h"
#include "IAttributes.h"
#include "IGUIEnvironment.h"
#include <cassert>
#include <algorithm>
#include <list>
#include <vector>

View file

@ -7,7 +7,7 @@
#include "IReferenceCounted.h"
#include "IGUISkin.h"
#include "rect.h"
#include "EFocusFlags.h"
#include "EFocusFlags.h" // IWYU pragma: export
#include "IEventReceiver.h"
#include "path.h"

View file

@ -3,7 +3,7 @@
#pragma once
#include "IGUIElement.h"
#include "IReferenceCounted.h"
#include "rect.h"
#include "irrTypes.h"

View file

@ -6,7 +6,6 @@
#include "IGUIElement.h"
#include "SColor.h"
#include "IGUISkin.h"
namespace irr
{

View file

@ -328,6 +328,8 @@ public:
return 32;
case ECF_D16:
return 16;
case ECF_D24:
return 32;
case ECF_D32:
return 32;
case ECF_D24S8:
@ -378,6 +380,7 @@ public:
{
switch (format) {
case ECF_D16:
case ECF_D24:
case ECF_D32:
case ECF_D24S8:
return true;

View file

@ -6,9 +6,7 @@
#include "IReferenceCounted.h"
#include "IImage.h"
#include "ITexture.h"
#include "path.h"
#include "irrArray.h"
namespace irr
{

View file

@ -5,8 +5,7 @@
#pragma once
#include "IReferenceCounted.h"
#include "irrString.h"
#include "coreutil.h"
#include "path.h"
namespace irr
{

View file

@ -5,7 +5,6 @@
#pragma once
#include "IReferenceCounted.h"
#include "irrArray.h"
#include "EHardwareBufferFlags.h"
#include "EPrimitiveTypes.h"
#include "SVertexIndex.h"

View file

@ -5,7 +5,6 @@
#pragma once
#include "SMaterial.h"
#include "S3DVertex.h"
namespace irr
{

View file

@ -7,7 +7,6 @@
#include "IReferenceCounted.h"
#include "vector3d.h"
#include "aabbox3d.h"
#include "matrix4.h"
#include "IAnimatedMesh.h"
#include "IMeshBuffer.h"
#include "SVertexManipulator.h"

View file

@ -5,8 +5,8 @@
#pragma once
#include "IReferenceCounted.h"
#include "coreutil.h"
#include "EReadFileType.h"
#include "path.h"
namespace irr
{

View file

@ -6,13 +6,11 @@
#include "IReferenceCounted.h"
#include "irrArray.h"
#include "irrString.h"
#include "path.h"
#include "vector3d.h"
#include "dimension2d.h"
#include "SColor.h"
#include "ESceneNodeTypes.h"
#include "SceneParameters.h"
#include "SceneParameters.h" // IWYU pragma: export
#include "ISkinnedMesh.h"
namespace irr

View file

@ -9,14 +9,13 @@
#include "ECullingTypes.h"
#include "EDebugSceneTypes.h"
#include "SMaterial.h"
#include "irrString.h"
#include "irrArray.h"
#include "aabbox3d.h"
#include "matrix4.h"
#include "IAttributes.h"
#include <list>
#include <optional>
#include <string>
namespace irr
{

View file

@ -5,11 +5,12 @@
#pragma once
#include "irrArray.h"
#include "IBoneSceneNode.h"
#include "IAnimatedMesh.h"
#include "SSkinMeshBuffer.h"
#include "quaternion.h"
#include <optional>
#include <string>
namespace irr
{

View file

@ -5,11 +5,10 @@
#pragma once
#include "IReferenceCounted.h"
#include "IImage.h"
#include "SColor.h"
#include "dimension2d.h"
#include "EDriverTypes.h"
#include "path.h"
#include "matrix4.h"
namespace irr
{
@ -75,9 +74,7 @@ enum E_TEXTURE_CREATION_FLAG
//! Allow the driver to keep a copy of the texture in memory
/** Enabling this makes calls to ITexture::lock a lot faster, but costs main memory.
Currently only used in combination with OpenGL drivers.
NOTE: Disabling this does not yet work correctly with alpha-textures.
So the default is on for now (but might change with Irrlicht 1.9 if we get the alpha-troubles fixed).
This is disabled by default.
*/
ETCF_ALLOW_MEMORY_COPY = 0x00000080,
@ -185,7 +182,7 @@ public:
//! Lock function.
/** Locks the Texture and returns a pointer to access the
pixels. After lock() has been called and all operations on the pixels
are done, you must call unlock().
are done, you must call unlock(). Afterwards the pointer becomes invalid.
Locks are not accumulating, hence one unlock will do for an arbitrary
number of previous locks. You should avoid locking different levels without
unlocking in between, though, because only the last level locked will be

View file

@ -5,7 +5,6 @@
#pragma once
#include "IReferenceCounted.h"
#include "irrArray.h"
#include "EHardwareBufferFlags.h"
#include "S3DVertex.h"

View file

@ -6,6 +6,7 @@
#include "rect.h"
#include "SColor.h"
#include "IImage.h"
#include "ITexture.h"
#include "irrArray.h"
#include "matrix4.h"

View file

@ -193,6 +193,11 @@ public:
/** If this returns false, you should not do any rendering. */
virtual bool isWindowVisible() const { return true; };
//! Checks if the Irrlicht device supports touch events.
/** Intentionally doesn't check whether a touch input device is available
or similar. */
virtual bool supportsTouchEvents() const { return false; }
//! Get the current color format of the window
/** \return Color format of the window. */
virtual video::ECOLOR_FORMAT getColorFormat() const = 0;

View file

@ -77,6 +77,9 @@ enum ECOLOR_FORMAT
//! 16 bit format using 16 bits for depth.
ECF_D16,
//! 32 bit(?) format using 24 bits for depth.
ECF_D24,
//! 32 bit format using 32 bits for depth.
ECF_D32,
@ -104,6 +107,7 @@ const c8 *const ColorFormatNames[ECF_UNKNOWN + 2] = {
"R16",
"R16G16",
"D16",
"D24",
"D32",
"D24S8",
"UNKNOWN",

View file

@ -63,12 +63,6 @@ struct SExposedVideoData
void *Window;
};
struct SOpenGLFB
{
//! The EGLNativeWindowType object.
void *Window;
};
struct SOGLESAndroid
{
//! The ANativeWindow object.
@ -80,7 +74,6 @@ struct SExposedVideoData
SOpenGLWin32 OpenGLWin32;
SOpenGLLinux OpenGLLinux;
SOpenGLOSX OpenGLOSX;
SOpenGLFB OpenGLFB;
SOGLESAndroid OGLESAndroid;
};
};

View file

@ -7,8 +7,8 @@
#include "SColor.h"
#include "matrix4.h"
#include "irrMath.h"
#include "EMaterialTypes.h"
#include "EMaterialProps.h"
#include "EMaterialTypes.h" // IWYU pragma: export
#include "EMaterialProps.h" // IWYU pragma: export
#include "SMaterialLayer.h"
#include "IrrCompileConfig.h" // for IRRLICHT_API

View file

@ -3,4 +3,4 @@
// For conditions of distribution and use, see copyright notice in irrlicht.h
// replaced by template
#include "CMeshBuffer.h"
#include "CMeshBuffer.h" // IWYU pragma: export

View file

@ -8,7 +8,6 @@
#include "CVertexBuffer.h"
#include "CIndexBuffer.h"
#include "S3DVertex.h"
#include "irrArray.h"
namespace irr
{

View file

@ -4,8 +4,6 @@
#pragma once
#include "irrTypes.h"
namespace irr
{
namespace video

View file

@ -4,9 +4,7 @@
#pragma once
#include "matrix4.h"
#include "S3DVertex.h"
#include "SColor.h"
#include "vector3d.h"
namespace irr
{

View file

@ -4,7 +4,6 @@
#pragma once
#include "irrString.h"
#include "path.h"
namespace irr

View file

@ -4,8 +4,10 @@
#pragma once
#include "irrMath.h"
#include "irrString.h"
#include "irrTypes.h"
#include <cfloat>
#include <climits>
#include <cmath>
namespace irr
{
@ -305,7 +307,7 @@ inline const char *fast_atof_move(const char *in, f32 &result)
if (numDecimals < IRR_ATOF_TABLE_SIZE) {
value += decimal * fast_atof_table[numDecimals];
} else {
value += decimal * (f32)pow(10.f, -(float)numDecimals);
value += decimal * std::pow(10.f, -(float)numDecimals);
}
in = afterDecimal;
}
@ -316,7 +318,7 @@ inline const char *fast_atof_move(const char *in, f32 &result)
// strtol10() will deal with both + and - signs,
// but calculate as f32 to prevent overflow at FLT_MAX
// Using pow with float cast instead of powf as otherwise accuracy decreases.
value *= (f32)pow(10.f, (f32)strtol10(in, &in));
value *= std::pow(10.f, (f32)strtol10(in, &in));
}
result = negative ? -value : value;

View file

@ -155,7 +155,7 @@ public:
}
//! Assignment operator
const array<T> &operator=(const array<T> &other)
array<T> &operator=(const array<T> &other)
{
if (this == &other)
return *this;

View file

@ -28,221 +28,14 @@
#pragma once
#include "aabbox3d.h"
#include "CMeshBuffer.h"
#include "coreutil.h"
#include "dimension2d.h"
#include "ECullingTypes.h"
#include "EDebugSceneTypes.h"
#include "EDriverFeatures.h"
#include "EDriverTypes.h"
#include "EGUIAlignment.h"
#include "EGUIElementTypes.h"
#include "EHardwareBufferFlags.h"
#include "EMaterialProps.h"
#include "EMaterialTypes.h"
#include "ESceneNodeTypes.h"
#include "fast_atof.h"
#include "IAnimatedMesh.h"
#include "IAnimatedMeshSceneNode.h"
#include "IAttributes.h"
#include "IBillboardSceneNode.h"
#include "IBoneSceneNode.h"
#include "ICameraSceneNode.h"
#include "IContextManager.h"
#include "ICursorControl.h"
#include "IDummyTransformationSceneNode.h"
#include "IEventReceiver.h"
#include "IFileList.h"
#include "IFileSystem.h"
#include "IGPUProgrammingServices.h"
#include "IGUIButton.h"
#include "IGUICheckBox.h"
#include "IGUIComboBox.h"
#include "IGUIEditBox.h"
#include "IGUIElement.h"
#include "IGUIEnvironment.h"
#include "IGUIFileOpenDialog.h"
#include "IGUIFont.h"
#include "IGUIFontBitmap.h"
#include "IGUIImage.h"
#include "IGUIListBox.h"
#include "IGUIScrollBar.h"
#include "IGUISkin.h"
#include "IGUISpriteBank.h"
#include "IGUIStaticText.h"
#include "IGUITabControl.h"
#include "IGUIToolbar.h"
#include "IImage.h"
#include "IImageLoader.h"
#include "IImageWriter.h"
#include "IIndexBuffer.h"
#include "ILogger.h"
#include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h"
#include "IMesh.h"
#include "IMeshBuffer.h"
#include "IMeshCache.h"
#include "IMeshLoader.h"
#include "IMeshManipulator.h"
#include "IMeshSceneNode.h"
#include "IOSOperator.h"
#include "IReadFile.h"
#include "IReferenceCounted.h"
#include "irrArray.h"
#include "IRenderTarget.h"
#include "IrrlichtDevice.h"
#include "irrMath.h"
#include "irrString.h"
#include "dimension2d.h"
#include "EDriverTypes.h"
#include "IEventReceiver.h"
#include "irrTypes.h"
#include "path.h"
#include "ISceneCollisionManager.h"
#include "ISceneManager.h"
#include "ISceneNode.h"
#include "IShaderConstantSetCallBack.h"
#include "ISkinnedMesh.h"
#include "ITexture.h"
#include "ITimer.h"
#include "IVertexBuffer.h"
#include "IVideoDriver.h"
#include "IWriteFile.h"
#include "Keycodes.h"
#include "line2d.h"
#include "line3d.h"
#include "matrix4.h"
#include "plane3d.h"
#include "position2d.h"
#include "quaternion.h"
#include "rect.h"
#include "S3DVertex.h"
#include "SAnimatedMesh.h"
#include "SceneParameters.h"
#include "SColor.h"
#include "SExposedVideoData.h"
#include "SIrrCreationParameters.h"
#include "SMaterial.h"
#include "SMesh.h"
#include "SMeshBuffer.h"
#include "SSkinMeshBuffer.h"
#include "SVertexIndex.h"
#include "SViewFrustum.h"
#include "vector2d.h"
#include "vector3d.h"
#include "IrrCompileConfig.h" // for IRRLICHT_API and IRRCALLCONV
/*! \mainpage Irrlicht Engine 1.9 API documentation
*
* <div align="center"><img src="logobig.png" ></div>
*
* \section intro Introduction
*
* Welcome to the Irrlicht Engine API documentation.
* Here you'll find any information you'll need to develop applications with
* the Irrlicht Engine. If you are looking for a tutorial on how to start, you'll
* find some on the homepage of the Irrlicht Engine at
* <A HREF="http://irrlicht.sourceforge.net" >irrlicht.sourceforge.net</A>
* or inside the SDK in the examples directory.
*
* The Irrlicht Engine is intended to be an easy-to-use 3d engine, so
* this documentation is an important part of it. If you have any questions or
* suggestions, just send a email to the author of the engine, Nikolaus Gebhardt
* (niko (at) irrlicht3d.org).
*
*
* \section links Links
*
* <A HREF="namespaces.html">Namespaces</A>: A very good place to start reading
* the documentation.<BR>
* <A HREF="annotated.html">Class list</A>: List of all classes with descriptions.<BR>
* <A HREF="functions.html">Class members</A>: Good place to find forgotten features.<BR>
*
* \section irrexample Short example
*
* A simple application, starting up the engine, loading a Quake 2 animated
* model file and the corresponding texture, animating and displaying it
* in front of a blue background and placing a user controlable 3d camera
* would look like the following code. I think this example shows the usage
* of the engine quite well:
*
* \code
* #include <irrlicht.h>
* using namespace irr;
*
* int main()
* {
* // start up the engine
* IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
* core::dimension2d<u32>(640,480));
*
* video::IVideoDriver* driver = device->getVideoDriver();
* scene::ISceneManager* scenemgr = device->getSceneManager();
*
* device->setWindowCaption(L"Hello World!");
*
* // load and show quake2 .md2 model
* scene::ISceneNode* node = scenemgr->addAnimatedMeshSceneNode(
* scenemgr->getMesh("quake2model.md2"));
*
* // if everything worked, add a texture and disable lighting
* if (node)
* {
* node->setMaterialTexture(0, driver->getTexture("texture.bmp"));
* node->setMaterialFlag(video::EMF_LIGHTING, false);
* }
*
* // add a first person shooter style user controlled camera
* scenemgr->addCameraSceneNodeFPS();
*
* // draw everything
* while(device->run() && driver)
* {
* driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,0,0,255));
* scenemgr->drawAll();
* driver->endScene();
* }
*
* // delete device
* device->drop();
* return 0;
* }
* \endcode
*
* Irrlicht can load a lot of file formats automatically, see irr::scene::ISceneManager::getMesh()
* for a detailed list. So if you would like to replace the simple blue screen background by
* a cool Quake 3 Map, optimized by an octree, just insert this code
* somewhere before the while loop:
*
* \code
* // add .pk3 archive to the file system
* device->getFileSystem()->addZipFileArchive("quake3map.pk3");
*
* // load .bsp file and show it using an octree
* scenemgr->addOctreeSceneNode(
* scenemgr->getMesh("quake3map.bsp"));
* \endcode
*
* As you can see, the engine uses namespaces. Everything in the engine is
* placed into the namespace 'irr', but there are also 5 sub namespaces.
* You can find a list of all namespaces with descriptions at the
* <A HREF="namespaces.html"> namespaces page</A>.
* This is also a good place to start reading the documentation. If you
* don't want to write the namespace names all the time, just use all namespaces like
* this:
* \code
* using namespace core;
* using namespace scene;
* using namespace video;
* using namespace io;
* using namespace gui;
* \endcode
*
* There is a lot more the engine can do, but I hope this gave a short
* overview over the basic features of the engine. For more examples, please take
* a look into the examples directory of the SDK.
*/
#include "SIrrCreationParameters.h"
//! Everything in the Irrlicht Engine can be found in this namespace.
namespace irr
{
@ -314,5 +107,5 @@ namespace video
}
/*! \file irrlicht.h
\brief Main header file of the irrlicht, the only file needed to include.
\brief Main header file of the irrlicht, needed to create a device.
*/

View file

@ -6,7 +6,6 @@
#include <string>
#include <unordered_set>
#include "IrrCompileConfig.h" // for IRRLICHT_API
#include "irrTypes.h"
#include "IContextManager.h"
#include <KHR/khrplatform.h>

View file

@ -277,7 +277,8 @@ inline quaternion &quaternion::operator=(const matrix4 &m)
}
}
return normalize();
normalize();
return *this;
}
#endif

View file

@ -198,7 +198,7 @@ local consts = List();
-- Parse a whole header, extracting the data.
local function ParseHeader( path, into, apiRegex, defs, consts, nameSet, noNewNames )
defs:AddFormat( "\t// %s", path );
local f = assert( io.open( path, "r" ), "Could not open " .. path );
local f = assert( io.open( path, "r" ) );
for line in f:lines() do
-- Do not parse PFN typedefs; they're easily reconstructible.
local T, rawName, args = line:match( apiRegex );
@ -340,7 +340,7 @@ end
------------ Write files ------------
-- Write loader header
local f = io.open( sourceTreePath .. "/include/mt_opengl.h", "wb" );
local f = assert(io.open( sourceTreePath .. "/include/mt_opengl.h", "wb" ));
f:write[[
// This code was generated by scripts/BindingGenerator.lua
// Do not modify it, modify and run the generator instead.
@ -350,7 +350,6 @@ f:write[[
#include <string>
#include <unordered_set>
#include "IrrCompileConfig.h" // for IRRLICHT_API
#include "irrTypes.h"
#include "IContextManager.h"
#include <KHR/khrplatform.h>
@ -408,7 +407,7 @@ f:write( "IRRLICHT_API extern OpenGLProcedures GL;\n" );
f:close();
-- Write loader implementation
f = io.open( sourceTreePath .. "/src/mt_opengl_loader.cpp", "wb" );
f = assert(io.open( sourceTreePath .. "/src/mt_opengl_loader.cpp", "wb" ));
f:write[[
// This code was generated by scripts/BindingGenerator.lua
// Do not modify it, modify and run the generator instead.

View file

@ -10,6 +10,7 @@
#include "IVideoDriver.h"
#include "IFileSystem.h"
#include "coreutil.h"
#include "os.h"
#include <algorithm>

View file

@ -12,93 +12,6 @@ namespace irr
namespace video
{
//! converts a monochrome bitmap to A1R5G5B5 data
void CColorConverter::convert1BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, s32 linepad, bool flip)
{
if (!in || !out)
return;
if (flip)
out += width * height;
for (s32 y = 0; y < height; ++y) {
s32 shift = 7;
if (flip)
out -= width;
for (s32 x = 0; x < width; ++x) {
out[x] = *in >> shift & 0x01 ? (s16)0xffff : (s16)0x8000;
if ((--shift) < 0) { // 8 pixel done
shift = 7;
++in;
}
}
if (shift != 7) // width did not fill last byte
++in;
if (!flip)
out += width;
in += linepad;
}
}
//! converts a 4 bit palettized image to A1R5G5B5
void CColorConverter::convert4BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad, bool flip)
{
if (!in || !out || !palette)
return;
if (flip)
out += width * height;
for (s32 y = 0; y < height; ++y) {
s32 shift = 4;
if (flip)
out -= width;
for (s32 x = 0; x < width; ++x) {
out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)((*in >> shift) & 0xf)]);
if (shift == 0) {
shift = 4;
++in;
} else
shift = 0;
}
if (shift == 0) // odd width
++in;
if (!flip)
out += width;
in += linepad;
}
}
//! converts a 8 bit palettized image into A1R5G5B5
void CColorConverter::convert8BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad, bool flip)
{
if (!in || !out || !palette)
return;
if (flip)
out += width * height;
for (s32 y = 0; y < height; ++y) {
if (flip)
out -= width; // one line back
for (s32 x = 0; x < width; ++x) {
out[x] = X8R8G8B8toA1R5G5B5(palette[(u8)(*in)]);
++in;
}
if (!flip)
out += width;
in += linepad;
}
}
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
void CColorConverter::convert8BitTo24Bit(const u8 *in, u8 *out, s32 width, s32 height, const u8 *palette, s32 linepad, bool flip)
{

View file

@ -15,14 +15,6 @@ namespace video
class CColorConverter
{
public:
//! converts a monochrome bitmap to A1R5G5B5
static void convert1BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, s32 linepad = 0, bool flip = false);
//! converts a 4 bit palettized image to A1R5G5B5
static void convert4BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad = 0, bool flip = false);
//! converts a 8 bit palettized image to A1R5G5B5
static void convert8BitTo16Bit(const u8 *in, s16 *out, s32 width, s32 height, const s32 *palette, s32 linepad = 0, bool flip = false);
//! converts a 8 bit palettized or non palettized image (A8) into R8G8B8
static void convert8BitTo24Bit(const u8 *in, u8 *out, s32 width, s32 height, const u8 *palette, s32 linepad = 0, bool flip = false);

View file

@ -51,9 +51,6 @@ bool CEGLManager::initialize(const SIrrlichtCreationParameters &params, const SE
#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_)
EglWindow = (NativeWindowType)Data.OpenGLLinux.X11Window;
EglDisplay = eglGetDisplay((NativeDisplayType)Data.OpenGLLinux.X11Display);
#elif defined(_IRR_COMPILE_WITH_FB_DEVICE_)
EglWindow = (NativeWindowType)Data.OpenGLFB.Window;
EglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
#endif
// We must check if EGL display is valid.

View file

@ -7,12 +7,11 @@
#include "IWriteFile.h"
#include "CZipReader.h"
#include "CFileList.h"
#include "stdio.h"
#include "os.h"
#include "CReadFile.h"
#include "CMemoryFile.h"
#include "CLimitReadFile.h"
#include "CWriteFile.h"
#include "coreutil.h"
#include <list>
#if defined(__STRICT_ANSI__)

View file

@ -9,6 +9,7 @@
#include "IAnimatedMesh.h"
#include "IReadFile.h"
#include "irrTypes.h"
#include "irr_ptr.h"
#include "matrix4.h"
#include "path.h"
#include "quaternion.h"
@ -27,7 +28,6 @@
#include <utility>
#include <variant>
#include <vector>
#include <iostream>
namespace irr {
@ -341,40 +341,24 @@ bool SelfType::isALoadableFileExtension(
*/
IAnimatedMesh* SelfType::createMesh(io::IReadFile* file)
{
if (file->getSize() <= 0) {
return nullptr;
}
std::optional<tiniergltf::GlTF> model = tryParseGLTF(file);
if (!model.has_value()) {
return nullptr;
}
if (model->extensionsRequired) {
os::Printer::log("glTF loader",
"model requires extensions, but we support none", ELL_ERROR);
return nullptr;
}
if (!(model->buffers.has_value()
&& model->bufferViews.has_value()
&& model->accessors.has_value()
&& model->meshes.has_value()
&& model->nodes.has_value())) {
os::Printer::log("glTF loader", "missing required fields", ELL_ERROR);
return nullptr;
}
auto *mesh = new CSkinnedMesh();
MeshExtractor parser(std::move(model.value()), mesh);
const char *filename = file->getFileName().c_str();
try {
parser.load();
} catch (std::runtime_error &e) {
os::Printer::log("glTF loader", e.what(), ELL_ERROR);
mesh->drop();
return nullptr;
tiniergltf::GlTF model = parseGLTF(file);
irr_ptr<CSkinnedMesh> mesh(new CSkinnedMesh());
MeshExtractor extractor(std::move(model), mesh.get());
try {
extractor.load();
for (const auto &warning : extractor.getWarnings()) {
os::Printer::log(filename, warning.c_str(), ELL_WARNING);
}
return mesh.release();
} catch (const std::runtime_error &e) {
os::Printer::log("error converting gltf to irrlicht mesh", e.what(), ELL_ERROR);
}
} catch (const std::runtime_error &e) {
os::Printer::log("error parsing gltf", e.what(), ELL_ERROR);
}
if (model->images.has_value())
os::Printer::log("glTF loader", "embedded images are not supported", ELL_WARNING);
return mesh;
return nullptr;
}
static void transformVertices(std::vector<video::S3DVertex> &vertices, const core::matrix4 &transform)
@ -685,7 +669,7 @@ void SelfType::MeshExtractor::loadAnimation(const std::size_t animIdx)
const auto &sampler = anim.samplers.at(channel.sampler);
if (sampler.interpolation != tiniergltf::AnimationSampler::Interpolation::LINEAR)
throw std::runtime_error("unsupported interpolation");
throw std::runtime_error("unsupported interpolation, only linear interpolation is supported");
const auto inputAccessor = Accessor<f32>::make(m_gltf_model, sampler.input);
const auto n_frames = inputAccessor.getCount();
@ -730,20 +714,40 @@ void SelfType::MeshExtractor::loadAnimation(const std::size_t animIdx)
void SelfType::MeshExtractor::load()
{
loadNodes();
for (const auto &load_mesh : m_mesh_loaders) {
load_mesh();
if (m_gltf_model.extensionsRequired)
throw std::runtime_error("model requires extensions, but we support none");
if (!(m_gltf_model.buffers.has_value()
&& m_gltf_model.bufferViews.has_value()
&& m_gltf_model.accessors.has_value()
&& m_gltf_model.meshes.has_value()
&& m_gltf_model.nodes.has_value())) {
throw std::runtime_error("missing required fields");
}
loadSkins();
// Load the first animation, if there is one.
if (m_gltf_model.animations.has_value()) {
if (m_gltf_model.animations->size() > 1) {
os::Printer::log("glTF loader",
"multiple animations are not supported", ELL_WARNING);
if (m_gltf_model.images.has_value())
warn("embedded images are not supported");
try {
loadNodes();
for (const auto &load_mesh : m_mesh_loaders) {
load_mesh();
}
loadAnimation(0);
m_irr_model->setAnimationSpeed(1);
loadSkins();
// Load the first animation, if there is one.
if (m_gltf_model.animations.has_value()) {
if (m_gltf_model.animations->size() > 1)
warn("multiple animations are not supported");
loadAnimation(0);
m_irr_model->setAnimationSpeed(1);
}
} catch (const std::out_of_range &e) {
throw std::runtime_error(e.what());
} catch (const std::bad_optional_access &e) {
throw std::runtime_error(e.what());
}
m_irr_model->finalize();
}
@ -905,15 +909,18 @@ void SelfType::MeshExtractor::copyTCoords(
/**
* This is where the actual model's GLTF file is loaded and parsed by tiniergltf.
*/
std::optional<tiniergltf::GlTF> SelfType::tryParseGLTF(io::IReadFile* file)
tiniergltf::GlTF SelfType::parseGLTF(io::IReadFile* file)
{
const bool isGlb = core::hasFileExtension(file->getFileName(), "glb");
auto size = file->getSize();
if (size < 0) // this can happen if `ftell` fails
return std::nullopt;
throw std::runtime_error("error reading file");
if (size == 0)
throw std::runtime_error("file is empty");
std::unique_ptr<char[]> buf(new char[size + 1]);
if (file->read(buf.get(), size) != static_cast<std::size_t>(size))
return std::nullopt;
throw std::runtime_error("file ended prematurely");
// We probably don't need this, but add it just to be sure.
buf[size] = '\0';
try {
@ -921,12 +928,10 @@ std::optional<tiniergltf::GlTF> SelfType::tryParseGLTF(io::IReadFile* file)
return tiniergltf::readGlb(buf.get(), size);
else
return tiniergltf::readGlTF(buf.get(), size);
} catch (const std::runtime_error &e) {
os::Printer::log("glTF loader", e.what(), ELL_ERROR);
return std::nullopt;
} catch (const std::out_of_range &e) {
os::Printer::log("glTF loader", e.what(), ELL_ERROR);
return std::nullopt;
throw std::runtime_error(e.what());
} catch (const std::bad_optional_access &e) {
throw std::runtime_error(e.what());
}
}

View file

@ -118,6 +118,9 @@ private:
std::size_t getPrimitiveCount(const std::size_t meshIdx) const;
void load();
const std::vector<std::string> &getWarnings() {
return warnings;
}
private:
const tiniergltf::GlTF m_gltf_model;
@ -126,6 +129,11 @@ private:
std::vector<std::function<void()>> m_mesh_loaders;
std::vector<CSkinnedMesh::SJoint *> m_loaded_nodes;
std::vector<std::string> warnings;
void warn(const std::string &warning) {
warnings.push_back(warning);
}
void copyPositions(const std::size_t accessorIdx,
std::vector<video::S3DVertex>& vertices) const;
@ -152,7 +160,7 @@ private:
void loadAnimation(const std::size_t animIdx);
};
std::optional<tiniergltf::GlTF> tryParseGLTF(io::IReadFile *file);
tiniergltf::GlTF parseGLTF(io::IReadFile *file);
};
} // namespace scene

View file

@ -1,402 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CImageLoaderBMP.h"
#include "IReadFile.h"
#include "SColor.h"
#include "CColorConverter.h"
#include "CImage.h"
#include "os.h"
#include "irrString.h"
namespace irr
{
namespace video
{
//! constructor
CImageLoaderBMP::CImageLoaderBMP()
{
#ifdef _DEBUG
setDebugName("CImageLoaderBMP");
#endif
}
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CImageLoaderBMP::isALoadableFileExtension(const io::path &filename) const
{
return core::hasFileExtension(filename, "bmp");
}
//! returns true if the file maybe is able to be loaded by this class
bool CImageLoaderBMP::isALoadableFileFormat(io::IReadFile *file) const
{
u16 headerID;
file->read(&headerID, sizeof(u16));
#ifdef __BIG_ENDIAN__
headerID = os::Byteswap::byteswap(headerID);
#endif
return headerID == 0x4d42;
}
// UB-safe overflow check
static inline bool overflowCheck(const void *base, size_t offset, const void *end)
{
auto baseI = reinterpret_cast<uintptr_t>(base),
endI = reinterpret_cast<uintptr_t>(end);
return baseI > endI || offset >= (endI - baseI);
}
// check whether &p[0] to &p[_off - 1] can be accessed
#define CHECKP(_off) \
if ((_off) < 0 || overflowCheck(p, _off, pEnd)) \
goto exit
// same for d
#define CHECKD(_off) \
if ((_off) < 0 || overflowCheck(d, _off, destEnd)) \
goto exit
void CImageLoaderBMP::decompress8BitRLE(u8 *&bmpData, s32 size, s32 width, s32 height, s32 pitch) const
{
u8 *p = bmpData;
const u8 *pEnd = bmpData + size;
u8 *newBmp = new u8[(width + pitch) * height];
u8 *d = newBmp;
const u8 *destEnd = newBmp + (width + pitch) * height;
s32 line = 0;
while (p < pEnd && d < destEnd) {
if (*p == 0) {
++p;
CHECKP(1);
switch (*p) {
case 0: // end of line
++p;
++line;
d = newBmp + (line * (width + pitch));
break;
case 1: // end of bmp
goto exit;
case 2:
++p;
CHECKP(2);
d += (u8)*p;
++p; // delta
d += ((u8)*p) * (width + pitch);
++p;
break;
default: {
// absolute mode
s32 count = (u8)*p;
++p;
s32 readAdditional = ((2 - (count % 2)) % 2);
CHECKP(count);
CHECKD(count);
for (s32 i = 0; i < count; ++i) {
*d = *p;
++p;
++d;
}
CHECKP(readAdditional);
for (s32 i = 0; i < readAdditional; ++i)
++p;
}
}
} else {
s32 count = (u8)*p;
++p;
CHECKP(1);
u8 color = *p;
++p;
CHECKD(count);
for (s32 i = 0; i < count; ++i) {
*d = color;
++d;
}
}
}
exit:
delete[] bmpData;
bmpData = newBmp;
}
// how many bytes will be touched given the current state of decompress4BitRLE
static inline u32 shiftedCount(s32 count, s32 shift)
{
_IRR_DEBUG_BREAK_IF(count < 0)
u32 ret = count / 2;
if (shift == 0 || count % 2 == 1)
++ret;
return ret;
}
void CImageLoaderBMP::decompress4BitRLE(u8 *&bmpData, s32 size, s32 width, s32 height, s32 pitch) const
{
const s32 lineWidth = (width + 1) / 2 + pitch;
u8 *p = bmpData;
const u8 *pEnd = bmpData + size;
u8 *newBmp = new u8[lineWidth * height];
u8 *d = newBmp;
const u8 *destEnd = newBmp + lineWidth * height;
s32 line = 0;
s32 shift = 4;
while (p < pEnd && d < destEnd) {
if (*p == 0) {
++p;
CHECKP(1);
switch (*p) {
case 0: // end of line
++p;
++line;
d = newBmp + (line * lineWidth);
shift = 4;
break;
case 1: // end of bmp
goto exit;
case 2: {
++p;
CHECKP(2);
s32 x = (u8)*p;
++p;
s32 y = (u8)*p;
++p;
d += x / 2 + y * lineWidth;
shift = x % 2 == 0 ? 4 : 0;
} break;
default: {
// absolute mode
s32 count = (u8)*p;
++p;
s32 readAdditional = ((2 - ((count) % 2)) % 2);
s32 readShift = 4;
CHECKP(shiftedCount(count, readShift));
CHECKD(shiftedCount(count, shift));
for (s32 i = 0; i < count; ++i) {
s32 color = (((u8)*p) >> readShift) & 0x0f;
readShift -= 4;
if (readShift < 0) {
++*p; // <- bug?
readShift = 4;
}
u8 mask = 0x0f << shift;
*d = (*d & (~mask)) | ((color << shift) & mask);
shift -= 4;
if (shift < 0) {
shift = 4;
++d;
}
}
CHECKP(readAdditional);
for (s32 i = 0; i < readAdditional; ++i)
++p;
}
}
} else {
s32 count = (u8)*p;
++p;
CHECKP(1);
s32 color1 = (u8)*p;
color1 = color1 & 0x0f;
s32 color2 = (u8)*p;
color2 = (color2 >> 4) & 0x0f;
++p;
CHECKD(shiftedCount(count, shift));
for (s32 i = 0; i < count; ++i) {
u8 mask = 0x0f << shift;
u8 toSet = (shift == 0 ? color1 : color2) << shift;
*d = (*d & (~mask)) | (toSet & mask);
shift -= 4;
if (shift < 0) {
shift = 4;
++d;
}
}
}
}
exit:
delete[] bmpData;
bmpData = newBmp;
}
#undef CHECKOFF
#undef CHECKP
#undef CHECKD
//! creates a surface from the file
IImage *CImageLoaderBMP::loadImage(io::IReadFile *file) const
{
SBMPHeader header;
file->read(&header, sizeof(header));
#ifdef __BIG_ENDIAN__
header.Id = os::Byteswap::byteswap(header.Id);
header.FileSize = os::Byteswap::byteswap(header.FileSize);
header.BitmapDataOffset = os::Byteswap::byteswap(header.BitmapDataOffset);
header.BitmapHeaderSize = os::Byteswap::byteswap(header.BitmapHeaderSize);
header.Width = os::Byteswap::byteswap(header.Width);
header.Height = os::Byteswap::byteswap(header.Height);
header.Planes = os::Byteswap::byteswap(header.Planes);
header.BPP = os::Byteswap::byteswap(header.BPP);
header.Compression = os::Byteswap::byteswap(header.Compression);
header.BitmapDataSize = os::Byteswap::byteswap(header.BitmapDataSize);
header.PixelPerMeterX = os::Byteswap::byteswap(header.PixelPerMeterX);
header.PixelPerMeterY = os::Byteswap::byteswap(header.PixelPerMeterY);
header.Colors = os::Byteswap::byteswap(header.Colors);
header.ImportantColors = os::Byteswap::byteswap(header.ImportantColors);
#endif
s32 pitch = 0;
//! return if the header is false
if (header.Id != 0x4d42)
return 0;
if (header.Compression > 2) { // we'll only handle RLE-Compression
os::Printer::log("Compression mode not supported.", ELL_ERROR);
return 0;
}
if (header.BPP > 32 || !checkImageDimensions(header.Width, header.Height)) {
os::Printer::log("Rejecting BMP with unreasonable size or BPP.", ELL_ERROR);
return 0;
}
// adjust bitmap data size to dword boundary
header.BitmapDataSize += (4 - (header.BitmapDataSize % 4)) % 4;
// read palette
long pos = file->getPos();
constexpr s32 paletteAllocSize = 256;
s32 paletteSize = (header.BitmapDataOffset - pos) / 4;
paletteSize = core::clamp(paletteSize, 0, paletteAllocSize);
s32 *paletteData = 0;
if (paletteSize) {
// always allocate an 8-bit palette to ensure enough space
paletteData = new s32[paletteAllocSize];
memset(paletteData, 0, paletteAllocSize * sizeof(s32));
file->read(paletteData, paletteSize * sizeof(s32));
#ifdef __BIG_ENDIAN__
for (s32 i = 0; i < paletteSize; ++i)
paletteData[i] = os::Byteswap::byteswap(paletteData[i]);
#endif
}
// read image data
if (!header.BitmapDataSize) {
// okay, lets guess the size
// some tools simply don't set it
header.BitmapDataSize = static_cast<u32>(file->getSize()) - header.BitmapDataOffset;
}
file->seek(header.BitmapDataOffset);
s32 widthInBytes;
{
f32 t = (header.Width) * (header.BPP / 8.0f);
widthInBytes = (s32)t;
t -= widthInBytes;
if (t != 0.0f)
++widthInBytes;
}
const s32 lineSize = widthInBytes + ((4 - (widthInBytes % 4))) % 4;
pitch = lineSize - widthInBytes;
u8 *bmpData = new u8[header.BitmapDataSize];
file->read(bmpData, header.BitmapDataSize);
// decompress data if needed
switch (header.Compression) {
case 1: // 8 bit rle
decompress8BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
header.BitmapDataSize = (header.Width + pitch) * header.Height;
break;
case 2: // 4 bit rle
decompress4BitRLE(bmpData, header.BitmapDataSize, header.Width, header.Height, pitch);
header.BitmapDataSize = ((header.Width + 1) / 2 + pitch) * header.Height;
break;
}
if (header.BitmapDataSize < lineSize * header.Height) {
os::Printer::log("Bitmap data is cut off.", ELL_ERROR);
delete[] paletteData;
delete[] bmpData;
return 0;
}
// create surface
core::dimension2d<u32> dim;
dim.Width = header.Width;
dim.Height = header.Height;
IImage *image = 0;
switch (header.BPP) {
case 1:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert1BitTo16Bit(bmpData, (s16 *)image->getData(), header.Width, header.Height, pitch, true);
break;
case 4:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert4BitTo16Bit(bmpData, (s16 *)image->getData(), header.Width, header.Height, paletteData, pitch, true);
break;
case 8:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert8BitTo16Bit(bmpData, (s16 *)image->getData(), header.Width, header.Height, paletteData, pitch, true);
break;
case 16:
image = new CImage(ECF_A1R5G5B5, dim);
if (image)
CColorConverter::convert16BitTo16Bit((s16 *)bmpData, (s16 *)image->getData(), header.Width, header.Height, pitch, true);
break;
case 24:
image = new CImage(ECF_R8G8B8, dim);
if (image)
CColorConverter::convert24BitTo24Bit(bmpData, (u8 *)image->getData(), header.Width, header.Height, pitch, true, true);
break;
case 32: // thx to Reinhard Ostermeier
image = new CImage(ECF_A8R8G8B8, dim);
if (image)
CColorConverter::convert32BitTo32Bit((s32 *)bmpData, (s32 *)image->getData(), header.Width, header.Height, pitch, true);
break;
};
// clean up
delete[] paletteData;
delete[] bmpData;
return image;
}
//! creates a loader which is able to load windows bitmaps
IImageLoader *createImageLoaderBMP()
{
return new CImageLoaderBMP;
}
} // end namespace video
} // end namespace irr

View file

@ -1,81 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "IImageLoader.h"
namespace irr
{
namespace video
{
// byte-align structures
#include "irrpack.h"
struct SBMPHeader
{
u16 Id; // BM - Windows 3.1x, 95, NT, 98, 2000, ME, XP
// BA - OS/2 Bitmap Array
// CI - OS/2 Color Icon
// CP - OS/2 Color Pointer
// IC - OS/2 Icon
// PT - OS/2 Pointer
u32 FileSize;
u32 Reserved;
u32 BitmapDataOffset;
u32 BitmapHeaderSize; // should be 28h for windows bitmaps or
// 0Ch for OS/2 1.x or F0h for OS/2 2.x
u32 Width;
u32 Height;
u16 Planes;
u16 BPP; // 1: Monochrome bitmap
// 4: 16 color bitmap
// 8: 256 color bitmap
// 16: 16bit (high color) bitmap
// 24: 24bit (true color) bitmap
// 32: 32bit (true color) bitmap
u32 Compression; // 0: none (Also identified by BI_RGB)
// 1: RLE 8-bit / pixel (Also identified by BI_RLE4)
// 2: RLE 4-bit / pixel (Also identified by BI_RLE8)
// 3: Bitfields (Also identified by BI_BITFIELDS)
u32 BitmapDataSize; // Size of the bitmap data in bytes. This number must be rounded to the next 4 byte boundary.
u32 PixelPerMeterX;
u32 PixelPerMeterY;
u32 Colors;
u32 ImportantColors;
} PACK_STRUCT;
// Default alignment
#include "irrunpack.h"
/*!
Surface Loader for Windows bitmaps
*/
class CImageLoaderBMP : public IImageLoader
{
public:
//! constructor
CImageLoaderBMP();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool isALoadableFileExtension(const io::path &filename) const override;
//! returns true if the file maybe is able to be loaded by this class
bool isALoadableFileFormat(io::IReadFile *file) const override;
//! creates a surface from the file
IImage *loadImage(io::IReadFile *file) const override;
private:
void decompress8BitRLE(u8 *&BmpData, s32 size, s32 width, s32 height, s32 pitch) const;
void decompress4BitRLE(u8 *&BmpData, s32 size, s32 width, s32 height, s32 pitch) const;
};
} // end namespace video
} // end namespace irr

View file

@ -6,8 +6,10 @@
#include "IReadFile.h"
#include "CImage.h"
#include "coreutil.h"
#include "os.h"
#include "irrString.h"
#include <csetjmp>
namespace irr
{

View file

@ -6,9 +6,8 @@
#include "IImageLoader.h"
#include <cstdio> // required for jpeglib.h
#include <cstdio> // IWYU pragma: keep (required for jpeglib.h)
#include <jpeglib.h> // use system lib
#include <setjmp.h>
namespace irr
{

View file

@ -7,7 +7,8 @@
#include <png.h> // use system lib png
#include "CImage.h"
#include "CReadFile.h"
#include "IReadFile.h"
#include "coreutil.h"
#include "os.h"
namespace irr

View file

@ -5,10 +5,10 @@
#include "CImageLoaderTGA.h"
#include "IReadFile.h"
#include "coreutil.h"
#include "os.h"
#include "CColorConverter.h"
#include "CImage.h"
#include "irrString.h"
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
@ -181,27 +181,16 @@ IImage *CImageLoaderTGA::loadImage(io::IReadFile *file) const
header.ImageWidth, header.ImageHeight,
0, 0, (header.ImageDescriptor & 0x20) == 0);
} else {
switch (header.ColorMapEntrySize) {
case 16:
image = new CImage(ECF_A1R5G5B5, core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert8BitTo16Bit((u8 *)data,
(s16 *)image->getData(),
header.ImageWidth, header.ImageHeight,
(s32 *)palette, 0,
(header.ImageDescriptor & 0x20) == 0);
break;
// Note: 24 bit with palette would need a 24 bit palette, too lazy doing that now (textures will prefer 32-bit later anyway)
default:
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert8BitTo32Bit((u8 *)data,
(u8 *)image->getData(),
header.ImageWidth, header.ImageHeight,
(u8 *)palette, 0,
(header.ImageDescriptor & 0x20) == 0);
break;
}
// Colormap is converted to A8R8G8B8 at this point thus the code can handle all color formats.
// This wastes some texture memory, but is less of a third of the code that does this optimally.
// If you want to refactor this: The possible color formats here are A1R5G5B5, B8G8R8, B8G8R8A8.
image = new CImage(ECF_A8R8G8B8, core::dimension2d<u32>(header.ImageWidth, header.ImageHeight));
if (image)
CColorConverter::convert8BitTo32Bit((u8 *)data,
(u8 *)image->getData(),
header.ImageWidth, header.ImageHeight,
(u8 *)palette, 0,
(header.ImageDescriptor & 0x20) == 0);
}
} break;
case 16:

View file

@ -6,15 +6,12 @@
#include "CColorConverter.h"
#include "IWriteFile.h"
#include "CImage.h"
#include "irrString.h"
#include "coreutil.h"
#include "os.h"
#include <cstdio> // required for jpeglib.h
extern "C" {
#include <cstdio> // IWYU pragma: keep (required for jpeglib.h)
#include <jpeglib.h>
#include <jerror.h>
}
namespace irr
{

View file

@ -4,10 +4,9 @@
#include "CImageWriterPNG.h"
#include "CImageLoaderPNG.h"
#include "CColorConverter.h"
#include "IWriteFile.h"
#include "irrString.h"
#include "coreutil.h"
#include "os.h" // for logging
#include <png.h> // use system lib png

View file

@ -38,7 +38,7 @@
#include "CEGLManager.h"
#endif
#if defined(_IRR_COMPILE_WITH_OPENGL_)
#if defined(_IRR_COMPILE_WITH_GLX_MANAGER_)
#include "CGLXManager.h"
#endif
@ -69,24 +69,6 @@
#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
namespace irr
{
namespace video
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
IVideoDriver *createOpenGLDriver(const irr::SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#endif
#ifdef _IRR_COMPILE_WITH_OGLES2_
IVideoDriver *createOGLES2Driver(const irr::SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#endif
#ifdef _IRR_COMPILE_WITH_WEBGL1_
IVideoDriver *createWebGL1Driver(const irr::SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#endif
}
} // end namespace irr
namespace
{
Atom X_ATOM_CLIPBOARD;
@ -286,10 +268,10 @@ void CIrrDeviceLinux::setupTopLevelXorgWindow()
os::Printer::log("Configuring X11-specific top level window properties", ELL_DEBUG);
// Set application name and class hints. For now name and class are the same.
// Note: SDL uses the executable name here (i.e. "minetest").
// Note: SDL uses the executable name here (i.e. "luanti").
XClassHint *classhint = XAllocClassHint();
classhint->res_name = const_cast<char *>("Minetest");
classhint->res_class = const_cast<char *>("Minetest");
classhint->res_name = const_cast<char *>("Luanti");
classhint->res_class = const_cast<char *>("Luanti");
XSetClassHint(XDisplay, XWindow, classhint);
XFree(classhint);
@ -397,10 +379,11 @@ bool CIrrDeviceLinux::createWindow()
if (WMCheck != None)
HasNetWM = true;
#if defined(_IRR_COMPILE_WITH_OPENGL_)
#if defined(_IRR_COMPILE_WITH_GLX_MANAGER_)
// don't use the XVisual with OpenGL, because it ignores all requested
// properties of the CreationParams
if (CreationParams.DriverType == video::EDT_OPENGL) {
if (CreationParams.DriverType == video::EDT_OPENGL
|| CreationParams.DriverType == video::EDT_OPENGL3) {
video::SExposedVideoData data;
data.OpenGLLinux.X11Display = XDisplay;
ContextManager = new video::CGLXManager(CreationParams, data, Screennr);
@ -539,51 +522,54 @@ void CIrrDeviceLinux::createDriver()
switch (CreationParams.DriverType) {
#ifdef _IRR_COMPILE_WITH_X11_
case video::EDT_OPENGL:
#ifdef _IRR_COMPILE_WITH_OPENGL_
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = XWindow;
data.OpenGLLinux.X11Display = XDisplay;
ContextManager->initialize(CreationParams, data);
#endif
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, ContextManager);
}
#else
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
break;
case video::EDT_OPENGL3:
{
#ifdef ENABLE_OPENGL3
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = XWindow;
data.OpenGLLinux.X11Display = XDisplay;
ContextManager->initialize(CreationParams, data);
#endif
VideoDriver = video::createOpenGL3Driver(CreationParams, FileSystem, ContextManager);
}
break;
case video::EDT_OGLES2:
#ifdef _IRR_COMPILE_WITH_OGLES2_
{
#ifdef _IRR_COMPILE_WITH_OGLES2_
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = XWindow;
data.OpenGLLinux.X11Display = XDisplay;
ContextManager = new video::CEGLManager();
ContextManager->initialize(CreationParams, data);
#endif
VideoDriver = video::createOGLES2Driver(CreationParams, FileSystem, ContextManager);
}
#else
os::Printer::log("No OpenGL-ES2 support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_WEBGL1:
#ifdef _IRR_COMPILE_WITH_WEBGL1_
{
#ifdef _IRR_COMPILE_WITH_WEBGL1_
video::SExposedVideoData data;
data.OpenGLLinux.X11Window = XWindow;
data.OpenGLLinux.X11Display = XDisplay;
ContextManager = new video::CEGLManager();
ContextManager->initialize(CreationParams, data);
#endif
VideoDriver = video::createWebGL1Driver(CreationParams, FileSystem, ContextManager);
}
#else
os::Printer::log("No WebGL1 support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_NULL:
VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
@ -591,7 +577,7 @@ void CIrrDeviceLinux::createDriver()
default:
os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
break;
#else
#else // no X11
case video::EDT_NULL:
VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
break;
@ -1205,6 +1191,17 @@ bool CIrrDeviceLinux::isWindowMaximized() const
return WindowMaximized;
}
//! Checks if the Irrlicht device supports touch events.
bool CIrrDeviceLinux::supportsTouchEvents() const
{
#if defined(_IRR_LINUX_X11_XINPUT2_)
return true;
#else
return false;
#endif
}
//! returns color format of the window.
video::ECOLOR_FORMAT CIrrDeviceLinux::getColorFormat() const
{
@ -1570,7 +1567,6 @@ bool CIrrDeviceLinux::activateJoysticks(core::array<SJoystickInfo> &joystickInfo
fcntl(info.fd, F_SETFL, O_NONBLOCK);
#endif
(void)memset(&info.persistentData, 0, sizeof(info.persistentData));
info.persistentData.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
info.persistentData.JoystickEvent.Joystick = ActiveJoysticks.size();

View file

@ -66,6 +66,9 @@ public:
//! returns last state from maximizeWindow() and restoreWindow()
bool isWindowMaximized() const override;
//! Checks if the Irrlicht device supports touch events.
bool supportsTouchEvents() const override;
//! returns color format of the window.
video::ECOLOR_FORMAT getColorFormat() const override;

View file

@ -12,6 +12,7 @@
#include "CIrrDeviceOSX.h"
#include "IEventReceiver.h"
#include "IVideoDriver.h"
#include "os.h"
#include "CTimer.h"
#include "irrString.h"
@ -432,14 +433,6 @@ long GetDictionaryLong(CFDictionaryRef theDict, const void *key)
return value;
}
namespace irr
{
namespace video
{
IVideoDriver *createOpenGLDriver(const SIrrlichtCreationParameters &param, io::IFileSystem *io, IContextManager *contextManager);
}
} // end namespace irr
static bool firstLaunch = true;
@implementation CIrrDelegateOSX {
@ -720,6 +713,7 @@ void CIrrDeviceMacOSX::createDriver()
#endif
break;
case video::EDT_OPENGL3:
case video::EDT_OGLES2:
os::Printer::log("This driver is not available on OSX.", ELL_ERROR);
break;

View file

@ -29,53 +29,6 @@
static int SDLDeviceInstances = 0;
namespace irr
{
namespace video
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
IVideoDriver *createOpenGLDriver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#else
static IVideoDriver *createOpenGLDriver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
#ifdef ENABLE_OPENGL3
IVideoDriver *createOpenGL3Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#else
static IVideoDriver *createOpenGL3Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No OpenGL 3 support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
#ifdef _IRR_COMPILE_WITH_OGLES2_
IVideoDriver *createOGLES2Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#else
static IVideoDriver *createOGLES2Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No OpenGL ES 2 support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
#ifdef _IRR_COMPILE_WITH_WEBGL1_
IVideoDriver *createWebGL1Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#else
static IVideoDriver *createWebGL1Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No WebGL 1 support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
} // end namespace video
} // end namespace irr
namespace irr
{
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
@ -341,7 +294,7 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters &param) :
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
#if defined(SDL_HINT_APP_NAME)
SDL_SetHint(SDL_HINT_APP_NAME, "Minetest");
SDL_SetHint(SDL_HINT_APP_NAME, "Luanti");
#endif
// Set IME hints
@ -713,7 +666,7 @@ bool CIrrDeviceSDL::run()
while (!Close && wrap_PollEvent(&SDL_event)) {
// os::Printer::log("event: ", core::stringc((int)SDL_event.type).c_str(), ELL_INFORMATION); // just for debugging
memset(&irrevent, 0, sizeof(irrevent));
irrevent = {};
switch (SDL_event.type) {
case SDL_MOUSEMOTION: {
@ -1293,6 +1246,12 @@ bool CIrrDeviceSDL::isWindowVisible() const
return !IsInBackground;
}
//! Checks if the Irrlicht device supports touch events.
bool CIrrDeviceSDL::supportsTouchEvents() const
{
return true;
}
//! returns if window is active. if not, nothing need to be drawn
bool CIrrDeviceSDL::isWindowActive() const
{

View file

@ -93,6 +93,9 @@ public:
//! Checks if the window could possibly be visible.
bool isWindowVisible() const override;
//! Checks if the Irrlicht device supports touch events.
bool supportsTouchEvents() const override;
//! Get the position of this window on screen
core::position2di getWindowPosition() override;

View file

@ -17,6 +17,42 @@
namespace irr
{
namespace video
{
#ifndef _IRR_COMPILE_WITH_OPENGL_
IVideoDriver *createOpenGLDriver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
#ifndef ENABLE_OPENGL3
IVideoDriver *createOpenGL3Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No OpenGL 3 support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
#ifndef _IRR_COMPILE_WITH_OGLES2_
IVideoDriver *createOGLES2Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No OpenGL ES 2 support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
#ifndef _IRR_COMPILE_WITH_WEBGL1_
IVideoDriver *createWebGL1Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
os::Printer::log("No WebGL 1 support compiled in.", ELL_ERROR);
return nullptr;
}
#endif
}
//! constructor
CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters &params) :
IrrlichtDevice(), VideoDriver(0), GUIEnvironment(0), SceneManager(0),

View file

@ -33,7 +33,15 @@ IFileSystem *createFileSystem();
namespace video
{
IVideoDriver *createNullDriver(io::IFileSystem *io, const core::dimension2d<u32> &screenSize);
IVideoDriver *createNullDriver(io::IFileSystem *io, const core::dimension2d<u32> &screenSize);
IVideoDriver *createOpenGLDriver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
IVideoDriver *createOpenGL3Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
IVideoDriver *createOGLES2Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
IVideoDriver *createWebGL1Driver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
}
//! Stub for an Irrlicht Device implementation

View file

@ -34,24 +34,10 @@
#include "CEGLManager.h"
#endif
#if defined(_IRR_COMPILE_WITH_OPENGL_)
#if defined(_IRR_COMPILE_WITH_WGL_MANAGER_)
#include "CWGLManager.h"
#endif
namespace irr
{
namespace video
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
IVideoDriver *createOpenGLDriver(const irr::SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#endif
#ifdef _IRR_COMPILE_WITH_OGLES2_
IVideoDriver *createOGLES2Driver(const irr::SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager);
#endif
}
} // end namespace irr
namespace irr
{
struct SJoystickWin32Control
@ -880,14 +866,23 @@ void CIrrDeviceWin32::createDriver()
ContextManager = new video::CWGLManager();
ContextManager->initialize(CreationParams, video::SExposedVideoData(HWnd));
#endif
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, ContextManager);
if (!VideoDriver)
os::Printer::log("Could not create OpenGL driver.", ELL_ERROR);
#else
os::Printer::log("OpenGL driver was not compiled in.", ELL_ERROR);
break;
case video::EDT_OPENGL3:
#ifdef ENABLE_OPENGL3
switchToFullScreen();
ContextManager = new video::CWGLManager();
ContextManager->initialize(CreationParams, video::SExposedVideoData(HWnd));
#endif
VideoDriver = video::createOpenGL3Driver(CreationParams, FileSystem, ContextManager);
if (!VideoDriver)
os::Printer::log("Could not create OpenGL 3 driver.", ELL_ERROR);
break;
case video::EDT_OGLES2:
#ifdef _IRR_COMPILE_WITH_OGLES2_
@ -895,14 +890,11 @@ void CIrrDeviceWin32::createDriver()
ContextManager = new video::CEGLManager();
ContextManager->initialize(CreationParams, video::SExposedVideoData(HWnd));
#endif
VideoDriver = video::createOGLES2Driver(CreationParams, FileSystem, ContextManager);
if (!VideoDriver)
os::Printer::log("Could not create OpenGL-ES2 driver.", ELL_ERROR);
#else
os::Printer::log("OpenGL-ES2 driver was not compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_WEBGL1:
os::Printer::log("WebGL1 driver not supported on Win32 device.", ELL_ERROR);

View file

@ -123,10 +123,10 @@ if(USE_SDL2)
if(NOT ANDROID)
set(DEFAULT_OPENGL3 TRUE)
endif()
option(ENABLE_OPENGL3 "Enable OpenGL 3+" ${DEFAULT_OPENGL3})
else()
set(ENABLE_OPENGL3 FALSE)
set(DEFAULT_OPENGL3 FALSE)
endif()
option(ENABLE_OPENGL3 "Enable OpenGL 3+" ${DEFAULT_OPENGL3})
if(ANDROID OR EMSCRIPTEN)
set(ENABLE_OPENGL FALSE)
@ -152,9 +152,11 @@ else()
endif()
endif()
if(ENABLE_OPENGL)
add_definitions(-D_IRR_COMPILE_WITH_OPENGL_)
set(OPENGL_DIRECT_LINK TRUE) # driver relies on this
if(ENABLE_OPENGL OR (ENABLE_OPENGL3 AND NOT USE_SDL2))
if(ENABLE_OPENGL)
add_definitions(-D_IRR_COMPILE_WITH_OPENGL_)
set(OPENGL_DIRECT_LINK TRUE) # driver relies on this
endif()
if(DEVICE STREQUAL "WINDOWS")
add_definitions(-D_IRR_COMPILE_WITH_WGL_MANAGER_)
elseif(DEVICE STREQUAL "X11")
@ -165,7 +167,11 @@ if(ENABLE_OPENGL)
endif()
if(ENABLE_OPENGL3)
if (NOT USE_SDL2)
if(DEVICE STREQUAL "WINDOWS")
# supported
elseif(DEVICE STREQUAL "X11")
# supported
elseif (NOT USE_SDL2)
message(FATAL_ERROR "OpenGL 3 driver requires SDL2")
endif()
endif()
@ -219,7 +225,7 @@ if(USE_SDL2)
if(NOT ANDROID)
find_package(SDL2 REQUIRED)
else()
# provided by MinetestAndroidLibs.cmake
# provided by AndroidLibs.cmake
endif()
message(STATUS "Found SDL2: ${SDL2_LIBRARIES}")
@ -313,21 +319,6 @@ add_library(IRRMESHOBJ OBJECT
target_link_libraries(IRRMESHOBJ PUBLIC tiniergltf::tiniergltf)
add_library(IRROBJ OBJECT
CBillboardSceneNode.cpp
CCameraSceneNode.cpp
CDummyTransformationSceneNode.cpp
CEmptySceneNode.cpp
CMeshManipulator.cpp
CSceneCollisionManager.cpp
CSceneManager.cpp
CMeshCache.cpp
)
# Make sure IRROBJ gets the transitive include directories for
# tiniergltf from IRRMESHOBJ.
target_link_libraries(IRROBJ PRIVATE IRRMESHOBJ)
set(IRRDRVROBJ
CNullDriver.cpp
CGLXManager.cpp
@ -379,7 +370,6 @@ endif()
set(IRRIMAGEOBJ
CColorConverter.cpp
CImage.cpp
CImageLoaderBMP.cpp
CImageLoaderJPG.cpp
CImageLoaderPNG.cpp
CImageLoaderTGA.cpp
@ -460,14 +450,29 @@ add_library(IRRGUIOBJ OBJECT
# Library
add_library(IrrlichtMt STATIC)
# There have to be some sources in IrrlichtMt to workaround Cmake Xcode generator bug
add_library(IrrlichtMt STATIC
CBillboardSceneNode.cpp
CCameraSceneNode.cpp
CDummyTransformationSceneNode.cpp
CEmptySceneNode.cpp
CMeshManipulator.cpp
CSceneCollisionManager.cpp
CSceneManager.cpp
CMeshCache.cpp
)
foreach(object_lib
IRRMESHOBJ IRROBJ IRRVIDEOOBJ
IRRMESHOBJ IRRVIDEOOBJ
IRRIOOBJ IRROTHEROBJ IRRGUIOBJ)
# Set include directories for object library compilation
target_include_directories(${object_lib} PRIVATE ${link_includes})
# Add objects from object library to main library
target_sources(IrrlichtMt PRIVATE $<TARGET_OBJECTS:${object_lib}>)
if(CMAKE_GENERATOR STREQUAL "Xcode")
# Workaround for Cmake Xcode project generator
target_link_libraries(IrrlichtMt PRIVATE ${object_lib})
else()
# Add objects from object library to main library
target_sources(IrrlichtMt PRIVATE $<TARGET_OBJECTS:${object_lib}>)
endif()
if(BUILD_WITH_TRACY)
target_link_libraries(${object_lib} PRIVATE Tracy::TracyClient)

View file

@ -22,9 +22,6 @@ namespace irr
namespace video
{
//! creates a loader which is able to load windows bitmaps
IImageLoader *createImageLoaderBMP();
//! creates a loader which is able to load jpeg images
IImageLoader *createImageLoaderJPG();
@ -79,7 +76,7 @@ CNullDriver::CNullDriver(io::IFileSystem *io, const core::dimension2d<u32> &scre
setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true);
setTextureCreationFlag(ETCF_AUTO_GENERATE_MIP_MAPS, true);
setTextureCreationFlag(ETCF_ALLOW_MEMORY_COPY, true);
setTextureCreationFlag(ETCF_ALLOW_MEMORY_COPY, false);
ViewPort = core::rect<s32>(core::position2d<s32>(0, 0), core::dimension2di(screenSize));
@ -93,7 +90,6 @@ CNullDriver::CNullDriver(io::IFileSystem *io, const core::dimension2d<u32> &scre
SurfaceLoader.push_back(video::createImageLoaderTGA());
SurfaceLoader.push_back(video::createImageLoaderPNG());
SurfaceLoader.push_back(video::createImageLoaderJPG());
SurfaceLoader.push_back(video::createImageLoaderBMP());
SurfaceWriter.push_back(video::createImageWriterJPG());
SurfaceWriter.push_back(video::createImageWriterPNG());
@ -108,9 +104,7 @@ CNullDriver::CNullDriver(io::IFileSystem *io, const core::dimension2d<u32> &scre
InitMaterial2D.ZBuffer = video::ECFN_DISABLED;
InitMaterial2D.UseMipMaps = false;
InitMaterial2D.forEachTexture([](auto &tex) {
// Using ETMINF_LINEAR_MIPMAP_NEAREST (bilinear) for 2D graphics looks
// much better and doesn't have any downsides (e.g. regarding pixel art).
tex.MinFilter = video::ETMINF_LINEAR_MIPMAP_NEAREST;
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
tex.MagFilter = video::ETMAGF_NEAREST;
tex.TextureWrapU = video::ETC_REPEAT;
tex.TextureWrapV = video::ETC_REPEAT;
@ -942,9 +936,10 @@ void CNullDriver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enab
setTextureCreationFlag(ETCF_OPTIMIZED_FOR_SPEED, false);
}
// set flag
TextureCreationFlags = (TextureCreationFlags & (~flag)) |
((((u32)!enabled) - 1) & flag);
if (enabled)
TextureCreationFlags |= flag;
else
TextureCreationFlags &= ~flag;
}
//! Returns if a texture creation flag is enabled or disabled.

View file

@ -24,39 +24,21 @@ public:
enum EOGLESFeatures
{
// If you update this enum also update the corresponding OGLESFeatureStrings string-array
IRR_GL_APPLE_texture_2D_limited_npot,
IRR_GL_APPLE_texture_format_BGRA8888,
IRR_GL_EXT_blend_minmax,
IRR_GL_EXT_read_format_bgra,
IRR_GL_EXT_texture_filter_anisotropic,
IRR_GL_EXT_texture_format_BGRA8888,
IRR_GL_EXT_texture_lod_bias,
IRR_GL_EXT_texture_rg,
IRR_GL_IMG_read_format,
IRR_GL_IMG_texture_format_BGRA8888,
IRR_GL_IMG_user_clip_plane,
IRR_GL_OES_blend_func_separate,
IRR_GL_OES_blend_subtract,
IRR_GL_OES_depth_texture,
IRR_GL_OES_depth24,
IRR_GL_OES_depth32,
IRR_GL_OES_element_index_uint,
IRR_GL_OES_framebuffer_object,
IRR_GL_OES_packed_depth_stencil,
IRR_GL_OES_point_size_array,
IRR_GL_OES_point_sprite,
IRR_GL_OES_read_format,
IRR_GL_OES_stencil_wrap,
IRR_GL_OES_texture_float,
IRR_GL_OES_texture_half_float,
IRR_GL_OES_texture_mirrored_repeat,
IRR_GL_OES_texture_npot,
IRR_OGLES_Feature_Count
};
COGLESCoreExtensionHandler() :
Version(0), MaxAnisotropy(1), MaxIndices(0xffff),
MaxAnisotropy(1), MaxIndices(0xffff),
MaxTextureSize(1), MaxTextureLODBias(0.f), StencilBuffer(false)
{
for (u32 i = 0; i < IRR_OGLES_Feature_Count; ++i)
@ -81,99 +63,27 @@ public:
os::Printer::log(getFeatureString(i), FeatureAvailable[i] ? " true" : " false");
}
bool queryGLESFeature(EOGLESFeatures feature) const
{
return FeatureAvailable[feature];
}
protected:
const char *getFeatureString(size_t index) const
{
// One for each EOGLESFeatures
static const char *const OGLESFeatureStrings[IRR_OGLES_Feature_Count] = {
"GL_APPLE_texture_2D_limited_npot",
"GL_APPLE_texture_format_BGRA8888",
"GL_EXT_blend_minmax",
"GL_EXT_read_format_bgra",
"GL_EXT_texture_filter_anisotropic",
"GL_EXT_texture_format_BGRA8888",
"GL_EXT_texture_lod_bias",
"GL_EXT_texture_rg",
"GL_IMG_read_format",
"GL_IMG_texture_format_BGRA8888",
"GL_IMG_user_clip_plane",
"GL_OES_blend_func_separate",
"GL_OES_blend_subtract",
"GL_OES_depth_texture",
"GL_OES_depth24",
"GL_OES_depth32",
"GL_OES_element_index_uint",
"GL_OES_framebuffer_object",
"GL_OES_packed_depth_stencil",
"GL_OES_point_size_array",
"GL_OES_point_sprite",
"GL_OES_read_format",
"GL_OES_stencil_wrap",
"GL_OES_texture_float",
"GL_OES_texture_half_float",
"GL_OES_texture_mirrored_repeat",
"GL_OES_texture_npot",
};
return OGLESFeatureStrings[index];
}
void getGLVersion()
{
Version = 0;
s32 multiplier = 100;
core::stringc version(glGetString(GL_VERSION));
for (u32 i = 0; i < version.size(); ++i) {
if (version[i] >= '0' && version[i] <= '9') {
if (multiplier > 1) {
Version += static_cast<u16>(core::floor32(atof(&(version[i]))) * multiplier);
multiplier /= 10;
} else {
break;
}
}
}
}
void getGLExtensions()
{
core::stringc extensions = glGetString(GL_EXTENSIONS);
os::Printer::log(extensions.c_str());
const u32 size = extensions.size() + 1;
c8 *str = new c8[size];
strncpy(str, extensions.c_str(), extensions.size());
str[extensions.size()] = ' ';
c8 *p = str;
for (u32 i = 0; i < size; ++i) {
if (str[i] == ' ') {
str[i] = 0;
if (*p)
for (size_t j = 0; j < IRR_OGLES_Feature_Count; ++j) {
if (!strcmp(getFeatureString(j), p)) {
FeatureAvailable[j] = true;
break;
}
}
p = p + strlen(p) + 1;
}
}
delete[] str;
}
COpenGLCoreFeature Feature;
u16 Version;
u8 MaxAnisotropy;
u32 MaxIndices;
u32 MaxTextureSize;

View file

@ -261,7 +261,14 @@ public:
if (LockImage && mode != ETLM_WRITE_ONLY) {
bool passed = true;
#ifdef IRR_COMPILE_GL_COMMON
#ifdef IRR_COMPILE_GL_COMMON // legacy driver
constexpr bool use_gl_impl = true;
#else
const bool use_gl_impl = Driver->Version.Spec != OpenGLSpec::ES;
#endif
if (use_gl_impl) {
IImage *tmpImage = LockImage; // not sure yet if the size required by glGetTexImage is always correct, if not we might have to allocate a different tmpImage and convert colors later on.
Driver->getCacheHandler()->getTextureCache().set(0, this);
@ -296,37 +303,26 @@ public:
delete[] tmpBuffer;
}
#elif defined(IRR_COMPILE_GLES2_COMMON)
COpenGLCoreTexture *tmpTexture = new COpenGLCoreTexture("OGL_CORE_LOCK_TEXTURE", Size, ETT_2D, ColorFormat, Driver);
} else {
GLuint tmpFBO = 0;
Driver->irrGlGenFramebuffers(1, &tmpFBO);
GLint prevViewportX = 0;
GLint prevViewportY = 0;
GLsizei prevViewportWidth = 0;
GLsizei prevViewportHeight = 0;
Driver->getCacheHandler()->getViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight);
Driver->getCacheHandler()->setViewport(0, 0, Size.Width, Size.Height);
GLuint prevFBO = 0;
Driver->getCacheHandler()->getFBO(prevFBO);
Driver->getCacheHandler()->setFBO(tmpFBO);
Driver->irrGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmpTexture->getOpenGLTextureName(), 0);
GL.Clear(GL_COLOR_BUFFER_BIT);
Driver->draw2DImage(this, layer, true);
Driver->irrGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, getOpenGLTextureName(), 0);
IImage *tmpImage = Driver->createImage(ECF_A8R8G8B8, Size);
GL.ReadPixels(0, 0, Size.Width, Size.Height, GL_RGBA, GL_UNSIGNED_BYTE, tmpImage->getData());
Driver->irrGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
Driver->getCacheHandler()->setFBO(prevFBO);
Driver->getCacheHandler()->setViewport(prevViewportX, prevViewportY, prevViewportWidth, prevViewportHeight);
Driver->irrGlDeleteFramebuffers(1, &tmpFBO);
delete tmpTexture;
void *src = tmpImage->getData();
void *dest = LockImage->getData();
@ -349,7 +345,8 @@ public:
break;
}
tmpImage->drop();
#endif
}
if (!passed) {
LockImage->drop();

View file

@ -40,8 +40,10 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters &params, io::IFil
bool COpenGLDriver::initDriver()
{
ContextManager->generateSurface();
ContextManager->generateContext();
if (!ContextManager->generateSurface())
return false;
if (!ContextManager->generateContext())
return false;
ExposedData = ContextManager->getContext();
ContextManager->activateContext(ExposedData, false);
GL.LoadAllProcedures(ContextManager);
@ -3237,19 +3239,9 @@ COpenGLCacheHandler *COpenGLDriver::getCacheHandler() const
return CacheHandler;
}
} // end namespace
} // end namespace
#endif // _IRR_COMPILE_WITH_OPENGL_
namespace irr
{
namespace video
{
IVideoDriver *createOpenGLDriver(const SIrrlichtCreationParameters &params, io::IFileSystem *io, IContextManager *contextManager)
{
#ifdef _IRR_COMPILE_WITH_OPENGL_
COpenGLDriver *ogl = new COpenGLDriver(params, io, contextManager);
if (!ogl->initDriver()) {
@ -3258,10 +3250,8 @@ IVideoDriver *createOpenGLDriver(const SIrrlichtCreationParameters &params, io::
}
return ogl;
#else
return 0;
#endif
}
} // end namespace
} // end namespace
} // end namespace video
} // end namespace irr
#endif // opengl

View file

@ -130,10 +130,10 @@ void COpenGLExtensionHandler::initExtensions(video::IContextManager *cmgr, bool
{
const f32 ogl_ver = core::fast_atof(reinterpret_cast<const c8 *>(glGetString(GL_VERSION)));
Version = static_cast<u16>(core::floor32(ogl_ver) * 100 + core::round32(core::fract(ogl_ver) * 10.0f));
if (Version >= 102)
os::Printer::log("OpenGL driver version is 1.2 or better.", ELL_INFORMATION);
if (Version >= 200)
os::Printer::log("OpenGL driver version is 2.0 or newer.", ELL_INFORMATION);
else
os::Printer::log("OpenGL driver version is not 1.2 or better.", ELL_WARNING);
os::Printer::log("OpenGL driver version is older than 2.0.", ELL_WARNING);
{
const char *t = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));

View file

@ -401,8 +401,10 @@ bool COpenGLSLMaterialRenderer::linkProgram()
#endif
if (maxlen == 0) {
os::Printer::log("GLSL (> 2.x): failed to retrieve uniform information", ELL_ERROR);
return false;
// Intel driver bug that seems to primarily happen on Win 8.1 or older:
// There are >0 uniforms yet the driver reports a max name length of 0.
os::Printer::log("GLSL (> 2.x): failed to retrieve uniform information", ELL_WARNING);
maxlen = 256; // hope that this is enough
}
// seems that some implementations use an extra null terminator
@ -471,8 +473,10 @@ bool COpenGLSLMaterialRenderer::linkProgram()
#endif
if (maxlen == 0) {
os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR);
return false;
// Intel driver bug that seems to primarily happen on Win 8.1 or older:
// There are >0 uniforms yet the driver reports a max name length of 0.
os::Printer::log("GLSL: failed to retrieve uniform information", ELL_WARNING);
maxlen = 256; // hope that this is enough
}
// seems that some implementations use an extra null terminator

View file

@ -140,28 +140,29 @@ IAnimatedMesh *CSceneManager::getMesh(io::IReadFile *file)
// load and create a mesh which we know already isn't in the cache and put it in there
IAnimatedMesh *CSceneManager::getUncachedMesh(io::IReadFile *file, const io::path &filename, const io::path &cachename)
{
IAnimatedMesh *msh = 0;
// iterate the list in reverse order so user-added loaders can override the built-in ones
bool unsupported = true;
for (auto it = MeshLoaderList.rbegin(); it != MeshLoaderList.rend(); it++) {
if ((*it)->isALoadableFileExtension(filename)) {
unsupported = false;
// reset file to avoid side effects of previous calls to createMesh
file->seek(0);
msh = (*it)->createMesh(file);
IAnimatedMesh *msh = (*it)->createMesh(file);
if (msh) {
MeshCache->addMesh(cachename, msh);
msh->drop();
break;
os::Printer::log("Loaded mesh", filename, ELL_DEBUG);
return msh;
}
}
}
if (!msh)
os::Printer::log("Could not load mesh, file format seems to be unsupported", filename, ELL_ERROR);
else
os::Printer::log("Loaded mesh", filename, ELL_DEBUG);
return msh;
os::Printer::log(unsupported
? "Could not load mesh, file format seems to be unsupported"
: "Attempt to load mesh failed",
filename, ELL_ERROR);
return nullptr;
}
//! returns the video driver

View file

@ -6,6 +6,7 @@
#pragma once
#include "ISceneManager.h"
#include "ISkinnedMesh.h"
#include "SMeshBuffer.h"
#include "quaternion.h"
@ -17,6 +18,7 @@ namespace scene
class IAnimatedMeshSceneNode;
class IBoneSceneNode;
class ISceneManager;
class CSkinnedMesh : public ISkinnedMesh
{

View file

@ -5,6 +5,9 @@
static const char *const copyright = "Irrlicht Engine (c) 2002-2017 Nikolaus Gebhardt"; // put string in binary
#include "irrlicht.h"
#include "matrix4.h"
#include "SMaterial.h"
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
#include "CIrrDeviceWin32.h"
#endif

View file

@ -144,7 +144,7 @@ void COpenGL3DriverBase::debugCb(GLenum source, GLenum type, GLuint id, GLenum s
ll = ELL_ERROR;
else if (severity == GL_DEBUG_SEVERITY_MEDIUM)
ll = ELL_WARNING;
char buf[256];
char buf[300];
snprintf_irr(buf, sizeof(buf), "%04x %04x %.*s", source, type, length, message);
os::Printer::log("GL", buf, ll);
}
@ -226,8 +226,8 @@ void COpenGL3DriverBase::initVersion()
printVersion();
// print renderer information
VendorName = GL.GetString(GL_VENDOR);
os::Printer::log("Vendor", VendorName.c_str(), ELL_INFORMATION);
VendorName = GL.GetString(GL_RENDERER);
os::Printer::log("Renderer", VendorName.c_str(), ELL_INFORMATION);
Version = getVersionFromOpenGL();
}
@ -700,15 +700,7 @@ void COpenGL3DriverBase::drawVertexPrimitiveList(const void *vertices, u32 verte
break;
}
case (EIT_32BIT): {
#ifdef GL_OES_element_index_uint
#ifndef GL_UNSIGNED_INT
#define GL_UNSIGNED_INT 0x1405
#endif
if (FeatureAvailable[COGLESCoreExtensionHandler::IRR_GL_OES_element_index_uint])
indexSize = GL_UNSIGNED_INT;
else
#endif
indexSize = GL_UNSIGNED_SHORT;
indexSize = GL_UNSIGNED_INT;
break;
}
}
@ -1683,7 +1675,7 @@ ITexture *COpenGL3DriverBase::addRenderTargetTextureCubemap(const irr::u32 sideL
//! Returns the maximum amount of primitives
u32 COpenGL3DriverBase::getMaximalPrimitiveCount() const
{
return 65535;
return Version.Spec == OpenGLSpec::ES ? 65535 : 0x7fffffff;
}
bool COpenGL3DriverBase::setRenderTargetEx(IRenderTarget *target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)

View file

@ -411,7 +411,7 @@ bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const s32 *ints
bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const u32 *ints, int count)
{
os::Printer::log("Unsigned int support needs at least GLES 3.0", ELL_WARNING);
os::Printer::log("Unsigned int support is unimplemented", ELL_WARNING);
return false;
}

View file

@ -4,6 +4,7 @@
#include "Driver.h"
#include <cassert>
#include <stdexcept>
#include "mt_opengl.h"
namespace irr
@ -18,7 +19,7 @@ E_DRIVER_TYPE COpenGL3Driver::getDriverType() const
OpenGLVersion COpenGL3Driver::getVersionFromOpenGL() const
{
GLint major, minor, profile;
GLint major = 0, minor = 0, profile = 0;
GL.GetIntegerv(GL_MAJOR_VERSION, &major);
GL.GetIntegerv(GL_MINOR_VERSION, &minor);
GL.GetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
@ -34,13 +35,22 @@ OpenGLVersion COpenGL3Driver::getVersionFromOpenGL() const
void COpenGL3Driver::initFeatures()
{
assert(Version.Spec == OpenGLSpec::Compat);
assert(isVersionAtLeast(3, 2));
if (Version.Spec != OpenGLSpec::Compat) {
auto msg = "OpenGL 3 driver requires Compatibility context";
os::Printer::log(msg, ELL_ERROR);
throw std::runtime_error(msg);
}
if (!isVersionAtLeast(3, 2)) {
auto msg = "OpenGL 3 driver requires OpenGL >= 3.2";
os::Printer::log(msg, ELL_ERROR);
throw std::runtime_error(msg);
}
initExtensions();
TextureFormats[ECF_A1R5G5B5] = {GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}; // WARNING: may not be renderable
TextureFormats[ECF_R5G6B5] = {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}; // GL_RGB565 is an extension until 4.1
TextureFormats[ECF_R8G8B8] = {GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE}; // WARNING: may not be renderable
// FIXME: shouldn't this simply be GL_UNSIGNED_BYTE?
TextureFormats[ECF_A8R8G8B8] = {GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV};
TextureFormats[ECF_R16F] = {GL_R16F, GL_RED, GL_HALF_FLOAT};
TextureFormats[ECF_G16R16F] = {GL_RG16F, GL_RG, GL_HALF_FLOAT};
@ -53,6 +63,7 @@ void COpenGL3Driver::initFeatures()
TextureFormats[ECF_R16] = {GL_R16, GL_RED, GL_UNSIGNED_SHORT};
TextureFormats[ECF_R16G16] = {GL_RG16, GL_RG, GL_UNSIGNED_SHORT};
TextureFormats[ECF_D16] = {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT};
TextureFormats[ECF_D24] = {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT};
TextureFormats[ECF_D32] = {GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}; // WARNING: may not be renderable (?!)
TextureFormats[ECF_D24S8] = {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8};

View file

@ -3,8 +3,10 @@
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "Driver.h"
#include <stdexcept>
#include <cassert>
#include <CColorConverter.h>
#include "mt_opengl.h"
#include "CColorConverter.h"
namespace irr
{
@ -19,7 +21,7 @@ E_DRIVER_TYPE COpenGLES2Driver::getDriverType() const
OpenGLVersion COpenGLES2Driver::getVersionFromOpenGL() const
{
auto version_string = reinterpret_cast<const char *>(GL.GetString(GL_VERSION));
int major, minor;
int major = 0, minor = 0;
if (sscanf(version_string, "OpenGL ES %d.%d", &major, &minor) != 2) {
os::Printer::log("Failed to parse OpenGL ES version string", version_string, ELL_ERROR);
return {OpenGLSpec::ES, 0, 0, 0};
@ -29,8 +31,16 @@ OpenGLVersion COpenGLES2Driver::getVersionFromOpenGL() const
void COpenGLES2Driver::initFeatures()
{
assert(Version.Spec == OpenGLSpec::ES);
assert(Version.Major >= 2);
if (Version.Spec != OpenGLSpec::ES) {
auto msg = "Context isn't OpenGL ES";
os::Printer::log(msg, ELL_ERROR);
throw std::runtime_error(msg);
}
if (!isVersionAtLeast(2, 0)) {
auto msg = "Open GL ES 2.0 is required";
os::Printer::log(msg, ELL_ERROR);
throw std::runtime_error(msg);
}
initExtensions();
static const GLenum BGRA8_EXT = 0x93A1;
@ -50,6 +60,7 @@ void COpenGLES2Driver::initFeatures()
TextureFormats[ECF_R8] = {GL_R8, GL_RED, GL_UNSIGNED_BYTE};
TextureFormats[ECF_R8G8] = {GL_RG8, GL_RG, GL_UNSIGNED_BYTE};
TextureFormats[ECF_D16] = {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT};
TextureFormats[ECF_D24] = {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT};
TextureFormats[ECF_D24S8] = {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8};
if (FeatureAvailable[IRR_GL_EXT_texture_format_BGRA8888])
@ -57,8 +68,12 @@ void COpenGLES2Driver::initFeatures()
else if (FeatureAvailable[IRR_GL_APPLE_texture_format_BGRA8888])
TextureFormats[ECF_A8R8G8B8] = {BGRA8_EXT, GL_BGRA, GL_UNSIGNED_BYTE};
if (FeatureAvailable[IRR_GL_OES_depth32])
TextureFormats[ECF_D32] = {GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT};
// OpenGL ES 3 doesn't include a GL_DEPTH_COMPONENT32, so still use
// OES_depth_texture for 32-bit depth texture support.
// OpenGL ES 3 would allow {GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT},
// but I guess that would have to be called ECF_D32F...
if (FeatureAvailable[IRR_GL_OES_depth_texture])
TextureFormats[ECF_D32] = {GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT};
} else {
// NOTE These are *texture* formats. They may or may not be suitable
// for render targets. The specs only talks on *sized* formats for the
@ -98,8 +113,9 @@ void COpenGLES2Driver::initFeatures()
if (FeatureAvailable[IRR_GL_OES_depth_texture]) {
TextureFormats[ECF_D16] = {GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT};
if (FeatureAvailable[IRR_GL_OES_depth32])
TextureFormats[ECF_D32] = {GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT};
// OES_depth_texture includes 32-bit depth texture support.
TextureFormats[ECF_D32] = {GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT};
if (FeatureAvailable[IRR_GL_OES_packed_depth_stencil])
TextureFormats[ECF_D24S8] = {GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8};
}