예제 #1
0
파일: Quad.cpp 프로젝트: ricktaylor/indigo
OOBase::SharedPtr<Indigo::Render::SGNode> Indigo::SGQuad::on_render_create(Render::SGGroup* parent)
{
	OOBase::SharedPtr<Render::SGNode> node;

	bool cached = true;
	OOBase::SharedPtr<OOGL::Texture> texture = m_image->make_texture(GL_RGBA8,cached);
	if (!texture)
		return node;

	if (!cached)
	{
		texture->parameter(GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		texture->parameter(GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
		texture->parameter(GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
		texture->parameter(GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
	}

	OOBase::SharedPtr< ::SGQuad> quad = OOBase::allocate_shared< ::SGQuad>(AABB(glm::vec3(0.5f,0.5f,0),glm::vec3(0.5f,0.5f,0)),texture,m_transparent,m_colour);
	if (!quad)
		LOG_ERROR_RETURN(("Failed to allocate: %s\n",OOBase::system_error_text()),node);

	node = OOBase::allocate_shared<Render::SGNode>(parent,OOBase::static_pointer_cast<Render::SGDrawable>(quad),visible(),transform());
	if (!node)
		LOG_ERROR_RETURN(("Failed to allocate: %s\n",OOBase::system_error_text()),node);

	return node;
}
예제 #2
0
OOBase::SharedPtr<Indigo::Render::UIDrawable> Indigo::NinePatch::make_drawable(const glm::vec4& colour, bool visible, const glm::ivec2& position, const glm::uvec2& size) const
{
	ASSERT_RENDER_THREAD();

	if (!valid())
		LOG_ERROR_RETURN(("NinePatch::make_drawable called when invalid!"),OOBase::SharedPtr<Indigo::Render::UIDrawable>());

	bool is_9 = (m_info->m_borders != glm::uvec4(0));
	bool cached = true;

	OOBase::SharedPtr<OOGL::Texture> texture = make_texture(GL_RGBA8,cached,is_9 ? 1 : 0);
	if (!texture)
		return OOBase::SharedPtr<Indigo::Render::UIDrawable>();

	if (cached)
	{
		texture->parameter(GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		texture->parameter(GL_TEXTURE_MIN_FILTER,is_9 ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR);
		texture->parameter(GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
		texture->parameter(GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
	}

	if (is_9)
		return OOBase::allocate_shared<Render::UINinePatch,OOBase::ThreadLocalAllocator>(texture,colour,m_info,visible,position,size);
	else
		return OOBase::allocate_shared<Render::UIImage,OOBase::ThreadLocalAllocator>(texture,colour,visible,position,size);
}
예제 #3
0
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;
	}
}
예제 #4
0
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);
}
예제 #5
0
bool Indigo::run(const char* name, void (*fn)(void*), void* param)
{
	// Create render comms pipe
	PIPE_RACK::instance().m_render_pipe =  OOBase::allocate_shared<Indigo::Pipe,OOBase::ThreadLocalAllocator>("render");
	if (!PIPE_RACK::instance().m_render_pipe)
		LOG_ERROR_RETURN(("Failed to allocate render pipe: %s",OOBase::system_error_text()),false);

	render_init(PIPE_RACK::instance().m_render_pipe.get());

	// Not sure if we need to set this first...
	glfwSetErrorCallback(&on_glfw_error);

	if (!glfwInit())
		LOG_ERROR_RETURN(("glfwInit failed"),false);

	// Set defaults
	glfwDefaultWindowHints();

	bool ret = false;
	OOBase::SharedPtr<OOBase::Thread> thread;
	PIPE_RACK::instance().m_logic_pipe = Indigo::start_thread(name,thread);
	if (PIPE_RACK::instance().m_logic_pipe)
	{
		ret = PIPE_RACK::instance().m_logic_pipe->call(OOBase::make_delegate<OOBase::ThreadLocalAllocator>(fn),param);
		if (ret)
			thread->join();
	}

	glfwTerminate();

	return ret;
}
예제 #6
0
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);
}
예제 #7
0
void Indigo::Render::UILayer::on_losecursor()
{
	for (OOBase::Vector<OOBase::WeakPtr<UIDrawable>,OOBase::ThreadLocalAllocator>::iterator i=m_cursor_hits.begin();i;++i)
	{
		OOBase::SharedPtr<UIDrawable> d = i->lock();
		if (d)
			d->on_cursorenter(false);
	}
	m_cursor_hits.clear();
}
예제 #8
0
void Indigo::Render::UILayer::on_mousebutton(const OOGL::Window::mouse_click_t& click)
{
	bool handled = false;
	for (OOBase::Vector<OOBase::WeakPtr<UIDrawable>,OOBase::ThreadLocalAllocator>::iterator i=m_cursor_hits.begin();!handled && i;++i)
	{
		OOBase::SharedPtr<UIDrawable> d = i->lock();
		if (d)
			handled = d->on_mousebutton(click);
	}
}
예제 #9
0
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;
}
예제 #10
0
bool Indigo::ZipResource::open(const char* filename)
{
	OOBase::SharedPtr<detail::ZipFile> zip = OOBase::allocate_shared<detail::ZipFile>();
	if (!zip)
		LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),false);

	bool r = zip->open(filename);
	if (r)
		zip.swap(m_zip);

	return r;
}
예제 #11
0
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;
	}
}
예제 #12
0
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);
}
예제 #13
0
OOBase::SharedPtr<Indigo::Render::Layer> Indigo::ImageLayer::create_render_layer(Render::Window* window)
{
	OOBase::SharedPtr< ::ImageLayer> layer;
	bool cached = true;
	OOBase::SharedPtr<OOGL::Texture> texture = m_image->make_texture(GL_RGBA8,cached,1);
	if (!texture)
		return layer;

	if (!cached)
	{
		texture->parameter(GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		texture->parameter(GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		texture->parameter(GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
		texture->parameter(GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
	}
	
	layer = OOBase::allocate_shared< ::ImageLayer,OOBase::ThreadLocalAllocator>(texture,window,m_colour);
	if (!layer)
		LOG_ERROR(("Failed to allocate layer: %s",OOBase::system_error_text()));

	return layer;
}
예제 #14
0
void Indigo::UIDialog::internal_do_modal(Window& wnd, const OOBase::SharedPtr<UILayer>& layer)
{
    if (!layer)
        LOG_WARNING(("No layer assigned to dialog!"));
    else
    {
        OOBase::Delegate0<void,OOBase::ThreadLocalAllocator> prev_close = layer->on_close(OOBase::make_delegate<OOBase::ThreadLocalAllocator>(this,&UIDialog::on_window_close));

        if (wnd.add_layer(layer))
        {
            layer->show(true);
            wnd.show();

            for (m_live = true; m_live;)
                thread_pipe()->get();

            layer->show(false);
            wnd.remove_layer(layer);
        }

        layer->on_close(prev_close);
    }
}
예제 #15
0
void OOGL::VertexArrayObject::attribute(GLuint index, const OOBase::SharedPtr<BufferObject>& buffer, GLint components, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset)
{
	m_state->bind(shared_from_this());

	assert(buffer->target() == GL_ARRAY_BUFFER);
	m_state->bind(buffer);

	m_state_fns->glVertexAttribPointer(index,components,type,normalized ? GL_TRUE : GL_FALSE,stride,reinterpret_cast<const GLvoid*>(offset));

	OOBase::Table<GLuint,OOBase::SharedPtr<BufferObject>,OOBase::Less<GLuint>,OOBase::ThreadLocalAllocator>::iterator i = m_attributes.find(index);
	if (i)
		i->second = buffer;
	else
		m_attributes.insert(index,buffer);
}
예제 #16
0
파일: Pipe.cpp 프로젝트: ricktaylor/indigo
static OOBase::SharedPtr<Indigo::detail::IPC::Queue> register_queue(const char* name)
{
	OOBase::SharedPtr<Indigo::detail::IPC::Queue> queue;

	PipeTable::table_t::iterator i = PIPE_TABLE::instance().m_queues.find(name);
	if (i == PIPE_TABLE::instance().m_queues.end())
	{
		OOBase::String str;
		if (!str.assign(name))
			LOG_ERROR_RETURN(("Failed to assign string: %s",OOBase::system_error_text()),queue);

		queue = OOBase::allocate_shared<Indigo::detail::IPC::Queue>();
		if (!queue)
			LOG_ERROR_RETURN(("Failed to allocate queue: %s",OOBase::system_error_text()),queue);

		i = PIPE_TABLE::instance().m_queues.insert(str,queue);
		if (i == PIPE_TABLE::instance().m_queues.end())
		{
			LOG_ERROR(("Failed to insert queue: %s",OOBase::system_error_text()));
			queue.reset();
		}
	}
	return i->second;
}
예제 #17
0
bool Indigo::Render::UILayer::on_cursormove(const glm::dvec2& pos)
{
	if (!visible())
		return false;

	const glm::uvec2& sz = size();
	glm::ivec2 ipos = glm::clamp(glm::ivec2(glm::floor(pos)),glm::ivec2(0),glm::ivec2(sz.x-1,sz.y-1));

	OOBase::Vector<OOBase::WeakPtr<UIDrawable>,OOBase::ThreadLocalAllocator> hits;
	hit_test(hits,ipos);

	for (OOBase::Vector<OOBase::WeakPtr<UIDrawable>,OOBase::ThreadLocalAllocator>::iterator i=m_cursor_hits.begin();i;)
	{
		if (hits.find(*i))
			++i;
		else
		{
			OOBase::SharedPtr<UIDrawable> d = i->lock();

			i = m_cursor_hits.erase(i);

			if (d && d->on_cursorenter(false))
				break;
		}
	}

	for (OOBase::Vector<OOBase::WeakPtr<UIDrawable>,OOBase::ThreadLocalAllocator>::iterator i=hits.begin();i;++i)
	{
		if (m_cursor_hits.remove(*i) == 0)
		{
			OOBase::SharedPtr<UIDrawable> d = i->lock();
			if (d && d->on_cursorenter(true))
				break;
		}
	}

	m_cursor_hits.swap(hits);

	bool handled = false;
	for (OOBase::Vector<OOBase::WeakPtr<UIDrawable>,OOBase::ThreadLocalAllocator>::iterator i=m_cursor_hits.begin();!handled && i;)
	{
		OOBase::SharedPtr<UIDrawable> d = i->lock();
		if (!d)
			m_cursor_hits.erase(i);
		else
		{
			handled = d->on_cursormove();
			++i;
		}
	}

	return m_owner->m_modal || handled;
}
예제 #18
0
		bool operator ()(const OOBase::SharedPtr<wchar_t>& s1, const OOBase::SharedPtr<wchar_t>& s2) const
		{
			return (_wcsicmp(s1.get(),s2.get()) < 0);
		}
예제 #19
0
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;
}
예제 #20
0
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;
}
예제 #21
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;
}