aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_particles.cpp
blob: 6769f5c230d86b6d0eef226dbda0eccf0cf379c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "lua_api/l_particles.h"
#include "lua_api/l_internal.h"
#include "common/c_converter.h"
#include "server.h"

// add_particle({pos=, velocity=, acceleration=, expirationtime=,
// 		size=, collisiondetection=, vertical=, texture=, player=})
// pos/velocity/acceleration = {x=num, y=num, z=num}
// expirationtime = num (seconds)
// size = num
// collisiondetection = bool
// vertical = bool
// texture = e.g."default_wood.png"
int ModApiParticles::l_add_particle(lua_State *L)
{
	// Get parameters
	v3f pos, vel, acc;
	    pos= vel= acc= v3f(0, 0, 0);
	float expirationtime, size;
	      expirationtime= size= 1;
	bool collisiondetection, vertical;
	     collisiondetection= vertical= false;
	std::string texture = "";
	const char *playername = "";

	if (lua_gettop(L) > 1) // deprecated
	{
		log_deprecated(L,"Deprecated add_particle call with individual parameters instead of definition");
		pos = check_v3f(L, 1);
		vel = check_v3f(L, 2);
		acc = check_v3f(L, 3);
		expirationtime = luaL_checknumber(L, 4);
		size = luaL_checknumber(L, 5);
		collisiondetection = lua_toboolean(L, 6);
		texture = luaL_checkstring(L, 7);
		if (lua_gettop(L) == 8) // only spawn for a single player
			playername = luaL_checkstring(L, 8);
	}
	else if (lua_istable(L, 1))
	{
		int table = lua_gettop(L);
		lua_pushnil(L);
		while (lua_next(L, table) != 0)
		{
			const char *key = lua_tostring(L, -2);
				  if(strcmp(key,"pos")==0){
					pos=check_v3f(L, -1);
			}else if(strcmp(key,"vel")==0){
					vel=check_v3f(L, -1);
			}else if(strcmp(key,"acc")==0){
					acc=check_v3f(L, -1);
			}else if(strcmp(key,"expirationtime")==0){
					expirationtime=luaL_checknumber(L, -1);
			}else if(strcmp(key,"size")==0){
					size=luaL_checknumber(L, -1);
			}else if(strcmp(key,"collisiondetection")==0){
					collisiondetection=lua_toboolean(L, -1);
			}else if(strcmp(key,"vertical")==0){
					vertical=lua_toboolean(L, -1);
			}else if(strcmp(key,"texture")==0){
					texture=luaL_checkstring(L, -1);
			}else if(strcmp(key,"playername")==0){
					playername=luaL_checkstring(L, -1);
			}
			lua_pop(L, 1);
		}
	}
	if (strcmp(playername, "")==0) // spawn for all players
	{
		getServer(L)->spawnParticleAll(pos, vel, acc,
			expirationtime, size, collisiondetection, vertical, texture);
	}
	else
	{
		getServer(L)->spawnParticle(playername,
			pos, vel, acc, expirationtime,
			size, collisiondetection, vertical, texture);
	}
	return 1;
}

// add_particlespawner({amount=, time=,
//				minpos=, maxpos=,
//				minvel=, maxvel=,
//				minacc=, maxacc=,
//				minexptime=, maxexptime=,
//				minsize=, maxsize=,
//				collisiondetection=,
//				vertical=,
//				texture=,
//				player=})
// minpos/maxpos/minvel/maxvel/minacc/maxacc = {x=num, y=num, z=num}
// minexptime/maxexptime = num (seconds)
// minsize/maxsize = num
// collisiondetection = bool
// vertical = bool
// texture = e.g."default_wood.png"
int ModApiParticles::l_add_particlespawner(lua_State *L)
{
	// Get parameters
	u16 amount = 1;
	v3f minpos, maxpos, minvel, maxvel, minacc, maxacc;
	    minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0);
	float time, minexptime, maxexptime, minsize, maxsize;
	      time= minexptime= maxexptime= minsize= maxsize= 1;
	bool collisiondetection, vertical;
	     collisiondetection= vertical= false;
	std::string texture = "";
	const char *playername = "";

	if (lua_gettop(L) > 1) //deprecated
	{
		log_deprecated(L,"Deprecated add_particlespawner call with individual parameters instead of definition");
		amount = luaL_checknumber(L, 1);
		time = luaL_checknumber(L, 2);
		minpos = check_v3f(L, 3);
		maxpos = check_v3f(L, 4);
		minvel = check_v3f(L, 5);
		maxvel = check_v3f(L, 6);
		minacc = check_v3f(L, 7);
		maxacc = check_v3f(L, 8);
		minexptime = luaL_checknumber(L, 9);
		maxexptime = luaL_checknumber(L, 10);
		minsize = luaL_checknumber(L, 11);
		maxsize = luaL_checknumber(L, 12);
		collisiondetection = lua_toboolean(L, 13);
		texture = luaL_checkstring(L, 14);
		if (lua_gettop(L) == 15) // only spawn for a single player
			playername = luaL_checkstring(L, 15);
	}
	else if (lua_istable(L, 1))
	{
		int table = lua_gettop(L);
		lua_pushnil(L);
		while (lua_next(L, table) != 0)
		{
			const char *key = lua_tostring(L, -2);
			      if(strcmp(key,"amount")==0){
					amount=luaL_checknumber(L, -1);
			}else if(strcmp(key,"time")==0){
					time=luaL_checknumber(L, -1);
			}else if(strcmp(key,"minpos")==0){
					minpos=check_v3f(L, -1);
			}else if(strcmp(key,"maxpos")==0){
					maxpos=check_v3f(L, -1);
			}else if(strcmp(key,"minvel")==0){
					minvel=check_v3f(L, -1);
			}else if(strcmp(key,"maxvel")==0){
					maxvel=check_v3f(L, -1);
			}else if(strcmp(key,"minacc")==0){
					minacc=check_v3f(L, -1);
			}else if(strcmp(key,"maxacc")==0){
					maxacc=check_v3f(L, -1);
			}else if(strcmp(key,"minexptime")==0){
					minexptime=luaL_checknumber(L, -1);
			}else if(strcmp(key,"maxexptime")==0){
					maxexptime=luaL_checknumber(L, -1);
			}else if(strcmp(key,"minsize")==0){
					minsize=luaL_checknumber(L, -1);
			}else if(strcmp(key,"maxsize")==0){
					maxsize=luaL_checknumber(L, -1);
			}else if(strcmp(key,"collisiondetection")==0){
					collisiondetection=lua_toboolean(L, -1);
			}else if(strcmp(key,"vertical")==0){
					vertical=lua_toboolean(L, -1);
			}else if(strcmp(key,"texture")==0){
					texture=luaL_checkstring(L, -1);
			}else if(strcmp(key,"playername")==0){
					playername=luaL_checkstring(L, -1);
			}
			lua_pop(L, 1);
		}
	}
	if (strcmp(playername, "")==0) //spawn for all players
	{
		u32 id = getServer(L)->addParticleSpawnerAll(	amount, time,
							minpos, maxpos,
							minvel, maxvel,
							minacc, maxacc,
							minexptime, maxexptime,
							minsize, maxsize,
							collisiondetection,
							vertical,
							texture);
		lua_pushnumber(L, id);
	}
	else
	{
		u32 id = getServer(L)->addParticleSpawner(playername,
							amount, time,
							minpos, maxpos,
							minvel, maxvel,
							minacc, maxacc,
							minexptime, maxexptime,
							minsize, maxsize,
							collisiondetection,
							vertical,
							texture);
		lua_pushnumber(L, id);
	}
	return 1;
}

// delete_particlespawner(id, player)
// player (string) is optional
int ModApiParticles::l_delete_particlespawner(lua_State *L)
{
	// Get parameters
	u32 id = luaL_checknumber(L, 1);

	if (lua_gettop(L) == 2) // only delete for one player
	{
		const char *playername = luaL_checkstring(L, 2);
		getServer(L)->deleteParticleSpawner(playername, id);
	}
	else // delete for all players
	{
		getServer(L)->deleteParticleSpawnerAll(id);
	}
	return 1;
}

void ModApiParticles::Initialize(lua_State *L, int top)
{
	API_FCT(add_particle);
	API_FCT(add_particlespawner);
	API_FCT(delete_particlespawner);
}

span> params.WindowSize = core::dimension2d<u32>(screen_w, screen_h); params.Bits = bits; params.AntiAlias = fsaa; params.Fullscreen = fullscreen; params.Stencilbuffer = false; params.Stereobuffer = stereo_buffer; params.Vsync = vsync; params.EventReceiver = receiver; params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu"); params.ZBufferBits = 24; #ifdef __ANDROID__ params.PrivateData = porting::app_global; params.OGLES2ShaderPath = std::string( porting::path_user + DIR_DELIM + "media" + DIR_DELIM + "Shaders" + DIR_DELIM).c_str(); #endif m_device = createDeviceEx(params); s_singleton = this; } RenderingEngine::~RenderingEngine() { m_device->drop(); s_singleton = nullptr; } v2u32 RenderingEngine::getWindowSize() const { return m_device->getVideoDriver()->getScreenSize(); } void RenderingEngine::setResizable(bool resize) { m_device->setResizable(resize); } video::IVideoDriver *RenderingEngine::getVideoDriver() { return m_device->getVideoDriver(); } bool RenderingEngine::print_video_modes() { IrrlichtDevice *nulldevice; bool vsync = g_settings->getBool("vsync"); u16 fsaa = g_settings->getU16("fsaa"); MyEventReceiver *receiver = new MyEventReceiver(); SIrrlichtCreationParameters params = SIrrlichtCreationParameters(); params.DriverType = video::EDT_NULL; params.WindowSize = core::dimension2d<u32>(640, 480); params.Bits = 24; params.AntiAlias = fsaa; params.Fullscreen = false; params.Stencilbuffer = false; params.Vsync = vsync; params.EventReceiver = receiver; params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu"); nulldevice = createDeviceEx(params); if (!nulldevice) { delete receiver; return false; } std::cout << _("Available video modes (WxHxD):") << std::endl; video::IVideoModeList *videomode_list = nulldevice->getVideoModeList(); if (videomode_list != NULL) { s32 videomode_count = videomode_list->getVideoModeCount(); core::dimension2d<u32> videomode_res; s32 videomode_depth; for (s32 i = 0; i < videomode_count; ++i) { videomode_res = videomode_list->getVideoModeResolution(i); videomode_depth = videomode_list->getVideoModeDepth(i); std::cout << videomode_res.Width << "x" << videomode_res.Height << "x" << videomode_depth << std::endl; } std::cout << _("Active video mode (WxHxD):") << std::endl; videomode_res = videomode_list->getDesktopResolution(); videomode_depth = videomode_list->getDesktopDepth(); std::cout << videomode_res.Width << "x" << videomode_res.Height << "x" << videomode_depth << std::endl; } nulldevice->drop(); delete receiver; return videomode_list != NULL; } void RenderingEngine::setXorgClassHint( const video::SExposedVideoData &video_data, const std::string &name) { #ifdef XORG_USED if (video_data.OpenGLLinux.X11Display == NULL) return; XClassHint *classhint = XAllocClassHint(); classhint->res_name = (char *)name.c_str(); classhint->res_class = (char *)name.c_str(); XSetClassHint((Display *)video_data.OpenGLLinux.X11Display, video_data.OpenGLLinux.X11Window, classhint); XFree(classhint); #endif } bool RenderingEngine::setWindowIcon() { #if defined(XORG_USED) #if RUN_IN_PLACE return setXorgWindowIconFromPath( porting::path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png"); #else // We have semi-support for reading in-place data if we are // compiled with RUN_IN_PLACE. Don't break with this and // also try the path_share location. return setXorgWindowIconFromPath( ICON_DIR "/hicolor/128x128/apps/" PROJECT_NAME ".png") || setXorgWindowIconFromPath(porting::path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png"); #endif #elif defined(_WIN32) const video::SExposedVideoData exposedData = m_device->getVideoDriver()->getExposedVideoData(); HWND hWnd; // Window handle switch (m_device->getVideoDriver()->getDriverType()) { case video::EDT_DIRECT3D8: hWnd = reinterpret_cast<HWND>(exposedData.D3D8.HWnd); break; case video::EDT_DIRECT3D9: hWnd = reinterpret_cast<HWND>(exposedData.D3D9.HWnd); break; case video::EDT_OPENGL: hWnd = reinterpret_cast<HWND>(exposedData.OpenGLWin32.HWnd); break; default: return false; } // Load the ICON from resource file const HICON hicon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(130) // The ID of the ICON defined in // winresource.rc ); if (hicon) { SendMessage(hWnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(hicon)); SendMessage(hWnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(hicon)); return true; } return false; #else return false; #endif } bool RenderingEngine::setXorgWindowIconFromPath(const std::string &icon_file) { #ifdef XORG_USED video::IVideoDriver *v_driver = m_device->getVideoDriver(); video::IImageLoader *image_loader = NULL; u32 cnt = v_driver->getImageLoaderCount(); for (u32 i = 0; i < cnt; i++) { if (v_driver->getImageLoader(i)->isALoadableFileExtension( icon_file.c_str())) { image_loader = v_driver->getImageLoader(i); break; } } if (!image_loader) { warningstream << "Could not find image loader for file '" << icon_file << "'" << std::endl; return false; } io::IReadFile *icon_f = m_device->getFileSystem()->createAndOpenFile(icon_file.c_str()); if (!icon_f) { warningstream << "Could not load icon file '" << icon_file << "'" << std::endl; return false; } video::IImage *img = image_loader->loadImage(icon_f); if (!img) { warningstream << "Could not load icon file '" << icon_file << "'" << std::endl; icon_f->drop(); return false; } u32 height = img->getDimension().Height; u32 width = img->getDimension().Width; size_t icon_buffer_len = 2 + height * width; long *icon_buffer = new long[icon_buffer_len]; icon_buffer[0] = width; icon_buffer[1] = height; for (u32 x = 0; x < width; x++) { for (u32 y = 0; y < height; y++) { video::SColor col = img->getPixel(x, y); long pixel_val = 0; pixel_val |= (u8)col.getAlpha() << 24; pixel_val |= (u8)col.getRed() << 16; pixel_val |= (u8)col.getGreen() << 8; pixel_val |= (u8)col.getBlue(); icon_buffer[2 + x + y * width] = pixel_val; } } img->drop(); icon_f->drop(); const video::SExposedVideoData &video_data = v_driver->getExposedVideoData(); Display *x11_dpl = (Display *)video_data.OpenGLLinux.X11Display; if (x11_dpl == NULL) { warningstream << "Could not find x11 display for setting its icon." << std::endl; delete[] icon_buffer; return false; } Window x11_win = (Window)video_data.OpenGLLinux.X11Window; Atom net_wm_icon = XInternAtom(x11_dpl, "_NET_WM_ICON", False); Atom cardinal = XInternAtom(x11_dpl, "CARDINAL", False); XChangeProperty(x11_dpl, x11_win, net_wm_icon, cardinal, 32, PropModeReplace, (const unsigned char *)icon_buffer, icon_buffer_len); delete[] icon_buffer; #endif return true; } /* Draws a screen with a single text on it. Text will be removed when the screen is drawn the next time. Additionally, a progressbar can be drawn when percent is set between 0 and 100. */ void RenderingEngine::_draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv, ITextureSource *tsrc, float dtime, int percent, bool clouds) { v2u32 screensize = RenderingEngine::get_instance()->getWindowSize(); v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight()); v2s32 center(screensize.X / 2, screensize.Y / 2); core::rect<s32> textrect(center - textsize / 2, center + textsize / 2); gui::IGUIStaticText *guitext = guienv->addStaticText(text.c_str(), textrect, false, false); guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds"); if (cloud_menu_background) { g_menuclouds->step(dtime * 3); g_menuclouds->render(); get_video_driver()->beginScene( true, true, video::SColor(255, 140, 186, 250)); g_menucloudsmgr->drawAll(); } else get_video_driver()->beginScene(true, true, video::SColor(255, 0, 0, 0)); // draw progress bar if ((percent >= 0) && (percent <= 100)) { video::ITexture *progress_img = tsrc->getTexture("progress_bar.png"); video::ITexture *progress_img_bg = tsrc->getTexture("progress_bar_bg.png"); if (progress_img && progress_img_bg) { #ifndef __ANDROID__ const core::dimension2d<u32> &img_size = progress_img_bg->getSize(); u32 imgW = rangelim(img_size.Width, 200, 600); u32 imgH = rangelim(img_size.Height, 24, 72); #else const core::dimension2d<u32> img_size(256, 48); float imgRatio = (float)img_size.Height / img_size.Width; u32 imgW = screensize.X / 2.2f; u32 imgH = floor(imgW * imgRatio); #endif v2s32 img_pos((screensize.X - imgW) / 2, (screensize.Y - imgH) / 2); draw2DImageFilterScaled(get_video_driver(), progress_img_bg, core::rect<s32>(img_pos.X, img_pos.Y, img_pos.X + imgW, img_pos.Y + imgH), core::rect<s32>(0, 0, img_size.Width, img_size.Height), 0, 0, true); draw2DImageFilterScaled(get_video_driver(), progress_img, core::rect<s32>(img_pos.X, img_pos.Y, img_pos.X + (percent * imgW) / 100, img_pos.Y + imgH), core::rect<s32>(0, 0, (percent * img_size.Width) / 100, img_size.Height), 0, 0, true); } } guienv->drawAll(); get_video_driver()->endScene(); guitext->remove(); } std::vector<core::vector3d<u32>> RenderingEngine::getSupportedVideoModes() { IrrlichtDevice *nulldevice = createDevice(video::EDT_NULL); sanity_check(nulldevice); std::vector<core::vector3d<u32>> mlist; video::IVideoModeList *modelist = nulldevice->getVideoModeList(); s32 num_modes = modelist->getVideoModeCount(); for (s32 i = 0; i != num_modes; i++) { core::dimension2d<u32> mode_res = modelist->getVideoModeResolution(i); u32 mode_depth = (u32)modelist->getVideoModeDepth(i); mlist.push_back(core::vector3d<u32>( mode_res.Width, mode_res.Height, mode_depth)); } nulldevice->drop(); return mlist; } std::vector<irr::video::E_DRIVER_TYPE> RenderingEngine::getSupportedVideoDrivers() { std::vector<irr::video::E_DRIVER_TYPE> drivers; for (int i = 0; i != irr::video::EDT_COUNT; i++) { if (irr::IrrlichtDevice::isDriverSupported((irr::video::E_DRIVER_TYPE)i)) drivers.push_back((irr::video::E_DRIVER_TYPE)i); } return drivers; } void RenderingEngine::_draw_scene(Camera *camera, Client *client, LocalPlayer *player, Hud *hud, Minimap *mapper, gui::IGUIEnvironment *guienv, const v2u32 &screensize, const video::SColor &skycolor, bool show_hud, bool show_minimap) { bool draw_wield_tool = (show_hud && (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) && camera->getCameraMode() < CAMERA_MODE_THIRD); bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) && (camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT)); #ifdef HAVE_TOUCHSCREENGUI try { draw_crosshair = !g_settings->getBool("touchtarget"); } catch (SettingNotFoundException) { } #endif const std::string &draw_mode = g_settings->get("3d_mode"); if (draw_mode == "anaglyph") { draw_anaglyph_3d_mode( camera, show_hud, hud, draw_wield_tool, client, guienv); draw_crosshair = false; } else if (draw_mode == "interlaced") { draw_interlaced_3d_mode(camera, show_hud, hud, screensize, draw_wield_tool, client, guienv, skycolor); draw_crosshair = false; } else if (draw_mode == "sidebyside") { draw_sidebyside_3d_mode(camera, show_hud, hud, screensize, draw_wield_tool, client, guienv, skycolor); show_hud = false; } else if (draw_mode == "topbottom") { draw_top_bottom_3d_mode(camera, show_hud, hud, screensize, draw_wield_tool, client, guienv, skycolor); show_hud = false; } else if (draw_mode == "pageflip") { draw_pageflip_3d_mode(camera, show_hud, hud, screensize, draw_wield_tool, client, guienv, skycolor); draw_crosshair = false; show_hud = false; } else { draw_plain(camera, show_hud, hud, screensize, draw_wield_tool, client, guienv, skycolor); } /* Post effects */ client->getEnv().getClientMap().renderPostFx(camera->getCameraMode()); // TODO how to make those 3d too if (show_hud) { if (draw_crosshair) hud->drawCrosshair(); hud->drawHotbar(client->getPlayerItem()); hud->drawLuaElements(camera->getOffset()); camera->drawNametags(); if (mapper && show_minimap) mapper->drawMinimap(); } guienv->drawAll(); } void RenderingEngine::draw_anaglyph_3d_mode(Camera *camera, bool show_hud, Hud *hud, bool draw_wield_tool, Client *client, gui::IGUIEnvironment *guienv) { /* preserve old setup*/ irr::core::vector3df oldPosition = camera->getCameraNode()->getPosition(); irr::core::vector3df oldTarget = camera->getCameraNode()->getTarget(); irr::core::matrix4 startMatrix = camera->getCameraNode()->getAbsoluteTransformation(); irr::core::vector3df focusPoint = (camera->getCameraNode()->getTarget() - camera->getCameraNode()->getAbsolutePosition()) .setLength(1) + camera->getCameraNode()->getAbsolutePosition(); // Left eye... irr::core::vector3df leftEye; irr::core::matrix4 leftMove; leftMove.setTranslation(irr::core::vector3df( -g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f)); leftEye = (startMatrix * leftMove).getTranslation(); // clear the depth buffer, and color getVideoDriver()->beginScene(true, true, irr::video::SColor(0, 200, 200, 255)); getVideoDriver()->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED; getVideoDriver()->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK; getVideoDriver()->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW; camera->getCameraNode()->setPosition(leftEye); camera->getCameraNode()->setTarget(focusPoint); get_scene_manager()->drawAll(); getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix); if (show_hud) { hud->drawSelectionMesh(); if (draw_wield_tool) camera->drawWieldedTool(&leftMove); } guienv->drawAll(); // Right eye... irr::core::vector3df rightEye; irr::core::matrix4 rightMove; rightMove.setTranslation(irr::core::vector3df( g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f)); rightEye = (startMatrix * rightMove).getTranslation(); // clear the depth buffer getVideoDriver()->clearZBuffer(); getVideoDriver()->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN + irr::video::ECP_BLUE; getVideoDriver()->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK; getVideoDriver()->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW; camera->getCameraNode()->setPosition(rightEye); camera->getCameraNode()->setTarget(focusPoint); get_scene_manager()->drawAll(); getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix); if (show_hud) { hud->drawSelectionMesh(); if (draw_wield_tool) camera->drawWieldedTool(&rightMove); } guienv->drawAll(); getVideoDriver()->getOverrideMaterial().Material.ColorMask = irr::video::ECP_ALL; getVideoDriver()->getOverrideMaterial().EnableFlags = 0; getVideoDriver()->getOverrideMaterial().EnablePasses = 0; camera->getCameraNode()->setPosition(oldPosition); camera->getCameraNode()->setTarget(oldTarget); } void RenderingEngine::init_texture( const v2u32 &screensize, video::ITexture **texture, const char *name) { if (*texture) { getVideoDriver()->removeTexture(*texture); } *texture = getVideoDriver()->addRenderTargetTexture( core::dimension2d<u32>(screensize.X, screensize.Y), name, irr::video::ECF_A8R8G8B8); } video::ITexture *RenderingEngine::draw_image(const v2u32 &screensize, parallax_sign psign, const irr::core::matrix4 &startMatrix, const irr::core::vector3df &focusPoint, bool show_hud, Camera *camera, Hud *hud, bool draw_wield_tool, Client *client, gui::IGUIEnvironment *guienv, const video::SColor &skycolor) { static video::ITexture *images[2] = {NULL, NULL}; static v2u32 last_screensize = v2u32(0, 0); video::ITexture *image = NULL; if (screensize != last_screensize) { init_texture(screensize, &images[1], "mt_drawimage_img1"); init_texture(screensize, &images[0], "mt_drawimage_img2"); last_screensize = screensize; } if (psign == RIGHT) image = images[1]; else image = images[0]; getVideoDriver()->setRenderTarget(image, true, true, irr::video::SColor(255, skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue())); irr::core::vector3df eye_pos; irr::core::matrix4 movement; movement.setTranslation(irr::core::vector3df( (int)psign * g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f)); eye_pos = (startMatrix * movement).getTranslation(); // clear the depth buffer