bool Indigo::UIPanel::on_render_create(Indigo::Render::UIGroup* group) { if (m_background) { OOBase::SharedPtr<Render::UIDrawable> bk = m_background->make_drawable(m_colour,true,glm::ivec2(),size()); if (!bk) return false; if (!group->add_drawable(bk)) return false; m_render_background = bk.get(); } OOBase::SharedPtr<Indigo::Render::UIGroup> subgroup = OOBase::allocate_shared<Indigo::Render::UIGroup,OOBase::ThreadLocalAllocator>(true,glm::ivec2(),size()) ; if (!subgroup) LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),false); if (!group->add_drawable(subgroup)) return false; m_render_parent = subgroup.get(); return UIGroup::on_render_create(group); }
OOBase::SharedPtr<Indigo::Render::Layer> Indigo::UILayer::create_render_layer(Indigo::Render::Window* window) { glm::uvec2 sz(window->window()->size()); if (sz != size()) Indigo::logic_pipe()->call(OOBase::make_delegate<OOBase::ThreadLocalAllocator>(this,&Indigo::UILayer::on_layout),sz); OOBase::SharedPtr<Indigo::Render::UILayer> group = OOBase::allocate_shared<Indigo::Render::UILayer,OOBase::ThreadLocalAllocator>(window,this,visible(),position(),size()); if (!group) LOG_ERROR(("Failed to allocate group: %s",OOBase::system_error_text())); else if (!on_render_create(group.get())) group.reset(); m_render_parent = group.get(); return OOBase::static_pointer_cast<Indigo::Render::Layer>(group); }
void NinePatchFactory::layout_patch(GLsizei patch, const glm::uvec2& size, const glm::uvec4& borders, const glm::uvec2& tex_size) { static const unsigned int ushort_max = 0xFFFF; OOBase::SharedPtr<vertex_data> attribs = m_ptrVertices->auto_map<vertex_data>(GL_MAP_WRITE_BIT,patch * vertices_per_patch * sizeof(vertex_data),vertices_per_patch * sizeof(vertex_data)); vertex_data* a = attribs.get(); a[0].x = 0.f; a[1].x = static_cast<float>(borders.x); a[3].x = static_cast<float>(size.x); a[2].x = a[3].x - borders.z; a[0].u = 0; a[1].u = static_cast<GLushort>(static_cast<float>(borders.x) / tex_size.x * ushort_max); a[2].u = static_cast<GLushort>(static_cast<float>(tex_size.x - borders.z) / tex_size.x * ushort_max); a[3].u = ushort_max; for (size_t i=0;i<4;++i) { a[i+12].x = a[i+8].x = a[i+4].x = a[i].x; a[i].y = static_cast<float>(size.y); a[i+4].y = a[i].y - borders.y; a[i+8].y = static_cast<float>(borders.w); a[i+12].y = 0.f; a[i+12].u = a[i+8].u = a[i+4].u = a[i].u; a[i].v = 0; a[i+4].v = static_cast<GLushort>(static_cast<float>(borders.w) / tex_size.y * ushort_max); a[i+8].v = static_cast<GLushort>(static_cast<float>(tex_size.y - borders.y) / tex_size.y * ushort_max); a[i+12].v = ushort_max; } }
void Indigo::Render::UIGroup::add_subgroup(UIWidget* widget, bool* ret) { *ret = false; OOBase::SharedPtr<Render::UIGroup> group = OOBase::allocate_shared<Render::UIGroup,OOBase::ThreadLocalAllocator>((widget->state() & Indigo::UIWidget::eWS_visible) != 0,widget->position(),widget->size()); if (!group) LOG_ERROR(("Failed to allocate group: %s",OOBase::system_error_text())); else if (!m_children.push_back(group)) LOG_ERROR(("Failed to insert group: %s",OOBase::system_error_text())); else if (!widget->on_render_create(group.get())) m_children.pop_back(); else { widget->m_render_group = group.get(); *ret = true; } }
bool Indigo::NinePatch::load(const ResourceBundle& resource, const char* name, int components) { OOBase::SharedPtr<const unsigned char> buffer = resource.load<unsigned char>(name); if (!buffer) return false; return this->load(buffer.get(),resource.size(name),components); }
glm::vec4 Indigo::ImageLayer::colour(const glm::vec4& colour) { glm::vec4 prev_colour = m_colour; if (colour != prev_colour) { OOBase::SharedPtr< ::ImageLayer> layer = OOBase::static_pointer_cast< ::ImageLayer>(render_layer()); if (layer) render_pipe()->post(OOBase::make_delegate<OOBase::ThreadLocalAllocator>(layer.get(),&::ImageLayer::colour),colour); } return prev_colour; }
bool operator ()(const OOBase::SharedPtr<wchar_t>& s1, const OOBase::SharedPtr<wchar_t>& s2) const { return (_wcsicmp(s1.get(),s2.get()) < 0); }
OOBase::SharedPtr<const char> Indigo::detail::ZipFile::load(const OOBase::String& prefix, const char* name) { OOBase::SharedPtr<const char> ret; OOBase::String filename(prefix); if (!filename.append(name)) LOG_ERROR_RETURN(("Failed to append string: %s",OOBase::system_error_text()),ret); OOBase::Table<OOBase::String,Info>::iterator i=m_mapFiles.find(filename); if (!i) return ret; // Read the local file header if (m_file.seek(i->second.m_offset,OOBase::File::seek_begin) == OOBase::uint64_t(-1)) LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),ret); OOBase::uint8_t header[30]; if (m_file.read(header,30) != 30) LOG_ERROR_RETURN(("Failed to read local file header header in zip"),ret); static const OOBase::uint8_t LFR_HEADER[4] = { 0x50, 0x4b, 0x03, 0x04 }; if (memcmp(header,LFR_HEADER,4) != 0) LOG_ERROR_RETURN(("Invalid local file header header in zip"),ret); OOBase::uint16_t compression = read_uint16(header,8); OOBase::uint32_t compressed_size = read_uint32(header,18); size_t offset = 30 + read_uint16(header,26) + read_uint16(header,28); OOBase::SharedPtr<const char> mapping = m_file.auto_map<const char>(false,i->second.m_offset + offset,compressed_size); if (!mapping) LOG_ERROR_RETURN(("Failed to map file content: %s",OOBase::system_error_text()),ret); if (compression == 0) { ret = mapping; } else if (compression == 8) { void* p = OOBase::CrtAllocator::allocate(i->second.m_length,1); if (!p) LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),ret); if (stbi_zlib_decode_noheader_buffer(static_cast<char*>(p),(int)i->second.m_length,mapping.get(),(int)compressed_size) == -1) { LOG_ERROR(("Failed to inflate file: %s",stbi_failure_reason())); OOBase::CrtAllocator::free(p); } else { ret = OOBase::const_pointer_cast<const char>(OOBase::make_shared<char>(static_cast<char*>(p))); if (!ret) { LOG_ERROR(("Failed to allocate: %s",OOBase::system_error_text())); OOBase::CrtAllocator::free(p); } } } else LOG_ERROR(("Unsupported zip compression method: %u",compression)); return ret; }
GLsizei NinePatchFactory::alloc_patch(const glm::uvec2& size, const glm::uvec4& borders, const glm::uvec2& tex_size) { GLsizei patch = -1; for (free_list_t::iterator i=m_listFree.begin(); i; ++i) { if (i->second == 1) { patch = i->first; m_listFree.erase(i); break; } else if (i->second > 1) { patch = i->first; i->first += 1; i->second -= 1; break; } } if (patch == -1) { if (!m_ptrProgram && !create_program()) return patch; if (!m_ptrVAO) { m_ptrVAO = OOBase::allocate_shared<OOGL::VertexArrayObject,OOBase::ThreadLocalAllocator>(); if (!m_ptrVAO) LOG_ERROR_RETURN(("Failed to allocate VAO: %s",OOBase::system_error_text(ERROR_OUTOFMEMORY)),patch); } m_ptrVAO->bind(); GLsizei new_size = 16; while (new_size < m_allocated + 1) new_size *= 2; OOBase::SharedPtr<OOGL::BufferObject> ptrNewVertices = OOBase::allocate_shared<OOGL::BufferObject,OOBase::ThreadLocalAllocator>(GL_ARRAY_BUFFER,GL_DYNAMIC_DRAW,new_size * vertices_per_patch * sizeof(vertex_data)); OOBase::SharedPtr<OOGL::BufferObject> ptrNewElements = OOBase::allocate_shared<OOGL::BufferObject,OOBase::ThreadLocalAllocator>(GL_ELEMENT_ARRAY_BUFFER,GL_DYNAMIC_DRAW,new_size * elements_per_patch * sizeof(GLuint)); if (!ptrNewVertices || !ptrNewElements) LOG_ERROR_RETURN(("Failed to allocate VBO: %s",OOBase::system_error_text(ERROR_OUTOFMEMORY)),patch); if (m_ptrVertices) ptrNewVertices->copy(0,m_ptrVertices,0,m_allocated * vertices_per_patch * sizeof(vertex_data)); if (m_ptrElements) ptrNewElements->copy(0,m_ptrElements,0,m_allocated * elements_per_patch * sizeof(GLuint)); m_ptrVertices.swap(ptrNewVertices); m_ptrElements.swap(ptrNewElements); free_list_t::iterator last = m_listFree.back(); if (last) last->second += new_size - m_allocated; else last = m_listFree.insert(m_allocated,new_size - m_allocated); m_allocated = new_size; patch = last->first; last->first += 1; last->second -= 1; GLint a = m_ptrProgram->attribute_location("in_Position"); m_ptrVAO->attribute(a,m_ptrVertices,2,GL_FLOAT,false,sizeof(vertex_data),offsetof(vertex_data,x)); m_ptrVAO->enable_attribute(a); a = m_ptrProgram->attribute_location("in_TexCoord"); if (a != -1) { m_ptrVAO->attribute(a,m_ptrVertices,2,GL_UNSIGNED_SHORT,true,sizeof(vertex_data),offsetof(vertex_data,u)); m_ptrVAO->enable_attribute(a); } m_ptrVAO->element_array(m_ptrElements); m_ptrVAO->unbind(); } OOBase::SharedPtr<GLuint> ei = m_ptrElements->auto_map<GLuint>(GL_MAP_WRITE_BIT,patch * elements_per_patch * sizeof(GLuint),elements_per_patch * sizeof(GLuint)); GLuint* e = ei.get(); GLuint idx = patch * vertices_per_patch; for (size_t i=0;i<12;++i) { e[i*2] = static_cast<GLuint>(idx + i); e[i*2 + 1] = static_cast<GLuint>(idx + i + 4); } layout_patch(patch,size,borders,tex_size); return patch; }
bool Indigo::UIGroup::add_widget(const OOBase::SharedPtr<UIWidget>& widget, const char* name, size_t len) { if (!m_children.push_back(widget)) LOG_ERROR_RETURN(("Failed to insert widget: %s",OOBase::system_error_text()),false); if (name && len && !add_named_widget(widget,name,len)) { m_children.pop_back(); return false; } if (!m_render_group) return true; bool ret = false; if (!render_pipe()->call(OOBase::make_delegate<OOBase::ThreadLocalAllocator>(m_render_parent,&Render::UIGroup::add_subgroup),widget.get(),&ret) || !ret) m_children.pop_back(); return ret; }