kategoria: ANSI C
[#1] [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?
Cześć,
zamulił mnie pewien problem, może macie jakieś sprawdzone pomysły? Jest to "ogólny problem C - wskaźnikowy"
ale ze względu na Amigowe podejście, może uda się znaleźć jak najbardziej optymalne podejście?

Zwykle w podobnych sytuacjach korzystałem z std::vector i jakiejś struktury przechowującej różne dane bitmapy,
lub po prostu ręcznie 2-3 takie struktury jako osobne zmienne, ale teraz nie da rady.
Próbuje pisać bardziej pod C (na razie w Win i tak), żeby potem łatwiej pod Amigę przepisać.

Rzecz dotyczy nieskompresowanych Bitmap RGB (po 8 bit na kanał) które mają sobie siedzieć w FAST RAM,
ilość np. MAX 20, rozmiar dla ułatwienia dajmy stały 128x128 - więc można przyjąć że rozmiar każdej zajmie tyle samo,

Dane pojedynczej bitmapy są jako tablica unsigned char, czyli surowe RGBRGBRGB..

1. Wydaje mi się, że najlepiej by było zaalokować od razu przestrzeń na wszystkie bitmapy razem, a następnie
ułożyć "jedna po drugiej". Tylko by trzeba zrobić jakąś tablicę wskaźników zdaje się, żeby mieć od razu adres do początku danej textury. Chyba tak by to musiało wygladać:
unsigned char pixelR = textury[numer][jakiś_index];

Znalazłem parę metod jak to porobić w C - wiec z tym podejściem chyba nie byłoby problemu.

2. Albo w taki sposób, któy mi daje wiecej możliwości bo moge dodać więcej informacji o bitmapie
unsigned char pixelR = textury[numer].pixel[jakiś_index];

struct sBitmap
{
    unsigned char* pixels;
};

int main()
{
    sBitmap* my_bitmap = new sBitmap[10];

    for (int i = 0; i < 10; i++)
        my_bitmap[i].pixels = new unsigned char[10];

    my_bitmap[4].pixels[2] = 45;
    // nie ma problemow
}


Tylko właśnie tu mi się pojawił problem, że kiedy zacząłem owijać to w funkcje to wymiękłem na wskaźnikach, tu nawet uproszoczny,
bo nawet nie wiem jak sie dostać do pixels:
struct sBitmap
{
    unsigned char pixels;
};

sBitmap* BitmapArray;

void foo(sBitmap** data)
{
    *data = (sBitmap*)malloc(5 * sizeof(sBitmap));

    for (int i = 0; i < 5; i++)
    {
        // jak mam się dostać do data[i].pixels ? i w dodatku zaalokowac miejsce na textury?
    }
}

int main()
{
    foo(&BitmapArray);
}



Podsumowując, chce po prostu wrzucić do RAMU textury i mieć do nich szybki i łatwy dostęp...
z góry dzięki, jeśli coś Komuś przyjdzie do głowy :)
[wyróżniony] [#2] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@mateusz_s, post #1

Wydaje mi się, że musisz najpierw stworzyć strukturę jak
struct costam {
pixel[128*128];
};


a potem zdefiniować wskaźnik do takiej struktury

struct costam *innego


przypisujesz temu wskaźnikowi adres początku szeregu twoich tekstur, a potem wyłuskujesz bodajże w ten sposób

innego[i].pixel[px]


możesz też przekazywać adres do struktury jako parametr

unsigned int read_px(struct textures *texture, int t_index, int p_index  ) {

return texture[t_index].pixel[p_index]

}


Tu może być dużo błędów, ale mam nadzieję, że cię na coś naprowadzi, bo ja ruszam C całkowicie od święta i po amatorsku.
Jest jeszcze coś takiego jak rzutowanie tablicy na dane w pamięci, ale to raczej ktoś inny by musiał przytoczyć jakiś przykład.

Awaryjnie możesz zrobić funkcję, która ci odczyta dany piksel, lub obliczyć adres tego piksela samemu

unsigned int read_px(unsigned int* data, int indeks_tekstury, int_nr_piksela){
     unsigned int *pix_ptr;
     pix_ptr = data + (void*) ((128*128*indeks_tekstury) + nr_piksela)
     return *pix_ptr;
}



Ostatnia aktualizacja: 31.01.2021 05:28:36 przez WyciorX
[wyróżniony] [#3] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@mateusz_s, post #1

struct sBitmap
{
  unsigned char *pixels;
}

struct sBitmap *BitmapArrayPtr;

void foo(struct sBitmap **data)
{
  *data = (struct sBitmap*)malloc(5 * sizeof(struct sBitmap));

  for (i = 0; i < 5; i++)
  {
    (*data)[i].pixels = malloc(128*128*3);
  }
}

int main(void)
{
  foo(&BitmapArrayPtr);
  return 0;
}
Uwaga techniczna. Zazwyczaj opłaca się trzymać 8-bitowe trójki RGB w słowach 32-bitowych np. z zerem na początku. Dostęp do poszczególnych pikseli (wyznaczenie ich adresu) jest wtedy nieco szybszy.

Ostatnia aktualizacja: 31.01.2021 09:16:50 przez Krashan
[#4] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@Krashan, post #3

Wielkie dzięki :)
Kiedy próbuję ogarniać podwójne wskaźniki
mózg wylewa mi się uszami

I jeszcze za tą podpowiedź,
też o to miałem zapytać i zupełnie zapomniałem.. :)



Ostatnia aktualizacja: 31.01.2021 09:40:11 przez mateusz_s
[#5] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@Krashan, post #3

Skoro już poruszyliśmy temat trzymania RGB jako 32 bity - to jeszcze tak pokombinowałem,
żeby móc łatwo manipulować osobnymi składowymi RGB i ewentualnie od razu coś zrobić na słowie 32 bitowym.
Trzymam pojedynczy pixel zarówno jako int i jako sRGBA za pomocą unii - nie było problemów.
Mam nadzieję, że GCC od Bebbo nie bedzie krzyczał.. ale gdzieś wyczytałem że powinno być ok.

struct sRGBA
{
    unsigned char r, g, b, a;
};

union uPixel
{
    unsigned int hex;
    sRGBA c;
};

struct sBitmap
{
    uPixel* pixel;
};

sBitmap* BitmapArrayPtr;

void foo(sBitmap** data)
{
    *data = (sBitmap*)malloc(5 * sizeof(sBitmap));

    for (int i = 0; i < 5; i++)
    {
        (*data)[i].pixel = (uPixel*)malloc(5);
    }
}


int main()
{
    foo(&BitmapArrayPtr);

    BitmapArrayPtr[3].pixel[4].c.r = 255;
    BitmapArrayPtr[3].pixel[4].c.g = 0;
    BitmapArrayPtr[3].pixel[4].c.b = 0;
    BitmapArrayPtr[3].pixel[4].c.a = 0;

    printf("%d", BitmapArrayPtr[3].pixel[4].c.r);
    printf("%d", BitmapArrayPtr[3].pixel[4].hex);

   return 0;
}


Nie wiem czy to nie przesada, ale chyba w ten sposób łatwiej bym mógł manipulować
poszczególnymi składowymi w razie konieczności.

Np. Będę chciał zmniejszyć intensywność pixela, do tej pory - w starym kodzie robiłem tak, tj. mnożyłem każda składową:

output_buffer[index_i] = (mb_texture_2.pixels[texture_index] * intensity_value) >> 8;
output_buffer[index_i + 1] = (mb_texture_2.pixels[texture_index + 1] * intensity_value) >> 8;
output_buffer[index_i + 2] = (mb_texture_2.pixels[texture_index + 2] * intensity_value) >> 8;

// gdzie intensity value [0-255]


no i właśnie gdybym trzymał pixel tylko int to musiałbym chyba najpierw przesunąć bity i pobrać wartości rgb, a potem znowu "złożyć" do int,
to chyba za dużo roboty, chyba że można prościej.. ??


ps.
generalnie, to czymś takim się bawię, Raycaster - bardzo mnie wciągnęło - wydajna technika do 2.5D (wolf3d)
ale generalnie da się wyciągnąć z niej dużo więcej niż w wolfie3d, do tego dość prosto i często wydajnie.
Mam też pewien pomysł na fajny efekt, który można uzyskać niskim kosztem i jestem ciekawy jakby to wyszło nawet w 320x240.
Staram się mocno optymalizować i np. używać bardziej wydajnych algorytmów np. do przeszukiwania grida, prekalkulowane tablice,
potem pewnie jakieś fixed pointy, a może potem Koledzy z forum coś tam pomogą w asm :P

Patrząc jak radzą sobie "nowe" karty typu V1200 czy Warp 1260 - chciałbym przenieść potem fragment
i zupełnie z ciekawości zobaczyć jak to pociągnie chociaż w 320x240.

no i teraz generalnie robie refaktor znowu całego kodu, tak bardziej pod C i stram się nadać jakąś strukturę całości - równolegle robiąc edytor.

poniżej test różnych ruchów - przy manipulacji myszką.



no i równolegle robię też edytor - bo "ręcznie" już nie da się mapki zrobić - a korci mnie żeby sobie już pochodzić po czymś większym ;p
na razie podstawowe rzeczy, ale zrobiłem możliwość dowolnie skośnych ścianek wiec wyjdzie taki "poł-doom" ;p



ps.
To rzeczy co zamieściłem to robie na razie w Win, ale tylko WinApi i + wywalenia bufora pixeli przez podstawową na ekran,
bez żadnych akceleracji..



Ostatnia aktualizacja: 31.01.2021 12:25:00 przez mateusz_s
[#6] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@mateusz_s, post #5

Zastanawiam się czemu w Twoim najnowszym kodzie bufor pikseli dla każdej z 5 bitmap ma 5 bajtów... malloc() zawsze ma rozmiar podany w bajtach, niezależnie od tego na co to potem sobie zrzutujemy.
[#7] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@mateusz_s, post #5

Tu koledzy programiści Ci dają cenne profesjonalne rady. Ze mnie programista żaden, ale przez lata dłubania z nieszczęsnym Blaskiem doszedłem do tego:

Jeśli ściany są pod kątem prostym i mapa jest oparta na siatce, to przy rzucaniu promienia zamiast sprawdzać w co promień trafia co krok, możesz sprawdzać tylko punkty na siatce, czyli tam gdzie ściana może się pojawić. Tak było w wolfensteinie. Wiadomo, że nakłada to pewne ograniczenia, ale wydajnościowo się opłaca.

Obrazek poglądowy
[#8] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@Krashan, post #6

nie, te 5 bajtów to przykład tylko..

a właściwie to sam już nie wiem potem to sprawdze jeszcze

Ostatnia aktualizacja: 31.01.2021 15:29:05 przez mateusz_s
[#9] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@mastaszek, post #7

tak, ja korzystam z tej dość szybkiej implementacji:
https://theshoemaker.de/2016/02/ray-casting-in-2d-grids/

a jak wyjdzie docelowym sprzęcie - może się kiedyś przekonam
jak dojdę do tego etapu :) w każdym razie celuje w te karty turbo z RTG..

po prostu mnie to ciekawi, sama technika wciąga, coś się tam uczę przy okazji,
i mam jeden pomysł który chce wypróbować i zobaczyć efekt..
[#10] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@mateusz_s, post #9

Mam pytanie natury lamerskiej. Jak mój kod jest pisany pod systemem - otwieranie ekaranow bibliotek etc. to jak uruchomie to na amidze z karta graficzna to bedzie dzialac i nie musze juz nic dorabiac? Czy taki systemowy program jest uruchamialny na NG? Nie mam jak sprawdzic a amige poznaje od "srodka" od niedawna a moja ami to goła klasyczna a4k
[#11] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@arturB, post #10

tzn. ja jestem w podobnej sytuacji, do końca nie wiem, bo nawet nigdy nie miałem RTG

ale to chyba wszystko zależy w jakiej rozdzielczości Twój program będzie działać i czy na full screen czy w okienku, gdzieś te wartości muszą być ustalone.. podobnie jak na PC

Jak w okienku to zakładam, że na Twoim pulpicie w dużej rozdzielczości pojawi się
po prostu Twoje okienko w takim rozmiarze jak je zdefiniowałeś, albo dałeś np. jakeiś % wartości względem aktualnych ustawień pulpitu..

Jak na pełnym ekranie - no to zakładam, że zostanie otworzony po prostu nowy screen -
ktorego rozdzielczosc też musisz określić:

1. można by to zrobić w startowym programie typu LAUNCHER gdzie wybierasz sobie w jakiejs rozdzielczosci chcesz odpakić grę (powinna się pojawić lista zgodnych trybów)..
albo domyslnie może być ustawione np. 320x240 a w jakich Advanced dodatkowe tryby,
i przy okazji odpalałaby się wersja skompilowana pod 040, 060, 080

2. albo w samej grze w opcjach..

w moim przypadku, chciałbym chyba tą pierwszą opcję żeby np. robić sobie benchmarki na róznych rozdzilczościach bo cała grafika jest generowana - wiec w tym przypadku ma sens.

no ale zobacz, jal ludzie odpalają jakieś Doomy czy Wolfy na Vampirach itp. tak samo to działa..





Ostatnia aktualizacja: 31.01.2021 17:19:02 przez mateusz_s
[#12] Re: [C] Seria bitmap w FAST RAM - jak tym najlepiej zarządzić?

@arturB, post #10

Mam pytanie natury lamerskiej. Jak mój kod jest pisany pod systemem - otwieranie ekaranow bibliotek etc. to jak uruchomie to na amidze z karta graficzna to bedzie dzialac i nie musze juz nic dorabiac?
Im „czyściej” systemowo piszesz bez chodzenia na skróty i sztuczek, tym większa szansa, że tak będzie.
Czy taki systemowy program jest uruchamialny na NG?
Co do zasady tak, uwzględniając to, co napisałem powyżej.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem