summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp207
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h4
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp2
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp5
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp12
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h1
-rw-r--r--drivers/gles2/shaders/canvas.glsl3
-rw-r--r--drivers/gles2/shaders/copy.glsl22
-rw-r--r--drivers/gles2/shaders/scene.glsl118
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp5
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp46
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp166
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h6
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1
-rw-r--r--drivers/gles3/shader_gles3.h12
-rw-r--r--drivers/gles3/shaders/scene.glsl6
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp18
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h1
-rw-r--r--drivers/rtaudio/audio_driver_rtaudio.cpp11
-rw-r--r--drivers/unix/dir_access_unix.cpp6
-rw-r--r--drivers/unix/net_socket_posix.cpp6
-rw-r--r--drivers/unix/os_unix.cpp12
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp18
-rw-r--r--drivers/windows/file_access_windows.cpp4
26 files changed, 466 insertions, 230 deletions
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index cf8fb08f76..850b90d59b 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -95,11 +95,6 @@ Error AudioDriverCoreAudio::init() {
result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &output_device_address_cb, this);
ERR_FAIL_COND_V(result != noErr, FAILED);
-
- prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
-
- result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &input_device_address_cb, this);
- ERR_FAIL_COND_V(result != noErr, FAILED);
#endif
AudioStreamBasicDescription strdesc;
@@ -123,26 +118,6 @@ Error AudioDriverCoreAudio::init() {
break;
}
- zeromem(&strdesc, sizeof(strdesc));
- size = sizeof(strdesc);
- result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, &size);
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
- switch (strdesc.mChannelsPerFrame) {
- case 1: // Mono
- capture_channels = 1;
- break;
-
- case 2: // Stereo
- capture_channels = 2;
- break;
-
- default:
- // Unknown number of channels, default to stereo
- capture_channels = 2;
- break;
- }
-
mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
zeromem(&strdesc, sizeof(strdesc));
@@ -158,11 +133,6 @@ Error AudioDriverCoreAudio::init() {
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
- strdesc.mChannelsPerFrame = capture_channels;
-
- result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, sizeof(strdesc));
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
int latency = GLOBAL_DEF_RST("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);
@@ -175,9 +145,6 @@ Error AudioDriverCoreAudio::init() {
unsigned int buffer_size = buffer_frames * channels;
samples_in.resize(buffer_size);
input_buf.resize(buffer_size);
- input_buffer.resize(buffer_size * 8);
- input_position = 0;
- input_size = 0;
print_verbose("CoreAudio: detected " + itos(channels) + " channels");
print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
@@ -189,16 +156,10 @@ Error AudioDriverCoreAudio::init() {
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
ERR_FAIL_COND_V(result != noErr, FAILED);
- zeromem(&callback, sizeof(AURenderCallbackStruct));
- callback.inputProc = &AudioDriverCoreAudio::input_callback;
- callback.inputProcRefCon = this;
- result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callback, sizeof(callback));
- ERR_FAIL_COND_V(result != noErr, FAILED);
-
result = AudioUnitInitialize(audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
- return OK;
+ return capture_init();
}
OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
@@ -265,7 +226,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
bufferList.mBuffers[0].mNumberChannels = ad->capture_channels;
bufferList.mBuffers[0].mDataByteSize = ad->input_buf.size() * sizeof(int16_t);
- OSStatus result = AudioUnitRender(ad->audio_unit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);
+ OSStatus result = AudioUnitRender(ad->input_unit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);
if (result == noErr) {
for (int i = 0; i < inNumberFrames * ad->capture_channels; i++) {
int32_t sample = ad->input_buf[i] << 16;
@@ -332,6 +293,8 @@ bool AudioDriverCoreAudio::try_lock() {
}
void AudioDriverCoreAudio::finish() {
+ capture_finish();
+
if (audio_unit) {
OSStatus result;
@@ -375,6 +338,7 @@ void AudioDriverCoreAudio::finish() {
ERR_PRINT("AudioComponentInstanceDispose failed");
}
+ audio_unit = NULL;
unlock();
}
@@ -384,20 +348,160 @@ void AudioDriverCoreAudio::finish() {
}
}
-Error AudioDriverCoreAudio::capture_start() {
+Error AudioDriverCoreAudio::capture_init() {
+ 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, &input_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+#ifdef OSX_ENABLED
+ AudioObjectPropertyAddress prop;
+ prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
+ prop.mScope = kAudioObjectPropertyScopeGlobal;
+ prop.mElement = kAudioObjectPropertyElementMaster;
+
+ result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop, &input_device_address_cb, this);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+#endif
UInt32 flag = 1;
- OSStatus result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
+ result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+ flag = 0;
+ result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ UInt32 size;
+#ifdef OSX_ENABLED
+ AudioDeviceID deviceId;
+ size = sizeof(AudioDeviceID);
+ AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
+
+ result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, NULL, &size, &deviceId);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+#endif
+
+ AudioStreamBasicDescription strdesc;
+ zeromem(&strdesc, sizeof(strdesc));
+ size = sizeof(strdesc);
+ result = AudioUnitGetProperty(input_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, &size);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ switch (strdesc.mChannelsPerFrame) {
+ case 1: // Mono
+ capture_channels = 1;
+ break;
+
+ case 2: // Stereo
+ capture_channels = 2;
+ break;
+
+ default:
+ // Unknown number of channels, default to stereo
+ capture_channels = 2;
+ break;
+ }
+
+ mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+
+ zeromem(&strdesc, sizeof(strdesc));
+ strdesc.mFormatID = kAudioFormatLinearPCM;
+ strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
+ strdesc.mChannelsPerFrame = capture_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(input_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &strdesc, sizeof(strdesc));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ AURenderCallbackStruct callback;
+ zeromem(&callback, sizeof(AURenderCallbackStruct));
+ callback.inputProc = &AudioDriverCoreAudio::input_callback;
+ callback.inputProcRefCon = this;
+ result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, kInputBus, &callback, sizeof(callback));
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ result = AudioUnitInitialize(input_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
return OK;
}
+void AudioDriverCoreAudio::capture_finish() {
+ if (input_unit) {
+ lock();
+
+ AURenderCallbackStruct callback;
+ zeromem(&callback, sizeof(AURenderCallbackStruct));
+ OSStatus result = AudioUnitSetProperty(input_unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callback, sizeof(callback));
+ if (result != noErr) {
+ ERR_PRINT("AudioUnitSetProperty failed");
+ }
+
+ result = AudioUnitUninitialize(input_unit);
+ if (result != noErr) {
+ ERR_PRINT("AudioUnitUninitialize failed");
+ }
+
+#ifdef OSX_ENABLED
+ AudioObjectPropertyAddress prop;
+ prop.mSelector = kAudioHardwarePropertyDefaultInputDevice;
+ prop.mScope = kAudioObjectPropertyScopeGlobal;
+ prop.mElement = kAudioObjectPropertyElementMaster;
+
+ result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop, &input_device_address_cb, this);
+ if (result != noErr) {
+ ERR_PRINT("AudioObjectRemovePropertyListener failed");
+ }
+#endif
+
+ result = AudioComponentInstanceDispose(input_unit);
+ if (result != noErr) {
+ ERR_PRINT("AudioComponentInstanceDispose failed");
+ }
+
+ input_unit = NULL;
+ unlock();
+ }
+}
+
+Error AudioDriverCoreAudio::capture_start() {
+
+ input_buffer_init(buffer_frames);
+
+ OSStatus result = AudioOutputUnitStart(input_unit);
+ if (result != noErr) {
+ ERR_PRINTS("AudioOutputUnitStart failed, code: " + itos(result));
+ }
+
+ return OK;
+}
+
Error AudioDriverCoreAudio::capture_stop() {
- UInt32 flag = 0;
- OSStatus result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
- ERR_FAIL_COND_V(result != noErr, FAILED);
+ if (input_unit) {
+ OSStatus result = AudioOutputUnitStop(input_unit);
+ if (result != noErr) {
+ ERR_PRINTS("AudioOutputUnitStop failed, code: " + itos(result));
+ }
+ }
return OK;
}
@@ -531,12 +635,14 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
}
if (found) {
- OSStatus result = AudioUnitSetProperty(audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, capture ? kInputBus : kOutputBus, &deviceId, sizeof(AudioDeviceID));
+ OSStatus result = AudioUnitSetProperty(capture ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
ERR_FAIL_COND(result != noErr);
- // Reset audio input to keep synchronisation.
- input_position = 0;
- input_size = 0;
+ if (capture) {
+ // Reset audio input to keep synchronisation.
+ input_position = 0;
+ input_size = 0;
+ }
}
}
@@ -580,6 +686,7 @@ String AudioDriverCoreAudio::capture_get_device() {
AudioDriverCoreAudio::AudioDriverCoreAudio() {
audio_unit = NULL;
+ input_unit = NULL;
active = false;
mutex = NULL;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index d3f7c8d596..474a9e43ae 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -43,6 +43,7 @@
class AudioDriverCoreAudio : public AudioDriver {
AudioComponentInstance audio_unit;
+ AudioComponentInstance input_unit;
bool active;
Mutex *mutex;
@@ -83,6 +84,9 @@ class AudioDriverCoreAudio : public AudioDriver {
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
+ Error capture_init();
+ void capture_finish();
+
public:
const char *get_name() const {
return "CoreAudio";
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 18b5dd3483..9227c04e71 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -1111,6 +1111,7 @@ void RasterizerCanvasGLES2::initialize() {
// polygon buffer
{
uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
poly_size *= 1024;
poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float));
glGenBuffers(1, &data.polygon_buffer);
@@ -1122,6 +1123,7 @@ void RasterizerCanvasGLES2::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_size_kb", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_index_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_index_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
index_size *= 1024; // kb
glGenBuffers(1, &data.polygon_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 848ac8b78f..175587b1bb 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -74,6 +74,10 @@
#include <EGL/eglext.h>
#endif
+#if defined(MINGW_ENABLED) || defined(_MSC_VER)
+#define strcpy strcpy_s
+#endif
+
#ifndef IPHONE_ENABLED
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
@@ -84,6 +88,7 @@ static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GL
return; //these are ultimately annoying, so removing for now
char debSource[256], debType[256], debSev[256];
+
if (source == _EXT_DEBUG_SOURCE_API_ARB)
strcpy(debSource, "OpenGL");
else if (source == _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index fbcbebc88c..c4b6c607a2 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -2455,13 +2455,20 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_ASYM_PANO, asymmetrical);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, !asymmetrical);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, true);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
- storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, true);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA, false);
storage->shaders.copy.bind();
storage->shaders.copy.set_uniform(CopyShaderGLES2::MULTIPLIER, p_energy);
+ if (asymmetrical) {
+ // pack the bits we need from our projection matrix
+ storage->shaders.copy.set_uniform(CopyShaderGLES2::ASYM_PROJ, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1]);
+ ///@TODO I couldn't get mat3 + p_transform.basis to work, that would be better here.
+ storage->shaders.copy.set_uniform(CopyShaderGLES2::PANO_TRANSFORM, p_transform);
+ }
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -2469,6 +2476,8 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
glBindBuffer(GL_ARRAY_BUFFER, 0);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_ASYM_PANO, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, false);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, false);
storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
}
@@ -3037,6 +3046,7 @@ void RasterizerSceneGLES2::initialize() {
{
uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/limits/buffers/immediate_buffer_size_kb", 2048);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/immediate_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/immediate_buffer_size_kb", PROPERTY_HINT_RANGE, "0,8192,1,or_greater"));
glGenBuffers(1, &state.immediate_buffer);
glBindBuffer(GL_ARRAY_BUFFER, state.immediate_buffer);
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index b42e2dfb1f..c928f753b1 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -43,7 +43,6 @@
/*
#include "shaders/blend_shape.glsl.gen.h"
#include "shaders/canvas.glsl.gen.h"
-#include "shaders/copy.glsl.gen.h"
#include "shaders/particles.glsl.gen.h"
*/
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index b990384949..79d4eb2243 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -148,7 +148,10 @@ void main() {
vec4 color = color_interp;
+#if !defined(COLOR_USED)
+ //default behavior, texture by color
color *= texture2D(color_texture, uv_interp);
+#endif
#ifdef SCREEN_UV_USED
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index 16bbde196d..0b8da4f875 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -35,6 +35,8 @@ void main() {
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
cube_interp = cube_in;
+#elif defined(USE_ASYM_PANO)
+ uv_interp = vertex_attrib.xy;
#else
uv_interp = uv_in;
#endif
@@ -68,6 +70,11 @@ varying vec2 uv_interp;
#endif
/* clang-format on */
+#ifdef USE_ASYM_PANO
+uniform highp mat4 pano_transform;
+uniform highp vec4 asym_proj;
+#endif
+
#ifdef USE_CUBEMAP
uniform samplerCube source_cube; // texunit:0
#else
@@ -108,6 +115,21 @@ void main() {
vec4 color = texturePanorama(source, normalize(cube_interp));
+#elif defined(USE_ASYM_PANO)
+
+ // When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
+ // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1.
+ // The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
+
+ vec3 cube_normal;
+ cube_normal.z = -1000000.0;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
+ cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
+ cube_normal = mat3(pano_transform) * cube_normal;
+ cube_normal.z = -cube_normal.z;
+
+ vec4 color = texturePanorama(source, normalize(cube_normal.xyz));
+
#elif defined(USE_CUBEMAP)
vec4 color = textureCube(source_cube, normalize(cube_interp));
#else
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index fae010b003..2a781605d1 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -75,12 +75,12 @@ attribute highp vec4 instance_custom_data; // attrib:12
// uniforms
//
-uniform mat4 camera_matrix;
-uniform mat4 camera_inverse_matrix;
-uniform mat4 projection_matrix;
-uniform mat4 projection_inverse_matrix;
+uniform highp mat4 camera_matrix;
+uniform highp mat4 camera_inverse_matrix;
+uniform highp mat4 projection_matrix;
+uniform highp mat4 projection_inverse_matrix;
-uniform mat4 world_transform;
+uniform highp mat4 world_transform;
uniform highp float time;
@@ -156,22 +156,22 @@ varying highp vec3 diffuse_interp;
varying highp vec3 specular_interp;
// general for all lights
-uniform vec4 light_color;
-uniform float light_specular;
+uniform highp vec4 light_color;
+uniform highp float light_specular;
// directional
-uniform vec3 light_direction;
+uniform highp vec3 light_direction;
// omni
-uniform vec3 light_position;
+uniform highp vec3 light_position;
-uniform float light_range;
-uniform float light_attenuation;
+uniform highp float light_range;
+uniform highp float light_attenuation;
// spot
-uniform float light_spot_attenuation;
-uniform float light_spot_range;
-uniform float light_spot_angle;
+uniform highp float light_spot_attenuation;
+uniform highp float light_spot_range;
+uniform highp float light_spot_angle;
void light_compute(
vec3 N,
@@ -262,9 +262,9 @@ void light_compute(
#ifdef USE_REFLECTION_PROBE1
-uniform mat4 refprobe1_local_matrix;
+uniform highp mat4 refprobe1_local_matrix;
varying mediump vec4 refprobe1_reflection_normal_blend;
-uniform vec3 refprobe1_box_extents;
+uniform highp vec3 refprobe1_box_extents;
#ifndef USE_LIGHTMAP
varying mediump vec3 refprobe1_ambient_normal;
@@ -274,9 +274,9 @@ varying mediump vec3 refprobe1_ambient_normal;
#ifdef USE_REFLECTION_PROBE2
-uniform mat4 refprobe2_local_matrix;
+uniform highp mat4 refprobe2_local_matrix;
varying mediump vec4 refprobe2_reflection_normal_blend;
-uniform vec3 refprobe2_box_extents;
+uniform highp vec3 refprobe2_box_extents;
#ifndef USE_LIGHTMAP
varying mediump vec3 refprobe2_ambient_normal;
@@ -310,7 +310,6 @@ uniform highp float fog_height_max;
uniform mediump float fog_height_curve;
#endif
-
#endif //fog
void main() {
@@ -360,7 +359,7 @@ void main() {
normal = normalize((world_matrix * vec4(normal, 0.0)).xyz);
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP)
- tangent = normalize((world_matrix * vec4(tangent, 0.0)), xyz);
+ tangent = normalize((world_matrix * vec4(tangent, 0.0)).xyz);
binormal = normalize((world_matrix * vec4(binormal, 0.0)).xyz);
#endif
#endif
@@ -625,19 +624,19 @@ VERTEX_SHADER_CODE
{
- float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
+ float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
- fog_amount = pow(fog_z, fog_depth_curve);
+ fog_amount = pow(fog_z, fog_depth_curve);
}
#endif
#ifdef FOG_HEIGHT_ENABLED
{
- float y = (camera_matrix * vec4(vertex_interp, 1.0)).y;
- fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
+ float y = (camera_matrix * vec4(vertex_interp, 1.0)).y;
+ fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
}
#endif
- fog_interp = vec4(fog_color,fog_amount);
+ fog_interp = vec4(fog_color, fog_amount);
#endif //fog
@@ -671,13 +670,13 @@ precision highp int;
// uniforms
//
-uniform mat4 camera_matrix;
+uniform highp mat4 camera_matrix;
/* clang-format on */
-uniform mat4 camera_inverse_matrix;
-uniform mat4 projection_matrix;
-uniform mat4 projection_inverse_matrix;
+uniform highp mat4 camera_inverse_matrix;
+uniform highp mat4 projection_matrix;
+uniform highp mat4 projection_inverse_matrix;
-uniform mat4 world_transform;
+uniform highp mat4 world_transform;
uniform highp float time;
@@ -704,9 +703,9 @@ varying mediump vec3 refprobe1_ambient_normal;
#else
uniform bool refprobe1_use_box_project;
-uniform vec3 refprobe1_box_extents;
+uniform highp vec3 refprobe1_box_extents;
uniform vec3 refprobe1_box_offset;
-uniform mat4 refprobe1_local_matrix;
+uniform highp mat4 refprobe1_local_matrix;
#endif //use vertex lighting
@@ -731,9 +730,9 @@ varying mediump vec3 refprobe2_ambient_normal;
#else
uniform bool refprobe2_use_box_project;
-uniform vec3 refprobe2_box_extents;
+uniform highp vec3 refprobe2_box_extents;
uniform vec3 refprobe2_box_offset;
-uniform mat4 refprobe2_local_matrix;
+uniform highp mat4 refprobe2_local_matrix;
#endif //use vertex lighting
@@ -874,29 +873,29 @@ uniform float ambient_energy;
varying highp vec3 diffuse_interp;
varying highp vec3 specular_interp;
-uniform vec3 light_direction; //may be used by fog, so leave here
+uniform highp vec3 light_direction; //may be used by fog, so leave here
#else
//done in fragment
// general for all lights
-uniform vec4 light_color;
-uniform float light_specular;
+uniform highp vec4 light_color;
+uniform highp float light_specular;
// directional
-uniform vec3 light_direction;
+uniform highp vec3 light_direction;
// omni
-uniform vec3 light_position;
+uniform highp vec3 light_position;
-uniform float light_attenuation;
+uniform highp float light_attenuation;
// spot
-uniform float light_spot_attenuation;
-uniform float light_spot_range;
-uniform float light_spot_angle;
+uniform highp float light_spot_attenuation;
+uniform highp float light_spot_range;
+uniform highp float light_spot_angle;
#endif
//this is needed outside above if because dual paraboloid wants it
-uniform float light_range;
+uniform highp float light_range;
#ifdef USE_SHADOW
@@ -1308,8 +1307,7 @@ LIGHT_SHADER_CODE
#define SAMPLE_SHADOW_TEXEL(p_shadow, p_pos, p_depth) step(p_depth, texture2D(p_shadow, p_pos).r)
#define SAMPLE_SHADOW_TEXEL_PROJ(p_shadow, p_pos) step(p_pos.z, texture2DProj(p_shadow, p_pos).r)
-float sample_shadow(
- highp sampler2D shadow, highp vec4 spos) {
+float sample_shadow(highp sampler2D shadow, highp vec4 spos) {
#ifdef SHADOW_MODE_PCF_13
@@ -1924,12 +1922,12 @@ FRAGMENT_SHADER_CODE
highp vec4 splane = shadow_coord;
splane.xyz /= splane.w;
- float shadow = sample_shadow(light_shadow_atlas, splane.xy, splane.z);
+ float shadow = sample_shadow(light_shadow_atlas, splane);
light_att *= shadow;
}
#endif
-#endif
+#endif // LIGHT_MODE_SPOT
#ifdef USE_VERTEX_LIGHTING
//vertex lighting
@@ -2021,8 +2019,8 @@ FRAGMENT_SHADER_CODE
#if defined(USE_VERTEX_LIGHTING)
- gl_FragColor.rgb = mix(gl_FragColor.rgb,fog_interp.rgb,fog_interp.a);
-#else //pixel based fog
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_interp.rgb, fog_interp.a);
+#else //pixel based fog
float fog_amount = 0.0;
#ifdef LIGHT_MODE_DIRECTIONAL
@@ -2036,26 +2034,26 @@ FRAGMENT_SHADER_CODE
{
- float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
+ float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
- fog_amount = pow(fog_z, fog_depth_curve);
+ fog_amount = pow(fog_z, fog_depth_curve);
- if (fog_transmit_enabled) {
- vec3 total_light = gl_FragColor.rgb;
- float transmit = pow(fog_z, fog_transmit_curve);
- fog_color = mix(max(total_light, fog_color), fog_color, transmit);
- }
+ if (fog_transmit_enabled) {
+ vec3 total_light = gl_FragColor.rgb;
+ float transmit = pow(fog_z, fog_transmit_curve);
+ fog_color = mix(max(total_light, fog_color), fog_color, transmit);
+ }
}
#endif
#ifdef FOG_HEIGHT_ENABLED
{
- float y = (camera_matrix * vec4(vertex, 1.0)).y;
- fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
+ float y = (camera_matrix * vec4(vertex, 1.0)).y;
+ fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
}
#endif
- gl_FragColor.rgb = mix(gl_FragColor.rgb,fog_color,fog_amount);
+ gl_FragColor.rgb = mix(gl_FragColor.rgb, fog_color, fog_amount);
#endif //use vertex lit
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index a9b46baf53..f0932c2f80 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -2027,6 +2027,7 @@ void RasterizerCanvasGLES3::initialize() {
{
uint32_t poly_size = GLOBAL_DEF_RST("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
poly_size *= 1024; //kb
poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float));
glGenBuffers(1, &data.polygon_buffer);
@@ -2074,6 +2075,7 @@ void RasterizerCanvasGLES3::initialize() {
glGenVertexArrays(1, &data.polygon_buffer_pointer_array);
uint32_t index_size = GLOBAL_DEF_RST("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
index_size *= 1024; //kb
glGenBuffers(1, &data.polygon_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 2b3be9d0bd..2f6a556773 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -73,6 +73,10 @@ RasterizerScene *RasterizerGLES3::get_scene() {
#define _EXT_DEBUG_SEVERITY_LOW_ARB 0x9148
#define _EXT_DEBUG_OUTPUT 0x92E0
+#if defined(MINGW_ENABLED) || defined(_MSC_VER)
+#define strcpy strcpy_s
+#endif
+
#ifdef GLAD_ENABLED
// Restricting to GLAD as only used in initialize() with GLAD_GL_ARB_debug_output
#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
@@ -432,6 +436,7 @@ void RasterizerGLES3::register_config() {
GLOBAL_DEF("rendering/quality/filters/anisotropic_filter_level", 4);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/filters/anisotropic_filter_level", PropertyInfo(Variant::INT, "rendering/quality/filters/anisotropic_filter_level", PROPERTY_HINT_RANGE, "1,16,1"));
GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::REAL, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"));
}
RasterizerGLES3::RasterizerGLES3() {
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 14c436fd00..792e9eb238 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -653,7 +653,7 @@ bool RasterizerSceneGLES3::reflection_probe_instance_begin_render(RID p_instance
int best_free = -1;
int best_used = -1;
- uint64_t best_used_frame;
+ uint64_t best_used_frame = 0;
for (int i = 0; i < reflection_atlas->reflections.size(); i++) {
if (reflection_atlas->reflections[i].owner == RID()) {
@@ -1246,14 +1246,11 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
case ShaderLanguage::TYPE_SAMPLER3D: {
target = GL_TEXTURE_3D;
+ tex = storage->resources.white_tex_3d;
- switch (texture_hints[i]) {
-
- // TODO
- default: {
- tex = storage->resources.white_tex_3d;
- } break;
- }
+ //switch (texture_hints[i]) {
+ // TODO
+ //}
} break;
@@ -1431,7 +1428,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
if (particles->draw_order == VS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->particle_valid_histories[1]) {
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer, this was used 2 frames ago so it should be good enough for flushing
- RasterizerGLES3Particle *particle_array = (RasterizerGLES3Particle *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+ RasterizerGLES3Particle *particle_array;
+#ifndef __EMSCRIPTEN__
+ particle_array = static_cast<RasterizerGLES3Particle *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
+#else
+ PoolVector<RasterizerGLES3Particle> particle_vector;
+ particle_vector.resize(particles->amount);
+ PoolVector<RasterizerGLES3Particle>::Write w = particle_vector.write();
+ particle_array = w.ptr();
+ glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), particle_array);
+#endif
SortArray<RasterizerGLES3Particle, RasterizerGLES3ParticleSort> sorter;
@@ -1443,7 +1449,17 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
sorter.sort(particle_array, particles->amount);
+#ifndef __EMSCRIPTEN__
glUnmapBuffer(GL_ARRAY_BUFFER);
+#else
+ w = PoolVector<RasterizerGLES3Particle>::Write();
+ particle_array = NULL;
+ {
+ PoolVector<RasterizerGLES3Particle>::Read r = particle_vector.read();
+ glBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), r.ptr());
+ }
+ particle_vector = PoolVector<RasterizerGLES3Particle>();
+#endif
#ifdef DEBUG_ENABLED
if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
@@ -2519,7 +2535,7 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, false);
}
-void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform) {
+void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog) {
//store camera into ubo
store_camera(p_cam_projection, state.ubo_data.projection_matrix);
@@ -2570,7 +2586,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.ubo_data.fog_color_enabled[0] = linear_fog.r;
state.ubo_data.fog_color_enabled[1] = linear_fog.g;
state.ubo_data.fog_color_enabled[2] = linear_fog.b;
- state.ubo_data.fog_color_enabled[3] = env->fog_enabled ? 1.0 : 0.0;
+ state.ubo_data.fog_color_enabled[3] = (!p_no_fog && env->fog_enabled) ? 1.0 : 0.0;
Color linear_sun = env->fog_sun_color.to_linear();
state.ubo_data.fog_sun_color_amount[0] = linear_sun.r;
@@ -4083,7 +4099,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
state.ubo_data.screen_pixel_size[1] = 1.0 / storage->frame.current_rt->height;
}
- _setup_environment(env, p_cam_projection, p_cam_transform);
+ _setup_environment(env, p_cam_projection, p_cam_transform, p_reflection_probe.is_valid());
bool fb_cleared = false;
@@ -4855,10 +4871,7 @@ void RasterizerSceneGLES3::initialize() {
glBindBuffer(GL_UNIFORM_BUFFER, 0);
render_list.max_elements = GLOBAL_DEF_RST("rendering/limits/rendering/max_renderable_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS);
- if (render_list.max_elements > 1000000)
- render_list.max_elements = 1000000;
- if (render_list.max_elements < 1024)
- render_list.max_elements = 1024;
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/rendering/max_renderable_elements", PropertyInfo(Variant::INT, "rendering/limits/rendering/max_renderable_elements", PROPERTY_HINT_RANGE, "1024,1000000,1"));
{
//quad buffers
@@ -5057,6 +5070,7 @@ void RasterizerSceneGLES3::initialize() {
{
uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/limits/buffers/immediate_buffer_size_kb", 2048);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/immediate_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/immediate_buffer_size_kb", PROPERTY_HINT_RANGE, "0,8192,1,or_greater"));
glGenBuffers(1, &state.immediate_buffer);
glBindBuffer(GL_ARRAY_BUFFER, state.immediate_buffer);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index b4c4a0558f..4b4a0b9303 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -831,7 +831,7 @@ public:
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_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_no_fog = false);
void _setup_directional_light(int p_index, const Transform &p_camera_inverse_transform, bool p_use_shadows);
void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix &p_camera_projection, RID p_shadow_atlas);
void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix &p_camera_projection, RID p_reflection_atlas, Environment *p_env);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 58c0a104c1..8a73804eec 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -101,6 +101,28 @@
#define _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
#define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#ifdef __EMSCRIPTEN__
+#include <emscripten/emscripten.h>
+
+void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) {
+
+ /* clang-format off */
+ EM_ASM({
+ GLctx.getBufferSubData($0, $1, HEAPU8, $2, $3);
+ }, target, offset, data, size);
+ /* clang-format on */
+}
+
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) {
+
+ /* clang-format off */
+ EM_ASM({
+ GLctx.bufferSubData($0, $1, HEAPU8, $2, $3);
+ }, target, offset, data, size);
+ /* clang-format on */
+}
+#endif
+
void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) {
#ifdef GLES_OVER_GL
@@ -730,7 +752,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p
}
};
- GLenum blit_target;
+ GLenum blit_target = GL_TEXTURE_2D;
switch (texture->type) {
case VS::TEXTURE_TYPE_2D: {
@@ -948,7 +970,7 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I
Image::Format real_format;
Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb);
- GLenum blit_target;
+ GLenum blit_target = GL_TEXTURE_2D;
switch (texture->type) {
case VS::TEXTURE_TYPE_2D: {
@@ -3494,21 +3516,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_array(RID p_mesh, i
Surface *surface = mesh->surfaces[p_surface];
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
-
- ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
-
PoolVector<uint8_t> ret;
ret.resize(surface->array_byte_size);
+ glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ glGetBufferSubData(GL_ARRAY_BUFFER, 0, surface->array_byte_size, w.ptr());
+ }
+#else
+ void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
+ ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
{
-
PoolVector<uint8_t>::Write w = ret.write();
copymem(w.ptr(), data, surface->array_byte_size);
}
glUnmapBuffer(GL_ARRAY_BUFFER);
+#endif
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
return ret;
}
@@ -3521,22 +3548,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_index_array(RID p_m
ERR_FAIL_COND_V(surface->index_array_len == 0, PoolVector<uint8_t>());
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
- void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
-
- ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
-
PoolVector<uint8_t> ret;
ret.resize(surface->index_array_byte_size);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, w.ptr());
+ }
+#else
+ void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
+ ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
{
-
PoolVector<uint8_t>::Write w = ret.write();
copymem(w.ptr(), data, surface->index_array_byte_size);
}
-
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+#endif
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return ret;
}
@@ -3577,23 +3608,26 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap
for (int i = 0; i < mesh->surfaces[p_surface]->blend_shapes.size(); i++) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
- void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
-
- ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
-
PoolVector<uint8_t> ret;
ret.resize(mesh->surfaces[p_surface]->array_byte_size);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ {
+ PoolVector<uint8_t>::Write w = ret.write();
+ glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, w.ptr());
+ }
+#else
+ void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
+ ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
{
-
PoolVector<uint8_t>::Write w = ret.write();
copymem(w.ptr(), data, mesh->surfaces[p_surface]->array_byte_size);
}
+ glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+#endif
bsarr.push_back(ret);
-
- glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
}
return bsarr;
@@ -4066,35 +4100,37 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
multimesh->data.resize(format_floats * p_instances);
+ float *dataptr = multimesh->data.ptrw();
+
for (int i = 0; i < p_instances * format_floats; i += format_floats) {
int color_from = 0;
int custom_data_from = 0;
if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) {
- multimesh->data.write[i + 0] = 1.0;
- multimesh->data.write[i + 1] = 0.0;
- multimesh->data.write[i + 2] = 0.0;
- multimesh->data.write[i + 3] = 0.0;
- multimesh->data.write[i + 4] = 0.0;
- multimesh->data.write[i + 5] = 1.0;
- multimesh->data.write[i + 6] = 0.0;
- multimesh->data.write[i + 7] = 0.0;
+ dataptr[i + 0] = 1.0;
+ dataptr[i + 1] = 0.0;
+ dataptr[i + 2] = 0.0;
+ dataptr[i + 3] = 0.0;
+ dataptr[i + 4] = 0.0;
+ dataptr[i + 5] = 1.0;
+ dataptr[i + 6] = 0.0;
+ dataptr[i + 7] = 0.0;
color_from = 8;
custom_data_from = 8;
} else {
- multimesh->data.write[i + 0] = 1.0;
- multimesh->data.write[i + 1] = 0.0;
- multimesh->data.write[i + 2] = 0.0;
- multimesh->data.write[i + 3] = 0.0;
- multimesh->data.write[i + 4] = 0.0;
- multimesh->data.write[i + 5] = 1.0;
- multimesh->data.write[i + 6] = 0.0;
- multimesh->data.write[i + 7] = 0.0;
- multimesh->data.write[i + 8] = 0.0;
- multimesh->data.write[i + 9] = 0.0;
- multimesh->data.write[i + 10] = 1.0;
- multimesh->data.write[i + 11] = 0.0;
+ dataptr[i + 0] = 1.0;
+ dataptr[i + 1] = 0.0;
+ dataptr[i + 2] = 0.0;
+ dataptr[i + 3] = 0.0;
+ dataptr[i + 4] = 0.0;
+ dataptr[i + 5] = 1.0;
+ dataptr[i + 6] = 0.0;
+ dataptr[i + 7] = 0.0;
+ dataptr[i + 8] = 0.0;
+ dataptr[i + 9] = 0.0;
+ dataptr[i + 10] = 1.0;
+ dataptr[i + 11] = 0.0;
color_from = 12;
custom_data_from = 12;
}
@@ -4109,14 +4145,14 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
} cu;
cu.colu = 0xFFFFFFFF;
- multimesh->data.write[i + color_from + 0] = cu.colf;
+ dataptr[i + color_from + 0] = cu.colf;
custom_data_from = color_from + 1;
} else if (multimesh->color_format == VS::MULTIMESH_COLOR_FLOAT) {
- multimesh->data.write[i + color_from + 0] = 1.0;
- multimesh->data.write[i + color_from + 1] = 1.0;
- multimesh->data.write[i + color_from + 2] = 1.0;
- multimesh->data.write[i + color_from + 3] = 1.0;
+ dataptr[i + color_from + 0] = 1.0;
+ dataptr[i + color_from + 1] = 1.0;
+ dataptr[i + color_from + 2] = 1.0;
+ dataptr[i + color_from + 3] = 1.0;
custom_data_from = color_from + 4;
}
@@ -4130,13 +4166,13 @@ void RasterizerStorageGLES3::multimesh_allocate(RID p_multimesh, int p_instances
} cu;
cu.colu = 0;
- multimesh->data.write[i + custom_data_from + 0] = cu.colf;
+ dataptr[i + custom_data_from + 0] = cu.colf;
} else if (multimesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_FLOAT) {
- multimesh->data.write[i + custom_data_from + 0] = 0.0;
- multimesh->data.write[i + custom_data_from + 1] = 0.0;
- multimesh->data.write[i + custom_data_from + 2] = 0.0;
- multimesh->data.write[i + custom_data_from + 3] = 0.0;
+ dataptr[i + custom_data_from + 0] = 0.0;
+ dataptr[i + custom_data_from + 1] = 0.0;
+ dataptr[i + custom_data_from + 2] = 0.0;
+ dataptr[i + custom_data_from + 3] = 0.0;
}
}
@@ -5999,9 +6035,21 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, AABB());
+ const float *data;
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
- float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ PoolVector<uint8_t> vector;
+ vector.resize(particles->amount * 16 * 6);
+ {
+ PoolVector<uint8_t>::Write w = vector.write();
+ glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, w.ptr());
+ }
+ PoolVector<uint8_t>::Read r = vector.read();
+ data = reinterpret_cast<const float *>(r.ptr());
+#else
+ data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
+#endif
AABB aabb;
Transform inv = particles->emission_transform.affine_inverse();
@@ -6018,7 +6066,13 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
aabb.expand_to(pos);
}
+#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
+ r = PoolVector<uint8_t>::Read();
+ vector = PoolVector<uint8_t>();
+#else
glUnmapBuffer(GL_ARRAY_BUFFER);
+#endif
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
float longest_axis = 0;
@@ -6841,7 +6895,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
glDisable(GL_SCISSOR_TEST);
glColorMask(1, 1, 1, 1);
- if (rt->buffers.active == false) {
+ if (!rt->buffers.active) {
glDepthMask(GL_TRUE);
}
@@ -7684,6 +7738,8 @@ void RasterizerStorageGLES3::initialize() {
{
//transform feedback buffers
uint32_t xf_feedback_size = GLOBAL_DEF_RST("rendering/limits/buffers/blend_shape_max_buffer_size_kb", 4096);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/blend_shape_max_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/blend_shape_max_buffer_size_kb", PROPERTY_HINT_RANGE, "0,8192,1,or_greater"));
+
for (int i = 0; i < 2; i++) {
glGenBuffers(1, &resources.transform_feedback_buffers[i]);
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 9a4798ac2a..8c26e09037 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -43,6 +43,12 @@
#include "shaders/cubemap_filter.glsl.gen.h"
#include "shaders/particles.glsl.gen.h"
+// WebGL 2.0 has no MapBufferRange/UnmapBuffer, but offers a non-ES style BufferSubData API instead.
+#ifdef __EMSCRIPTEN__
+void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+#endif
+
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3;
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index dbc8507951..be36b41417 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -872,6 +872,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
+ actions[VS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth";
actions[VS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor";
actions[VS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h
index 9db4942163..0d360e8453 100644
--- a/drivers/gles3/shader_gles3.h
+++ b/drivers/gles3/shader_gles3.h
@@ -128,11 +128,13 @@ private:
Vector<GLint> texture_uniform_locations;
uint32_t code_version;
bool ok;
- Version() {
- code_version = 0;
- ok = false;
- uniform_location = NULL;
- }
+ Version() :
+ id(0),
+ vert_id(0),
+ frag_id(0),
+ uniform_location(NULL),
+ code_version(0),
+ ok(false) {}
};
Version *version;
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 598bd3465e..91ab34f775 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -1340,7 +1340,7 @@ void reflection_process(int idx, vec3 vertex, vec3 normal, vec3 binormal, vec3 t
reflection_accum += reflection;
}
-#ifndef USE_LIGHTMAP
+#if !defined(USE_LIGHTMAP) && !defined(USE_LIGHTMAP_CAPTURE)
if (reflections[idx].ambient.a > 0.0) { //compute ambient using skybox
vec3 local_amb_vec = (reflections[idx].local_matrix * vec4(normal, 0.0)).xyz;
@@ -1957,7 +1957,7 @@ FRAGMENT_SHADER_CODE
} else {
specular_light += env_reflection_light;
}
-#ifndef USE_LIGHTMAP
+#if !defined(USE_LIGHTMAP) && !defined(USE_LIGHTMAP_CAPTURE)
if (ambient_accum.a > 0.0) {
ambient_light = ambient_accum.rgb / ambient_accum.a;
}
@@ -2053,7 +2053,7 @@ FRAGMENT_SHADER_CODE
emission = emission * rev_amount + fog_color * fog_amount;
ambient_light *= rev_amount;
- specular_light *rev_amount;
+ specular_light *= rev_amount;
diffuse_light *= rev_amount;
}
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index 9c02549e39..d78316945f 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -613,20 +613,18 @@ Error AudioDriverPulseAudio::capture_init_device() {
break;
}
- print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels");
-
pa_sample_spec spec;
spec.format = PA_SAMPLE_S16LE;
spec.channels = pa_rec_map.channels;
spec.rate = mix_rate;
- int latency = 30;
- input_buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
- int buffer_size = input_buffer_frames * spec.channels;
+ int input_latency = 30;
+ int input_buffer_frames = closest_power_of_2(input_latency * mix_rate / 1000);
+ int input_buffer_size = input_buffer_frames * spec.channels;
pa_buffer_attr attr;
- attr.fragsize = buffer_size * sizeof(int16_t);
+ attr.fragsize = input_buffer_size * sizeof(int16_t);
pa_rec_str = pa_stream_new(pa_ctx, "Record", &spec, &pa_rec_map);
if (pa_rec_str == NULL) {
@@ -642,9 +640,10 @@ Error AudioDriverPulseAudio::capture_init_device() {
ERR_FAIL_V(ERR_CANT_OPEN);
}
- input_buffer.resize(input_buffer_frames * 8);
- input_position = 0;
- input_size = 0;
+ input_buffer_init(input_buffer_frames);
+
+ print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels");
+ print_verbose("PulseAudio: input buffer frames: " + itos(input_buffer_frames) + " calculated latency: " + itos(input_buffer_frames * 1000 / mix_rate) + "ms");
return OK;
}
@@ -760,7 +759,6 @@ AudioDriverPulseAudio::AudioDriverPulseAudio() {
mix_rate = 0;
buffer_frames = 0;
- input_buffer_frames = 0;
pa_buffer_size = 0;
channels = 0;
pa_ready = 0;
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index f8358a452b..d8bab841ff 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -64,7 +64,6 @@ class AudioDriverPulseAudio : public AudioDriver {
unsigned int mix_rate;
unsigned int buffer_frames;
- unsigned int input_buffer_frames;
unsigned int pa_buffer_size;
int channels;
int pa_ready;
diff --git a/drivers/rtaudio/audio_driver_rtaudio.cpp b/drivers/rtaudio/audio_driver_rtaudio.cpp
index 10ba0663f2..bc6ceb1e7e 100644
--- a/drivers/rtaudio/audio_driver_rtaudio.cpp
+++ b/drivers/rtaudio/audio_driver_rtaudio.cpp
@@ -114,11 +114,12 @@ Error AudioDriverRtAudio::init() {
unsigned int buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
print_verbose("Audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
- short int tries = 2;
+ short int tries = 4;
- while (tries >= 0) {
+ while (tries > 0) {
switch (speaker_mode) {
case SPEAKER_MODE_STEREO: parameters.nChannels = 2; break;
+ case SPEAKER_SURROUND_31: parameters.nChannels = 4; break;
case SPEAKER_SURROUND_51: parameters.nChannels = 6; break;
case SPEAKER_SURROUND_71: parameters.nChannels = 8; break;
};
@@ -128,12 +129,14 @@ Error AudioDriverRtAudio::init() {
active = true;
break;
- } catch (RtAudioError &e) {
+ } catch (RtAudioError) {
// try with less channels
ERR_PRINT("Unable to open audio, retrying with fewer channels...");
switch (speaker_mode) {
- case SPEAKER_SURROUND_51: speaker_mode = SPEAKER_MODE_STEREO; break;
+ case SPEAKER_MODE_STEREO: break; // Required to silence unhandled enum value warning.
+ case SPEAKER_SURROUND_31: speaker_mode = SPEAKER_MODE_STEREO; break;
+ case SPEAKER_SURROUND_51: speaker_mode = SPEAKER_SURROUND_31; break;
case SPEAKER_SURROUND_71: speaker_mode = SPEAKER_SURROUND_51; break;
}
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 48b4369b7e..929e67faa9 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -309,7 +309,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
// prev_dir is the directory we are changing out of
String prev_dir;
char real_current_dir_name[2048];
- getcwd(real_current_dir_name, 2048);
+ ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == NULL, ERR_BUG);
if (prev_dir.parse_utf8(real_current_dir_name))
prev_dir = real_current_dir_name; //no utf8, maybe latin?
@@ -330,7 +330,7 @@ Error DirAccessUnix::change_dir(String p_dir) {
// the directory exists, so set current_dir to try_dir
current_dir = try_dir;
- chdir(prev_dir.utf8().get_data());
+ ERR_FAIL_COND_V(chdir(prev_dir.utf8().get_data()) != 0, ERR_BUG);
return OK;
}
@@ -405,7 +405,7 @@ DirAccessUnix::DirAccessUnix() {
// set current directory to an absolute path of the current directory
char real_current_dir_name[2048];
- getcwd(real_current_dir_name, 2048);
+ ERR_FAIL_COND(getcwd(real_current_dir_name, 2048) == NULL);
if (current_dir.parse_utf8(real_current_dir_name))
current_dir = real_current_dir_name;
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 3f03175403..f981be66ce 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -42,12 +42,8 @@
#include <sys/types.h>
#include <unistd.h>
#ifndef NO_FCNTL
-#ifdef __HAIKU__
#include <fcntl.h>
#else
-#include <sys/fcntl.h>
-#endif
-#else
#include <sys/ioctl.h>
#endif
#include <netinet/in.h>
@@ -59,7 +55,7 @@
#include <netinet/tcp.h>
-#if defined(OSX_ENABLED) || defined(IPHONE_ENABLED)
+#if defined(__APPLE__)
#define MSG_NOSIGNAL SO_NOSIGPIPE
#endif
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 6c70934bc6..279274734f 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -288,6 +288,11 @@ uint64_t OS_Unix::get_ticks_usec() const {
Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr) {
+#ifdef __EMSCRIPTEN__
+ // Don't compile this code at all to avoid undefined references.
+ // Actual virtual call goes to OS_JavaScript.
+ ERR_FAIL_V(ERR_BUG);
+#else
if (p_blocking && r_pipe) {
String argss;
@@ -354,6 +359,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
return OK;
+#endif
}
Error OS_Unix::kill(const ProcessID &p_pid) {
@@ -487,9 +493,11 @@ String OS_Unix::get_executable_path() const {
//fix for running from a symlink
char buf[256];
memset(buf, 0, 256);
- readlink("/proc/self/exe", buf, sizeof(buf));
+ ssize_t len = readlink("/proc/self/exe", buf, sizeof(buf));
String b;
- b.parse_utf8(buf);
+ if (len > 0) {
+ b.parse_utf8(buf, len);
+ }
if (b == "") {
WARN_PRINT("Couldn't get executable path from /proc/self/exe, using argv[0]");
return OS::get_executable_path();
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 3d4979175b..8665f701b1 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -336,10 +336,7 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
HRESULT hr = audio_input.audio_client->GetBufferSize(&max_frames);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
- // Set the buffer size
- input_buffer.resize(max_frames * CAPTURE_BUFFER_CHANNELS);
- input_position = 0;
- input_size = 0;
+ input_buffer_init(max_frames);
return OK;
}
@@ -796,19 +793,18 @@ Error AudioDriverWASAPI::capture_start() {
return err;
}
- if (audio_input.active == false) {
- audio_input.audio_client->Start();
- audio_input.active = true;
-
- return OK;
+ if (audio_input.active) {
+ return FAILED;
}
- return FAILED;
+ audio_input.audio_client->Start();
+ audio_input.active = true;
+ return OK;
}
Error AudioDriverWASAPI::capture_stop() {
- if (audio_input.active == true) {
+ if (audio_input.active) {
audio_input.audio_client->Stop();
audio_input.active = false;
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index b4492a2022..2582478259 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -114,7 +114,7 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
path = path + ".tmp";
}
- f = _wfopen(path.c_str(), mode_string);
+ _wfopen_s(&f, path.c_str(), mode_string);
if (f == NULL) {
last_error = ERR_FILE_CANT_OPEN;
@@ -278,7 +278,7 @@ bool FileAccessWindows::file_exists(const String &p_name) {
FILE *g;
//printf("opening file %s\n", p_fname.c_str());
String filename = fix_path(p_name);
- g = _wfopen(filename.c_str(), L"rb");
+ _wfopen_s(&g, filename.c_str(), L"rb");
if (g == NULL) {
return false;