This commit is contained in:
sfan5
2023-04-06 11:20:03 +02:00
48 changed files with 5690 additions and 459 deletions

View File

@ -20,15 +20,10 @@
#include <SDL_video.h>
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
#ifdef _IRR_COMPILE_WITH_OGLES2_
#include "CEGLManager.h"
#endif
#include <emscripten.h>
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "CSDLManager.h"
#endif
static int SDLDeviceInstances = 0;
@ -38,14 +33,42 @@ namespace irr
{
#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
@ -232,28 +255,6 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
// create keymap
createKeyMap();
if (CreationParams.Fullscreen) {
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
SDL_Flags |= SDL_WINDOW_FULLSCREEN;
#else
SDL_Flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
#endif
}
if (Resizable)
SDL_Flags |= SDL_WINDOW_RESIZABLE;
if (CreationParams.WindowMaximized)
SDL_Flags |= SDL_WINDOW_MAXIMIZED;
if (CreationParams.DriverType == video::EDT_OPENGL)
{
SDL_Flags |= SDL_WINDOW_OPENGL;
if (!CreationParams.Doublebuffer)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
}
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
SDL_Flags |= SDL_WINDOW_OPENGL;
#endif //_IRR_EMSCRIPTEN_PLATFORM_
// create window
if (CreationParams.DriverType != video::EDT_NULL)
{
@ -343,6 +344,19 @@ void CIrrDeviceSDL::logAttributes()
bool CIrrDeviceSDL::createWindow()
{
if (CreationParams.Fullscreen) {
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
SDL_Flags |= SDL_WINDOW_FULLSCREEN;
#else
SDL_Flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
#endif
}
if (Resizable)
SDL_Flags |= SDL_WINDOW_RESIZABLE;
if (CreationParams.WindowMaximized)
SDL_Flags |= SDL_WINDOW_MAXIMIZED;
SDL_Flags |= SDL_WINDOW_OPENGL;
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
if ( Width != 0 || Height != 0 )
emscripten_set_canvas_size( Width, Height);
@ -389,54 +403,73 @@ bool CIrrDeviceSDL::createWindow()
if ( Close )
return false;
if (CreationParams.DriverType == video::EDT_OPENGL) {
if (CreationParams.Bits == 16) {
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 4);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 4);
SDL_GL_SetAttribute(
SDL_GL_ALPHA_SIZE, CreationParams.WithAlphaChannel ? 1 : 0);
} else {
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(
SDL_GL_ALPHA_SIZE, CreationParams.WithAlphaChannel ? 8 : 0);
}
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, CreationParams.ZBufferBits);
if (CreationParams.Doublebuffer)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, CreationParams.Stencilbuffer ? 8 : 0);
if (CreationParams.Stereobuffer)
SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
if (CreationParams.AntiAlias > 1) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias);
}
if (!Window)
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
if (!Window && CreationParams.AntiAlias > 1) {
while (--CreationParams.AntiAlias > 1) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias);
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
if (Window)
break;
}
if (!Window) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
if (Window)
os::Printer::log("AntiAliasing disabled due to lack of support!");
}
}
switch (CreationParams.DriverType) {
case video::EDT_OPENGL:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
break;
case video::EDT_OPENGL3:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
break;
case video::EDT_OGLES1:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
break;
case video::EDT_OGLES2:
case video::EDT_WEBGL1:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
break;
default:;
}
if (Window)
{
Context = SDL_GL_CreateContext(Window);
}
} else if (!Window)
#ifdef _DEBUG
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG);
#endif
if (CreationParams.Bits == 16) {
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, CreationParams.WithAlphaChannel ? 1 : 0);
} else {
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, CreationParams.WithAlphaChannel ? 8 : 0);
}
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, CreationParams.ZBufferBits);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, CreationParams.Doublebuffer);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, CreationParams.Stencilbuffer ? 8 : 0);
SDL_GL_SetAttribute(SDL_GL_STEREO, CreationParams.Stereobuffer);
if (CreationParams.AntiAlias > 1) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias);
}
if (!Window)
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
if (!Window) {
os::Printer::log("Could not create window...", SDL_GetError(), ELL_WARNING);
}
if (!Window && CreationParams.AntiAlias > 1) {
while (--CreationParams.AntiAlias > 1) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, CreationParams.AntiAlias);
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
if (Window)
break;
}
if (!Window) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
if (Window)
os::Printer::log("AntiAliasing disabled due to lack of support!", ELL_WARNING);
}
}
if ( !Window && CreationParams.Doublebuffer)
{
@ -447,7 +480,14 @@ bool CIrrDeviceSDL::createWindow()
}
if ( !Window )
{
os::Printer::log("Could not initialize display!" );
os::Printer::log("Could not initialize display", SDL_GetError(), ELL_ERROR);
return false;
}
Context = SDL_GL_CreateContext(Window);
if (!Context) {
os::Printer::log("Could not initialize context", SDL_GetError(), ELL_ERROR);
SDL_DestroyWindow(Window);
return false;
}
@ -459,79 +499,22 @@ bool CIrrDeviceSDL::createWindow()
//! create the driver
void CIrrDeviceSDL::createDriver()
{
if (CreationParams.DriverType == video::EDT_NULL) {
VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
return;
}
ContextManager = new video::CSDLManager(this);
switch(CreationParams.DriverType)
{
case video::DEPRECATED_EDT_DIRECT3D8_NO_LONGER_EXISTS:
os::Printer::log("DIRECT3D8 Driver is no longer supported in Irrlicht. Try another one.", ELL_ERROR);
break;
case video::EDT_DIRECT3D9:
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
os::Printer::log("SDL device does not support DIRECT3D9 driver. Try another one.", ELL_ERROR);
#else
os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR);
#endif // _IRR_COMPILE_WITH_DIRECT3D_9_
break;
case video::EDT_OPENGL:
#ifdef _IRR_COMPILE_WITH_OPENGL_
ContextManager = new video::CSDLManager(this);
VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, ContextManager);
#else
os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_OGLES2:
#if defined(_IRR_COMPILE_WITH_OGLES2_) && defined(_IRR_EMSCRIPTEN_PLATFORM_)
{
video::SExposedVideoData data;
ContextManager = new video::CEGLManager();
ContextManager->initialize(CreationParams, data);
VideoDriver = video::createOGLES2Driver(CreationParams, FileSystem, ContextManager);
}
#else
os::Printer::log("No OpenGL-ES2 support compiled in.", ELL_ERROR);
#endif
break;
case video::EDT_WEBGL1:
#if defined(_IRR_COMPILE_WITH_WEBGL1_) && defined(_IRR_EMSCRIPTEN_PLATFORM_)
{
video::SExposedVideoData data;
ContextManager = new video::CEGLManager();
ContextManager->initialize(CreationParams, data);
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);
break;
default:
os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
break;
}
// In case we got the size from the canvas
if ( VideoDriver && CreationParams.WindowSize.Width == 0 && CreationParams.WindowSize.Height == 0 && Width > 0 && Height > 0 )
{
#ifdef _IRR_EMSCRIPTEN_PLATFORM_
SDL_CreateWindowAndRenderer(Width, Height, SDL_Flags, &Window, &Renderer);
#else //_IRR_EMSCRIPTEN_PLATFORM_
Window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, Width, Height, SDL_Flags);
#endif //_IRR_EMSCRIPTEN_PLATFOR
VideoDriver->OnResize(core::dimension2d<u32>(Width, Height));
case video::EDT_OPENGL: VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, ContextManager); break;
case video::EDT_OPENGL3: VideoDriver = video::createOpenGL3Driver(CreationParams, FileSystem, ContextManager); break;
case video::EDT_OGLES2: VideoDriver = video::createOGLES2Driver(CreationParams, FileSystem, ContextManager); break;
case video::EDT_WEBGL1: VideoDriver = video::createWebGL1Driver(CreationParams, FileSystem, ContextManager); break;
default:;
}
if (!VideoDriver)
os::Printer::log("Could not create video driver", ELL_ERROR);
}

View File

@ -89,8 +89,7 @@ elseif(APPLE)
elseif(ANDROID)
add_definitions(-D_IRR_ANDROID_PLATFORM_ -D_IRR_COMPILE_ANDROID_ASSET_READER_)
if(USE_SDL2)
message(WARNING "SDL2 backend is not supported on Android")
set(USE_SDL2 FALSE)
message(SEND_ERROR "SDL2 backend is not supported on Android")
endif()
set(DEVICE "Android")
elseif(EMSCRIPTEN)
@ -140,6 +139,8 @@ endif()
# OpenGL
option(ENABLE_OPENGL3 "Enable OpenGL 3+" FALSE)
if(ANDROID OR EMSCRIPTEN)
set(ENABLE_OPENGL FALSE)
else()
@ -185,7 +186,18 @@ if(ENABLE_OPENGL)
endif()
endif()
if(ENABLE_OPENGL3)
if (NOT USE_SDL2)
message(SEND_ERROR "OpenGL3 support requires SDL2")
endif()
set(USE_SDLGL ON)
set(USE_SDLGL3 ON)
endif()
if(ENABLE_GLES1)
if (USE_SDL2)
message(SEND_ERROR "OpenGL ES 1 is not supported with SDL2")
endif()
add_definitions(-D_IRR_COMPILE_WITH_OGLES1_)
if(DEVICE MATCHES "^(WINDOWS|X11|ANDROID)$")
add_definitions(-D_IRR_COMPILE_WITH_EGL_MANAGER_ -D_IRR_OGLES1_USE_EXTPOINTER_)
@ -196,6 +208,9 @@ if(ENABLE_GLES2)
add_definitions(-D_IRR_COMPILE_WITH_OGLES2_)
if(DEVICE MATCHES "^(WINDOWS|X11|ANDROID)$" OR EMSCRIPTEN)
add_definitions(-D_IRR_COMPILE_WITH_EGL_MANAGER_ -D_IRR_OGLES2_USE_EXTPOINTER_)
elseif(DEVICE STREQUAL "SDL")
set(USE_SDLGL ON)
set(USE_SDLGLES2 ON)
endif()
endif()
@ -215,8 +230,15 @@ endif()
message(STATUS "Device: ${DEVICE}")
message(STATUS "OpenGL: ${ENABLE_OPENGL}")
message(STATUS "OpenGL 3: ${USE_SDLGL3}")
message(STATUS "OpenGL ES: ${ENABLE_GLES1}")
message(STATUS "OpenGL ES 2: ${ENABLE_GLES2}")
if (USE_SDLGLES2)
message(STATUS "OpenGL ES 2: ON (unified)")
elseif (ENABLE_GLES2)
message(STATUS "OpenGL ES 2: ON (legacy)")
else()
message(STATUS "OpenGL ES 2: OFF")
endif()
message(STATUS "WebGL: ${ENABLE_WEBGL1}")
# Required libs
@ -336,12 +358,6 @@ set(IRRDRVROBJ
COpenGLExtensionHandler.cpp
COGLESDriver.cpp
COGLESExtensionHandler.cpp
COGLES2Driver.cpp
COGLES2ExtensionHandler.cpp
COGLES2FixedPipelineRenderer.cpp
COGLES2MaterialRenderer.cpp
COGLES2Renderer2D.cpp
CWebGL1Driver.cpp
CGLXManager.cpp
CWGLManager.cpp
CEGLManager.cpp
@ -366,6 +382,37 @@ add_library(IRRVIDEOOBJ OBJECT
${IRRIMAGEOBJ}
)
if(USE_SDLGL)
target_sources(IRRVIDEOOBJ PRIVATE
OpenGL/Driver.cpp
OpenGL/ExtensionHandler.cpp
OpenGL/FixedPipelineRenderer.cpp
OpenGL/MaterialRenderer.cpp
OpenGL/Renderer2D.cpp
)
endif()
if(USE_SDLGL3)
target_sources(IRRVIDEOOBJ PRIVATE
OpenGL3/Driver.cpp
)
endif()
if(USE_SDLGLES2)
target_sources(IRRVIDEOOBJ PRIVATE
OpenGLES2/Driver.cpp
)
else()
target_sources(IRRVIDEOOBJ PRIVATE
COGLES2Driver.cpp
COGLES2ExtensionHandler.cpp
COGLES2FixedPipelineRenderer.cpp
COGLES2MaterialRenderer.cpp
COGLES2Renderer2D.cpp
CWebGL1Driver.cpp
)
endif()
add_library(IRRIOOBJ OBJECT
CFileList.cpp
CFileSystem.cpp
@ -388,6 +435,10 @@ add_library(IRROTHEROBJ OBJECT
os.cpp
)
if(ENABLE_OPENGL3)
target_compile_definitions(IRROTHEROBJ PRIVATE ENABLE_OPENGL3)
endif()
if(ANDROID)
target_sources(IRROTHEROBJ PRIVATE
Android/CIrrDeviceAndroid.cpp

View File

@ -719,27 +719,6 @@ void CNullDriver::draw3DLine(const core::vector3df& start,
}
//! Draws a 3d triangle.
void CNullDriver::draw3DTriangle(const core::triangle3df& triangle, SColor color)
{
S3DVertex vertices[3];
vertices[0].Pos=triangle.pointA;
vertices[0].Color=color;
vertices[0].Normal=triangle.getNormal().normalize();
vertices[0].TCoords.set(0.f,0.f);
vertices[1].Pos=triangle.pointB;
vertices[1].Color=color;
vertices[1].Normal=vertices[0].Normal;
vertices[1].TCoords.set(0.5f,1.f);
vertices[2].Pos=triangle.pointC;
vertices[2].Color=color;
vertices[2].Normal=vertices[0].Normal;
vertices[2].TCoords.set(1.f,0.f);
const u16 indexList[] = {0,1,2};
drawVertexPrimitiveList(vertices, 3, indexList, 1, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
}
//! Draws a 3d axis aligned box.
void CNullDriver::draw3DBox(const core::aabbox3d<f32>& box, SColor color)
{
@ -779,31 +758,6 @@ void CNullDriver::draw2DImage(const video::ITexture* texture, const core::positi
}
//! draws a set of 2d images, using a color and the alpha channel of the
//! texture if desired. The images are drawn beginning at pos and concatenated
//! in one line. All drawings are clipped against clipRect (if != 0).
//! The subtextures are defined by the array of sourceRects and are chosen
//! by the indices given.
void CNullDriver::draw2DImageBatch(const video::ITexture* texture,
const core::position2d<s32>& pos,
const core::array<core::rect<s32> >& sourceRects,
const core::array<s32>& indices,
s32 kerningWidth,
const core::rect<s32>* clipRect, SColor color,
bool useAlphaChannelOfTexture)
{
core::position2d<s32> target(pos);
for (u32 i=0; i<indices.size(); ++i)
{
draw2DImage(texture, target, sourceRects[indices[i]],
clipRect, color, useAlphaChannelOfTexture);
target.X += sourceRects[indices[i]].getWidth();
target.X += kerningWidth;
}
}
//! draws a set of 2d images, using a color and the alpha channel of the
//! texture if desired.
void CNullDriver::draw2DImageBatch(const video::ITexture* texture,
@ -844,16 +798,6 @@ void CNullDriver::draw2DImage(const video::ITexture* texture, const core::positi
}
//! Draws the outline of a 2d rectangle
void CNullDriver::draw2DRectangleOutline(const core::recti& pos, SColor color)
{
draw2DLine(pos.UpperLeftCorner, core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), color);
draw2DLine(core::position2di(pos.LowerRightCorner.X, pos.UpperLeftCorner.Y), pos.LowerRightCorner, color);
draw2DLine(pos.LowerRightCorner, core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), color);
draw2DLine(core::position2di(pos.UpperLeftCorner.X, pos.LowerRightCorner.Y), pos.UpperLeftCorner, color);
}
//! Draw a 2d rectangle
void CNullDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos, const core::rect<s32>* clip)
{
@ -877,38 +821,6 @@ void CNullDriver::draw2DLine(const core::position2d<s32>& start,
{
}
//! Draws a pixel
void CNullDriver::drawPixel(u32 x, u32 y, const SColor & color)
{
}
//! Draws a non filled concyclic regular 2d polygon.
void CNullDriver::draw2DPolygon(core::position2d<s32> center,
f32 radius, video::SColor color, s32 count)
{
if (count < 2)
return;
core::position2d<s32> first;
core::position2d<s32> a,b;
for (s32 j=0; j<count; ++j)
{
b = a;
f32 p = j / (f32)count * (core::PI*2);
a = center + core::position2d<s32>((s32)(sin(p)*radius), (s32)(cos(p)*radius));
if (j==0)
first = a;
else
draw2DLine(a, b, color);
}
draw2DLine(a, first, color);
}
//! returns color format
ECOLOR_FORMAT CNullDriver::getColorFormat() const
@ -979,25 +891,6 @@ const wchar_t* CNullDriver::getName() const
}
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: First, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
void CNullDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)
{
}
//! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow.
void CNullDriver::drawStencilShadow(bool clearStencilBuffer,
video::SColor leftUpEdge, video::SColor rightUpEdge,
video::SColor leftDownEdge, video::SColor rightDownEdge)
{
}
//! Creates a boolean alpha channel of the texture based of an color key.
void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
video::SColor color,

View File

@ -126,9 +126,8 @@ namespace video
virtual void draw3DLine(const core::vector3df& start,
const core::vector3df& end, SColor color = SColor(255,255,255,255)) override;
//! Draws a 3d triangle.
virtual void draw3DTriangle(const core::triangle3df& triangle,
SColor color = SColor(255,255,255,255)) override;
[[deprecated]] virtual void draw3DTriangle(const core::triangle3df& triangle,
SColor color = SColor(255,255,255,255)) {}
//! Draws a 3d axis aligned box.
virtual void draw3DBox(const core::aabbox3d<f32>& box,
@ -154,14 +153,14 @@ namespace video
Note that the alpha component is used: If alpha is other than 255, the image will be transparent.
\param useAlphaChannelOfTexture: If true, the alpha channel of the texture is
used to draw the image. */
virtual void draw2DImageBatch(const video::ITexture* texture,
[[deprecated]] virtual void draw2DImageBatch(const video::ITexture* texture,
const core::position2d<s32>& pos,
const core::array<core::rect<s32> >& sourceRects,
const core::array<s32>& indices,
s32 kerningWidth = 0,
const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255),
bool useAlphaChannelOfTexture=false) override;
bool useAlphaChannelOfTexture=false) {}
//! Draws a set of 2d images, using a color and the alpha channel of the texture.
/** All drawings are clipped against clipRect (if != 0).
@ -205,7 +204,7 @@ namespace video
const core::rect<s32>* clip = 0) override;
//! Draws the outline of a 2d rectangle
void draw2DRectangleOutline(const core::recti& pos, SColor color=SColor(255,255,255,255)) override;
[[deprecated]] virtual void draw2DRectangleOutline(const core::recti& pos, SColor color=SColor(255,255,255,255)) {}
//! Draws a 2d line.
virtual void draw2DLine(const core::position2d<s32>& start,
@ -213,11 +212,11 @@ namespace video
SColor color=SColor(255,255,255,255)) override;
//! Draws a pixel
void drawPixel(u32 x, u32 y, const SColor & color) override;
[[deprecated]] virtual void drawPixel(u32 x, u32 y, const SColor & color) {}
//! Draws a non filled concyclic reqular 2d polygon.
virtual void draw2DPolygon(core::position2d<s32> center,
f32 radius, video::SColor Color, s32 vertexCount) override;
[[deprecated]] virtual void draw2DPolygon(core::position2d<s32> center,
f32 radius, video::SColor Color, s32 vertexCount) {}
virtual void setFog(SColor color=SColor(0,255,255,255),
E_FOG_TYPE fogType=EFT_FOG_LINEAR,
@ -268,17 +267,17 @@ namespace video
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: First, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles,
bool zfail=true, u32 debugDataVisible=0) override;
[[deprecated]] virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles,
bool zfail=true, u32 debugDataVisible=0) {}
//! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow.
virtual void drawStencilShadow(bool clearStencilBuffer=false,
[[deprecated]] virtual void drawStencilShadow(bool clearStencilBuffer=false,
video::SColor leftUpEdge = video::SColor(0,0,0,0),
video::SColor rightUpEdge = video::SColor(0,0,0,0),
video::SColor leftDownEdge = video::SColor(0,0,0,0),
video::SColor rightDownEdge = video::SColor(0,0,0,0)) override;
video::SColor rightDownEdge = video::SColor(0,0,0,0)) {}
//! Removes a texture from the texture cache and deletes it, freeing lot of

View File

@ -2,13 +2,10 @@
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __E_OGLES_CORE_EXTENSION_HANDLER_H_INCLUDED__
#define __E_OGLES_CORE_EXTENSION_HANDLER_H_INCLUDED__
#pragma once
// Can be included from different ES versions
// (this is also the reason why this file is header-only as correct OGL ES headers have to be included first)
#if defined(_IRR_COMPILE_WITH_OGLES2_) || defined(_IRR_COMPILE_WITH_OGLES1_)
#include "irrMath.h"
#include "COpenGLCoreFeature.h"
@ -773,6 +770,3 @@ namespace video
};
}
}
#endif // defined(_IRR_COMPILE_WITH_OGLES2_) || defined(_IRR_COMPILE_WITH_OGLES1_)
#endif // __E_OGLES_CORE_EXTENSION_HANDLER_H_INCLUDED__

View File

@ -10,6 +10,14 @@
#include "IRenderTarget.h"
#ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
#endif
#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
#endif
namespace irr
{
namespace video

View File

@ -433,9 +433,6 @@ public:
else
{
#ifdef IRR_OPENGL_HAS_glGenerateMipmap
#if !defined(IRR_COMPILE_GLES2_COMMON)
glEnable(GL_TEXTURE_2D); // Hack some ATI cards need this glEnable according to https://www.khronos.org/opengl/wiki/Common_Mistakes
#endif
Driver->irrGlGenerateMipmap(TextureType);
#endif
}

View File

@ -109,6 +109,9 @@ namespace video
{
switch (driver) {
case EDT_NULL: return true;
#ifdef ENABLE_OPENGL3
case EDT_OPENGL3: return true;
#endif
#ifdef _IRR_COMPILE_WITH_OPENGL_
case EDT_OPENGL: return true;
#endif

View File

@ -0,0 +1,36 @@
// Copyright (C) 2023 Vitaliy Lobachevskiy
// Copyright (C) 2015 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#define GL_GLEXT_PROTOTYPES
#include <SDL_video.h>
#include <SDL_opengl.h>
namespace irr
{
namespace video
{
// Forward declarations.
class COpenGLCoreFeature;
template <class TOpenGLDriver>
class COpenGLCoreTexture;
template <class TOpenGLDriver, class TOpenGLTexture>
class COpenGLCoreRenderTarget;
template <class TOpenGLDriver, class TOpenGLTexture>
class COpenGLCoreCacheHandler;
class COpenGL3DriverBase;
typedef COpenGLCoreTexture<COpenGL3DriverBase> COpenGL3Texture;
typedef COpenGLCoreRenderTarget<COpenGL3DriverBase, COpenGL3Texture> COpenGL3RenderTarget;
typedef COpenGLCoreCacheHandler<COpenGL3DriverBase, COpenGL3Texture> COpenGL3CacheHandler;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,395 @@
// Copyright (C) 2023 Vitaliy Lobachevskiy
// Copyright (C) 2014 Patryk Nadrowski
// Copyright (C) 2009-2010 Amundis
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include "SIrrCreationParameters.h"
#include "Common.h"
#include "CNullDriver.h"
#include "IMaterialRendererServices.h"
#include "EDriverFeatures.h"
#include "fast_atof.h"
#include "ExtensionHandler.h"
#include "IContextManager.h"
namespace irr
{
namespace video
{
struct VertexType;
class COpenGL3FixedPipelineRenderer;
class COpenGL3Renderer2D;
class COpenGL3DriverBase : public CNullDriver, public IMaterialRendererServices, public COpenGL3ExtensionHandler
{
friend class COpenGLCoreTexture<COpenGL3DriverBase>;
protected:
//! constructor (use createOpenGL3Driver instead)
COpenGL3DriverBase(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
public:
//! destructor
virtual ~COpenGL3DriverBase();
virtual bool beginScene(u16 clearFlag, SColor clearColor = SColor(255, 0, 0, 0), f32 clearDepth = 1.f, u8 clearStencil = 0,
const SExposedVideoData& videoData = SExposedVideoData(), core::rect<s32>* sourceRect = 0) override;
bool endScene() override;
//! sets transformation
void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) override;
struct SHWBufferLink_opengl : public SHWBufferLink
{
SHWBufferLink_opengl(const scene::IMeshBuffer *meshBuffer)
: SHWBufferLink(meshBuffer), vbo_verticesID(0), vbo_indicesID(0)
, vbo_verticesSize(0), vbo_indicesSize(0)
{}
u32 vbo_verticesID; //tmp
u32 vbo_indicesID; //tmp
u32 vbo_verticesSize; //tmp
u32 vbo_indicesSize; //tmp
};
bool updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
bool updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
//! updates hardware buffer if needed
bool updateHardwareBuffer(SHWBufferLink *HWBuffer) override;
//! Create hardware buffer from mesh
SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb) override;
//! Delete hardware buffer (only some drivers can)
void deleteHardwareBuffer(SHWBufferLink *HWBuffer) override;
//! Draw hardware buffer
void drawHardwareBuffer(SHWBufferLink *HWBuffer) override;
IRenderTarget* addRenderTarget() override;
//! draws a vertex primitive list
virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) override;
//! queries the features of the driver, returns true if feature is available
bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const override
{
return FeatureEnabled[feature] && COpenGL3ExtensionHandler::queryFeature(feature);
}
//! Sets a material.
void setMaterial(const SMaterial& material) override;
virtual void draw2DImage(const video::ITexture* texture,
const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color = SColor(255, 255, 255, 255), bool useAlphaChannelOfTexture = false) override;
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors = 0, bool useAlphaChannelOfTexture = false) override;
// internally used
virtual void draw2DImage(const video::ITexture* texture, u32 layer, bool flip);
void draw2DImageBatch(const video::ITexture* texture,
const core::array<core::position2d<s32> >& positions,
const core::array<core::rect<s32> >& sourceRects,
const core::rect<s32>* clipRect,
SColor color,
bool useAlphaChannelOfTexture) override;
//! draw an 2d rectangle
virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip = 0) override;
//!Draws an 2d rectangle with a gradient.
virtual void draw2DRectangle(const core::rect<s32>& pos,
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip = 0) override;
//! Draws a 2d line.
virtual void draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color = SColor(255, 255, 255, 255)) override;
//! Draws a single pixel
void drawPixel(u32 x, u32 y, const SColor & color) override;
//! Draws a 3d line.
virtual void draw3DLine(const core::vector3df& start,
const core::vector3df& end,
SColor color = SColor(255, 255, 255, 255)) override;
//! Draws a pixel
// virtual void drawPixel(u32 x, u32 y, const SColor & color);
//! Returns the name of the video driver.
const wchar_t* getName() const override;
//! Returns the maximum texture size supported.
core::dimension2du getMaxTextureSize() const override;
//! sets a viewport
void setViewPort(const core::rect<s32>& area) override;
//! Only used internally by the engine
void OnResize(const core::dimension2d<u32>& size) override;
//! Returns type of video driver
E_DRIVER_TYPE getDriverType() const override;
//! get color format of the current color buffer
ECOLOR_FORMAT getColorFormat() const override;
//! Returns the transformation set by setTransform
const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const override;
//! Can be called by an IMaterialRenderer to make its work easier.
void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, bool resetAllRenderstates) override;
//! Compare in SMaterial doesn't check texture parameters, so we should call this on each OnRender call.
void setTextureRenderStates(const SMaterial& material, bool resetAllRenderstates);
//! Get a vertex shader constant index.
s32 getVertexShaderConstantID(const c8* name) override;
//! Get a pixel shader constant index.
s32 getPixelShaderConstantID(const c8* name) override;
//! Sets a vertex shader constant.
void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) override;
//! Sets a pixel shader constant.
void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) override;
//! Sets a constant for the vertex shader based on an index.
bool setVertexShaderConstant(s32 index, const f32* floats, int count) override;
//! Int interface for the above.
bool setVertexShaderConstant(s32 index, const s32* ints, int count) override;
//! Uint interface for the above.
bool setVertexShaderConstant(s32 index, const u32* ints, int count) override;
//! Sets a constant for the pixel shader based on an index.
bool setPixelShaderConstant(s32 index, const f32* floats, int count) override;
//! Int interface for the above.
bool setPixelShaderConstant(s32 index, const s32* ints, int count) override;
//! Uint interface for the above.
bool setPixelShaderConstant(s32 index, const u32* ints, int count) override;
//! Adds a new material renderer to the VideoDriver
virtual s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData) override;
//! Adds a new material renderer to the VideoDriver
virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0) override;
//! Returns pointer to the IGPUProgrammingServices interface.
IGPUProgrammingServices* getGPUProgrammingServices() override;
//! Returns a pointer to the IVideoDriver interface.
IVideoDriver* getVideoDriver() override;
//! Returns the maximum amount of primitives
u32 getMaximalPrimitiveCount() const override;
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) override;
//! Creates a render target texture for a cubemap
ITexture* addRenderTargetTextureCubemap(const irr::u32 sideLen,
const io::path& name, const ECOLOR_FORMAT format) override;
virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255, 0, 0, 0),
f32 clearDepth = 1.f, u8 clearStencil = 0) override;
void clearBuffers(u16 flag, SColor color = SColor(255, 0, 0, 0), f32 depth = 1.f, u8 stencil = 0) override;
//! Returns an image created from the last rendered frame.
IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) override;
//! checks if an OpenGL error has happened and prints it (+ some internal code which is usually the line number)
bool testGLError(int code=0);
//! checks if an OGLES1 error has happened and prints it
bool testEGLError();
//! Set/unset a clipping plane.
bool setClipPlane(u32 index, const core::plane3df& plane, bool enable = false) override;
//! returns the current amount of user clip planes set.
u32 getClipPlaneCount() const;
//! returns the 0 indexed Plane
const core::plane3df& getClipPlane(u32 index) const;
//! Enable/disable a clipping plane.
void enableClipPlane(u32 index, bool enable) override;
//! Returns the graphics card vendor name.
core::stringc getVendorInfo() override
{
return VendorName;
};
void removeTexture(ITexture* texture) override;
//! Check if the driver supports creating textures with the given color format
bool queryTextureFormat(ECOLOR_FORMAT format) const override;
//! Used by some SceneNodes to check if a material should be rendered in the transparent render pass
bool needsTransparentRenderPass(const irr::video::SMaterial& material) const override;
//! Convert E_BLEND_FACTOR to OpenGL equivalent
GLenum getGLBlend(E_BLEND_FACTOR factor) const;
virtual bool getColorFormatParameters(ECOLOR_FORMAT format, GLint& internalFormat, GLenum& pixelFormat,
GLenum& pixelType, void(**converter)(const void*, s32, void*)) const;
//! Get current material.
const SMaterial& getCurrentMaterial() const;
COpenGL3CacheHandler* getCacheHandler() const;
protected:
//! inits the opengl-es driver
virtual bool genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer);
void chooseMaterial2D();
ITexture* createDeviceDependentTexture(const io::path& name, IImage* image) override;
ITexture* createDeviceDependentTextureCubemap(const io::path& name, const core::array<IImage*>& image) override;
//! Map Irrlicht wrap mode to OpenGL enum
GLint getTextureWrapMode(u8 clamp) const;
//! sets the needed renderstates
void setRenderStates3DMode();
//! sets the needed renderstates
void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel);
//! Prevent setRenderStateMode calls to do anything.
// hack to allow drawing meshbuffers in 2D mode.
// Better solution would be passing this flag through meshbuffers,
// but the way this is currently implemented in Irrlicht makes this tricky to implement
void lockRenderStateMode()
{
LockRenderStateMode = true;
}
//! Allow setRenderStateMode calls to work again
void unlockRenderStateMode()
{
LockRenderStateMode = false;
}
void draw2D3DVertexPrimitiveList(const void* vertices,
u32 vertexCount, const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType, bool is3D);
void createMaterialRenderers();
void loadShaderData(const io::path& vertexShaderName, const io::path& fragmentShaderName, c8** vertexShaderData, c8** fragmentShaderData);
bool setMaterialTexture(irr::u32 layerIdx, const irr::video::ITexture* texture);
//! Same as `CacheHandler->setViewport`, but also sets `ViewPort`
virtual void setViewPortRaw(u32 width, u32 height);
void drawQuad(const VertexType &vertexType, const S3DVertex (&vertices)[4]);
void drawArrays(GLenum primitiveType, const VertexType &vertexType, const void *vertices, int vertexCount);
void drawElements(GLenum primitiveType, const VertexType &vertexType, const void *vertices, const u16 *indices, int indexCount);
void drawElements(GLenum primitiveType, const VertexType &vertexType, uintptr_t vertices, uintptr_t indices, int indexCount);
void beginDraw(const VertexType &vertexType, uintptr_t verticesBase);
void endDraw(const VertexType &vertexType);
COpenGL3CacheHandler* CacheHandler;
core::stringw Name;
core::stringc VendorName;
SIrrlichtCreationParameters Params;
//! bool to make all renderstates reset if set to true.
bool ResetRenderStates;
bool LockRenderStateMode;
u8 AntiAlias;
struct SUserClipPlane
{
core::plane3df Plane;
bool Enabled;
};
core::array<SUserClipPlane> UserClipPlane;
core::matrix4 TextureFlipMatrix;
private:
COpenGL3Renderer2D* MaterialRenderer2DActive;
COpenGL3Renderer2D* MaterialRenderer2DTexture;
COpenGL3Renderer2D* MaterialRenderer2DNoTexture;
core::matrix4 Matrices[ETS_COUNT];
//! enumeration for rendering modes such as 2d and 3d for minimizing the switching of renderStates.
enum E_RENDER_MODE
{
ERM_NONE = 0, // no render state has been set yet.
ERM_2D, // 2d drawing rendermode
ERM_3D // 3d rendering mode
};
E_RENDER_MODE CurrentRenderMode;
bool Transformation3DChanged;
irr::io::path OGLES2ShaderPath;
SMaterial Material, LastMaterial;
//! Color buffer format
ECOLOR_FORMAT ColorFormat;
IContextManager* ContextManager;
std::vector<u16> QuadsIndices;
void initQuadsIndices(int max_vertex_count = 65536);
void debugCb(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message);
static void APIENTRY debugCb(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam);
};
} // end namespace video
} // end namespace irr

View File

@ -0,0 +1,66 @@
// Copyright (C) 2015 Patryk Nadrowski
// Copyright (C) 2009-2010 Amundis
// 2017 modified by Michael Zeilfelder (unifying extension handlers)
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "ExtensionHandler.h"
#include "irrString.h"
#include "SMaterial.h"
#include "fast_atof.h"
#include <mt_opengl.h>
namespace irr
{
namespace video
{
void COpenGL3ExtensionHandler::initExtensions()
{
GLint major, minor;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
Version = 100 * major + 10 * minor;
GLint ext_count = 0;
GL.GetIntegerv(GL_NUM_EXTENSIONS, &ext_count);
for (int k = 0; k < ext_count; k++) {
auto ext_name = (char *)GL.GetStringi(GL_EXTENSIONS, k);
for (size_t j=0; j<IRR_OGLES_Feature_Count; ++j) {
if (!strcmp(getFeatureString(j), ext_name)) {
FeatureAvailable[j] = true;
break;
}
}
}
GLint val=0;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &val);
Feature.MaxTextureUnits = static_cast<u8>(val);
#ifdef GL_EXT_texture_filter_anisotropic
if (FeatureAvailable[IRR_GL_EXT_texture_filter_anisotropic])
{
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &val);
MaxAnisotropy = static_cast<u8>(val);
}
#endif
#ifdef GL_MAX_ELEMENTS_INDICES
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &val);
MaxIndices=val;
#endif
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &val);
MaxTextureSize=static_cast<u32>(val);
#ifdef GL_EXT_texture_lod_bias
if (FeatureAvailable[IRR_GL_EXT_texture_lod_bias])
glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &MaxTextureLODBias);
#endif
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, DimAliasedPoint);
Feature.MaxTextureUnits = core::min_(Feature.MaxTextureUnits, static_cast<u8>(MATERIAL_MAX_TEXTURES));
Feature.ColorAttachment = 1;
}
} // end namespace video
} // end namespace irr

View File

@ -0,0 +1,187 @@
// Copyright (C) 2023 Vitaliy Lobachevskiy
// Copyright (C) 2015 Patryk Nadrowski
// Copyright (C) 2009-2010 Amundis
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include "EDriverFeatures.h"
#include "irrTypes.h"
#include "os.h"
#include "Common.h"
#include "COGLESCoreExtensionHandler.h"
namespace irr
{
namespace video
{
class COpenGL3ExtensionHandler : public COGLESCoreExtensionHandler
{
public:
COpenGL3ExtensionHandler() : COGLESCoreExtensionHandler() {}
void initExtensions();
bool queryFeature(video::E_VIDEO_DRIVER_FEATURE feature) const
{
switch (feature)
{
case EVDF_RENDER_TO_TARGET:
case EVDF_HARDWARE_TL:
case EVDF_MULTITEXTURE:
case EVDF_BILINEAR_FILTER:
case EVDF_MIP_MAP:
case EVDF_MIP_MAP_AUTO_UPDATE:
case EVDF_VERTEX_SHADER_1_1:
case EVDF_PIXEL_SHADER_1_1:
case EVDF_PIXEL_SHADER_1_2:
case EVDF_PIXEL_SHADER_2_0:
case EVDF_VERTEX_SHADER_2_0:
case EVDF_ARB_GLSL:
case EVDF_TEXTURE_NSQUARE:
case EVDF_TEXTURE_NPOT:
case EVDF_FRAMEBUFFER_OBJECT:
case EVDF_VERTEX_BUFFER_OBJECT:
case EVDF_COLOR_MASK:
case EVDF_ALPHA_TO_COVERAGE:
case EVDF_POLYGON_OFFSET:
case EVDF_BLEND_OPERATIONS:
case EVDF_BLEND_SEPARATE:
case EVDF_TEXTURE_MATRIX:
case EVDF_TEXTURE_CUBEMAP:
return true;
case EVDF_ARB_VERTEX_PROGRAM_1:
case EVDF_ARB_FRAGMENT_PROGRAM_1:
case EVDF_GEOMETRY_SHADER:
case EVDF_MULTIPLE_RENDER_TARGETS:
case EVDF_MRT_BLEND:
case EVDF_MRT_COLOR_MASK:
case EVDF_MRT_BLEND_FUNC:
case EVDF_OCCLUSION_QUERY:
return false;
case EVDF_TEXTURE_COMPRESSED_DXT:
return false; // NV Tegra need improvements here
case EVDF_TEXTURE_COMPRESSED_PVRTC:
return FeatureAvailable[IRR_GL_IMG_texture_compression_pvrtc];
case EVDF_TEXTURE_COMPRESSED_PVRTC2:
return FeatureAvailable[IRR_GL_IMG_texture_compression_pvrtc2];
case EVDF_TEXTURE_COMPRESSED_ETC1:
return FeatureAvailable[IRR_GL_OES_compressed_ETC1_RGB8_texture];
case EVDF_TEXTURE_COMPRESSED_ETC2:
return false;
case EVDF_STENCIL_BUFFER:
return StencilBuffer;
default:
return false;
};
}
inline void irrGlActiveTexture(GLenum texture)
{
glActiveTexture(texture);
}
inline void irrGlCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border,
GLsizei imageSize, const void* data)
{
glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
}
inline void irrGlCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize, const void* data)
{
glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
}
inline void irrGlUseProgram(GLuint prog)
{
glUseProgram(prog);
}
inline void irrGlBindFramebuffer(GLenum target, GLuint framebuffer)
{
glBindFramebuffer(target, framebuffer);
}
inline void irrGlDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
{
glDeleteFramebuffers(n, framebuffers);
}
inline void irrGlGenFramebuffers(GLsizei n, GLuint *framebuffers)
{
glGenFramebuffers(n, framebuffers);
}
inline GLenum irrGlCheckFramebufferStatus(GLenum target)
{
return glCheckFramebufferStatus(target);
}
inline void irrGlFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
glFramebufferTexture2D(target, attachment, textarget, texture, level);
}
inline void irrGlGenerateMipmap(GLenum target)
{
glGenerateMipmap(target);
}
inline void irrGlActiveStencilFace(GLenum face)
{
}
inline void irrGlDrawBuffer(GLenum mode)
{
}
inline void irrGlDrawBuffers(GLsizei n, const GLenum *bufs)
{
}
inline void irrGlBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
{
glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
}
inline void irrGlBlendEquation(GLenum mode)
{
glBlendEquation(mode);
}
inline void irrGlEnableIndexed(GLenum target, GLuint index)
{
}
inline void irrGlDisableIndexed(GLenum target, GLuint index)
{
}
inline void irrGlColorMaskIndexed(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
{
}
inline void irrGlBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst)
{
}
inline void irrGlBlendFuncSeparateIndexed(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
}
inline void irrGlBlendEquationIndexed(GLuint buf, GLenum mode)
{
}
inline void irrGlBlendEquationSeparateIndexed(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
{
}
};
}
}

View File

@ -0,0 +1,334 @@
// Copyright (C) 2014 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "FixedPipelineRenderer.h"
#include "IVideoDriver.h"
namespace irr
{
namespace video
{
// Base callback
COpenGL3MaterialBaseCB::COpenGL3MaterialBaseCB() :
FirstUpdateBase(true), WVPMatrixID(-1), WVMatrixID(-1), NMatrixID(-1), GlobalAmbientID(-1), MaterialAmbientID(-1), MaterialDiffuseID(-1), MaterialEmissiveID(-1), MaterialSpecularID(-1), MaterialShininessID(-1),
FogEnableID(-1), FogTypeID(-1), FogColorID(-1), FogStartID(-1),
FogEndID(-1), FogDensityID(-1), ThicknessID(-1), LightEnable(false), MaterialAmbient(SColorf(0.f, 0.f, 0.f)), MaterialDiffuse(SColorf(0.f, 0.f, 0.f)), MaterialEmissive(SColorf(0.f, 0.f, 0.f)), MaterialSpecular(SColorf(0.f, 0.f, 0.f)),
MaterialShininess(0.f), FogEnable(0), FogType(1), FogColor(SColorf(0.f, 0.f, 0.f, 1.f)), FogStart(0.f), FogEnd(0.f), FogDensity(0.f), Thickness(1.f)
{
}
void COpenGL3MaterialBaseCB::OnSetMaterial(const SMaterial& material)
{
LightEnable = material.Lighting;
MaterialAmbient = SColorf(material.AmbientColor);
MaterialDiffuse = SColorf(material.DiffuseColor);
MaterialEmissive = SColorf(material.EmissiveColor);
MaterialSpecular = SColorf(material.SpecularColor);
MaterialShininess = material.Shininess;
FogEnable = material.FogEnable ? 1 : 0;
Thickness = (material.Thickness > 0.f) ? material.Thickness : 1.f;
}
void COpenGL3MaterialBaseCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
IVideoDriver* driver = services->getVideoDriver();
if (FirstUpdateBase)
{
WVPMatrixID = services->getVertexShaderConstantID("uWVPMatrix");
WVMatrixID = services->getVertexShaderConstantID("uWVMatrix");
NMatrixID = services->getVertexShaderConstantID("uNMatrix");
GlobalAmbientID = services->getVertexShaderConstantID("uGlobalAmbient");
MaterialAmbientID = services->getVertexShaderConstantID("uMaterialAmbient");
MaterialDiffuseID = services->getVertexShaderConstantID("uMaterialDiffuse");
MaterialEmissiveID = services->getVertexShaderConstantID("uMaterialEmissive");
MaterialSpecularID = services->getVertexShaderConstantID("uMaterialSpecular");
MaterialShininessID = services->getVertexShaderConstantID("uMaterialShininess");
FogEnableID = services->getVertexShaderConstantID("uFogEnable");
FogTypeID = services->getVertexShaderConstantID("uFogType");
FogColorID = services->getVertexShaderConstantID("uFogColor");
FogStartID = services->getVertexShaderConstantID("uFogStart");
FogEndID = services->getVertexShaderConstantID("uFogEnd");
FogDensityID = services->getVertexShaderConstantID("uFogDensity");
ThicknessID = services->getVertexShaderConstantID("uThickness");
FirstUpdateBase = false;
}
const core::matrix4 W = driver->getTransform(ETS_WORLD);
const core::matrix4 V = driver->getTransform(ETS_VIEW);
const core::matrix4 P = driver->getTransform(ETS_PROJECTION);
core::matrix4 Matrix = P * V * W;
services->setPixelShaderConstant(WVPMatrixID, Matrix.pointer(), 16);
Matrix = V * W;
services->setPixelShaderConstant(WVMatrixID, Matrix.pointer(), 16);
Matrix.makeInverse();
services->setPixelShaderConstant(NMatrixID, Matrix.getTransposed().pointer(), 16);
services->setPixelShaderConstant(FogEnableID, &FogEnable, 1);
if (FogEnable)
{
SColor TempColor(0);
E_FOG_TYPE TempType = EFT_FOG_LINEAR;
bool TempPerFragment = false;
bool TempRange = false;
driver->getFog(TempColor, TempType, FogStart, FogEnd, FogDensity, TempPerFragment, TempRange);
FogType = (s32)TempType;
FogColor = SColorf(TempColor);
services->setPixelShaderConstant(FogTypeID, &FogType, 1);
services->setPixelShaderConstant(FogColorID, reinterpret_cast<f32*>(&FogColor), 4);
services->setPixelShaderConstant(FogStartID, &FogStart, 1);
services->setPixelShaderConstant(FogEndID, &FogEnd, 1);
services->setPixelShaderConstant(FogDensityID, &FogDensity, 1);
}
services->setPixelShaderConstant(ThicknessID, &Thickness, 1);
}
// EMT_SOLID + EMT_TRANSPARENT_ADD_COLOR + EMT_TRANSPARENT_ALPHA_CHANNEL + EMT_TRANSPARENT_VERTEX_ALPHA
COpenGL3MaterialSolidCB::COpenGL3MaterialSolidCB() :
FirstUpdate(true), TMatrix0ID(-1), AlphaRefID(-1), TextureUsage0ID(-1), TextureUnit0ID(-1), AlphaRef(0.5f), TextureUsage0(0), TextureUnit0(0)
{
}
void COpenGL3MaterialSolidCB::OnSetMaterial(const SMaterial& material)
{
COpenGL3MaterialBaseCB::OnSetMaterial(material);
AlphaRef = material.MaterialTypeParam;
TextureUsage0 = (material.TextureLayer[0].Texture) ? 1 : 0;
}
void COpenGL3MaterialSolidCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
COpenGL3MaterialBaseCB::OnSetConstants(services, userData);
IVideoDriver* driver = services->getVideoDriver();
if (FirstUpdate)
{
TMatrix0ID = services->getVertexShaderConstantID("uTMatrix0");
AlphaRefID = services->getVertexShaderConstantID("uAlphaRef");
TextureUsage0ID = services->getVertexShaderConstantID("uTextureUsage0");
TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
FirstUpdate = false;
}
core::matrix4 Matrix = driver->getTransform(ETS_TEXTURE_0);
services->setPixelShaderConstant(TMatrix0ID, Matrix.pointer(), 16);
services->setPixelShaderConstant(AlphaRefID, &AlphaRef, 1);
services->setPixelShaderConstant(TextureUsage0ID, &TextureUsage0, 1);
services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
}
// EMT_SOLID_2_LAYER + EMT_DETAIL_MAP
COpenGL3MaterialSolid2CB::COpenGL3MaterialSolid2CB() :
FirstUpdate(true), TMatrix0ID(-1), TMatrix1ID(-1), TextureUsage0ID(-1), TextureUsage1ID(-1), TextureUnit0ID(-1), TextureUnit1ID(-1),
TextureUsage0(0), TextureUsage1(0), TextureUnit0(0), TextureUnit1(1)
{
}
void COpenGL3MaterialSolid2CB::OnSetMaterial(const SMaterial& material)
{
COpenGL3MaterialBaseCB::OnSetMaterial(material);
TextureUsage0 = (material.TextureLayer[0].Texture) ? 1 : 0;
TextureUsage1 = (material.TextureLayer[1].Texture) ? 1 : 0;
}
void COpenGL3MaterialSolid2CB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
COpenGL3MaterialBaseCB::OnSetConstants(services, userData);
IVideoDriver* driver = services->getVideoDriver();
if (FirstUpdate)
{
TMatrix0ID = services->getVertexShaderConstantID("uTMatrix0");
TMatrix1ID = services->getVertexShaderConstantID("uTMatrix1");
TextureUsage0ID = services->getVertexShaderConstantID("uTextureUsage0");
TextureUsage1ID = services->getVertexShaderConstantID("uTextureUsage1");
TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
TextureUnit1ID = services->getVertexShaderConstantID("uTextureUnit1");
FirstUpdate = false;
}
core::matrix4 Matrix = driver->getTransform(ETS_TEXTURE_0);
services->setPixelShaderConstant(TMatrix0ID, Matrix.pointer(), 16);
Matrix = driver->getTransform(E_TRANSFORMATION_STATE(ETS_TEXTURE_0 + 1));
services->setPixelShaderConstant(TMatrix1ID, Matrix.pointer(), 16);
services->setPixelShaderConstant(TextureUsage0ID, &TextureUsage0, 1);
services->setPixelShaderConstant(TextureUsage1ID, &TextureUsage1, 1);
services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
services->setPixelShaderConstant(TextureUnit1ID, &TextureUnit1, 1);
}
// EMT_LIGHTMAP + EMT_LIGHTMAP_ADD + EMT_LIGHTMAP_M2 + EMT_LIGHTMAP_M4
COpenGL3MaterialLightmapCB::COpenGL3MaterialLightmapCB(float modulate) :
FirstUpdate(true), TMatrix0ID(-1), TMatrix1ID(-1), ModulateID(-1), TextureUsage0ID(-1), TextureUsage1ID(-1), TextureUnit0ID(-1), TextureUnit1ID(-1),
Modulate(modulate), TextureUsage0(0), TextureUsage1(0), TextureUnit0(0), TextureUnit1(1)
{
}
void COpenGL3MaterialLightmapCB::OnSetMaterial(const SMaterial& material)
{
COpenGL3MaterialBaseCB::OnSetMaterial(material);
TextureUsage0 = (material.TextureLayer[0].Texture) ? 1 : 0;
TextureUsage1 = (material.TextureLayer[1].Texture) ? 1 : 0;
}
void COpenGL3MaterialLightmapCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
COpenGL3MaterialBaseCB::OnSetConstants(services, userData);
IVideoDriver* driver = services->getVideoDriver();
if (FirstUpdate)
{
TMatrix0ID = services->getVertexShaderConstantID("uTMatrix0");
TMatrix1ID = services->getVertexShaderConstantID("uTMatrix1");
ModulateID = services->getVertexShaderConstantID("uModulate");
TextureUsage0ID = services->getVertexShaderConstantID("uTextureUsage0");
TextureUsage1ID = services->getVertexShaderConstantID("uTextureUsage1");
TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
TextureUnit1ID = services->getVertexShaderConstantID("uTextureUnit1");
FirstUpdate = false;
}
core::matrix4 Matrix = driver->getTransform(ETS_TEXTURE_0);
services->setPixelShaderConstant(TMatrix0ID, Matrix.pointer(), 16);
Matrix = driver->getTransform(E_TRANSFORMATION_STATE(ETS_TEXTURE_0 + 1));
services->setPixelShaderConstant(TMatrix1ID, Matrix.pointer(), 16);
services->setPixelShaderConstant(ModulateID, &Modulate, 1);
services->setPixelShaderConstant(TextureUsage0ID, &TextureUsage0, 1);
services->setPixelShaderConstant(TextureUsage1ID, &TextureUsage1, 1);
services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
services->setPixelShaderConstant(TextureUnit1ID, &TextureUnit1, 1);
}
// EMT_SPHERE_MAP + EMT_REFLECTION_2_LAYER + EMT_TRANSPARENT_REFLECTION_2_LAYER
COpenGL3MaterialReflectionCB::COpenGL3MaterialReflectionCB() :
FirstUpdate(true), TMatrix0ID(-1), TextureUsage0ID(-1), TextureUsage1ID(-1), TextureUnit0ID(-1), TextureUnit1ID(-1),
TextureUsage0(0), TextureUsage1(0), TextureUnit0(0), TextureUnit1(1)
{
}
void COpenGL3MaterialReflectionCB::OnSetMaterial(const SMaterial& material)
{
COpenGL3MaterialBaseCB::OnSetMaterial(material);
TextureUsage0 = (material.TextureLayer[0].Texture) ? 1 : 0;
TextureUsage1 = (material.TextureLayer[1].Texture) ? 1 : 0;
}
void COpenGL3MaterialReflectionCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
COpenGL3MaterialBaseCB::OnSetConstants(services, userData);
IVideoDriver* driver = services->getVideoDriver();
if (FirstUpdate)
{
TMatrix0ID = services->getVertexShaderConstantID("uTMatrix0");
TextureUsage0ID = services->getVertexShaderConstantID("uTextureUsage0");
TextureUsage1ID = services->getVertexShaderConstantID("uTextureUsage1");
TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
TextureUnit1ID = services->getVertexShaderConstantID("uTextureUnit1");
FirstUpdate = false;
}
core::matrix4 Matrix = driver->getTransform(ETS_TEXTURE_0);
services->setPixelShaderConstant(TMatrix0ID, Matrix.pointer(), 16);
services->setPixelShaderConstant(TextureUsage0ID, &TextureUsage0, 1);
services->setPixelShaderConstant(TextureUsage1ID, &TextureUsage1, 1);
services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
services->setPixelShaderConstant(TextureUnit1ID, &TextureUnit1, 1);
}
// EMT_ONETEXTURE_BLEND
COpenGL3MaterialOneTextureBlendCB::COpenGL3MaterialOneTextureBlendCB() :
FirstUpdate(true), TMatrix0ID(-1), BlendTypeID(-1), TextureUsage0ID(-1), TextureUnit0ID(-1), BlendType(0), TextureUsage0(0), TextureUnit0(0)
{
}
void COpenGL3MaterialOneTextureBlendCB::OnSetMaterial(const SMaterial& material)
{
COpenGL3MaterialBaseCB::OnSetMaterial(material);
BlendType = 0;
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) || textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
{
if (alphaSource == EAS_VERTEX_COLOR)
{
BlendType = 1;
}
else if (alphaSource == EAS_TEXTURE)
{
BlendType = 2;
}
}
TextureUsage0 = (material.TextureLayer[0].Texture) ? 1 : 0;
}
void COpenGL3MaterialOneTextureBlendCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
COpenGL3MaterialBaseCB::OnSetConstants(services, userData);
IVideoDriver* driver = services->getVideoDriver();
if (FirstUpdate)
{
TMatrix0ID = services->getVertexShaderConstantID("uTMatrix0");
BlendTypeID = services->getVertexShaderConstantID("uBlendType");
TextureUsage0ID = services->getVertexShaderConstantID("uTextureUsage0");
TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
FirstUpdate = false;
}
core::matrix4 Matrix = driver->getTransform(ETS_TEXTURE_0);
services->setPixelShaderConstant(TMatrix0ID, Matrix.pointer(), 16);
services->setPixelShaderConstant(BlendTypeID, &BlendType, 1);
services->setPixelShaderConstant(TextureUsage0ID, &TextureUsage0, 1);
services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
}
}
}

View File

@ -0,0 +1,180 @@
// Copyright (C) 2014 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include "IShaderConstantSetCallBack.h"
#include "IMaterialRendererServices.h"
namespace irr
{
namespace video
{
class COpenGL3MaterialBaseCB : public IShaderConstantSetCallBack
{
public:
COpenGL3MaterialBaseCB();
virtual void OnSetMaterial(const SMaterial& material);
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
protected:
bool FirstUpdateBase;
s32 WVPMatrixID;
s32 WVMatrixID;
s32 NMatrixID;
s32 GlobalAmbientID;
s32 MaterialAmbientID;
s32 MaterialDiffuseID;
s32 MaterialEmissiveID;
s32 MaterialSpecularID;
s32 MaterialShininessID;
s32 FogEnableID;
s32 FogTypeID;
s32 FogColorID;
s32 FogStartID;
s32 FogEndID;
s32 FogDensityID;
s32 ThicknessID;
bool LightEnable;
SColorf GlobalAmbient;
SColorf MaterialAmbient;
SColorf MaterialDiffuse;
SColorf MaterialEmissive;
SColorf MaterialSpecular;
f32 MaterialShininess;
s32 FogEnable;
s32 FogType;
SColorf FogColor;
f32 FogStart;
f32 FogEnd;
f32 FogDensity;
f32 Thickness;
};
class COpenGL3MaterialSolidCB : public COpenGL3MaterialBaseCB
{
public:
COpenGL3MaterialSolidCB();
virtual void OnSetMaterial(const SMaterial& material);
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
protected:
bool FirstUpdate;
s32 TMatrix0ID;
s32 AlphaRefID;
s32 TextureUsage0ID;
s32 TextureUnit0ID;
f32 AlphaRef;
s32 TextureUsage0;
s32 TextureUnit0;
};
class COpenGL3MaterialSolid2CB : public COpenGL3MaterialBaseCB
{
public:
COpenGL3MaterialSolid2CB();
virtual void OnSetMaterial(const SMaterial& material);
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
protected:
bool FirstUpdate;
s32 TMatrix0ID;
s32 TMatrix1ID;
s32 TextureUsage0ID;
s32 TextureUsage1ID;
s32 TextureUnit0ID;
s32 TextureUnit1ID;
s32 TextureUsage0;
s32 TextureUsage1;
s32 TextureUnit0;
s32 TextureUnit1;
};
class COpenGL3MaterialLightmapCB : public COpenGL3MaterialBaseCB
{
public:
COpenGL3MaterialLightmapCB(float modulate);
virtual void OnSetMaterial(const SMaterial& material);
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
protected:
bool FirstUpdate;
s32 TMatrix0ID;
s32 TMatrix1ID;
s32 ModulateID;
s32 TextureUsage0ID;
s32 TextureUsage1ID;
s32 TextureUnit0ID;
s32 TextureUnit1ID;
f32 Modulate;
s32 TextureUsage0;
s32 TextureUsage1;
s32 TextureUnit0;
s32 TextureUnit1;
};
class COpenGL3MaterialReflectionCB : public COpenGL3MaterialBaseCB
{
public:
COpenGL3MaterialReflectionCB();
virtual void OnSetMaterial(const SMaterial& material);
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
protected:
bool FirstUpdate;
s32 TMatrix0ID;
s32 TextureUsage0ID;
s32 TextureUsage1ID;
s32 TextureUnit0ID;
s32 TextureUnit1ID;
s32 TextureUsage0;
s32 TextureUsage1;
s32 TextureUnit0;
s32 TextureUnit1;
};
class COpenGL3MaterialOneTextureBlendCB : public COpenGL3MaterialBaseCB
{
public:
COpenGL3MaterialOneTextureBlendCB();
virtual void OnSetMaterial(const SMaterial& material);
virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
protected:
bool FirstUpdate;
s32 TMatrix0ID;
s32 BlendTypeID;
s32 TextureUsage0ID;
s32 TextureUnit0ID;
s32 BlendType;
s32 TextureUsage0;
s32 TextureUnit0;
};
}
}

View File

@ -0,0 +1,481 @@
// Copyright (C) 2014 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "MaterialRenderer.h"
#include "EVertexAttributes.h"
#include "IGPUProgrammingServices.h"
#include "IShaderConstantSetCallBack.h"
#include "IVideoDriver.h"
#include "os.h"
#include "Driver.h"
#include "COpenGLCoreTexture.h"
#include "COpenGLCoreCacheHandler.h"
namespace irr
{
namespace video
{
COpenGL3MaterialRenderer::COpenGL3MaterialRenderer(COpenGL3DriverBase* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
: Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), Program(0), UserData(userData)
{
#ifdef _DEBUG
setDebugName("MaterialRenderer");
#endif
switch (baseMaterial)
{
case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_TRANSPARENT_ALPHA_CHANNEL:
Alpha = true;
break;
case EMT_TRANSPARENT_ADD_COLOR:
FixedBlending = true;
break;
case EMT_ONETEXTURE_BLEND:
Blending = true;
break;
default:
break;
}
if (CallBack)
CallBack->grab();
init(outMaterialTypeNr, vertexShaderProgram, pixelShaderProgram);
}
COpenGL3MaterialRenderer::COpenGL3MaterialRenderer(COpenGL3DriverBase* driver,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial, s32 userData)
: Driver(driver), CallBack(callback), Alpha(false), Blending(false), FixedBlending(false), Program(0), UserData(userData)
{
switch (baseMaterial)
{
case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_TRANSPARENT_ALPHA_CHANNEL:
Alpha = true;
break;
case EMT_TRANSPARENT_ADD_COLOR:
FixedBlending = true;
break;
case EMT_ONETEXTURE_BLEND:
Blending = true;
break;
default:
break;
}
if (CallBack)
CallBack->grab();
}
COpenGL3MaterialRenderer::~COpenGL3MaterialRenderer()
{
if (CallBack)
CallBack->drop();
if (Program)
{
GLuint shaders[8];
GLint count;
glGetAttachedShaders(Program, 8, &count, shaders);
count=core::min_(count,8);
for (GLint i=0; i<count; ++i)
glDeleteShader(shaders[i]);
glDeleteProgram(Program);
Program = 0;
}
UniformInfo.clear();
}
GLuint COpenGL3MaterialRenderer::getProgram() const
{
return Program;
}
void COpenGL3MaterialRenderer::init(s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
bool addMaterial)
{
outMaterialTypeNr = -1;
Program = glCreateProgram();
if (!Program)
return;
if (vertexShaderProgram)
if (!createShader(GL_VERTEX_SHADER, vertexShaderProgram))
return;
if (pixelShaderProgram)
if (!createShader(GL_FRAGMENT_SHADER, pixelShaderProgram))
return;
for ( size_t i = 0; i < EVA_COUNT; ++i )
glBindAttribLocation( Program, i, sBuiltInVertexAttributeNames[i]);
if (!linkProgram())
return;
if (addMaterial)
outMaterialTypeNr = Driver->addMaterialRenderer(this);
}
bool COpenGL3MaterialRenderer::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
if (CallBack && Program)
CallBack->OnSetConstants(this, UserData);
return true;
}
void COpenGL3MaterialRenderer::OnSetMaterial(const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
COpenGL3CacheHandler* cacheHandler = Driver->getCacheHandler();
cacheHandler->setProgram(Program);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (Alpha)
{
cacheHandler->setBlend(true);
cacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (FixedBlending)
{
cacheHandler->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
cacheHandler->setBlend(true);
}
else if (Blending)
{
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
cacheHandler->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
cacheHandler->setBlend(true);
}
if (CallBack)
CallBack->OnSetMaterial(material);
}
void COpenGL3MaterialRenderer::OnUnsetMaterial()
{
}
bool COpenGL3MaterialRenderer::isTransparent() const
{
return (Alpha || Blending || FixedBlending);
}
s32 COpenGL3MaterialRenderer::getRenderCapability() const
{
return 0;
}
bool COpenGL3MaterialRenderer::createShader(GLenum shaderType, const char* shader)
{
if (Program)
{
GLuint shaderHandle = glCreateShader(shaderType);
glShaderSource(shaderHandle, 1, &shader, NULL);
glCompileShader(shaderHandle);
GLint status = 0;
glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE)
{
os::Printer::log("GLSL shader failed to compile", ELL_ERROR);
GLint maxLength=0;
GLint length;
glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH,
&maxLength);
if (maxLength)
{
GLchar *infoLog = new GLchar[maxLength];
glGetShaderInfoLog(shaderHandle, maxLength, &length, infoLog);
os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);
delete [] infoLog;
}
return false;
}
glAttachShader(Program, shaderHandle);
}
return true;
}
bool COpenGL3MaterialRenderer::linkProgram()
{
if (Program)
{
glLinkProgram(Program);
GLint status = 0;
glGetProgramiv(Program, GL_LINK_STATUS, &status);
if (!status)
{
os::Printer::log("GLSL shader program failed to link", ELL_ERROR);
GLint maxLength=0;
GLsizei length;
glGetProgramiv(Program, GL_INFO_LOG_LENGTH, &maxLength);
if (maxLength)
{
GLchar *infoLog = new GLchar[maxLength];
glGetProgramInfoLog(Program, maxLength, &length, infoLog);
os::Printer::log(reinterpret_cast<const c8*>(infoLog), ELL_ERROR);
delete [] infoLog;
}
return false;
}
GLint num = 0;
glGetProgramiv(Program, GL_ACTIVE_UNIFORMS, &num);
if (num == 0)
return true;
GLint maxlen = 0;
glGetProgramiv(Program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxlen);
if (maxlen == 0)
{
os::Printer::log("GLSL: failed to retrieve uniform information", ELL_ERROR);
return false;
}
// seems that some implementations use an extra null terminator.
++maxlen;
c8 *buf = new c8[maxlen];
UniformInfo.clear();
UniformInfo.reallocate(num);
for (GLint i=0; i < num; ++i)
{
SUniformInfo ui;
memset(buf, 0, maxlen);
GLint size;
glGetActiveUniform(Program, i, maxlen, 0, &size, &ui.type, reinterpret_cast<GLchar*>(buf));
core::stringc name = "";
// array support, workaround for some bugged drivers.
for (s32 i = 0; i < maxlen; ++i)
{
if (buf[i] == '[' || buf[i] == '\0')
break;
name += buf[i];
}
ui.name = name;
ui.location = glGetUniformLocation(Program, buf);
UniformInfo.push_back(ui);
}
delete [] buf;
}
return true;
}
void COpenGL3MaterialRenderer::setBasicRenderStates(const SMaterial& material,
const SMaterial& lastMaterial,
bool resetAllRenderstates)
{
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
s32 COpenGL3MaterialRenderer::getVertexShaderConstantID(const c8* name)
{
return getPixelShaderConstantID(name);
}
s32 COpenGL3MaterialRenderer::getPixelShaderConstantID(const c8* name)
{
for (u32 i = 0; i < UniformInfo.size(); ++i)
{
if (UniformInfo[i].name == name)
return i;
}
return -1;
}
void COpenGL3MaterialRenderer::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
os::Printer::log("Cannot set constant, please use high level shader call instead.", ELL_WARNING);
}
void COpenGL3MaterialRenderer::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
os::Printer::log("Cannot set constant, use high level shader call.", ELL_WARNING);
}
bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const f32* floats, int count)
{
return setPixelShaderConstant(index, floats, count);
}
bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const s32* ints, int count)
{
return setPixelShaderConstant(index, ints, count);
}
bool COpenGL3MaterialRenderer::setVertexShaderConstant(s32 index, const u32* ints, int count)
{
return setPixelShaderConstant(index, ints, count);
}
bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const f32* floats, int count)
{
if(index < 0 || UniformInfo[index].location < 0)
return false;
bool status = true;
switch (UniformInfo[index].type)
{
case GL_FLOAT:
glUniform1fv(UniformInfo[index].location, count, floats);
break;
case GL_FLOAT_VEC2:
glUniform2fv(UniformInfo[index].location, count/2, floats);
break;
case GL_FLOAT_VEC3:
glUniform3fv(UniformInfo[index].location, count/3, floats);
break;
case GL_FLOAT_VEC4:
glUniform4fv(UniformInfo[index].location, count/4, floats);
break;
case GL_FLOAT_MAT2:
glUniformMatrix2fv(UniformInfo[index].location, count/4, false, floats);
break;
case GL_FLOAT_MAT3:
glUniformMatrix3fv(UniformInfo[index].location, count/9, false, floats);
break;
case GL_FLOAT_MAT4:
glUniformMatrix4fv(UniformInfo[index].location, count/16, false, floats);
break;
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
{
if(floats)
{
const GLint id = (GLint)(*floats);
glUniform1iv(UniformInfo[index].location, 1, &id);
}
else
status = false;
}
break;
default:
status = false;
break;
}
return status;
}
bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const s32* ints, int count)
{
if(index < 0 || UniformInfo[index].location < 0)
return false;
bool status = true;
switch (UniformInfo[index].type)
{
case GL_INT:
case GL_BOOL:
glUniform1iv(UniformInfo[index].location, count, ints);
break;
case GL_INT_VEC2:
case GL_BOOL_VEC2:
glUniform2iv(UniformInfo[index].location, count/2, ints);
break;
case GL_INT_VEC3:
case GL_BOOL_VEC3:
glUniform3iv(UniformInfo[index].location, count/3, ints);
break;
case GL_INT_VEC4:
case GL_BOOL_VEC4:
glUniform4iv(UniformInfo[index].location, count/4, ints);
break;
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
glUniform1iv(UniformInfo[index].location, 1, ints);
break;
default:
status = false;
break;
}
return status;
}
bool COpenGL3MaterialRenderer::setPixelShaderConstant(s32 index, const u32* ints, int count)
{
os::Printer::log("Unsigned int support needs at least GLES 3.0", ELL_WARNING);
return false;
}
IVideoDriver* COpenGL3MaterialRenderer::getVideoDriver()
{
return Driver;
}
}
}

View File

@ -0,0 +1,99 @@
// Copyright (C) 2014 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#pragma once
#include "EMaterialTypes.h"
#include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h"
#include "IGPUProgrammingServices.h"
#include "irrArray.h"
#include "irrString.h"
#include "Common.h"
namespace irr
{
namespace video
{
class COpenGL3DriverBase;
class COpenGL3MaterialRenderer : public IMaterialRenderer, public IMaterialRendererServices
{
public:
COpenGL3MaterialRenderer(
COpenGL3DriverBase* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram = 0,
const c8* pixelShaderProgram = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
virtual ~COpenGL3MaterialRenderer();
GLuint getProgram() const;
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services);
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype);
virtual void OnUnsetMaterial();
virtual bool isTransparent() const;
virtual s32 getRenderCapability() const;
void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) override;
s32 getVertexShaderConstantID(const c8* name) override;
s32 getPixelShaderConstantID(const c8* name) override;
void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) override;
void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) override;
bool setVertexShaderConstant(s32 index, const f32* floats, int count) override;
bool setVertexShaderConstant(s32 index, const s32* ints, int count) override;
bool setVertexShaderConstant(s32 index, const u32* ints, int count) override;
bool setPixelShaderConstant(s32 index, const f32* floats, int count) override;
bool setPixelShaderConstant(s32 index, const s32* ints, int count) override;
bool setPixelShaderConstant(s32 index, const u32* ints, int count) override;
IVideoDriver* getVideoDriver() override;
protected:
COpenGL3MaterialRenderer(COpenGL3DriverBase* driver,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
void init(s32& outMaterialTypeNr, const c8* vertexShaderProgram, const c8* pixelShaderProgram, bool addMaterial = true);
bool createShader(GLenum shaderType, const char* shader);
bool linkProgram();
COpenGL3DriverBase* Driver;
IShaderConstantSetCallBack* CallBack;
bool Alpha;
bool Blending;
bool FixedBlending;
struct SUniformInfo
{
core::stringc name;
GLenum type;
GLint location;
};
GLuint Program;
core::array<SUniformInfo> UniformInfo;
s32 UserData;
};
}
}

View File

@ -0,0 +1,83 @@
// Copyright (C) 2014 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "Renderer2D.h"
#include "IGPUProgrammingServices.h"
#include "os.h"
#include "Driver.h"
#include "COpenGLCoreFeature.h"
#include "COpenGLCoreTexture.h"
#include "COpenGLCoreCacheHandler.h"
namespace irr
{
namespace video
{
COpenGL3Renderer2D::COpenGL3Renderer2D(const c8* vertexShaderProgram, const c8* pixelShaderProgram, COpenGL3DriverBase* driver, bool withTexture) :
COpenGL3MaterialRenderer(driver, 0, EMT_SOLID),
WithTexture(withTexture)
{
#ifdef _DEBUG
setDebugName("Renderer2D");
#endif
int Temp = 0;
init(Temp, vertexShaderProgram, pixelShaderProgram, false);
COpenGL3CacheHandler* cacheHandler = Driver->getCacheHandler();
cacheHandler->setProgram(Program);
// These states don't change later.
ThicknessID = getPixelShaderConstantID("uThickness");
if ( WithTexture )
{
TextureUsageID = getPixelShaderConstantID("uTextureUsage");
s32 TextureUnitID = getPixelShaderConstantID("uTextureUnit");
s32 TextureUnit = 0;
setPixelShaderConstant(TextureUnitID, &TextureUnit, 1);
s32 TextureUsage = 0;
setPixelShaderConstant(TextureUsageID, &TextureUsage, 1);
}
cacheHandler->setProgram(0);
}
COpenGL3Renderer2D::~COpenGL3Renderer2D()
{
}
void COpenGL3Renderer2D::OnSetMaterial(const video::SMaterial& material,
const video::SMaterial& lastMaterial,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
Driver->getCacheHandler()->setProgram(Program);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
f32 Thickness = (material.Thickness > 0.f) ? material.Thickness : 1.f;
setPixelShaderConstant(ThicknessID, &Thickness, 1);
if ( WithTexture )
{
s32 TextureUsage = material.TextureLayer[0].Texture ? 1 : 0;
setPixelShaderConstant(TextureUsageID, &TextureUsage, 1);
}
}
bool COpenGL3Renderer2D::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
return true;
}
}
}

View File

@ -0,0 +1,33 @@
// Copyright (C) 2014 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include "MaterialRenderer.h"
namespace irr
{
namespace video
{
class COpenGL3Renderer2D : public COpenGL3MaterialRenderer
{
public:
COpenGL3Renderer2D(const c8* vertexShaderProgram, const c8* pixelShaderProgram, COpenGL3DriverBase* driver, bool withTexture);
~COpenGL3Renderer2D();
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services);
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype);
protected:
bool WithTexture;
s32 ThicknessID;
s32 TextureUsageID;
};
}
}

View File

@ -0,0 +1,22 @@
// Copyright (C) 2023 Vitaliy Lobachevskiy
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "Driver.h"
namespace irr {
namespace video {
E_DRIVER_TYPE COpenGL3Driver::getDriverType() const {
return EDT_OPENGL3;
}
IVideoDriver* createOpenGL3Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager)
{
COpenGL3Driver* driver = new COpenGL3Driver(params, io, contextManager);
driver->genericDriverInit(params.WindowSize, params.Stencilbuffer); // don't call in constructor, it uses virtual function calls of driver
return driver;
}
}
}

View File

@ -0,0 +1,19 @@
// Copyright (C) 2023 Vitaliy Lobachevskiy
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include "OpenGL/Driver.h"
namespace irr {
namespace video {
class COpenGL3Driver : public COpenGL3DriverBase {
friend IVideoDriver* createOpenGL3Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
public:
using COpenGL3DriverBase::COpenGL3DriverBase;
E_DRIVER_TYPE getDriverType() const override;
};
}
}

View File

@ -0,0 +1,22 @@
// Copyright (C) 2023 Vitaliy Lobachevskiy
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#include "Driver.h"
namespace irr {
namespace video {
E_DRIVER_TYPE COpenGLES2Driver::getDriverType() const {
return EDT_OGLES2;
}
IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager)
{
COpenGLES2Driver* driver = new COpenGLES2Driver(params, io, contextManager);
driver->genericDriverInit(params.WindowSize, params.Stencilbuffer); // don't call in constructor, it uses virtual function calls of driver
return driver;
}
}
}

View File

@ -0,0 +1,19 @@
// Copyright (C) 2023 Vitaliy Lobachevskiy
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#pragma once
#include "OpenGL/Driver.h"
namespace irr {
namespace video {
class COpenGLES2Driver : public COpenGL3DriverBase {
friend IVideoDriver* createOGLES2Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, IContextManager* contextManager);
public:
using COpenGL3DriverBase::COpenGL3DriverBase;
E_DRIVER_TYPE getDriverType() const override;
};
}
}

View File

@ -756,11 +756,22 @@ void OpenGLProcedures::LoadAllProcedures(irr::video::IContextManager *cmgr)
if (!NamedBufferPageCommitment) NamedBufferPageCommitment = (PFNGLNAMEDBUFFERPAGECOMMITMENTPROC_MT)cmgr->getProcAddress("glNamedBufferPageCommitmentARB");
if (!TexPageCommitment) TexPageCommitment = (PFNGLTEXPAGECOMMITMENTPROC_MT)cmgr->getProcAddress("glTexPageCommitmentARB");
// OpenGL 3 way to enumerate extensions
int ext_count = 0;
GetIntegerv(NUM_EXTENSIONS, &ext_count);
extensions.reserve(ext_count);
for (int k = 0; k < ext_count; k++)
extensions.emplace((char *)GetStringi(EXTENSIONS, k));
if (ext_count)
return;
// OpenGL 2 / ES 2 way to enumerate extensions
auto ext_str = GetString(EXTENSIONS);
if (!ext_str)
return;
// get the extension string, chop it up
std::string ext_string = std::string((char*)GetString(EXTENSIONS));
std::stringstream ext_ss(ext_string);
std::stringstream ext_ss((char*)ext_str);
std::string tmp;
while (std::getline(ext_ss, tmp, ' '))
extensions.emplace(tmp);
}