obrót tekstury 2D softwarowy

obrót tekstury 2D softwarowy
wilkwielki
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 678
0

tak dobrze tylko że to tego cieniowania jak będą dodawane piksele z tła bo czyta tło i myślę że to troche głupio będzie wyglądać, to niech już będzie bez Smooth

tBane
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 526
0

Możesz zawsze zapisywać obraz najpierw do tablicy, potem przelatujesz tablicę i robiśz średnią z pikseli omijając puste piksele w taki sposób że jak piksel jest pusty to nie dodawaj do średniej

wilkwielki
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 678
0

chyba że tak, ja też myślałem czy można pobrać tablice z tablicy z obrazem a potem ten pobrany obraz obracać po staremu jak pisaliśmy obrót tekstury całej, czy wtedy nie było by straty na jakości grafiki? bo powinno nie być starty bo już sprawdzaliśmy i było ok na 100 %

tBane
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Poznań
  • Postów: 526
0

Albo można zrobić tak, że zapisujesz obraz do tablicy i liczysz średnią z sąsiednich pikseli dla wszystkich pustych pikseli

wilkwielki
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 678
0

już mam ale nie sprawdzałem, jeśli mnie zrozumiesz po tym kodzie o co chodzi mi a zauważysz błąd to popraw:

Kopiuj
unsigned char* GetDataFragmentTexture(int xs, int ys, int xe, int ye, int nr,int &width,int &height)
{
	int w = bi[nr].w;
	int h = bi[nr].h;
	int x = xe - xs;
	int y = ye - ys;
	int xpos = 0;
	int ypos = 0;
	width = x;
	height = y;
	unsigned char* gdata = new unsigned char[x * y * 3];
	for (int py = ys; py < ye; py += 1)
	{

		for (int px = xs; px < xe; px += 1)
		{

			int pis = (xpos * 3 + ypos * y * 3);

			int index = (px * 3 + (h - py) * w * 3);
			gdata[pis] = bi[nr].bitmapData[index];
			gdata[pis + 1] = bi[nr].bitmapData[index + 1];
			gdata[pis + 2] = bi[nr].bitmapData[index + 2];
			xpos += 1;
			if (xpos == x)
				xpos = 0;
		}
		ypos += 1;
	}
	return gdata;

}

potem u siebie w swojej funkcji obrotu zamiast tego:

Kopiuj
 int w = bi[nr].w;
    int h = bi[nr].h;
    int bpp = 3;
    const unsigned char* src = bi[nr].bitmapData;

wstaw to tej pierwszej funkcji z obrotem gdzie nie było utraty na jakości grafiki

Kopiuj
int w,h;
int bpp=3;
const unsigned char* src=GetDataFragmentTexture(xs,ys,xe,ye,nr,w,h);
wilkwielki
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 678
1

skończone i działa , są dwie fukcje

Kopiuj
unsigned char* GetDataFragmentTexture(int xs, int ys, int xe, int ye, int nr,int &width,int &height)
{
	int w = bi[nr].w;
	int h = bi[nr].h;
	int x = xe - xs;
	int y = ye - ys;
	int xpos = 0;
	int ypos = 0;
	width = x;
	height = y;
	unsigned char* gdata = new unsigned char[x * y * 3];
	for (int py = ys; py < ye; py += 1)
	{

		for (int px = xs; px < xe; px += 1)
		{

			int pis = (xpos * 3 + ypos * y * 3);

			int index = (px * 3 + (h - py) * w * 3);
			gdata[pis] = bi[nr].bitmapData[index];
			gdata[pis + 1] = bi[nr].bitmapData[index + 1];
			gdata[pis + 2] = bi[nr].bitmapData[index + 2];
			xpos += 1;
			if (xpos == x)
				xpos = 0;
		}
		ypos += 1;
	}
	return gdata;

}

void DrawObiectImageCoordRotate(int x, int y, int nr, float angleDeg, int xs, int ys, int xe, int ye)
{

	int w, h, bpp;
	bpp = 3;
	const unsigned char* src = GetDataFragmentTexture(xs, ys, xe, ye, nr, w, h);

	float ang = angleDeg * 3.14159265358979323846f / 180.f;
	float c = std::cos(ang);
	float s = std::sin(ang);

	// nowa obwiednia
	int newW = (int)std::ceil(std::fabs(w * c) + std::fabs(h * s));
	int newH = (int)std::ceil(std::fabs(w * s) + std::fabs(h * c));

	// środki
	float cx = (w - 1) * 0.5f;
	float cy = (h - 1) * 0.5f;
	float ncx = (newW - 1) * 0.5f;
	float ncy = (newH - 1) * 0.5f;

	// przesunięcie pozycji docelowej, aby obraz był wycentrowany względem (x,y)
	int offX = (int)std::round(ncx - cx);
	int offY = (int)std::round(ncy - cy);

	for (int py = 0; py < newH; ++py)
	{
		for (int px = 0; px < newW; ++px)
		{
			// współrzędne dst względem środka NOWEJ ramki
			float dx = px - ncx;
			float dy = py - ncy;

			// mapowanie dst -> src (obrót o -ang)
			float srcX = dx * c + dy * s + cx;
			float srcY = -dx * s + dy * c + cy;

			int ix = (int)std::floor(srcX + 0.5f);
			int iy = (int)std::floor(srcY + 0.5f);

			if (ix >= 0 && iy >= 0 && ix < w && iy < h)
			{
				int base = (iy * w + ix) * bpp; // jeśli BMP bottom-up: (h-1-iy)*w + ix
				unsigned char r = src[base + 0];
				unsigned char g = src[base + 1];
				unsigned char b = src[base + 2];
				// jeśli BGR -> zamień r<->b

				Color3iT(r, g, b);
				PutPixelT(x + px - offX, y + py - offY);
			}
			// else: piksel poza źródłem — zostaw tło/nie rysuj
		}
	}
}

i nie ma utraty na jakości grafiki tak jak Ci podał tBane chatgpt. tą pierwszą wersje 😀
DrawConsole.rar

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0
wilkwielki napisał(a):

teraz działa ale trzeba dodać dodatkowe wartości na nową szerokość i wysokość bo jest obcięte ale działa

To dlatego że trzeba iterować po x i y docelowego obrazka, i wyliczać pozycję piksela źródłowego (stosując obrót w odwrotną stronę).
Podejście "naiwne" – iterowanie po pikselach źródłowych i wyliczanie docelowej pozycji każdego piksela – da słaby jakościowo wynik.

Nowy rozmiar (żeby nic nie obcięło) to już trzeba by sobie osobno wyliczyć.

Spine
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6959
0

Przydałoby się ten software'owy renderer napisać jak należy.
Tak jak OpenGL, obracasz tylko rogi quada i renderujesz piksele tekstury na podstawie UV przypisanych do poszczególnych rogów.
Możesz stosować przy tym interpolację. Patrz ile w GIMPie jest wariantów interpolacji przy obracaniu:
screenshot-20250905152854.png

wilkwielki
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 678
1

powiem tak, algorytm który podał tBane z moją podpinką GetDataFragmentTexture jest perfekcyjny na 100 % ponieważ nie ma straty na jakości grafiki pod czas rotacji pikseli, interpolacji nie mogę zrobić ponieważ w efekcie wyjdzie filtrowanie z przypadku, tak nie ma być po to starta na jakości grafiki, więc lepiej już się nie da .. 😀

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.