Irrlicht Renderowanie Tekstury

0

Witam.
Piszę prostą mapę do gry i potrzebuję nałożyć teksturę na sześciokątną figurę (HexTile).
Nie wiem gdzie w moim kodzie jest błąd.

image

class HexTile : public scene::ISceneNode
{

	core::aabbox3d<f32> Box;
	video::S3DVertex Vertices[8];
	video::SMaterial Material;

public:

	HexTile(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
		: scene::ISceneNode(parent, mgr, id)
	{
		Material.Wireframe = false;
		Material.Lighting = false;
		Material.setTexture(0,driver->getTexture("Media/grass.png"));

		// verticves of hexagons
		Vertices[0] = video::S3DVertex(0, 0, 0, 0, 0, 0, video::SColor(255, 48, 48, 48), 0, 0);	// CENTER OF HEXTILE
		Vertices[1] = video::S3DVertex(0.0f, 0, outerRadius, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, 0);
		Vertices[2] = video::S3DVertex(innerRadius, 0, outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, 0);
		Vertices[3] = video::S3DVertex(innerRadius, 0, -outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, 0);
		Vertices[4] = video::S3DVertex(0.0f, 0, -outerRadius, 0, 0, 0, video::SColor(255, 128, 128, 48), 0, 0);
		Vertices[5] = video::S3DVertex(-innerRadius, 0, -outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, 0);
		Vertices[6] = video::S3DVertex(-innerRadius, 0, outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, 0);
		Vertices[7] = video::S3DVertex(0.0f, 0, outerRadius, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, 0);

		

		Box.reset(Vertices[0].Pos);
		for (s32 i = 1; i < 7; ++i)
			Box.addInternalPoint(Vertices[i].Pos);
	}

	virtual void OnRegisterSceneNode()
	{
		if (IsVisible)
			SceneManager->registerNodeForRendering(this);

		ISceneNode::OnRegisterSceneNode();
	}

	virtual void render()
	{
		u16 indices[] = { 0, 1, 2, /**/ 0, 2, 3, /**/ 0, 3, 4, /**/ 0, 4, 5, /**/ 0, 5, 6, /**/ 0, 6, 7 };
		IVideoDriver* driver = SceneManager->getVideoDriver();
		driver->setMaterial(Material);
		driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
		driver->drawVertexPrimitiveList(&Vertices[0], 3, &indices[0], 6, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);

	}

	virtual const core::aabbox3d<f32>& getBoundingBox() const
	{
		return Box;
	}

	virtual u32 getMaterialCount() const
	{
		return 1;
	}

	virtual video::SMaterial& getMaterial(u32 i)
	{
		return Material;
	}
};
1

ja też nie wiem, ale ja mam trochę mniej danych od Ciebie: nie mam skonfigurowanie IDE, kompilator, brak mi wszystkich biblioteki, nie wiem jaka platforma docelowa itp. :D
zrobił byś jakiś prosty przykład aby powtórzyć błąd u dowolnego użytkownika 4P ?

0

wystarczy pobrać stąd bibliotekę link. Następnie ją rozpakować na dysku C. W folderze z Irrlicht są "examples" przykładowe kody, które można odpalić. To tyle jeśli chodzi o kompilację i instalację Irrlicht. Sam posiłkowałem się przykładem "03.CustomSceneNode".

1

nie znam Irrlicht, ale na intuicję to bym tutaj się przyjrzał

Vertices[0] = video::S3DVertex(0, 0, 0, 0, 0, 0, video::SColor(255, 48, 48, 48), 0, 0);	// CENTER OF HEXTILE
Vertices[1] = video::S3DVertex(0.0f, 0, outerRadius, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, 0);

w szczególności w dokumentacji Irrlicht piszą, że ostatnie dwa argumenty to współrzędne tekstury tu i tv
https://irrlicht.sourceforge.io/docu/structirr_1_1video_1_1_s3_d_vertex.html
a ty wszędzie masz 0 w dwóch ostatnich argumentach. Być może ten ciemny kolor się bierze z tego, że jest to piksel na pozycji 0, 0 w twojej teksturze?

Chociaż problem może być też gdzie indziej. Czy masz dobrą kolejność wierzchołków w ściankach? Czy tekstura faktycznie się ładuje? itp.

0

Kolor tekstury w pozycji [0,0] to [26,155,60]. W tym jednak nie tkwi błąd :-/

image

0

Gdy wyłączę teksturę to generuje jasne pola więc to chyba nie jest wina światła ..

image

0

Zmieniłem parametry centralnego punktu i faktycznie renderuje tylko jeden kolor. Jak to naprawić ?

Vertices[0] = video::S3DVertex(0, 0, 0, 0, 0, 0, video::SColor(255, 255, 255, 255), 0, 0);	// CENTER OF HEXTILE

image

0

W miejsca tu, tv (współrzędne tekstury) wstawiłem współrzędne wierzchołków oto jaki efekt otrzymałem. \

// verticves of hexagons
Vertices[0] = video::S3DVertex(0, 0, 0, 0, 0, 0, video::SColor(255, 255, 255, 255), 0, 0);	// CENTER OF HEXTILE
Vertices[1] = video::S3DVertex(0.0f, 0, outerRadius, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, outerRadius*0.2f);
Vertices[2] = video::S3DVertex(innerRadius, 0, outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), innerRadius, outerRadius*0.5f);
Vertices[3] = video::S3DVertex(innerRadius, 0, -outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), innerRadius, -outerRadius*0.5f);
Vertices[4] = video::S3DVertex(0.0f, 0, -outerRadius, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, -outerRadius);
Vertices[5] = video::S3DVertex(-innerRadius, 0, -outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), -innerRadius, -outerRadius*0.5f);
Vertices[6] = video::S3DVertex(-innerRadius, 0, outerRadius * 0.5f, 0, 0, 0, video::SColor(255, 128, 48, 48), -innerRadius, outerRadius*0.5f);
Vertices[7] = video::S3DVertex(0.0f, 0, outerRadius, 0, 0, 0, video::SColor(255, 128, 48, 48), 0, outerRadius);

image

1

To spróbuj poustawiać ostatnie dwa argumenty, tam gdzie wg dokumentacji masz tu i tv https://irrlicht.sourceforge.io/docu/structirr_1_1video_1_1_s3_d_vertex.html
Żeby przypisać do każdego wierzchołka współrzędną teksturę.

Tylko możliwe, że współrzędne tekstury nie będą w pikselach, tylko będą od 0.0 (jeden brzeg tekstury) do 1.0 (drugi brzeg tekstury). Nie wiem, jak w Irrlicht, ale to mój guess, bo tak często bywa.
Czyli wtedy środek tekstury to byłby 0.5, 0.5 itp.

Natomiast ty na razie wszędzie masz tam 0, 0:

Vertices[0] = video::S3DVertex(0, 0, 0, 0, 0, 0, video::SColor(255, 48, 48, 48), 0, 0);	// CENTER OF HEXTILE

w tym miejscu spróbuj zrobić tak

Vertices[0] = video::S3DVertex(0, 0, 0, 0, 0, 0, video::SColor(255, 48, 48, 48), 0.5, 0.5);	// CENTER OF HEXTILE

ale analogicznie zmienić współrzędne tu, tv w innych wierzchołkach

0

współrzędne tu, tv ograniczyłem do wartości z zakresu [0, 1]. Teraz wszystko działa, dziękuję za pomoc ! :-)

video::SColor color = video::SColor(255, 255, 255, 255);

// verticves of hexagons
Vertices[0] = video::S3DVertex(0, 0, 0, 0, 0, 0, color, 0, 0);	// CENTER OF HEXTILE
Vertices[1] = video::S3DVertex(0.0f, 0, outerRadius, 0, 0, 0, color, 0, 1);
Vertices[2] = video::S3DVertex(innerRadius, 0, outerRadius * 0.5f, 0, 0, 0, color, 1, 0.5f);
Vertices[3] = video::S3DVertex(innerRadius, 0, -outerRadius * 0.5f, 0, 0, 0, color, 1, -0.5f);
Vertices[4] = video::S3DVertex(0.0f, 0, -outerRadius, 0, 0, 0, color, 0, -1);
Vertices[5] = video::S3DVertex(-innerRadius, 0, -outerRadius * 0.5f, 0, 0, 0, color, -1, -0.5f);
Vertices[6] = video::S3DVertex(-innerRadius, 0, outerRadius * 0.5f, 0, 0, 0, color, -1, 0.5f);
Vertices[7] = video::S3DVertex(0.0f, 0, outerRadius, 0, 0, 0, color, 0, 1);

image

1

ale teraz to wrappujesz tę teksturę od środka (czyli środek heksagonu zamiast środka tekstury ma 0, 0 czyli róg tekstury)
oraz twoje współrzędne zawierają wartości ujemne, a interpretacja takich wartości może być różna (zwykle się to określa "wrap mode").

może spróbuj tak zrobić, żeby środek kafla miał przypisany środek tekstury (0.5, 0.5),
a wszystkie inne wierzchołki od 0.0 do 1.0

1

Mam tak przypisane i jest git, bo działa.
Dziękuję wszystkim za pomoc w szczególności Tobie @LukeJL ! :-)

float texture_uv[]
{
	0.0f, 1.0f,
	1.0f, 0.5f,
	1.0f, -0.5f,
	0.0f, -1.0f,
	-1.0f, -0.5f,
	-1.0f, 0.5f,
	0.0f, 1.0f,
};

image

1 użytkowników online, w tym zalogowanych: 0, gości: 1