summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/SCsub1
-rw-r--r--drivers/coreaudio/SCsub8
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp315
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h89
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp51
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h8
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp10
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp4
-rw-r--r--drivers/gles3/shaders/canvas.glsl12
-rw-r--r--drivers/gles3/shaders/scene.glsl166
-rw-r--r--drivers/unix/file_access_unix.cpp6
-rw-r--r--drivers/unix/file_access_unix.h1
-rw-r--r--drivers/unix/os_unix.cpp93
-rw-r--r--drivers/unix/os_unix.h12
-rw-r--r--drivers/unix/syslog_logger.cpp71
-rw-r--r--drivers/unix/syslog_logger.h48
-rw-r--r--drivers/windows/dir_access_windows.cpp2
-rw-r--r--drivers/windows/file_access_windows.cpp6
-rw-r--r--drivers/windows/file_access_windows.h1
19 files changed, 733 insertions, 171 deletions
diff --git a/drivers/SCsub b/drivers/SCsub
index 195f7ec438..34d6254578 100644
--- a/drivers/SCsub
+++ b/drivers/SCsub
@@ -13,6 +13,7 @@ SConscript('windows/SCsub')
# Sounds drivers
SConscript('alsa/SCsub')
+SConscript('coreaudio/SCsub')
SConscript('pulseaudio/SCsub')
if (env["platform"] == "windows"):
SConscript("rtaudio/SCsub")
diff --git a/drivers/coreaudio/SCsub b/drivers/coreaudio/SCsub
new file mode 100644
index 0000000000..233593b0f9
--- /dev/null
+++ b/drivers/coreaudio/SCsub
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+Import('env')
+
+# Driver source files
+env.add_source_files(env.drivers_sources, "*.cpp")
+
+Export('env')
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
new file mode 100644
index 0000000000..c531d6af9d
--- /dev/null
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -0,0 +1,315 @@
+/*************************************************************************/
+/* audio_driver_coreaudio.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifdef COREAUDIO_ENABLED
+
+#include "audio_driver_coreaudio.h"
+#include "core/project_settings.h"
+#include "os/os.h"
+
+#define kOutputBus 0
+
+#ifdef OSX_ENABLED
+static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *__nullable inClientData) {
+ AudioDriverCoreAudio *driver = (AudioDriverCoreAudio *)inClientData;
+
+ driver->reopen();
+
+ return noErr;
+}
+#endif
+
+Error AudioDriverCoreAudio::initDevice() {
+ AudioComponentDescription desc;
+ zeromem(&desc, sizeof(desc));
+ desc.componentType = kAudioUnitType_Output;
+#ifdef OSX_ENABLED
+ desc.componentSubType = kAudioUnitSubType_HALOutput;
+#else
+ desc.componentSubType = kAudioUnitSubType_RemoteIO;
+#endif
+ desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+
+ AudioComponent comp = AudioComponentFindNext(NULL, &desc);
+ ERR_FAIL_COND_V(comp == NULL, FAILED);
+
+ OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ AudioStreamBasicDescription strdesc;
+
+ zeromem(&strdesc, sizeof(strdesc));
+ UInt32 size = sizeof(strdesc);
+ result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &strdesc, &size);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ switch (strdesc.mChannelsPerFrame) {
+ case 2: // Stereo
+ case 4: // Surround 3.1
+ case 6: // Surround 5.1
+ case 8: // Surround 7.1
+ channels = strdesc.mChannelsPerFrame;
+ break;
+
+ default:
+ // Unknown number of channels, default to stereo
+ channels = 2;
+ break;
+ }
+
+ mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
+
+ zeromem(&strdesc, sizeof(strdesc));
+ strdesc.mFormatID = kAudioFormatLinearPCM;
+ strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
+ strdesc.mChannelsPerFrame = channels;
+ strdesc.mSampleRate = mix_rate;
+ strdesc.mFramesPerPacket = 1;
+ strdesc.mBitsPerChannel = 16;
+ strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
+ strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
+
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
+ buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
+
+#ifdef OSX_ENABLED
+ result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+#endif
+
+ buffer_size = buffer_frames * channels;
+ samples_in.resize(buffer_size);
+
+ if (OS::get_singleton()->is_stdout_verbose()) {
+ print_line("CoreAudio: detected " + itos(channels) + " channels");
+ print_line("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
+ }
+
+ AURenderCallbackStruct callback;
+ zeromem(&callback, sizeof(AURenderCallbackStruct));
+ callback.inputProc = &AudioDriverCoreAudio::output_callback;
+ callback.inputProcRefCon = this;
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ result = AudioUnitInitialize(audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ return OK;
+}
+
+Error AudioDriverCoreAudio::finishDevice() {
+ OSStatus result;
+
+ if (active) {
+ result = AudioOutputUnitStop(audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ active = false;
+ }
+
+ result = AudioUnitUninitialize(audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ return OK;
+}
+
+Error AudioDriverCoreAudio::init() {
+ OSStatus result;
+
+ mutex = Mutex::create();
+ active = false;
+ channels = 2;
+
+#ifdef OSX_ENABLED
+ outputDeviceAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+ outputDeviceAddress.mScope = kAudioObjectPropertyScopeGlobal;
+ outputDeviceAddress.mElement = kAudioObjectPropertyElementMaster;
+
+ result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+#endif
+
+ return initDevice();
+};
+
+Error AudioDriverCoreAudio::reopen() {
+ bool restart = false;
+
+ lock();
+
+ if (active) {
+ restart = true;
+ }
+
+ Error err = finishDevice();
+ if (err != OK) {
+ ERR_PRINT("finishDevice failed");
+ unlock();
+ return err;
+ }
+
+ err = initDevice();
+ if (err != OK) {
+ ERR_PRINT("initDevice failed");
+ unlock();
+ return err;
+ }
+
+ if (restart) {
+ start();
+ }
+
+ unlock();
+
+ return OK;
+}
+
+OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber, UInt32 inNumberFrames,
+ AudioBufferList *ioData) {
+
+ AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon;
+
+ if (!ad->active || !ad->try_lock()) {
+ for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
+ AudioBuffer *abuf = &ioData->mBuffers[i];
+ zeromem(abuf->mData, abuf->mDataByteSize);
+ };
+ return 0;
+ };
+
+ for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
+
+ AudioBuffer *abuf = &ioData->mBuffers[i];
+ int frames_left = inNumberFrames;
+ int16_t *out = (int16_t *)abuf->mData;
+
+ while (frames_left) {
+
+ int frames = MIN(frames_left, ad->buffer_frames);
+ ad->audio_server_process(frames, ad->samples_in.ptr());
+
+ for (int j = 0; j < frames * ad->channels; j++) {
+
+ out[j] = ad->samples_in[j] >> 16;
+ }
+
+ frames_left -= frames;
+ out += frames * ad->channels;
+ };
+ };
+
+ ad->unlock();
+
+ return 0;
+};
+
+void AudioDriverCoreAudio::start() {
+ if (!active) {
+ OSStatus result = AudioOutputUnitStart(audio_unit);
+ if (result != noErr) {
+ ERR_PRINT("AudioOutputUnitStart failed");
+ } else {
+ active = true;
+ }
+ }
+};
+
+int AudioDriverCoreAudio::get_mix_rate() const {
+ return mix_rate;
+};
+
+AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const {
+ return get_speaker_mode_by_total_channels(channels);
+};
+
+void AudioDriverCoreAudio::lock() {
+ if (mutex)
+ mutex->lock();
+};
+
+void AudioDriverCoreAudio::unlock() {
+ if (mutex)
+ mutex->unlock();
+};
+
+bool AudioDriverCoreAudio::try_lock() {
+ if (mutex)
+ return mutex->try_lock() == OK;
+ return true;
+}
+
+void AudioDriverCoreAudio::finish() {
+ OSStatus result;
+
+ finishDevice();
+
+#ifdef OSX_ENABLED
+ result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
+ if (result != noErr) {
+ ERR_PRINT("AudioObjectRemovePropertyListener failed");
+ }
+#endif
+
+ AURenderCallbackStruct callback;
+ zeromem(&callback, sizeof(AURenderCallbackStruct));
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
+ if (result != noErr) {
+ ERR_PRINT("AudioUnitSetProperty failed");
+ }
+
+ if (mutex) {
+ memdelete(mutex);
+ mutex = NULL;
+ }
+};
+
+AudioDriverCoreAudio::AudioDriverCoreAudio() {
+ active = false;
+ mutex = NULL;
+
+ mix_rate = 0;
+ channels = 2;
+
+ buffer_size = 0;
+ buffer_frames = 0;
+
+ samples_in.clear();
+};
+
+AudioDriverCoreAudio::~AudioDriverCoreAudio(){};
+
+#endif
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
new file mode 100644
index 0000000000..33b3ba93ec
--- /dev/null
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -0,0 +1,89 @@
+/*************************************************************************/
+/* audio_driver_coreaudio.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifdef COREAUDIO_ENABLED
+
+#ifndef AUDIO_DRIVER_COREAUDIO_H
+#define AUDIO_DRIVER_COREAUDIO_H
+
+#include "servers/audio_server.h"
+
+#include <AudioUnit/AudioUnit.h>
+#ifdef OSX_ENABLED
+#include <CoreAudio/AudioHardware.h>
+#endif
+
+class AudioDriverCoreAudio : public AudioDriver {
+
+ AudioComponentInstance audio_unit;
+#ifdef OSX_ENABLED
+ AudioObjectPropertyAddress outputDeviceAddress;
+#endif
+ bool active;
+ Mutex *mutex;
+
+ int mix_rate;
+ unsigned int channels;
+ unsigned int buffer_frames;
+ unsigned int buffer_size;
+
+ Vector<int32_t> samples_in;
+
+ static OSStatus output_callback(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp *inTimeStamp,
+ UInt32 inBusNumber, UInt32 inNumberFrames,
+ AudioBufferList *ioData);
+
+ Error initDevice();
+ Error finishDevice();
+
+public:
+ const char *get_name() const {
+ return "CoreAudio";
+ };
+
+ virtual Error init();
+ virtual void start();
+ virtual int get_mix_rate() const;
+ virtual SpeakerMode get_speaker_mode() const;
+ virtual void lock();
+ virtual void unlock();
+ virtual void finish();
+
+ bool try_lock();
+ Error reopen();
+
+ AudioDriverCoreAudio();
+ ~AudioDriverCoreAudio();
+};
+
+#endif
+
+#endif
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 98a9211d0c..eaf0b06664 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "rasterizer_scene_gles3.h"
-
+#include "math_funcs.h"
#include "os/os.h"
#include "project_settings.h"
#include "rasterizer_canvas_gles3.h"
@@ -799,12 +799,12 @@ void RasterizerSceneGLES3::environment_set_sky(RID p_env, RID p_sky) {
env->sky = p_sky;
}
-void RasterizerSceneGLES3::environment_set_sky_scale(RID p_env, float p_scale) {
+void RasterizerSceneGLES3::environment_set_sky_custom_fov(RID p_env, float p_scale) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- env->sky_scale = p_scale;
+ env->sky_custom_fov = p_scale;
}
void RasterizerSceneGLES3::environment_set_bg_color(RID p_env, const Color &p_color) {
@@ -2319,7 +2319,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
}
}
-void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy) {
+void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) {
if (!p_sky)
return;
@@ -2365,16 +2365,28 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
//sky uv vectors
float vw, vh, zn;
- p_projection.get_viewport_size(vw, vh);
- zn = p_projection.get_z_near();
+ CameraMatrix camera;
+
+ if (p_custom_fov) {
+
+ float near_plane = p_projection.get_z_near();
+ float far_plane = p_projection.get_z_far();
+ float aspect = p_projection.get_aspect();
+
+ camera.set_perspective(p_custom_fov, aspect, near_plane, far_plane);
- float scale = p_scale;
+ } else {
+ camera = p_projection;
+ }
+
+ camera.get_viewport_size(vw, vh);
+ zn = p_projection.get_z_near();
for (int i = 0; i < 4; i++) {
Vector3 uv = vertices[i * 2 + 1];
- uv.x = (uv.x * 2.0 - 1.0) * vw * scale;
- uv.y = -(uv.y * 2.0 - 1.0) * vh * scale;
+ uv.x = (uv.x * 2.0 - 1.0) * vw;
+ uv.y = -(uv.y * 2.0 - 1.0) * vh;
uv.z = -zn;
vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
@@ -2522,9 +2534,10 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
float sign = li->light_ptr->negative ? -1 : 1;
Color linear_col = li->light_ptr->color.to_linear();
- ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
- ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
- ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
+ //compensate normalized diffuse range by multiplying by PI
+ ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
+ ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
+ ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
ubo_data.light_color_energy[3] = 0;
//omni, keep at 0
@@ -2662,9 +2675,9 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
float sign = li->light_ptr->negative ? -1 : 1;
Color linear_col = li->light_ptr->color.to_linear();
- ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
- ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
- ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
+ ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
+ ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
+ ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
ubo_data.light_color_energy[3] = 0;
Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin);
@@ -2748,9 +2761,9 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
float sign = li->light_ptr->negative ? -1 : 1;
Color linear_col = li->light_ptr->color.to_linear();
- ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
- ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
- ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
+ ubo_data.light_color_energy[0] = linear_col.r * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
+ ubo_data.light_color_energy[1] = linear_col.g * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
+ ubo_data.light_color_energy[2] = linear_col.b * sign * li->light_ptr->param[VS::LIGHT_PARAM_ENERGY] * Math_PI;
ubo_data.light_color_energy[3] = 0;
Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin);
@@ -4258,7 +4271,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); //switch to alpha fbo for sky, only diffuse/ambient matters
*/
- _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_scale, env->bg_energy);
+ _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_custom_fov, env->bg_energy);
}
//_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 04cb3597da..28a5cef0ee 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -352,7 +352,7 @@ public:
VS::EnvironmentBG bg_mode;
RID sky;
- float sky_scale;
+ float sky_custom_fov;
Color bg_color;
float bg_energy;
@@ -435,7 +435,7 @@ public:
Environment() {
bg_mode = VS::ENV_BG_CLEAR_COLOR;
- sky_scale = 1.0;
+ sky_custom_fov = 0.0;
bg_energy = 1.0;
sky_ambient = 0;
ambient_energy = 1.0;
@@ -520,7 +520,7 @@ public:
virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg);
virtual void environment_set_sky(RID p_env, RID p_sky);
- virtual void environment_set_sky_scale(RID p_env, float p_scale);
+ virtual void environment_set_sky_custom_fov(RID p_env, float p_scale);
virtual void environment_set_bg_color(RID p_env, const Color &p_color);
virtual void environment_set_bg_energy(RID p_env, float p_energy);
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer);
@@ -811,7 +811,7 @@ public:
_FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass);
- void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy);
+ void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy);
void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform);
void _setup_directional_light(int p_index, const Transform &p_camera_inverse_transform, bool p_use_shadows);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index ae41a936c6..44a9909bd7 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -2473,7 +2473,7 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
glGenBuffers(1, &material->ubo_id);
glBindBuffer(GL_UNIFORM_BUFFER, material->ubo_id);
- glBufferData(GL_UNIFORM_BUFFER, material->shader->ubo_size, NULL, GL_DYNAMIC_DRAW);
+ glBufferData(GL_UNIFORM_BUFFER, material->shader->ubo_size, NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
material->ubo_size = material->shader->ubo_size;
}
@@ -3768,7 +3768,7 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
glGenBuffers(1, &multimesh->buffer);
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
- glBufferData(GL_ARRAY_BUFFER, multimesh->data.size() * sizeof(float), NULL, GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, multimesh->data.size() * sizeof(float), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
@@ -5215,7 +5215,7 @@ void RasterizerStorageGLES3::particles_set_amount(RID p_particles, int p_amount)
glBindVertexArray(particles->particle_vaos[i]);
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[i]);
- glBufferData(GL_ARRAY_BUFFER, floats * sizeof(float), data, GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, floats * sizeof(float), data, GL_STATIC_DRAW);
for (int i = 0; i < 6; i++) {
glEnableVertexAttribArray(i);
@@ -6198,7 +6198,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
rt->buffers.effects_active = true;
}
- if (!rt->flags[RENDER_TARGET_NO_SAMPLING]) {
+ if (!rt->flags[RENDER_TARGET_NO_SAMPLING] && rt->width >= 2 && rt->height >= 2) {
for (int i = 0; i < 2; i++) {
@@ -6511,7 +6511,7 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
if (!co->vertex_id) {
glGenBuffers(1, &co->vertex_id);
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
} else {
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index b173958664..91159e3381 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -700,9 +700,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
/** CANVAS ITEM SHADER **/
- actions[VS::SHADER_CANVAS_ITEM].renames["SRC_VERTEX"] = "vertex";
actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
- actions[VS::SHADER_CANVAS_ITEM].renames["VERTEX_COLOR"] = "vertex_color";
actions[VS::SHADER_CANVAS_ITEM].renames["UV"] = "uv_interp";
actions[VS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "gl_PointSize";
@@ -711,6 +709,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] == "extra_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time";
actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass";
+ actions[VS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom";
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal";
@@ -720,6 +719,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE"] = "color_texture";
actions[VS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size";
+ actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL_TEXTURE"] = "normal_texture";
actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_UV"] = "screen_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_TEXTURE"] = "screen_texture";
actions[VS::SHADER_CANVAS_ITEM].renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size";
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index bf8eaf601d..731d6968ce 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -105,13 +105,16 @@ VERTEX_SHADER_GLOBALS
void main() {
- vec4 vertex_color = color_attrib;
+ vec4 color = color_attrib;
#ifdef USE_INSTANCING
mat4 extra_matrix2 = extra_matrix * transpose(mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0)));
- vertex_color*=instance_color;
+ color*=instance_color;
+ vec4 instance_custom = instance_custom_data;
+
#else
mat4 extra_matrix2 = extra_matrix;
+ vec4 instance_custom = vec4(0.0);
#endif
#ifdef USE_TEXTURE_RECT
@@ -135,7 +138,7 @@ void main() {
//compute h and v frames and adjust UV interp for animation
int total_frames = h_frames * v_frames;
- int frame = min(int(float(total_frames) *instance_custom_data.z),total_frames-1);
+ int frame = min(int(float(total_frames) *instance_custom.z),total_frames-1);
float frame_w = 1.0/float(h_frames);
float frame_h = 1.0/float(v_frames);
uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames);
@@ -146,7 +149,6 @@ void main() {
#define extra_matrix extra_matrix2
{
- vec2 src_vtx=outvec.xy;
VERTEX_SHADER_CODE
@@ -165,7 +167,7 @@ VERTEX_SHADER_CODE
#undef extra_matrix
- color_interp = vertex_color;
+ color_interp = color;
#ifdef USE_PIXEL_SNAP
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 9b78430325..341a5bf2c7 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -1,5 +1,6 @@
[vertex]
+#define M_PI 3.14159265359
/*
from VisualServer:
@@ -163,10 +164,10 @@ uniform int spot_light_count;
out vec4 diffuse_light_interp;
out vec4 specular_light_interp;
-void light_compute(vec3 N, vec3 L,vec3 V, vec3 light_color,float roughness,inout vec3 diffuse, inout vec3 specular) {
+void light_compute(vec3 N, vec3 L,vec3 V, vec3 light_color, float roughness, inout vec3 diffuse, inout vec3 specular) {
float dotNL = max(dot(N,L), 0.0 );
- diffuse += dotNL * light_color;
+ diffuse += dotNL * light_color / M_PI;
if (roughness > 0.0) {
@@ -887,9 +888,13 @@ float GTR1(float NdotH, float a)
return (a2-1.0) / (M_PI*log(a2)*t);
}
+vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) {
+ float dielectric = (0.034 * 2.0) * specular;
+ // energy conservation
+ return mix(vec3(dielectric), albedo, metallic); // TODO: reference?
+}
-
-void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 attenuation,vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
+void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
@@ -903,40 +908,42 @@ LIGHT_SHADER_CODE
#else
-
- float dotNL = max(dot(N,L), 0.0 );
+ float NdotL = dot(N,L);
+ float cNdotL = max(NdotL, 0.0); // clamped NdotL
+ float NdotV = dot(N, V);
+ float cNdotV = max(NdotV, 0.0);
#if defined(DIFFUSE_OREN_NAYAR)
- vec3 light_amount;
+ vec3 diffuse_brdf_NL;
#else
- float light_amount;
+ float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance
#endif
#if defined(DIFFUSE_LAMBERT_WRAP)
//energy conserving lambert wrap shader
- light_amount = max(0.0,(dot(N,L) + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
+ diffuse_brdf_NL = max(0.0,(NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
#elif defined(DIFFUSE_OREN_NAYAR)
{
+ // see http://mimosa-pudica.net/improved-oren-nayar.html
float LdotV = dot(L, V);
- float NdotL = dot(L, N);
- float NdotV = dot(N, V);
+
float s = LdotV - NdotL * NdotV;
float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
- float sigma2 = roughness * roughness;
- vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33));
+ float sigma2 = roughness * roughness; // TODO: this needs checking
+ vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) );
float B = 0.45 * sigma2 / (sigma2 + 0.09);
- light_amount = max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
+ diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI);
}
#elif defined(DIFFUSE_TOON)
- light_amount = smoothstep(-roughness,max(roughness,0.01),dot(N,L));
+ diffuse_brdf_NL = smoothstep(-roughness,max(roughness,0.01),NdotL);
#elif defined(DIFFUSE_BURLEY)
@@ -944,40 +951,38 @@ LIGHT_SHADER_CODE
vec3 H = normalize(V + L);
- float NoL = max(0.0,dot(N, L));
- float LoH = max(0.0,dot(L, H));
- float NoV = max(0.0,dot(N, V));
-
- float FD90 = 0.5 + 2.0 * LoH * LoH * roughness;
- float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(NoV);
- float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(NoL);
- light_amount = ( (1.0 / M_PI) * FdV * FdL );
+ float cLdotH = max(0.0,dot(L, H));
+
+ float FD90 = 0.5 + 2.0 * cLdotH * cLdotH * roughness;
+ float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotV);
+ float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotL);
+ diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL;
/*
float energyBias = mix(roughness, 0.0, 0.5);
float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
float fd90 = energyBias + 2.0 * VoH * VoH * roughness;
float f0 = 1.0;
- float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NoL, 5.0);
- float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NoV, 5.0);
+ float lightScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotL, 5.0);
+ float viewScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotV, 5.0);
- light_amount = lightScatter * viewScatter * energyFactor;*/
+ diffuse_brdf_NL = lightScatter * viewScatter * energyFactor;*/
}
#else
//lambert
- light_amount = dotNL;
+ diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
#endif
#if defined(TRANSMISSION_USED)
- diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission) * attenuation;
+ diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation;
#else
- diffuse += light_color * diffuse_color * light_amount * attenuation;
+ diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
#endif
- float dotNV = max(dot(N,V), 0.0 );
+
#if defined(LIGHT_USE_RIM)
- float rim_light = pow(1.0-dotNV,(1.0-roughness)*16.0);
- diffuse += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
+ float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0);
+ diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
#endif
@@ -989,37 +994,37 @@ LIGHT_SHADER_CODE
#if defined(SPECULAR_BLINN)
vec3 H = normalize(V + L);
- float dotNH = max(dot(N,H), 0.0 );
- float intensity = pow( dotNH, (1.0-roughness) * 256.0);
- specular += light_color * intensity * specular_blob_intensity * attenuation;
+ float cNdotH = max(dot(N,H), 0.0 );
+ float intensity = pow( cNdotH, (1.0-roughness) * 256.0);
+ specular_light += light_color * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_PHONG)
vec3 R = normalize(-reflect(L,N));
- float dotNV = max(0.0,dot(R,V));
- float intensity = pow( dotNV, (1.0-roughness) * 256.0);
- specular += light_color * intensity * specular_blob_intensity * attenuation;
+ float cRdotV = max(0.0,dot(R,V));
+ float intensity = pow( cRdotV, (1.0-roughness) * 256.0);
+ specular_light += light_color * intensity * specular_blob_intensity * attenuation;
#elif defined(SPECULAR_TOON)
vec3 R = normalize(-reflect(L,N));
- float dotNV = dot(R,V);
+ float RdotV = dot(R,V);
float mid = 1.0-roughness;
mid*=mid;
- float intensity = smoothstep(mid-roughness*0.5,mid+roughness*0.5,dotNV) * mid;
- diffuse += light_color * intensity * specular_blob_intensity * attenuation; //write to diffuse, as in toon shading you generally want no reflection
+ float intensity = smoothstep(mid-roughness*0.5, mid+roughness*0.5, RdotV) * mid;
+ diffuse_light += light_color * intensity * specular_blob_intensity * attenuation; // write to diffuse_light, as in toon shading you generally want no reflection
#elif defined(SPECULAR_DISABLED)
//none..
-#else
+#elif defined(SPECULAR_SCHLICK_GGX)
// shlick+ggx as default
float alpha = roughness * roughness;
vec3 H = normalize(V + L);
- float dotNH = max(dot(N,H), 0.0 );
- float dotLH = max(dot(L,H), 0.0 );
+ float cNdotH = max(dot(N,H), 0.0);
+ float cLdotH = max(dot(L,H), 0.0);
#if defined(LIGHT_USE_ANISOTROPY)
@@ -1028,38 +1033,46 @@ LIGHT_SHADER_CODE
float ry = roughness*aspect;
float ax = rx*rx;
float ay = ry*ry;
- float dotXH = dot( T, H );
- float dotYH = dot( B, H );
- float pi = M_PI;
- float denom = dotXH*dotXH / (ax*ax) + dotYH*dotYH / (ay*ay) + dotNH*dotNH;
- float D = 1.0 / ( pi * ax*ay * denom*denom );
+ float XdotH = dot( T, H );
+ float YdotH = dot( B, H );
+ float denom = XdotH*XdotH / (ax*ax) + YdotH*YdotH / (ay*ay) + cNdotH*cNdotH;
+ float D = 1.0 / ( M_PI * ax*ay * denom*denom );
#else
float alphaSqr = alpha * alpha;
- float pi = M_PI;
- float denom = dotNH * dotNH * (alphaSqr - 1.0) + 1.0;
- float D = alphaSqr / (pi * denom * denom);
+ float denom = cNdotH * cNdotH * (alphaSqr - 1.0) + 1.0;
+ float D = alphaSqr / (M_PI * denom * denom);
#endif
// F
- float F0 = 1.0;
- float dotLH5 = SchlickFresnel( dotLH );
- float F = F0 + (1.0 - F0) * (dotLH5);
+ float F0 = 1.0; // FIXME
+ float cLdotH5 = SchlickFresnel(cLdotH);
+ float F = mix(cLdotH5, 1.0, F0);
// V
float k = alpha / 2.0f;
- float vis = G1V(dotNL, k) * G1V(dotNV, k);
+ float vis = G1V(cNdotL, k) * G1V(cNdotV, k);
- float speci = dotNL * D * F * vis;
+ float speci = cNdotL * D * F * vis;
- specular += speci * light_color * specular_blob_intensity * attenuation;
+ specular_light += speci * light_color * specular_blob_intensity * attenuation;
#endif
#if defined(LIGHT_USE_CLEARCOAT)
- float Dr = GTR1(dotNH, mix(.1,.001,clearcoat_gloss));
- float Fr = mix(.04, 1.0, dotLH5);
- float Gr = G1V(dotNL, .25) * G1V(dotNV, .25);
- specular += .25*clearcoat*Gr*Fr*Dr;
+# if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN)
+ vec3 H = normalize(V + L);
+# endif
+# if !defined(SPECULAR_SCHLICK_GGX)
+ float cNdotH = max(dot(N,H), 0.0);
+ float cLdotH = max(dot(L,H), 0.0);
+ float cLdotH5 = SchlickFresnel(cLdotH);
+#endif
+ float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss));
+ float Fr = mix(.04, 1.0, cLdotH5);
+ float Gr = G1V(cNdotL, .25) * G1V(cNdotV, .25);
+
+
+ specular_light += .25*clearcoat*Gr*Fr*Dr;
#endif
}
@@ -1087,9 +1100,7 @@ float sample_shadow(highp sampler2DShadow shadow, vec2 shadow_pixel_size, vec2 p
avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y*2.0),depth,1.0));
return avg*(1.0/13.0);
-#endif
-
-#ifdef SHADOW_MODE_PCF_5
+#elif defined(SHADOW_MODE_PCF_5)
float avg=textureProj(shadow,vec4(pos,depth,1.0));
avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0));
@@ -1097,11 +1108,11 @@ float sample_shadow(highp sampler2DShadow shadow, vec2 shadow_pixel_size, vec2 p
avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0));
avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0));
return avg*(1.0/5.0);
-#endif
-#if !defined(SHADOW_MODE_PCF_5) && !defined(SHADOW_MODE_PCF_13)
+#else
return textureProj(shadow,vec4(pos,depth,1.0));
+
#endif
}
@@ -1143,7 +1154,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
}
#endif
-void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -1932,9 +1943,9 @@ FRAGMENT_SHADER_CODE
- //energu conservation
- diffuse_light=mix(diffuse_light,vec3(0.0),metallic);
- ambient_light=mix(ambient_light,vec3(0.0),metallic);
+ //energy conservation
+ diffuse_light *= 1.0-metallic; // TODO: avoid diffuse and ambient light calculations when metallic == 1
+ ambient_light *= 1.0-metallic;
{
@@ -1943,18 +1954,17 @@ FRAGMENT_SHADER_CODE
//simplify for toon, as
specular_light *= specular * metallic * albedo * 2.0;
#else
- //brdf approximation (Lazarov 2013)
- float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
- vec3 dielectric = vec3(0.034) * specular * 2.0;
- //energy conservation
- vec3 f0 = mix(dielectric, albedo, metallic);
+ // Environment brdf approximation (Lazarov 2013)
+ // see https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04);
vec4 r = roughness * c0 + c1;
+ float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
float a004 = min( r.x * r.x, exp2( -9.28 * ndotv ) ) * r.x + r.y;
- vec2 brdf = vec2( -1.04, 1.04 ) * a004 + r.zw;
+ vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;
- specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
+ vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo);
+ specular_light *= AB.x * specular_color + AB.y;
#endif
}
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 649f874cf4..206f57d4a2 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -223,6 +223,12 @@ Error FileAccessUnix::get_error() const {
return last_error;
}
+void FileAccessUnix::flush() {
+
+ ERR_FAIL_COND(!f);
+ fflush(f);
+}
+
void FileAccessUnix::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!f);
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index e2848e4128..96f2ff8e26 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -72,6 +72,7 @@ public:
virtual Error get_error() const; ///< get last error
+ virtual void flush();
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String &p_path); ///< return true if a file exists
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 75c8a153f6..29fe73f170 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -64,39 +64,7 @@
#include <string.h>
#include <sys/time.h>
#include <sys/wait.h>
-
-extern bool _print_error_enabled;
-
-void OS_Unix::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
-
- if (!_print_error_enabled)
- return;
-
- const char *err_details;
- if (p_rationale && p_rationale[0])
- err_details = p_rationale;
- else
- err_details = p_code;
-
- switch (p_type) {
- case ERR_ERROR:
- print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
- case ERR_WARNING:
- print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
- case ERR_SCRIPT:
- print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
- case ERR_SHADER:
- print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
- print("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
- break;
- }
-}
+#include <unistd.h>
void OS_Unix::debug_break() {
@@ -165,29 +133,16 @@ void OS_Unix::initialize_core() {
}
}
-void OS_Unix::finalize_core() {
+void OS_Unix::initialize_logger() {
+ Vector<Logger *> loggers;
+ loggers.push_back(memnew(UnixTerminalLogger));
+ loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
+ _set_logger(memnew(CompositeLogger(loggers)));
}
-void OS_Unix::vprint(const char *p_format, va_list p_list, bool p_stder) {
-
- if (p_stder) {
-
- vfprintf(stderr, p_format, p_list);
- fflush(stderr);
- } else {
-
- vprintf(p_format, p_list);
- fflush(stdout);
- }
+void OS_Unix::finalize_core() {
}
-void OS_Unix::print(const char *p_format, ...) {
-
- va_list argp;
- va_start(argp, p_format);
- vprintf(p_format, argp);
- va_end(argp);
-}
void OS_Unix::alert(const String &p_alert, const String &p_title) {
fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data());
@@ -559,4 +514,38 @@ String OS_Unix::get_executable_path() const {
#endif
}
+void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+ if (!should_log(true)) {
+ return;
+ }
+
+ const char *err_details;
+ if (p_rationale && p_rationale[0])
+ err_details = p_rationale;
+ else
+ err_details = p_code;
+
+ switch (p_type) {
+ case ERR_WARNING:
+ logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_SCRIPT:
+ logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_SHADER:
+ logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_ERROR:
+ default:
+ logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ }
+}
+
+UnixTerminalLogger::~UnixTerminalLogger() {}
+
#endif
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 19e79728fb..1cc44c0ffd 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -54,11 +54,11 @@ protected:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual void initialize_logger();
virtual void initialize_core();
virtual int unix_initialize_audio(int p_audio_driver);
//virtual void initialize(int p_video_driver,int p_audio_driver);
- //virtual void finalize();
virtual void finalize_core();
String stdin_buf;
@@ -66,10 +66,6 @@ protected:
String get_global_settings_path() const;
public:
- virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
-
- virtual void print(const char *p_format, ...);
- virtual void vprint(const char *p_format, va_list p_list, bool p_stder = false);
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual String get_stdin_string(bool p_block);
@@ -120,6 +116,12 @@ public:
//virtual void run( MainLoop * p_main_loop );
};
+class UnixTerminalLogger : public StdLogger {
+public:
+ virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
+ virtual ~UnixTerminalLogger();
+};
+
#endif
#endif
diff --git a/drivers/unix/syslog_logger.cpp b/drivers/unix/syslog_logger.cpp
new file mode 100644
index 0000000000..d57f391325
--- /dev/null
+++ b/drivers/unix/syslog_logger.cpp
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* syslog_logger.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifdef UNIX_ENABLED
+
+#include "syslog_logger.h"
+#include "print_string.h"
+#include <syslog.h>
+
+void SyslogLogger::logv(const char *p_format, va_list p_list, bool p_err) {
+ if (!should_log(p_err)) {
+ return;
+ }
+
+ vsyslog(p_err ? LOG_ERR : LOG_INFO, p_format, p_list);
+}
+
+void SyslogLogger::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+ if (!should_log(true)) {
+ return;
+ }
+
+ const char *err_type = "**ERROR**";
+ switch (p_type) {
+ case ERR_ERROR: err_type = "**ERROR**"; break;
+ case ERR_WARNING: err_type = "**WARNING**"; break;
+ case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break;
+ case ERR_SHADER: err_type = "**SHADER ERROR**"; break;
+ default: ERR_PRINT("Unknown error type"); break;
+ }
+
+ const char *err_details;
+ if (p_rationale && *p_rationale)
+ err_details = p_rationale;
+ else
+ err_details = p_code;
+
+ syslog(p_type == ERR_WARNING ? LOG_WARNING : LOG_ERR, "%s: %s\n At: %s:%i:%s() - %s", err_type, err_details, p_file, p_line, p_function, p_code);
+}
+
+SyslogLogger::~SyslogLogger() {
+}
+
+#endif \ No newline at end of file
diff --git a/drivers/unix/syslog_logger.h b/drivers/unix/syslog_logger.h
new file mode 100644
index 0000000000..b3cf2f9e3a
--- /dev/null
+++ b/drivers/unix/syslog_logger.h
@@ -0,0 +1,48 @@
+/*************************************************************************/
+/* syslog_logger.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SYSLOG_LOGGER_H
+#define SYSLOG_LOGGER_H
+
+#ifdef UNIX_ENABLED
+
+#include "io/logger.h"
+
+class SyslogLogger : public Logger {
+public:
+ virtual void logv(const char *p_format, va_list p_list, bool p_err);
+ virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type);
+
+ virtual ~SyslogLogger();
+};
+
+#endif
+
+#endif \ No newline at end of file
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 6d6a6027d9..8d6e78dbee 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -162,10 +162,10 @@ Error DirAccessWindows::make_dir(String p_dir) {
GLOBAL_LOCK_FUNCTION
+ p_dir = fix_path(p_dir);
if (p_dir.is_rel_path())
p_dir = get_current_dir().plus_file(p_dir);
- p_dir = fix_path(p_dir);
p_dir = p_dir.replace("/", "\\");
bool success;
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index d128b58244..3b6e469c9c 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -207,6 +207,12 @@ Error FileAccessWindows::get_error() const {
return last_error;
}
+void FileAccessWindows::flush() {
+
+ ERR_FAIL_COND(!f);
+ fflush(f);
+}
+
void FileAccessWindows::store_8(uint8_t p_dest) {
ERR_FAIL_COND(!f);
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 15cbdca739..e5e7fd4a13 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -64,6 +64,7 @@ public:
virtual Error get_error() const; ///< get last error
+ virtual void flush();
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String &p_name); ///< return true if a file exists