Exemple #1
0
void ConvexPolygonShape2DSW::set_data(const Variant& p_data) {

	ERR_FAIL_COND(p_data.get_type()!=Variant::VECTOR2_ARRAY && p_data.get_type()!=Variant::REAL_ARRAY);


	if (points)
		memdelete_arr(points);
	points=NULL;
	point_count=0;

	if (p_data.get_type()==Variant::VECTOR2_ARRAY) {
		DVector<Vector2> arr=p_data;
		ERR_FAIL_COND(arr.size()==0);
		point_count=arr.size();
		points = memnew_arr(Point,point_count);
		DVector<Vector2>::Read r = arr.read();

		for(int i=0;i<point_count;i++) {
			points[i].pos=r[i];
		}

		for(int i=0;i<point_count;i++) {

			Vector2 p = points[i].pos;
			Vector2 pn = points[(i+1)%point_count].pos;
			points[i].normal=(pn-p).tangent().normalized();
		}
	} else {

		DVector<real_t> dvr = p_data;
		point_count=dvr.size()/4;
		ERR_FAIL_COND(point_count==0);

		points = memnew_arr(Point,point_count);
		DVector<real_t>::Read r = dvr.read();

		for(int i=0;i<point_count;i++) {

			int idx=i<<2;
			points[i].pos.x=r[idx+0];
			points[i].pos.y=r[idx+1];
			points[i].normal.x=r[idx+2];
			points[i].normal.y=r[idx+3];

		}
	}


	ERR_FAIL_COND(point_count==0);
	Rect2 aabb;
	aabb.pos=points[0].pos;
	for(int i=1;i<point_count;i++)
		aabb.expand_to(points[i].pos);

	configure(aabb);
}
Error AudioDriverXAudio2::init() {

	active = false;
	thread_exited = false;
	exit_thread = false;
	pcm_open = false;
	samples_in = NULL;

	mix_rate = 48000;
	// FIXME: speaker_mode seems unused in the Xaudio2 driver so far
	speaker_mode = SPEAKER_MODE_STEREO;
	channels = 2;

	int latency = GLOBAL_DEF("audio/output_latency", 25);
	buffer_size = closest_power_of_2(latency * mix_rate / 1000);

	samples_in = memnew_arr(int32_t, buffer_size * channels);
	for (int i = 0; i < AUDIO_BUFFERS; i++) {
		samples_out[i] = memnew_arr(int16_t, buffer_size * channels);
		xaudio_buffer[i].AudioBytes = buffer_size * channels * sizeof(int16_t);
		xaudio_buffer[i].pAudioData = (const BYTE *)(samples_out[i]);
		xaudio_buffer[i].Flags = 0;
	}

	HRESULT hr;
	hr = XAudio2Create(&xaudio, 0, XAUDIO2_DEFAULT_PROCESSOR);
	if (hr != S_OK) {
		ERR_EXPLAIN("Error creating XAudio2 engine.");
		ERR_FAIL_V(ERR_UNAVAILABLE);
	}
	hr = xaudio->CreateMasteringVoice(&mastering_voice);
	if (hr != S_OK) {
		ERR_EXPLAIN("Error creating XAudio2 mastering voice.");
		ERR_FAIL_V(ERR_UNAVAILABLE);
	}

	wave_format.nChannels = channels;
	wave_format.cbSize = 0;
	wave_format.nSamplesPerSec = mix_rate;
	wave_format.wFormatTag = WAVE_FORMAT_PCM;
	wave_format.wBitsPerSample = 16;
	wave_format.nBlockAlign = channels * wave_format.wBitsPerSample >> 3;
	wave_format.nAvgBytesPerSec = mix_rate * wave_format.nBlockAlign;

	hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, &voice_callback);
	if (hr != S_OK) {
		ERR_EXPLAIN("Error creating XAudio2 source voice. " + itos(hr));
		ERR_FAIL_V(ERR_UNAVAILABLE);
	}

	mutex = Mutex::create();
	thread = Thread::create(AudioDriverXAudio2::thread_func, this);

	return OK;
};
Error AudioDriverPulseAudio::init() {

	active = false;
	thread_exited = false;
	exit_thread = false;
	pcm_open = false;
	samples_in = NULL;
	samples_out = NULL;

	mix_rate = GLOBAL_DEF("audio/mix_rate",44100);
	speaker_mode = SPEAKER_MODE_STEREO;
	channels = 2;

	pa_sample_spec spec;
	spec.format = PA_SAMPLE_S16LE;
	spec.channels = channels;
	spec.rate = mix_rate;

	int latency = GLOBAL_DEF("audio/output_latency", 25);
	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);

	pa_buffer_attr attr;
	// set to appropriate buffer size from global settings
	attr.tlength = buffer_size;
	// set them to be automatically chosen
	attr.prebuf = (uint32_t)-1;
	attr.maxlength = (uint32_t)-1;
	attr.minreq = (uint32_t)-1;

	int error_code;
	pulse = pa_simple_new(	NULL,         // default server
				"Godot",      // application name
				PA_STREAM_PLAYBACK,
				NULL,         // default device
				"Sound",      // stream description
				&spec,
				NULL,         // use default channel map
				&attr,         // use buffering attributes from above
				&error_code
				);

	if (pulse == NULL) {
		fprintf(stderr, "PulseAudio ERR: %s\n", pa_strerror(error_code));\
		ERR_FAIL_COND_V(pulse == NULL, ERR_CANT_OPEN);
	}


	samples_in = memnew_arr(int32_t, buffer_size * channels);
	samples_out = memnew_arr(int16_t, buffer_size * channels);

	mutex = Mutex::create();
	thread = Thread::create(AudioDriverPulseAudio::thread_func, this);

	return OK;
}
Exemple #4
0
EventQueue::EventQueue(uint32_t p_buffer_size) {

	buffer_end = 0;
	buffer_max_used = 0;
	buffer_size = p_buffer_size;
	event_buffer = memnew_arr(uint8_t, buffer_size);
}
Exemple #5
0
Error AudioDriverIphone::init() {

	active = false;
	channels = 2;

	AudioStreamBasicDescription strdesc;
	strdesc.mFormatID = kAudioFormatLinearPCM;
	strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
	strdesc.mChannelsPerFrame = channels;
	strdesc.mSampleRate = 44100;
	strdesc.mFramesPerPacket = 1;
	strdesc.mBitsPerChannel = 16;
	strdesc.mBytesPerFrame =
		strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
	strdesc.mBytesPerPacket =
		strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;

	OSStatus result = noErr;
	AURenderCallbackStruct callback;
	AudioComponentDescription desc;
	AudioComponent comp = NULL;
	const AudioUnitElement output_bus = 0;
	const AudioUnitElement bus = output_bus;
	const AudioUnitScope scope = kAudioUnitScope_Input;

	zeromem(&desc, sizeof(desc));
	desc.componentType = kAudioUnitType_Output;
	desc.componentSubType = kAudioUnitSubType_RemoteIO;  /* !!! FIXME: ? */
	comp = AudioComponentFindNext(NULL, &desc);
	desc.componentManufacturer = kAudioUnitManufacturer_Apple;

	result = AudioComponentInstanceNew(comp, &audio_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);
	ERR_FAIL_COND_V(comp == NULL, FAILED);

	result = AudioUnitSetProperty(audio_unit,
								  kAudioUnitProperty_StreamFormat,
								  scope, bus, &strdesc, sizeof(strdesc));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	zeromem(&callback, sizeof(AURenderCallbackStruct));
	callback.inputProc = &AudioDriverIphone::output_callback;
	callback.inputProcRefCon = this;
	result = AudioUnitSetProperty(audio_unit,
								  kAudioUnitProperty_SetRenderCallback,
								  scope, bus, &callback, sizeof(callback));
	ERR_FAIL_COND_V(result != noErr, FAILED);

	result = AudioUnitInitialize(audio_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	result = AudioOutputUnitStart(audio_unit);
	ERR_FAIL_COND_V(result != noErr, FAILED);

	const int samples = 1024;
	samples_in = memnew_arr(int32_t, samples); // whatever
	buffer_frames = samples / channels;

	return FAILED;
};
Exemple #6
0
void MethodBind::_generate_argument_types(int p_count) {

	set_argument_count(p_count);
	Variant::Type *argt = memnew_arr(Variant::Type, p_count + 1);
	argt[0] = _gen_argument_type(-1);
	for (int i = 0; i < p_count; i++) {
		argt[i + 1] = _gen_argument_type(i);
	}
	set_argument_types(argt);
}
Exemple #7
0
MessageQueue::MessageQueue() {

	ERR_FAIL_COND(singleton!=NULL);
	singleton=this;

	buffer_end=0;
	buffer_max_used=0;
	buffer_size=GLOBAL_DEF( "core/message_queue_size_kb", DEFAULT_QUEUE_SIZE_KB );
	buffer_size*=1024;
	buffer = memnew_arr( uint8_t, buffer_size );
}
Exemple #8
0
void PoolAllocator::create_pool(void *p_mem, int p_size, int p_max_entries) {

	pool = (uint8_t *)p_mem;
	pool_size = p_size;

	entry_array = memnew_arr(Entry, p_max_entries);
	entry_indices = memnew_arr(int, p_max_entries);
	entry_max = p_max_entries;
	entry_count = 0;

	free_mem = p_size;
	free_mem_peak = p_size;

	check_count = 0;
}
Error AudioDriverAndroid::init(){

	mutex = Mutex::create();
/*
	// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
	   this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
	   SDL_CalculateAudioSpec(&this->spec);

	   if (this->spec.samples == 0) {
	       // Init failed?
	       SDL_SetError("Java-side initialization failed!");
	       return 0;
	   }
*/

	//Android_JNI_SetupThread();


  //        __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");


	JNIEnv *env = ThreadAndroid::get_env();
	int mix_rate = GLOBAL_DEF("audio/mix_rate",44100);

	int latency = GLOBAL_DEF("audio/output_latency",25);
	latency=50;
	unsigned int buffer_size = nearest_power_of_2( latency * mix_rate / 1000 );
	if (OS::get_singleton()->is_stdout_verbose()) {
		print_line("audio buffer size: "+itos(buffer_size));
	}

	__android_log_print(ANDROID_LOG_INFO,"godot","Initializing audio! params: %i,%i ",mix_rate,buffer_size);
	audioBuffer = env->CallObjectMethod(io,_init_audio, mix_rate, buffer_size);


	ERR_FAIL_COND_V( audioBuffer == NULL, ERR_INVALID_PARAMETER);

	audioBuffer = env->NewGlobalRef(audioBuffer);

	jboolean isCopy = JNI_FALSE;
	audioBufferPinned = env->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
	audioBufferFrames = env->GetArrayLength((jshortArray)audioBuffer);
	audioBuffer32 = memnew_arr(int32_t,audioBufferFrames);

	return OK;
}
Error AudioDriverNacl::init(){

	int frame_size = 4096;
	sample_frame_count_ = pp::AudioConfig::RecommendSampleFrameCount(godot_instance,PP_AUDIOSAMPLERATE_44100, frame_size);
	sample_count = sample_frame_count_ * 2;

	audio_ = pp::Audio(godot_instance,
					   pp::AudioConfig(godot_instance,
									   PP_AUDIOSAMPLERATE_44100,
									   sample_frame_count_),
					   &AudioDriverNacl::output_callback,
					   this);

	samples_in = memnew_arr(int32_t, sample_frame_count_ * 2);

	return OK;
}
void BakedLightBaker::_make_bvh() {

	Vector<BVH*> bases;
	bases.resize(triangles.size());
	int max_depth=0;
	for(int i=0;i<triangles.size();i++) {
		bases[i]=memnew( BVH );
		bases[i]->leaf=&triangles[i];
		bases[i]->aabb.pos=triangles[i].vertices[0];
		bases[i]->aabb.expand_to(triangles[i].vertices[1]);
		bases[i]->aabb.expand_to(triangles[i].vertices[2]);
		bases[i]->center=bases[i]->aabb.pos+bases[i]->aabb.size*0.5;
	}

	bvh=_parse_bvh(bases.ptr(),bases.size(),1,max_depth);
	ray_stack = memnew_arr(uint32_t,max_depth);
	bvh_stack = memnew_arr(BVH*,max_depth);
}
Exemple #12
0
String StringBuilder::as_string() const {

	if (string_length == 0)
		return "";

	CharType *buffer = memnew_arr(CharType, string_length);

	int current_position = 0;

	int godot_string_elem = 0;
	int c_string_elem = 0;

	for (int i = 0; i < appended_strings.size(); i++) {
		if (appended_strings[i] == -1) {
			// Godot string
			const String &s = strings[godot_string_elem];

			memcpy(buffer + current_position, s.ptr(), s.length() * sizeof(CharType));

			current_position += s.length();

			godot_string_elem++;
		} else {

			const char *s = c_strings[c_string_elem];

			for (int32_t j = 0; j < appended_strings[i]; j++) {
				buffer[current_position + j] = s[j];
			}

			current_position += appended_strings[i];

			c_string_elem++;
		}
	}

	String final_string = String(buffer, string_length);

	memdelete_arr(buffer);

	return final_string;
}
Exemple #13
0
Error AudioDriverDummy::init() {

	active=false;
	thread_exited=false;
	exit_thread=false;
	pcm_open = false;
	samples_in = NULL;


	mix_rate = 44100;
	speaker_mode = SPEAKER_MODE_STEREO;
	channels = 2;

	int latency = GLOBAL_DEF("audio/output_latency",25);
	buffer_size = nearest_power_of_2( latency * mix_rate / 1000 );

	samples_in = memnew_arr(int32_t, buffer_size*channels);

	mutex=Mutex::create();
	thread = Thread::create(AudioDriverDummy::thread_func, this);

	return OK;
};
Exemple #14
0
Error AudioDriverMediaKit::init() {
	active = false;

	mix_rate = 44100;
	output_format = OUTPUT_STEREO;
	channels = 2;

	int latency = GLOBAL_DEF("audio/output_latency", 25);
	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
	samples_in = memnew_arr(int32_t, buffer_size * channels);

	media_raw_audio_format format;
	format = media_raw_audio_format::wildcard;
	format.frame_rate = mix_rate;
	format.channel_count = channels;
	format.format = media_raw_audio_format::B_AUDIO_INT;
	format.byte_order = B_MEDIA_LITTLE_ENDIAN;
	format.buffer_size = buffer_size * sizeof(int32_t) * channels;

	player = new BSoundPlayer(
		&format,
		"godot_sound_server",
		AudioDriverMediaKit::PlayBuffer,
		NULL,
		this
	);

	if (player->InitCheck() != B_OK) {
		fprintf(stderr, "MediaKit ERR: can not create a BSoundPlayer instance\n");
		ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN);
	}

	mutex = Mutex::create();
	player->Start();

	return OK;
}
Exemple #15
0
ShaderGLES2::Version *ShaderGLES2::get_current_version() {

	Version *_v = version_map.getptr(conditional_version);

	if (_v) {
		if (conditional_version.code_version != 0) {
			CustomCode *cc = custom_code_map.getptr(conditional_version.code_version);
			ERR_FAIL_COND_V(!cc, _v);
			if (cc->version == _v->code_version)
				return _v;
		} else {
			return _v;
		}
	}

	if (!_v)
		version_map[conditional_version] = Version();

	Version &v = version_map[conditional_version];

	if (!_v) {
		v.uniform_location = memnew_arr(GLint, uniform_count);
	} else {
		if (v.ok) {
			glDeleteShader(v.vert_id);
			glDeleteShader(v.frag_id);
			glDeleteProgram(v.id);
			v.id = 0;
		}
	}

	v.ok = false;

	Vector<const char *> strings;

#ifdef GLES_OVER_GL
	strings.push_back("#version 120\n");
	strings.push_back("#define USE_GLES_OVER_GL\n");
#else
	strings.push_back("#version 100\n");
//angle does not like
#ifdef JAVASCRIPT_ENABLED
	strings.push_back("#define USE_HIGHP_PRECISION\n");
#endif

#endif

	int define_line_ofs = 1;

	for (int j = 0; j < conditional_count; j++) {
		bool enable = (conditional_version.version & (1 << j)) > 0;

		if (enable) {
			strings.push_back(conditional_defines[j]);
			define_line_ofs++;
			DEBUG_PRINT(conditional_defines[j]);
		}
	}

	// keep them around during the function
	CharString code_string;
	CharString code_string2;
	CharString code_globals;

	CustomCode *cc = NULL;

	if (conditional_version.code_version > 0) {
		cc = custom_code_map.getptr(conditional_version.code_version);

		ERR_FAIL_COND_V(!cc, NULL);
		v.code_version = cc->version;
		define_line_ofs += 2;
	}

	// program

	v.id = glCreateProgram();
	ERR_FAIL_COND_V(v.id == 0, NULL);

	if (cc) {
		for (int i = 0; i < cc->custom_defines.size(); i++) {
			strings.push_back(cc->custom_defines.write[i]);
			DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i].get_data()));
		}
	}

	// vertex shader

	int string_base_size = strings.size();

	strings.push_back(vertex_code0.get_data());

	if (cc) {
		code_globals = cc->vertex_globals.ascii();
		strings.push_back(code_globals.get_data());
	}

	strings.push_back(vertex_code1.get_data());

	if (cc) {
		code_string = cc->vertex.ascii();
		strings.push_back(code_string.get_data());
	}

	strings.push_back(vertex_code2.get_data());

#ifdef DEBUG_SHADER

	DEBUG_PRINT("\nVertex Code:\n\n" + String(code_string.get_data()));

#endif

	v.vert_id = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(v.vert_id, strings.size(), &strings[0], NULL);
	glCompileShader(v.vert_id);

	GLint status;

	glGetShaderiv(v.vert_id, GL_COMPILE_STATUS, &status);
	if (status == GL_FALSE) {
		GLsizei iloglen;
		glGetShaderiv(v.vert_id, GL_INFO_LOG_LENGTH, &iloglen);

		if (iloglen < 0) {
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;

			ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?");
		} else {
			if (iloglen == 0) {
				iloglen = 4096; // buggy driver (Adreno 220+)
			}

			char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
			ilogmem[iloglen] = '\0';
			glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem);

			String err_string = get_shader_name() + ": Vertex shader compilation failed:\n";

			err_string += ilogmem;

			_display_error_with_code(err_string, strings);

			Memory::free_static(ilogmem);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;
		}

		ERR_FAIL_V(NULL);
	}

	strings.resize(string_base_size);

	// fragment shader

	strings.push_back(fragment_code0.get_data());

	if (cc) {
		code_globals = cc->fragment_globals.ascii();
		strings.push_back(code_globals.get_data());
	}

	strings.push_back(fragment_code1.get_data());

	if (cc) {
		code_string = cc->light.ascii();
		strings.push_back(code_string.get_data());
	}

	strings.push_back(fragment_code2.get_data());

	if (cc) {
		code_string2 = cc->fragment.ascii();
		strings.push_back(code_string2.get_data());
	}

	strings.push_back(fragment_code3.get_data());

#ifdef DEBUG_SHADER

	if (cc) {
		DEBUG_PRINT("\nFragment Code:\n\n" + String(cc->fragment_globals));
	}
	DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data()));
#endif

	v.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(v.frag_id, strings.size(), &strings[0], NULL);
	glCompileShader(v.frag_id);

	glGetShaderiv(v.frag_id, GL_COMPILE_STATUS, &status);
	if (status == GL_FALSE) {
		GLsizei iloglen;
		glGetShaderiv(v.frag_id, GL_INFO_LOG_LENGTH, &iloglen);

		if (iloglen < 0) {
			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;

			ERR_PRINT("No OpenGL fragment shader compiler log. What the frick?");
		} else {
			if (iloglen == 0) {
				iloglen = 4096; // buggy driver (Adreno 220+)
			}

			char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
			ilogmem[iloglen] = '\0';
			glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem);

			String err_string = get_shader_name() + ": Fragment shader compilation failed:\n";

			err_string += ilogmem;

			_display_error_with_code(err_string, strings);

			Memory::free_static(ilogmem);
			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;
		}

		ERR_FAIL_V(NULL);
	}

	glAttachShader(v.id, v.frag_id);
	glAttachShader(v.id, v.vert_id);

	// bind the attribute locations. This has to be done before linking so that the
	// linker doesn't assign some random indices

	for (int i = 0; i < attribute_pair_count; i++) {
		glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name);
	}

	glLinkProgram(v.id);

	glGetProgramiv(v.id, GL_LINK_STATUS, &status);
	if (status == GL_FALSE) {
		GLsizei iloglen;
		glGetProgramiv(v.id, GL_INFO_LOG_LENGTH, &iloglen);

		if (iloglen < 0) {
			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;

			ERR_PRINT("No OpenGL program link log. What the frick?");
			ERR_FAIL_V(NULL);
		}

		if (iloglen == 0) {
			iloglen = 4096; // buggy driver (Adreno 220+)
		}

		char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
		ilogmem[iloglen] = '\0';
		glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem);

		String err_string = get_shader_name() + ": Program linking failed:\n";

		err_string += ilogmem;

		_display_error_with_code(err_string, strings);

		Memory::free_static(ilogmem);
		glDeleteShader(v.frag_id);
		glDeleteShader(v.vert_id);
		glDeleteProgram(v.id);
		v.id = 0;

		ERR_FAIL_V(NULL);
	}

	// get uniform locations

	glUseProgram(v.id);

	for (int i = 0; i < uniform_count; i++) {
		v.uniform_location[i] = glGetUniformLocation(v.id, uniform_names[i]);
	}

	for (int i = 0; i < texunit_pair_count; i++) {
		GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name);
		if (loc >= 0) {
			if (texunit_pairs[i].index < 0) {
				glUniform1i(loc, max_image_units + texunit_pairs[i].index);
			} else {
				glUniform1i(loc, texunit_pairs[i].index);
			}
		}
	}

	if (cc) {
		// uniforms
		for (int i = 0; i < cc->custom_uniforms.size(); i++) {
			String native_uniform_name = _mkid(cc->custom_uniforms[i]);
			GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data());
			v.custom_uniform_locations[cc->custom_uniforms[i]] = location;
		}

		// textures
		for (int i = 0; i < cc->texture_uniforms.size(); i++) {
			String native_uniform_name = _mkid(cc->texture_uniforms[i]);
			GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data());
			v.custom_uniform_locations[cc->texture_uniforms[i]] = location;
		}
	}

	glUseProgram(0);
	v.ok = true;

	if (cc) {
		cc->versions.insert(conditional_version.version);
	}

	return &v;
}
void AudioDriverOpenSL::start() {

	mutex = Mutex::create();
	active = false;

	SLint32 numOutputs = 0;
	SLuint32 deviceID = 0;
	SLresult res;

	buffer_size = 1024;

	for (int i = 0; i < BUFFER_COUNT; i++) {

		buffers[i] = memnew_arr(int16_t, buffer_size * 2);
		memset(buffers[i], 0, buffer_size * 4);
	}

	mixdown_buffer = memnew_arr(int32_t, buffer_size * 2);

	/* Callback context for the buffer queue callback function */

	/* Get the SL Engine Interface which is implicit */
	res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void *)&EngineItf);

	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);

	{
		const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB };
		const SLboolean req[1] = { SL_BOOLEAN_FALSE };
		res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0, ids, req);
	}

	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);
	// Realizing the Output Mix object in synchronous mode.
	res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE);
	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);

	SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, BUFFER_COUNT };
	//bufferQueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
	//bufferQueue.numBuffers = BUFFER_COUNT; /* Four buffers in our buffer queue */
	/* Setup the format of the content in the buffer queue */
	pcm.formatType = SL_DATAFORMAT_PCM;
	pcm.numChannels = 2;
	pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
	pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
	pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
	pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
#ifdef BIG_ENDIAN_ENABLED
	pcm.endianness = SL_BYTEORDER_BIGENDIAN;
#else
	pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
#endif
	audioSource.pFormat = (void *)&pcm;
	audioSource.pLocator = (void *)&loc_bufq;

	/* Setup the data sink structure */
	locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
	locator_outputmix.outputMix = OutputMix;
	audioSink.pLocator = (void *)&locator_outputmix;
	audioSink.pFormat = NULL;
	/* Initialize the context for Buffer queue callbacks */
	//cntxt.pDataBase = (void*)&pcmData;
	//cntxt.pData = cntxt.pDataBase;
	//cntxt.size = sizeof(pcmData);

	/* Create the music player */

	{
		const SLInterfaceID ids[2] = { SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND };
		const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE };

		res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player, &audioSource, &audioSink, 1, ids, req);
		ERR_FAIL_COND(res != SL_RESULT_SUCCESS);
	}
	/* Realizing the player in synchronous mode. */
	res = (*player)->Realize(player, SL_BOOLEAN_FALSE);
	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);
	/* Get seek and play interfaces */
	res = (*player)->GetInterface(player, SL_IID_PLAY, (void *)&playItf);
	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);
	res = (*player)->GetInterface(player, SL_IID_BUFFERQUEUE,
			(void *)&bufferQueueItf);
	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);
	/* Setup to receive buffer queue event callbacks */
	res = (*bufferQueueItf)->RegisterCallback(bufferQueueItf, _buffer_callbacks, this);
	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);

	last_free = 0;

	//fill up buffers
	for (int i = 0; i < BUFFER_COUNT; i++) {
		/* Enqueue a few buffers to get the ball rolling */
		res = (*bufferQueueItf)->Enqueue(bufferQueueItf, buffers[i], 4 * buffer_size); /* Size given in */
	}

	res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
	ERR_FAIL_COND(res != SL_RESULT_SUCCESS);

	active = true;
}
Exemple #17
0
Error AudioDriverBB10::init(const char *p_name) {

	active = false;
	thread_exited = false;
	exit_thread = false;
	pcm_open = false;
	samples_in = NULL;
	samples_out = NULL;

	mix_rate = 44100;
	speaker_mode = SPEAKER_MODE_STEREO;

	char *dev_name;
	if (p_name == NULL) {
		dev_name = "pcmPreferred";
	} else {
		dev_name = (char *)p_name;
	}
	printf("******** reconnecting to device %s\n", dev_name);
	int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK);
	ERR_FAIL_COND_V(ret < 0, FAILED);
	pcm_open = true;

	snd_pcm_channel_info_t cinfo;
	zeromem(&cinfo, sizeof(cinfo));
	cinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
	snd_pcm_plugin_info(pcm_handle, &cinfo);

	printf("rates %i, %i, %i, %i, %i\n", cinfo.rates, cinfo.rates & SND_PCM_RATE_44100, cinfo.rates & SND_PCM_RATE_32000, cinfo.rates & SND_PCM_RATE_22050, cinfo.max_rate);

	mix_rate = cinfo.max_rate;

	printf("formats %i, %i, %i\n", cinfo.formats, cinfo.formats & SND_PCM_FMT_S16_BE, cinfo.formats & SND_PCM_FMT_S16_LE);
	ERR_FAIL_COND_V(!(cinfo.formats & SND_PCM_FMT_S16_LE), FAILED);

	printf("voices %i\n", cinfo.max_voices);
	speaker_mode = SPEAKER_MODE_STEREO;

	snd_pcm_channel_params_t cp;
	zeromem(&cp, sizeof(cp));
	cp.mode = SND_PCM_MODE_BLOCK;
	cp.channel = SND_PCM_CHANNEL_PLAYBACK;
	cp.start_mode = SND_PCM_START_DATA;
	cp.stop_mode = SND_PCM_STOP_STOP;
	//cp.buf.block.frag_size = cinfo.max_fragment_size;
	cp.buf.block.frag_size = 512;
	cp.buf.block.frags_max = 1;
	cp.buf.block.frags_min = 1;
	cp.format.interleave = 1;
	cp.format.rate = mix_rate;
	cp.format.voices = speaker_mode;
	cp.format.format = SND_PCM_SFMT_S16_LE;

	ret = snd_pcm_plugin_params(pcm_handle, &cp);
	printf("ret is %i, %i\n", ret, cp.why_failed);
	ERR_FAIL_COND_V(ret < 0, FAILED);

	ret = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
	ERR_FAIL_COND_V(ret < 0, FAILED);

	snd_mixer_group_t group;
	zeromem(&group, sizeof(group));
	snd_pcm_channel_setup_t setup;
	zeromem(&setup, sizeof(setup));
	setup.channel = SND_PCM_CHANNEL_PLAYBACK;
	setup.mode = SND_PCM_MODE_BLOCK;
	setup.mixer_gid = &group.gid;
	ret = snd_pcm_plugin_setup(pcm_handle, &setup);
	ERR_FAIL_COND_V(ret < 0, FAILED);

	pcm_frag_size = setup.buf.block.frag_size;
	pcm_max_frags = 1;

	sample_buf_count = pcm_frag_size * pcm_max_frags / 2;
	printf("sample count %i, %i, %i\n", sample_buf_count, pcm_frag_size, pcm_max_frags);
	samples_in = memnew_arr(int32_t, sample_buf_count);
	samples_out = memnew_arr(int16_t, sample_buf_count);

	thread = Thread::create(AudioDriverBB10::thread_func, this);

	return OK;
};
Exemple #18
0
static Vector<Vector<Vector2> > _b2d_decompose(const Vector<Vector2> &p_polygon) {

	Vector<Vector<Vector2> > res;
	if (p_polygon.size() < 3)
		return res;

	b2Vec2 *polys = memnew_arr(b2Vec2, p_polygon.size());
	for (int i = 0; i < p_polygon.size(); i++)
		polys[i] = b2Vec2(p_polygon[i].x, p_polygon[i].y);

	b2Polygon *p = new b2Polygon(polys, p_polygon.size());
	b2Polygon *decomposed = new b2Polygon[p->nVertices - 2]; //maximum number of polys

	memdelete_arr(polys);

	int32 nPolys = DecomposeConvex(p, decomposed, p->nVertices - 2);
	//int32 extra = 0;
	for (int32 i = 0; i < nPolys; ++i) {
		//   b2FixtureDef* toAdd = &pdarray[i+extra];
		// *toAdd = *prototype;
		//Hmm, shouldn't have to do all this...
		b2Polygon curr = decomposed[i];
		//TODO ewjordan: move this triangle handling to a better place so that
		//it happens even if this convenience function is not called.
		if (curr.nVertices == 3) {
			//Check here for near-parallel edges, since we can't
			//handle this in merge routine
			for (int j = 0; j < 3; ++j) {
				int32 lower = (j == 0) ? (curr.nVertices - 1) : (j - 1);
				int32 middle = j;
				int32 upper = (j == curr.nVertices - 1) ? (0) : (j + 1);
				float32 dx0 = curr.x[middle] - curr.x[lower];
				float32 dy0 = curr.y[middle] - curr.y[lower];
				float32 dx1 = curr.x[upper] - curr.x[middle];
				float32 dy1 = curr.y[upper] - curr.y[middle];
				float32 norm0 = sqrtf(dx0 * dx0 + dy0 * dy0);
				float32 norm1 = sqrtf(dx1 * dx1 + dy1 * dy1);
				if (!(norm0 > 0.0f && norm1 > 0.0f)) {
					//Identical points, don't do anything!
					goto Skip;
				}
				dx0 /= norm0;
				dy0 /= norm0;
				dx1 /= norm1;
				dy1 /= norm1;
				float32 cross = dx0 * dy1 - dx1 * dy0;
				float32 dot = dx0 * dx1 + dy0 * dy1;
				if (fabs(cross) < b2_angularSlop && dot > 0) {
					//Angle too close, split the triangle across from this point.
					//This is guaranteed to result in two triangles that satify
					//the tolerance (one of the angles is 90 degrees)
					float32 dx2 = curr.x[lower] - curr.x[upper];
					float32 dy2 = curr.y[lower] - curr.y[upper];
					float32 norm2 = sqrtf(dx2 * dx2 + dy2 * dy2);
					if (norm2 == 0.0f) {
						goto Skip;
					}
					dx2 /= norm2;
					dy2 /= norm2;
					float32 thisArea = curr.GetArea();
					float32 thisHeight = 2.0f * thisArea / norm2;
					float32 buffer2 = dx2;
					dx2 = dy2;
					dy2 = -buffer2;
					//Make two new polygons
					//printf("dx2: %f, dy2: %f, thisHeight: %f, middle: %d\n",dx2,dy2,thisHeight,middle);
					float32 newX1[3] = { curr.x[middle] + dx2 * thisHeight, curr.x[lower], curr.x[middle] };
					float32 newY1[3] = { curr.y[middle] + dy2 * thisHeight, curr.y[lower], curr.y[middle] };
					float32 newX2[3] = { newX1[0], curr.x[middle], curr.x[upper] };
					float32 newY2[3] = { newY1[0], curr.y[middle], curr.y[upper] };
					b2Polygon p1(newX1, newY1, 3);
					b2Polygon p2(newX2, newY2, 3);
					if (p1.IsUsable()) {
						add_to_res(res, p1);
						//++extra;
					} else if (B2_POLYGON_REPORT_ERRORS) {
						printf("Didn't add unusable polygon.  Dumping vertices:\n");
						p1.print();
					}
					if (p2.IsUsable()) {
						add_to_res(res, p2);

						//p2.AddTo(pdarray[i+extra]);

						//bd->CreateFixture(toAdd);
					} else if (B2_POLYGON_REPORT_ERRORS) {
						printf("Didn't add unusable polygon.  Dumping vertices:\n");
						p2.print();
					}
					goto Skip;
				}
			}
		}
		if (decomposed[i].IsUsable()) {
			add_to_res(res, decomposed[i]);

			//decomposed[i].AddTo(*toAdd);
			//bd->CreateFixture((const b2FixtureDef*)toAdd);
		} else if (B2_POLYGON_REPORT_ERRORS) {
			printf("Didn't add unusable polygon.  Dumping vertices:\n");
			decomposed[i].print();
		}
	Skip:;
	}
	//delete[] pdarray;
	delete[] decomposed;
	delete p;
	return res; // pdarray; //needs to be deleted after body is created
}
Exemple #19
0
PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_error) {

#define _MIN_SIZE 1.0
#define _MAX_LENGTH 20

	int face_count = p_array.size();
	PoolVector<Face3>::Read facesr = p_array.read();
	const Face3 *faces = facesr.ptr();

	Rect3 global_aabb;

	for (int i = 0; i < face_count; i++) {

		if (i == 0) {

			global_aabb = faces[i].get_aabb();
		} else {

			global_aabb.merge_with(faces[i].get_aabb());
		}
	}

	global_aabb.grow_by(0.01); // avoid numerical error

	// determine amount of cells in grid axis
	int div_x, div_y, div_z;

	if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH)
		div_x = (int)(global_aabb.size.x / _MIN_SIZE) + 1;
	else
		div_x = _MAX_LENGTH;

	if (global_aabb.size.y / _MIN_SIZE < _MAX_LENGTH)
		div_y = (int)(global_aabb.size.y / _MIN_SIZE) + 1;
	else
		div_y = _MAX_LENGTH;

	if (global_aabb.size.z / _MIN_SIZE < _MAX_LENGTH)
		div_z = (int)(global_aabb.size.z / _MIN_SIZE) + 1;
	else
		div_z = _MAX_LENGTH;

	Vector3 voxelsize = global_aabb.size;
	voxelsize.x /= div_x;
	voxelsize.y /= div_y;
	voxelsize.z /= div_z;

	// create and initialize cells to zero
	//print_line("Wrapper: Initializing Cells");

	uint8_t ***cell_status = memnew_arr(uint8_t **, div_x);
	for (int i = 0; i < div_x; i++) {

		cell_status[i] = memnew_arr(uint8_t *, div_y);

		for (int j = 0; j < div_y; j++) {

			cell_status[i][j] = memnew_arr(uint8_t, div_z);

			for (int k = 0; k < div_z; k++) {

				cell_status[i][j][k] = 0;
			}
		}
	}

	// plot faces into cells
	//print_line("Wrapper (1/6): Plotting Faces");

	for (int i = 0; i < face_count; i++) {

		Face3 f = faces[i];
		for (int j = 0; j < 3; j++) {

			f.vertex[j] -= global_aabb.pos;
		}
		_plot_face(cell_status, 0, 0, 0, div_x, div_y, div_z, voxelsize, f);
	}

	// determine which cells connect to the outside by traversing the outside and recursively flood-fill marking

	//print_line("Wrapper (2/6): Flood Filling");

	for (int i = 0; i < div_x; i++) {

		for (int j = 0; j < div_y; j++) {

			_mark_outside(cell_status, i, j, 0, div_x, div_y, div_z);
			_mark_outside(cell_status, i, j, div_z - 1, div_x, div_y, div_z);
		}
	}

	for (int i = 0; i < div_z; i++) {

		for (int j = 0; j < div_y; j++) {

			_mark_outside(cell_status, 0, j, i, div_x, div_y, div_z);
			_mark_outside(cell_status, div_x - 1, j, i, div_x, div_y, div_z);
		}
	}

	for (int i = 0; i < div_x; i++) {

		for (int j = 0; j < div_z; j++) {

			_mark_outside(cell_status, i, 0, j, div_x, div_y, div_z);
			_mark_outside(cell_status, i, div_y - 1, j, div_x, div_y, div_z);
		}
	}

	// build faces for the inside-outside cell divisors

	//print_line("Wrapper (3/6): Building Faces");

	PoolVector<Face3> wrapped_faces;

	for (int i = 0; i < div_x; i++) {

		for (int j = 0; j < div_y; j++) {

			for (int k = 0; k < div_z; k++) {

				_build_faces(cell_status, i, j, k, div_x, div_y, div_z, wrapped_faces);
			}
		}
	}

	//print_line("Wrapper (4/6): Transforming Back Vertices");

	// transform face vertices to global coords

	int wrapped_faces_count = wrapped_faces.size();
	PoolVector<Face3>::Write wrapped_facesw = wrapped_faces.write();
	Face3 *wrapped_faces_ptr = wrapped_facesw.ptr();

	for (int i = 0; i < wrapped_faces_count; i++) {

		for (int j = 0; j < 3; j++) {

			Vector3 &v = wrapped_faces_ptr[i].vertex[j];
			v = v * voxelsize;
			v += global_aabb.pos;
		}
	}

	// clean up grid
	//print_line("Wrapper (5/6): Grid Cleanup");

	for (int i = 0; i < div_x; i++) {

		for (int j = 0; j < div_y; j++) {

			memdelete_arr(cell_status[i][j]);
		}

		memdelete_arr(cell_status[i]);
	}

	memdelete_arr(cell_status);
	if (p_error)
		*p_error = voxelsize.length();

	//print_line("Wrapper (6/6): Finished.");
	return wrapped_faces;
}
Exemple #20
0
Error AudioDriverALSA::init() {

	active = false;
	thread_exited = false;
	exit_thread = false;
	pcm_open = false;
	samples_in = NULL;
	samples_out = NULL;

	mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
	speaker_mode = SPEAKER_MODE_STEREO;
	channels = 2;

	int status;
	snd_pcm_hw_params_t *hwparams;
	snd_pcm_sw_params_t *swparams;

#define CHECK_FAIL(m_cond)                                       \
	if (m_cond) {                                                \
		fprintf(stderr, "ALSA ERR: %s\n", snd_strerror(status)); \
		snd_pcm_close(pcm_handle);                               \
		ERR_FAIL_COND_V(m_cond, ERR_CANT_OPEN);                  \
	}

	//todo, add
	//6 chans - "plug:surround51"
	//4 chans - "plug:surround40";

	status = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);

	ERR_FAIL_COND_V(status < 0, ERR_CANT_OPEN);

	snd_pcm_hw_params_alloca(&hwparams);

	status = snd_pcm_hw_params_any(pcm_handle, hwparams);
	CHECK_FAIL(status < 0);

	status = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
	CHECK_FAIL(status < 0);

	//not interested in anything else
	status = snd_pcm_hw_params_set_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_LE);
	CHECK_FAIL(status < 0);

	//todo: support 4 and 6
	status = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2);
	CHECK_FAIL(status < 0);

	status = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &mix_rate, NULL);
	CHECK_FAIL(status < 0);

	int latency = GLOBAL_DEF("audio/output_latency", 25);
	buffer_size = closest_power_of_2(latency * mix_rate / 1000);

	// set buffer size from project settings
	status = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size);
	CHECK_FAIL(status < 0);

	// make period size 1/8
	period_size = buffer_size >> 3;
	status = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &period_size, NULL);
	CHECK_FAIL(status < 0);

	unsigned int periods = 2;
	status = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &periods, NULL);
	CHECK_FAIL(status < 0);

	status = snd_pcm_hw_params(pcm_handle, hwparams);
	CHECK_FAIL(status < 0);

	//snd_pcm_hw_params_free(&hwparams);

	snd_pcm_sw_params_alloca(&swparams);

	status = snd_pcm_sw_params_current(pcm_handle, swparams);
	CHECK_FAIL(status < 0);

	status = snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, period_size);
	CHECK_FAIL(status < 0);

	status = snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1);
	CHECK_FAIL(status < 0);

	status = snd_pcm_sw_params(pcm_handle, swparams);
	CHECK_FAIL(status < 0);

	samples_in = memnew_arr(int32_t, period_size * channels);
	samples_out = memnew_arr(int16_t, period_size * channels);

	snd_pcm_nonblock(pcm_handle, 0);

	mutex = Mutex::create();
	thread = Thread::create(AudioDriverALSA::thread_func, this);

	return OK;
};
Exemple #21
0
ShaderGLES3::Version *ShaderGLES3::get_current_version() {

	Version *_v = version_map.getptr(conditional_version);

	if (_v) {

		if (conditional_version.code_version != 0) {
			CustomCode *cc = custom_code_map.getptr(conditional_version.code_version);
			ERR_FAIL_COND_V(!cc, _v);
			if (cc->version == _v->code_version)
				return _v;
		} else {
			return _v;
		}
	}

	if (!_v)
		version_map[conditional_version] = Version();

	Version &v = version_map[conditional_version];

	if (!_v) {

		v.uniform_location = memnew_arr(GLint, uniform_count);

	} else {
		if (v.ok) {
			//bye bye shaders
			glDeleteShader(v.vert_id);
			glDeleteShader(v.frag_id);
			glDeleteProgram(v.id);
			v.id = 0;
		}
	}

	v.ok = false;
	/* SETUP CONDITIONALS */

	Vector<const char *> strings;
#ifdef GLES_OVER_GL
	strings.push_back("#version 330\n");
	strings.push_back("#define GLES_OVER_GL\n");
#else
	strings.push_back("#version 300 es\n");
#endif

	int define_line_ofs = 1;

	for (int i = 0; i < custom_defines.size(); i++) {

		strings.push_back(custom_defines[i].get_data());
		define_line_ofs++;
	}

	for (int j = 0; j < conditional_count; j++) {

		bool enable = ((1 << j) & conditional_version.version);
		strings.push_back(enable ? conditional_defines[j] : "");
		if (enable)
			define_line_ofs++;

		if (enable) {
			DEBUG_PRINT(conditional_defines[j]);
		}
	}

	//keep them around during the function
	CharString code_string;
	CharString code_string2;
	CharString code_globals;
	CharString material_string;

	CustomCode *cc = NULL;

	if (conditional_version.code_version > 0) {
		//do custom code related stuff

		ERR_FAIL_COND_V(!custom_code_map.has(conditional_version.code_version), NULL);
		cc = &custom_code_map[conditional_version.code_version];
		v.code_version = cc->version;
		define_line_ofs += 2;
	}

	/* CREATE PROGRAM */

	v.id = glCreateProgram();

	ERR_FAIL_COND_V(v.id == 0, NULL);

	/* VERTEX SHADER */

	if (cc) {
		for (int i = 0; i < cc->custom_defines.size(); i++) {

			strings.push_back(cc->custom_defines[i].get_data());
			DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i]));
		}
	}

	int strings_base_size = strings.size();

	//vertex precision is high
	strings.push_back("precision highp float;\n");
	strings.push_back("precision highp int;\n");
#ifndef GLES_OVER_GL
	strings.push_back("precision highp sampler2D;\n");
	strings.push_back("precision highp samplerCube;\n");
	strings.push_back("precision highp sampler2DArray;\n");
#endif

	strings.push_back(vertex_code0.get_data());

	if (cc) {
		material_string = cc->uniforms.ascii();
		strings.push_back(material_string.get_data());
	}

	strings.push_back(vertex_code1.get_data());

	if (cc) {
		code_globals = cc->vertex_globals.ascii();
		strings.push_back(code_globals.get_data());
	}

	strings.push_back(vertex_code2.get_data());

	if (cc) {
		code_string = cc->vertex.ascii();
		strings.push_back(code_string.get_data());
	}

	strings.push_back(vertex_code3.get_data());
#ifdef DEBUG_SHADER

	DEBUG_PRINT("\nVertex Code:\n\n" + String(code_string.get_data()));
	for (int i = 0; i < strings.size(); i++) {

		//print_line("vert strings "+itos(i)+":"+String(strings[i]));
	}
#endif

	v.vert_id = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(v.vert_id, strings.size(), &strings[0], NULL);
	glCompileShader(v.vert_id);

	GLint status;

	glGetShaderiv(v.vert_id, GL_COMPILE_STATUS, &status);
	if (status == GL_FALSE) {
		// error compiling
		GLsizei iloglen;
		glGetShaderiv(v.vert_id, GL_INFO_LOG_LENGTH, &iloglen);

		if (iloglen < 0) {

			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;

			ERR_PRINT("Vertex shader compilation failed with empty log");
		} else {

			if (iloglen == 0) {

				iloglen = 4096; //buggy driver (Adreno 220+....)
			}

			char *ilogmem = (char *)memalloc(iloglen + 1);
			ilogmem[iloglen] = 0;
			glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem);

			String err_string = get_shader_name() + ": Vertex Program Compilation Failed:\n";

			err_string += ilogmem;
			_display_error_with_code(err_string, strings);
			memfree(ilogmem);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;
		}

		ERR_FAIL_V(NULL);
	}

	//_display_error_with_code("pepo", strings);

	/* FRAGMENT SHADER */

	strings.resize(strings_base_size);
	//fragment precision is medium
	strings.push_back("precision highp float;\n");
	strings.push_back("precision highp int;\n");
#ifndef GLES_OVER_GL
	strings.push_back("precision highp sampler2D;\n");
	strings.push_back("precision highp samplerCube;\n");
	strings.push_back("precision highp sampler2DArray;\n");
#endif

	strings.push_back(fragment_code0.get_data());
	if (cc) {
		material_string = cc->uniforms.ascii();
		strings.push_back(material_string.get_data());
	}

	strings.push_back(fragment_code1.get_data());

	if (cc) {
		code_globals = cc->fragment_globals.ascii();
		strings.push_back(code_globals.get_data());
	}

	strings.push_back(fragment_code2.get_data());

	if (cc) {
		code_string = cc->light.ascii();
		strings.push_back(code_string.get_data());
	}

	strings.push_back(fragment_code3.get_data());

	if (cc) {
		code_string2 = cc->fragment.ascii();
		strings.push_back(code_string2.get_data());
	}

	strings.push_back(fragment_code4.get_data());

#ifdef DEBUG_SHADER
	DEBUG_PRINT("\nFragment Globals:\n\n" + String(code_globals.get_data()));
	DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string2.get_data()));
	for (int i = 0; i < strings.size(); i++) {

		//print_line("frag strings "+itos(i)+":"+String(strings[i]));
	}
#endif

	v.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(v.frag_id, strings.size(), &strings[0], NULL);
	glCompileShader(v.frag_id);

	glGetShaderiv(v.frag_id, GL_COMPILE_STATUS, &status);
	if (status == GL_FALSE) {
		// error compiling
		GLsizei iloglen;
		glGetShaderiv(v.frag_id, GL_INFO_LOG_LENGTH, &iloglen);

		if (iloglen < 0) {

			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;
			ERR_PRINT("Fragment shader compilation failed with empty log");
		} else {

			if (iloglen == 0) {

				iloglen = 4096; //buggy driver (Adreno 220+....)
			}

			char *ilogmem = (char *)memalloc(iloglen + 1);
			ilogmem[iloglen] = 0;
			glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem);

			String err_string = get_shader_name() + ": Fragment Program Compilation Failed:\n";

			err_string += ilogmem;
			_display_error_with_code(err_string, strings);
			ERR_PRINT(err_string.ascii().get_data());
			memfree(ilogmem);
			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;
		}

		ERR_FAIL_V(NULL);
	}

	glAttachShader(v.id, v.frag_id);
	glAttachShader(v.id, v.vert_id);

	// bind attributes before linking
	for (int i = 0; i < attribute_pair_count; i++) {

		glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name);
	}

	//if feedback exists, set it up

	if (feedback_count) {
		Vector<const char *> feedback;
		for (int i = 0; i < feedback_count; i++) {

			if (feedbacks[i].conditional == -1 || (1 << feedbacks[i].conditional) & conditional_version.version) {
				//conditional for this feedback is enabled
				feedback.push_back(feedbacks[i].name);
			}
		}

		if (feedback.size()) {
			glTransformFeedbackVaryings(v.id, feedback.size(), feedback.ptr(), GL_INTERLEAVED_ATTRIBS);
		}
	}

	glLinkProgram(v.id);

	glGetProgramiv(v.id, GL_LINK_STATUS, &status);

	if (status == GL_FALSE) {
		// error linking
		GLsizei iloglen;
		glGetProgramiv(v.id, GL_INFO_LOG_LENGTH, &iloglen);

		if (iloglen < 0) {

			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram(v.id);
			v.id = 0;
			ERR_FAIL_COND_V(iloglen <= 0, NULL);
		}

		if (iloglen == 0) {

			iloglen = 4096; //buggy driver (Adreno 220+....)
		}

		char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
		ilogmem[iloglen] = 0;
		glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem);

		String err_string = get_shader_name() + ": Program LINK FAILED:\n";

		err_string += ilogmem;
		_display_error_with_code(err_string, strings);
		ERR_PRINT(err_string.ascii().get_data());
		Memory::free_static(ilogmem);
		glDeleteShader(v.frag_id);
		glDeleteShader(v.vert_id);
		glDeleteProgram(v.id);
		v.id = 0;

		ERR_FAIL_V(NULL);
	}

	/* UNIFORMS */

	glUseProgram(v.id);

	//print_line("uniforms:  ");
	for (int j = 0; j < uniform_count; j++) {

		v.uniform_location[j] = glGetUniformLocation(v.id, uniform_names[j]);
		//print_line("uniform "+String(uniform_names[j])+" location "+itos(v.uniform_location[j]));
	}

	// set texture uniforms
	for (int i = 0; i < texunit_pair_count; i++) {

		GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name);
		if (loc >= 0) {
			if (texunit_pairs[i].index < 0) {
				glUniform1i(loc, max_image_units + texunit_pairs[i].index); //negative, goes down
			} else {

				glUniform1i(loc, texunit_pairs[i].index);
			}
		}
	}

	// assign uniform block bind points
	for (int i = 0; i < ubo_count; i++) {

		GLint loc = glGetUniformBlockIndex(v.id, ubo_pairs[i].name);
		if (loc >= 0)
			glUniformBlockBinding(v.id, loc, ubo_pairs[i].index);
	}

	if (cc) {

		v.texture_uniform_locations.resize(cc->texture_uniforms.size());
		for (int i = 0; i < cc->texture_uniforms.size(); i++) {

			v.texture_uniform_locations.write[i] = glGetUniformLocation(v.id, String(cc->texture_uniforms[i]).ascii().get_data());
			glUniform1i(v.texture_uniform_locations[i], i + base_material_tex_index);
		}
	}

	glUseProgram(0);

	v.ok = true;

	return &v;
}
Exemple #22
0
ShaderGLES2::Version* ShaderGLES2::get_current_version() {

	Version *_v=version_map.getptr(conditional_version);

	if (_v) {

		if (conditional_version.code_version!=0) {
			CustomCode *cc=custom_code_map.getptr(conditional_version.code_version);
			ERR_FAIL_COND_V(!cc,_v);
			if (cc->version==_v->code_version)
				return _v;
		} else {
			return _v;
		}

	}



	if (!_v)
		version_map[conditional_version]=Version();


	Version &v = version_map[conditional_version];

	if (!_v) {

		v.uniform_location = memnew_arr( GLint, uniform_count );

	} else {
		if (v.ok) {
			//bye bye shaders
			glDeleteShader( v.vert_id );
			glDeleteShader( v.frag_id );
			glDeleteProgram( v.id );
			v.id=0;
		}

	}

	v.ok=false;
	/* SETUP CONDITIONALS */
	
	Vector<const char*> strings;
#ifdef GLEW_ENABLED
	strings.push_back("#version 120\n"); //ATI requieres this before anything
#endif
	int define_line_ofs=1;

	for(int j=0;j<conditional_count;j++) {
		
		bool enable=((1<<j)&conditional_version.version);
		strings.push_back(enable?conditional_defines[j]:"");
		if (enable)
			define_line_ofs++;

		if (enable) {
			DEBUG_PRINT(conditional_defines[j]);
		}

	}
	
	//keep them around during the function
	CharString code_string;
	CharString code_string2;
	CharString code_globals;


	//print_line("code version? "+itos(conditional_version.code_version));

	CustomCode *cc=NULL;

	if ( conditional_version.code_version>0 ) {
		//do custom code related stuff

		ERR_FAIL_COND_V( !custom_code_map.has( conditional_version.code_version ), NULL );
		cc=&custom_code_map[conditional_version.code_version];
		v.code_version=cc->version;
		define_line_ofs+=2;
	}


	/* CREATE PROGRAM */
	
	v.id = glCreateProgram();
	
	ERR_FAIL_COND_V(v.id==0, NULL);
	
	/* VERTEX SHADER */


	if (cc) {
		for(int i=0;i<cc->custom_defines.size();i++) {

			strings.push_back(cc->custom_defines[i]);
			DEBUG_PRINT("CD #"+itos(i)+": "+String(cc->custom_defines[i]));
		}
	}

	int strings_base_size=strings.size();
#if 0
	if (cc) {

		String _code_string = "#define VERTEX_SHADER_CODE "+cc->vertex+"\n";
		String _code_globals = "#define VERTEX_SHADER_GLOBALS "+cc->vertex_globals+"\n";

		code_string=_code_string.ascii();
		code_globals=_code_globals.ascii();
		DEBUG_PRINT( code_globals.get_data() );
		DEBUG_PRINT( code_string.get_data() );
		strings.push_back(code_globals);
		strings.push_back(code_string);
	}
#endif


	strings.push_back(vertex_code0.get_data());
	if (cc) {
		code_globals=cc->vertex_globals.ascii();
		strings.push_back(code_globals.get_data());
	}
	strings.push_back(vertex_code1.get_data());

	if (cc) {
		code_string=cc->vertex.ascii();
		strings.push_back(code_string.get_data());
	}

	strings.push_back(vertex_code2.get_data());
#ifdef DEBUG_SHADER

	DEBUG_PRINT("\nVertex Code:\n\n"+String(code_string.get_data()));
	for(int i=0;i<strings.size();i++) {

		//print_line("vert strings "+itos(i)+":"+String(strings[i]));
	}
#endif


	v.vert_id = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(v.vert_id,strings.size(),&strings[0],NULL);
	glCompileShader(v.vert_id);
	
	GLint status;
	
	glGetShaderiv(v.vert_id,GL_COMPILE_STATUS,&status);			
	if (status==GL_FALSE) {
	// error compiling
		GLsizei iloglen;
		glGetShaderiv(v.vert_id,GL_INFO_LOG_LENGTH,&iloglen);
		
		if (iloglen<0) {
			
			glDeleteShader(v.vert_id);
			glDeleteProgram( v.id );
			v.id=0;
			
			ERR_PRINT("NO LOG, WTF");
		} else {

			if (iloglen==0) {

				iloglen = 4096; //buggy driver (Adreno 220+....)
			}

			
			char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
			ilogmem[iloglen]=0;
			glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem); 	
			
			String err_string=get_shader_name()+": Vertex Program Compilation Failed:\n";
			
			err_string+=ilogmem;
			err_string=_fix_error_code_line(err_string,vertex_code_start,define_line_ofs);
			ERR_PRINT(err_string.ascii().get_data());
			Memory::free_static(ilogmem);
			glDeleteShader(v.vert_id);
			glDeleteProgram( v.id );
			v.id=0;
			
		}
		
		ERR_FAIL_V(NULL);
	}	
	
	/* FRAGMENT SHADER */

	strings.resize(strings_base_size);
#if 0
	if (cc) {

		String _code_string = "#define FRAGMENT_SHADER_CODE "+cc->fragment+"\n";
		String _code_globals = "#define FRAGMENT_SHADER_GLOBALS "+cc->fragment_globals+"\n";

		code_string=_code_string.ascii();
		code_globals=_code_globals.ascii();
		DEBUG_PRINT( code_globals.get_data() );
		DEBUG_PRINT( code_string.get_data() );
		strings.push_back(code_globals);
		strings.push_back(code_string);
	}
#endif


	strings.push_back(fragment_code0.get_data());
	if (cc) {
		code_globals=cc->fragment_globals.ascii();
		strings.push_back(code_globals.get_data());
	}
	strings.push_back(fragment_code1.get_data());

	if (cc) {
		code_string=cc->fragment.ascii();
		strings.push_back(code_string.get_data());
	}

	strings.push_back(fragment_code2.get_data());

	if (cc) {
		code_string2=cc->light.ascii();
		strings.push_back(code_string2.get_data());
	}

	strings.push_back(fragment_code3.get_data());

#ifdef DEBUG_SHADER
	DEBUG_PRINT("\nFragment Code:\n\n"+String(code_string.get_data()));
	for(int i=0;i<strings.size();i++) {

		//print_line("frag strings "+itos(i)+":"+String(strings[i]));
	}
#endif

	v.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(v.frag_id,strings.size(),&strings[0],NULL);
	glCompileShader(v.frag_id);
	
	glGetShaderiv(v.frag_id,GL_COMPILE_STATUS,&status);			
	if (status==GL_FALSE) {
	// error compiling
		GLsizei iloglen;
		glGetShaderiv(v.frag_id,GL_INFO_LOG_LENGTH,&iloglen);
		
		if (iloglen<0) {

			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram( v.id );
			v.id=0;
			ERR_PRINT("NO LOG, WTF");
		} else {
			
			if (iloglen==0) {

				iloglen = 4096; //buggy driver (Adreno 220+....)
			}

			char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
			ilogmem[iloglen]=0;
			glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem); 	
			
			String err_string=get_shader_name()+": Fragment Program Compilation Failed:\n";
			
			err_string+=ilogmem;
			err_string=_fix_error_code_line(err_string,fragment_code_start,define_line_ofs);
			ERR_PRINT(err_string.ascii().get_data());
			Memory::free_static(ilogmem);
			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram( v.id );
			v.id=0;
			
		}
		
		ERR_FAIL_V( NULL );
	}		
	
	glAttachShader(v.id,v.frag_id);
	glAttachShader(v.id,v.vert_id);

	// bind attributes before linking
	for (int i=0;i<attribute_pair_count;i++) {

		glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name );
	}

	glLinkProgram(v.id);
	
	glGetProgramiv(v.id, GL_LINK_STATUS, &status);
	
	if (status==GL_FALSE) {
	// error linking
		GLsizei iloglen;
		glGetProgramiv(v.id,GL_INFO_LOG_LENGTH,&iloglen);
		
		if (iloglen<0) {
			
			glDeleteShader(v.frag_id);
			glDeleteShader(v.vert_id);
			glDeleteProgram( v.id );
			v.id=0;
			ERR_FAIL_COND_V(iloglen<=0, NULL);		
		}

		if (iloglen==0) {

			iloglen = 4096; //buggy driver (Adreno 220+....)
		}

		
		char *ilogmem = (char*)Memory::alloc_static(iloglen+1);
		ilogmem[iloglen]=0;
		glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem); 	
		
		String err_string=get_shader_name()+": Program LINK FAILED:\n";
		
		err_string+=ilogmem;
		err_string=_fix_error_code_line(err_string,fragment_code_start,define_line_ofs);
		ERR_PRINT(err_string.ascii().get_data());
		Memory::free_static(ilogmem);
		glDeleteShader(v.frag_id);
		glDeleteShader(v.vert_id);
		glDeleteProgram( v.id );
		v.id=0;
		
		ERR_FAIL_V(NULL);
	}
	
	/* UNIFORMS */		
	
	glUseProgram(v.id);


	//print_line("uniforms:  ");
	for(int j=0;j<uniform_count;j++) {
		
		
		v.uniform_location[j]=glGetUniformLocation(v.id,uniform_names[j]);
		//print_line("uniform "+String(uniform_names[j])+" location "+itos(v.uniform_location[j]));
	}
	
	// set texture uniforms
	for (int i=0;i<texunit_pair_count;i++) {

		GLint loc = glGetUniformLocation(v.id,texunit_pairs[i].name);
		if (loc>=0)
			glUniform1i(loc,texunit_pairs[i].index);
	}

	if ( cc ) {

		v.custom_uniform_locations.resize(cc->custom_uniforms.size());
		for(int i=0;i<cc->custom_uniforms.size();i++) {

			v.custom_uniform_locations[i]=glGetUniformLocation(v.id,String(cc->custom_uniforms[i]).ascii().get_data());
		}
	}

	glUseProgram(0);
	

	v.ok=true;

	return &v;
}
Exemple #23
0
Error PCKPacker::flush(bool p_verbose) {

	if (!file) {
		ERR_FAIL_COND_V(!file, ERR_INVALID_PARAMETER);
		return ERR_INVALID_PARAMETER;
	};

	// write the index

	file->store_32(files.size());

	for (int i=0; i<files.size(); i++) {

		file->store_pascal_string(files[i].path);
		files[i].offset_offset = file->get_pos();
		file->store_64(0); // offset
		file->store_64(files[i].size); // size

		// # empty md5
		file->store_32(0);
		file->store_32(0);
		file->store_32(0);
		file->store_32(0);
	};


	uint64_t ofs = file->get_pos();
	ofs = _align(ofs, alignment);

	_pad(file, ofs - file->get_pos());

	const uint32_t buf_max = 65536;
	uint8_t *buf = memnew_arr(uint8_t, buf_max);

	int count = 0;
	for (int i=0; i<files.size(); i++) {

		FileAccess* src = FileAccess::open(files[i].src_path, FileAccess::READ);
		uint64_t to_write = files[i].size;
		while (to_write > 0) {

			int read = src->get_buffer(buf, MIN(to_write, buf_max));
			file->store_buffer(buf, read);
			to_write -= read;
		};

		uint64_t pos = file->get_pos();
		file->seek(files[i].offset_offset); // go back to store the file's offset
		file->store_64(ofs);
		file->seek(pos);

		ofs = _align(ofs + files[i].size, alignment);
		_pad(file, ofs - pos);

		src->close();
		memdelete(src);
		count += 1;
		if (p_verbose) {
			if (count % 100 == 0) {
				printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100);
				fflush(stdout);
			};
		};
	};

	if (p_verbose)
		printf("\n");

	file->close();

	return OK;
};