Example #1
0
/* find the opaque pixel value corresponding to an RGBA triple */
u32 gdi_map_RGBA(hdc_t hdc, u8 r, u8 g, u8 b, u8 a)
{
  u32 pix_val = 0;
  u32 handle = (u32)class_get_handle_by_id(SURFACE_CLASS_ID);
  void *p_surf = dc_hdc2pdc(hdc)->p_curn_surface;

  switch(surface_get_format(handle, p_surf))
  {
    case OSD_COLORFORMAT_RGB4BIT:
    case OSD_COLORFORMAT_RGB8BIT:
      pix_val = gdi_find_color(surface_get_palette_addr(handle, p_surf), r, g, b, a);
      break;
      /*
         case PIX_16ARGB1555:
         pix_val = ((a&0x01)<<15) | ((r&0x1F) <<10) | ((g&0x1F) <<5) | (b&0x1F);
         break;

         case PIX_16ARGB0565:
         pix_val = ((r&0x1F) <<11) | ((g&0x3F) <<5) | (b&0x1F);
         break;

         case PIX_16ARGB4444:
         pix_val = ((a&0x0F)<<12) | ((r&0x0F) <<8) | ((g&0x0F) <<4) | (b&0x0F);
         break;

         case PIX_24ARGB0888:
         pix_val = ((r&0xFF) <<16) | ((g&0xFF) <<8) | (b&0xFF);
         break;

         case PIX_32ARGB8888:
         pix_val = ((a&0xFF)<<24) | ((r&0xFF) <<16) | ((g&0xFF) <<8) | (b&0xFF);
         break;
       */
    default:
      pix_val = 0;
  }

  return pix_val;
}
Example #2
0
Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {

	if (triangle_mesh.is_valid())
		return triangle_mesh;

	int facecount = 0;

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

		if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
			continue;

		if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {

			facecount += surface_get_array_index_len(i);
		} else {

			facecount += surface_get_array_len(i);
		}
	}

	if (facecount == 0 || (facecount % 3) != 0)
		return triangle_mesh;

	PoolVector<Vector3> faces;
	faces.resize(facecount);
	PoolVector<Vector3>::Write facesw = faces.write();

	int widx = 0;

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

		if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
			continue;

		Array a = surface_get_arrays(i);

		int vc = surface_get_array_len(i);
		PoolVector<Vector3> vertices = a[ARRAY_VERTEX];
		PoolVector<Vector3>::Read vr = vertices.read();

		if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {

			int ic = surface_get_array_index_len(i);
			PoolVector<int> indices = a[ARRAY_INDEX];
			PoolVector<int>::Read ir = indices.read();

			for (int i = 0; i < ic; i++) {
				int index = ir[i];
				facesw[widx++] = vr[index];
			}

		} else {

			for (int i = 0; i < vc; i++)
				facesw[widx++] = vr[i];
		}
	}

	facesw = PoolVector<Vector3>::Write();

	triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
	triangle_mesh->create(faces);

	return triangle_mesh;
}
Example #3
0
void gdi_get_RGBA(hdc_t hdc, u32 pix_val, u8 *p_r, u8 *p_g, u8 *p_b, u8 *p_a)
{
  void *p_surf = dc_hdc2pdc(hdc)->p_curn_surface;
  u32 handle = (u32)class_get_handle_by_id(SURFACE_CLASS_ID);
  palette_t *p_pal = surface_get_palette_addr(handle, p_surf);
  
  switch(surface_get_format(handle, p_surf))
  {
    case OSD_COLORFORMAT_RGB4BIT:
    case OSD_COLORFORMAT_RGB8BIT:
      if(pix_val < p_pal->cnt)
      {
        *p_a = p_pal->p_entry[pix_val].a;
        *p_r = p_pal->p_entry[pix_val].r;
        *p_g = p_pal->p_entry[pix_val].g;
        *p_b = p_pal->p_entry[pix_val].b;
      }
      break;
      /*
         case PIX_16ARGB1555:
         pix_val = pix_val&0xFFFF;

       *a = (u8)(pix_val>>15)&0x01;
       *r = (u8)(pix_val>>10)&0x1F;
       *g = (u8)(pix_val>>5)&0x1F;
       *b = (u8)(pix_val)&0x1F;
         break;

         case PIX_16ARGB0565:
         pix_val = pix_val&0xFFFF;

       *a = 0xFF;
       *r = (u8)(pix_val>>11)&0x1F;
       *g = (u8)(pix_val>>5)&0x3F;
       *b = (u8)(pix_val)&0x1F;
         break;

         case PIX_16ARGB4444:
         pix_val = pix_val&0xFFFF;

       *a = (u8)(pix_val>>12)&0x0F;
       *r = (u8)(pix_val>>8)&0x0F;
       *g = (u8)(pix_val>>4)&0x0F;
       *b = (u8)(pix_val)&0x0F;
         break;

         case PIX_24ARGB0888:
         pix_val = pix_val&0xFFFFFF;

       *a = 0xFF;
       *r = (u8)(pix_val>>16)&0xFF;
       *g = (u8)(pix_val>>8)&0xFF;
       *b = (u8)(pix_val)&0xFF;
         break;

         case PIX_32ARGB8888:
       *a = (u8)(pix_val>>24)&0xFF;
       *r = (u8)(pix_val>>16)&0xFF;
       *g = (u8)(pix_val>>8)&0xFF;
       *b = (u8)(pix_val)&0xFF;
         break;
       */
    default:
      *p_a = *p_r = *p_g = *p_b = 0xFF;
  }
}
Example #4
0
Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {

	ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
	ERR_EXPLAIN("Can't unwrap mesh with blend shapes");
	ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE);

	Vector<float> vertices;
	Vector<float> normals;
	Vector<int> indices;
	Vector<int> face_materials;
	Vector<float> uv;
	Vector<Pair<int, int> > uv_index;

	Vector<ArrayMeshLightmapSurface> surfaces;
	for (int i = 0; i < get_surface_count(); i++) {
		ArrayMeshLightmapSurface s;
		s.primitive = surface_get_primitive_type(i);

		if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) {
			ERR_EXPLAIN("Only triangles are supported for lightmap unwrap");
			ERR_FAIL_V(ERR_UNAVAILABLE);
		}
		s.format = surface_get_format(i);
		if (!(s.format & ARRAY_FORMAT_NORMAL)) {
			ERR_EXPLAIN("Normals are required for lightmap unwrap");
			ERR_FAIL_V(ERR_UNAVAILABLE);
		}

		Array arrays = surface_get_arrays(i);
		s.material = surface_get_material(i);
		s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays);

		PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX];
		int vc = rvertices.size();
		PoolVector<Vector3>::Read r = rvertices.read();

		PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL];
		PoolVector<Vector3>::Read rn = rnormals.read();

		int vertex_ofs = vertices.size() / 3;

		vertices.resize((vertex_ofs + vc) * 3);
		normals.resize((vertex_ofs + vc) * 3);
		uv_index.resize(vertex_ofs + vc);

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

			Vector3 v = p_base_transform.xform(r[j]);
			Vector3 n = p_base_transform.basis.xform(rn[j]).normalized();

			vertices[(j + vertex_ofs) * 3 + 0] = v.x;
			vertices[(j + vertex_ofs) * 3 + 1] = v.y;
			vertices[(j + vertex_ofs) * 3 + 2] = v.z;
			normals[(j + vertex_ofs) * 3 + 0] = n.x;
			normals[(j + vertex_ofs) * 3 + 1] = n.y;
			normals[(j + vertex_ofs) * 3 + 2] = n.z;
			uv_index[j + vertex_ofs] = Pair<int, int>(i, j);
		}

		PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX];
		int ic = rindices.size();

		if (ic == 0) {

			for (int j = 0; j < vc / 3; j++) {
				if (Face3(r[j * 3 + 0], r[j * 3 + 1], r[j * 3 + 2]).is_degenerate())
					continue;

				indices.push_back(vertex_ofs + j * 3 + 0);
				indices.push_back(vertex_ofs + j * 3 + 1);
				indices.push_back(vertex_ofs + j * 3 + 2);
				face_materials.push_back(i);
			}

		} else {
			PoolVector<int>::Read ri = rindices.read();

			for (int j = 0; j < ic / 3; j++) {
				if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate())
					continue;
				indices.push_back(vertex_ofs + ri[j * 3 + 0]);
				indices.push_back(vertex_ofs + ri[j * 3 + 1]);
				indices.push_back(vertex_ofs + ri[j * 3 + 2]);
				face_materials.push_back(i);
			}
		}

		surfaces.push_back(s);
	}

	//unwrap

	float *gen_uvs;
	int *gen_vertices;
	int *gen_indices;
	int gen_vertex_count;
	int gen_index_count;
	int size_x;
	int size_y;

	bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);

	if (!ok) {
		return ERR_CANT_CREATE;
	}

	//remove surfaces
	while (get_surface_count()) {
		surface_remove(0);
	}

	//create surfacetools for each surface..
	Vector<Ref<SurfaceTool> > surfaces_tools;

	for (int i = 0; i < surfaces.size(); i++) {
		Ref<SurfaceTool> st;
		st.instance();
		st->begin(Mesh::PRIMITIVE_TRIANGLES);
		st->set_material(surfaces[i].material);
		surfaces_tools.push_back(st); //stay there
	}

	print_line("gen indices: " + itos(gen_index_count));
	//go through all indices
	for (int i = 0; i < gen_index_count; i += 3) {

		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG);
		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG);
		ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG);

		ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);

		int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first;

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

			SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second];

			if (surfaces[surface].format & ARRAY_FORMAT_COLOR) {
				surfaces_tools[surface]->add_color(v.color);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
				surfaces_tools[surface]->add_uv(v.uv);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
				surfaces_tools[surface]->add_normal(v.normal);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
				Plane t;
				t.normal = v.tangent;
				t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
				surfaces_tools[surface]->add_tangent(t);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_BONES) {
				surfaces_tools[surface]->add_bones(v.bones);
			}
			if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
				surfaces_tools[surface]->add_weights(v.weights);
			}

			Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
			surfaces_tools[surface]->add_uv2(uv2);

			surfaces_tools[surface]->add_vertex(v.vertex);
		}
	}

	//free stuff
	::free(gen_vertices);
	::free(gen_indices);
	::free(gen_uvs);

	//generate surfaces

	for (int i = 0; i < surfaces_tools.size(); i++) {
		surfaces_tools[i]->index();
		surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
	}

	set_lightmap_size_hint(Size2(size_x, size_y));

	return OK;
}