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; }
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); }
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; };
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); }
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 ); }
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); }
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; }
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; };
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; }
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; }
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; };
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 }
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; }
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; };
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; }
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; }
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; };