Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - TileMap OpenGL (non riesco a far renderizzare in modo corretto)
Forum - C/C++ - TileMap OpenGL (non riesco a far renderizzare in modo corretto)

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 12:23
Mercoledì, 04/01/2023
Salve a tutti e scusatemi per il disturbo... io avrei un problema con la renderizzazione di alcuni oggetti in 2D per poter creare una mappa....
In pratica io leggo da un file di testo dove dentro ci sono solo numeri.... ogni numero corrisponde a un MapObject che ha un ID....
Quindi se nel file di testo ad esempio scrivo
1 e l'id del MapObject allora renderizza questo oggetto.... non so se riesco a farmi capire bene cmq il problema è che quando mi renderizza gli oggetti la seconda linea è uguale alla prima....cmq provo a postarvi il codice per farvi capire meglio....

Ho una classe TileMap:

TileMap.hpp

Codice sorgente - presumibilmente C++

  1. #ifndef __TILEMAP_HPP__
  2. #define __TILEMAP_HPP__
  3.  
  4. #include "MapObject.hpp"
  5.  
  6. class TileMap {
  7.  
  8.     public:
  9.         std::vector<MapObject> MapObj;
  10.        
  11.        
  12.         TileMap() {}        
  13.         TileMap(std::vector<MapObject> &mapObject, const char* tileMapFile, unsigned int map_width, unsigned int map_height);
  14.         void onInit(std::vector<MapObject> &mapObject, std::vector<std::vector<unsigned int>> data, unsigned int map_width, unsigned int map_height);
  15.         void onRenderer(unsigned int screen_width, unsigned int screen_height);
  16.         void onDestroy();
  17.  
  18. };
  19.  
  20. #endif // __TILEMAP_HPP__



TileMap.cpp
Codice sorgente - presumibilmente C++

  1. #include "TileMap.hpp"
  2. #include <string>
  3. #include <fstream>
  4. #include <sstream>
  5. #include <iostream>
  6.  
  7. /* ============================================================================================== */
  8. /*                                              TileMap                                           */
  9. /* ============================================================================================== */
  10. TileMap::TileMap(std::vector<MapObject> &mapObject, const char* tileMapFile, unsigned int map_width, unsigned int map_height){
  11.  
  12.     MapObj = mapObject;
  13.  
  14.     std::vector<unsigned int> tileData;
  15.     unsigned int tileCode;
  16.     std::string line;
  17.     std::vector<std::vector<unsigned int>> Data;
  18.  
  19.     std::ifstream file(tileMapFile);
  20.     if(!file.is_open()){
  21.         std::cout << "Error open Map File" << std::endl;
  22.     }
  23.    
  24.     while(std::getline(file, line)){
  25.         std::istringstream sstream(line);
  26.         while(sstream >> tileCode){
  27.             tileData.push_back(tileCode);
  28.  
  29.         }
  30.         Data.push_back(tileData);
  31.     }
  32.    
  33.     file.close();
  34.  
  35.     std::cout  << Data.size() - 1 << std::endl; //Y
  36.     std::cout  << Data[0].size() << std::endl; //X
  37.  
  38.     if(Data.size() > 0){
  39.         onInit(mapObject, Data, map_width, map_height);
  40.     }
  41.    
  42.  
  43.     // unsigned int width = Data[0].size(); //X
  44.     // unsigned int height = Data.size(); //Y
  45.    
  46. }
  47.  
  48.  
  49.  
  50. /* ============================================================================================== */
  51. /*                                             onInit                                             */
  52. /* ============================================================================================== */
  53. void TileMap::onInit(std::vector<MapObject> &mapObject, std::vector<std::vector<unsigned int>> data, unsigned int map_width, unsigned int map_height){
  54.  
  55.     unsigned int widthVectorX = data[0].size(); //X
  56.     unsigned int heightVectorY = data.size() - 1; //Y
  57.     unsigned int mapObjectPositionX = map_width / widthVectorX;
  58.     unsigned int mapObjectPositionY = map_height / heightVectorY;
  59.  
  60.     for(int y = 0; y < heightVectorY; y++){
  61.         for(int x = 0; x < widthVectorX; x++){
  62.            
  63.             for(auto &mObj : mapObject){
  64.                 if(data[y][x] == mObj.ID && mObj.ID == 1){
  65.                     mObj.Position = glm::vec2(mObj.Size.x *  x, mObj.Size.y *  y);
  66.                     mObj.Color = glm::vec3(0.4, 0.7, 0.1);
  67.                     MapObj.push_back(mObj);
  68.                     std::cout << "Sono mattone 1" <<  " X: " << mObj.Position.x << " Y: " << mObj.Position.y << std::endl;
  69.                 }
  70.  
  71.                 if(data[y][x] == mObj.ID && mObj.ID == 2){
  72.                     mObj.Position = glm::vec2(mObj.Size.x *  x,  mObj.Size.y *  y);
  73.                     mObj.Color = glm::vec3(0.8, 0.3, 0.2);
  74.                     MapObj.push_back(mObj);
  75.  
  76.                     std::cout << "Sono mattone 2" <<  " X: " << mObj.Position.x << " Y: " << mObj.Position.y << std::endl;
  77.                 }
  78.  
  79.                 if(data[y][x] == mObj.ID && mObj.ID == 3){
  80.                     mObj.Position = glm::vec2(mObj.Size.x *  x,  mObj.Size.y *  y);
  81.                     mObj.Color = glm::vec3(0.2, 0.4, 0.6);
  82.                     MapObj.push_back(mObj);
  83.                     std::cout << "Sono mattone 3" <<  " X: " << mObj.Position.x << " Y: " << mObj.Position.y << std::endl;
  84.                 }
  85.                
  86.             }
  87.            
  88.         }
  89.        
  90.     }
  91.    
  92.    
  93. }
  94.  
  95.  
  96.  
  97. /* ============================================================================================== */
  98. /*                                           onRenderer                                           */
  99. /* ============================================================================================== */
  100. void TileMap::onRenderer(unsigned int screen_width, unsigned int screen_height){
  101.    
  102.     for(auto mObj : MapObj){
  103.         mObj.onRenderer(screen_width, screen_height);
  104.     }
  105.    
  106. }



File Di testo dove leggo gli id degli oggetti
Codice sorgente - presumibilmente Plain Text

  1. 1 2 2 1 2 3 1 2 2 1 1 1 1
  2. 3 1 1 1 1 2 2 3 1 2 2 1 2



Ho allegato un'immagine per farvi vedere come me lo renderizza
in pratica la seconda linea è uguale alla prima... credo che sia un problema di posizione perchè ho provato a mostrare a video ogni posizione degli oggetti e si trova...però con capisco perchè mi da questo problema...
spero qualcuno possa aiutarmi


Gemini ha allegato un file: Schermata del 2023-01-04 12-21-35.png (20541 bytes)
Clicca qui per guardare l'immagine
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2197
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 0:12
Lunedì, 09/01/2023
Ciao gemini.

Non so dirti, ma vedo tutto completamente senza senso.
Ti spiego.
Ho fatto diversi progetti del genere molto elaborati quindi ho una certa esperienza e posso consigliarti come muoverti.

Parto dal principio,


Il metodo che hai usato è il peggiore che si possa usare.
Non perché scredito quello che hai fatto attenzione!
Ma penso che recuperare una mappa da un file salvato in questo modo, sia completamente sbagliato.

Una mappa andrebbe serializzata in una lista correlata di una struttura, e successivamente implementata.
Così con un semplice ciclo for, stampi a video tutte le texture2d.
Ovviamente non parlo di risorsa completa, ma del sourceRect che prende inizio X,Y e Fine X,Y della porzione dello sprite da renderizzare.


Un esempio è questo mio piccolo progetto
https://github.com/Thejuster/Mappy

Viene proprio illustrato l'utilizzo di Liste e Strutture serializzate su file e poi re-implementate a runtime.
Ho usato Qt, ma non dovrebbe essere un problema riscriverle tanto stai usando opengl da quel che vedo.


Se proprio vuoi usare questo metodo, ho cercato di trovare nel tuo sorgente postato, la dimensione della mappa
ma non ho trovato nulla di utile. solo un metodo OnInit

Fatto sta, che per disegnare correttamente i pezzi di tiles, devi sapere esattamente ogni blocco quanto misura così come la dimensione della mappa.

Se ho dei blocchi di 32x32 pixel esempio, e ho una mappa larga 640,
automaticamente so che ho 20 blocchi per riga.  ( 32 * 20 = 640 ) Larghezza della mappa

Codice sorgente - presumibilmente Plain Text

  1. for(int y = 0; y < map_height; y+=32)
  2. {
  3.     for(int x = 0; x < map_width; x+=32)
  4.     {
  5.          //Aggiungo il pezzo a posizione X e Y al vettore
  6.  
  7.    }
  8. }



Ma come detto, è sempre un metodo molto brutto sia da comprendere che da utilizzare.
Anche perché andrai ad incasinarti con gli ID del tipo di blocco da visualizzare.
Quindi e meglio usare una struttura.

Per concludere la risposta la tuo problema succede questo perché probabilmente non esegui correttamente il ciclo
per andare a posizionare i blocchi con le giuste posizioni dal file, proprio perché non utilizzando una struttura devi andare un pò a caso sperando che non sbagli a scrivere un numero o a dividerli correttamente per la dimensione della mappa.




PM Quote
Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 17:21
Martedì, 10/01/2023
ciao Thejuster e grazie per la risposta... in effetti come metodo e un pò un casino anche per me che ho scritto la funzione avvolte fado in chaos...comunque proverò a studiare un pò come hai detto tu di usare una struttura...darò un'occhiata al tuo progetto e cercherò di implementarlo nel mio.... ah un'altra cosa non so se sto sbagliando a scriverlo in questo topic o devo aprirne un'altro...
in pratica ho anche un'altro problemino... sto facendo un'animazione di un player che cammina quindi passo i primi vertici delle coordinate delle texute e poi le modifico con Uniform dello shader passandogli le coordinate della texture proprio come hai detto tu.... riesco a renderizzarle correttamente quando ad esempio imposto x_image 32 y_image 0 (quindi sarebbe la prima immagine di 32x32 che ho nel mio atlas...ora il problema è che quando provo a fare un animazione e creo un ciclo for e su una linea ho 3 immagini di un player che cammina verso il basso faccio un for in questo modo

for(int a  = 0; a < 2; a++){
            playerObj.GetShader().Use();
            playerObj.GetShader().setFloat("x_dir", (0.32 * a) * time ); //0.50
            playerObj.GetShader().setFloat("y_dir", 0.0);
    }

ma mi mostra le immagini in sequenza cioè non mi fa la moltiplicazione di 32*0 - 32*1 ecc e renderizza ogni blocco di texture ma me le mostra lineari... provo a allegare una gif per far capire meglio...mi credi? sulle stupidaggini xke sicuramente sarà una stupidaggine.... mi perdo.... poi vedo se x favore puoi dirmi se sto sbagliando io in qualcosa nel ciclo o boh... cmq scusami per le domande niubbe xD ma studio opengl da pochi mesi...e ancora devo conoscerlo bene bene

ho fatto un piccolissimo video per mostrarvi quello che sto dicendo xke un'altra mia pecca è nel sapermi spiegare XD
https://files.fm/u/89ssvawnh

Ultima modifica effettuata da Gemini il 10/01/2023 alle 19:39
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2197
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 20:27
Martedì, 10/01/2023
Tranquillo nessun problema :rotfl:

Per quanto riguarda la serializzazione e posizione della struttura puoi dare un occhiata qui

https://github.com/Thejuster/Mappy/blob/master/mappysaver.h

ho utilizzato la struttura

Codice sorgente - presumibilmente C/C++

  1. //structure
  2.     struct Tile
  3.     {
  4.     public:
  5.         int ID;
  6.         int x,y,w,h,Tx,Ty,Tw,Th;
  7.         QRect rect;
  8.     };
  9.  
  10.  
  11.     QList<Tile> Tiles;



x = posizione X del blocco
y = posozione Y
w = larghezza blocco (32px)
h = altezza blocco (32px);
Tx = Tile Source X
Ty = Tile Source Y
Tw = Larghezza del tile (32px)
Th = Altezza del Tile (32px)

in seguito aggiungo gli elementi alla lista

Dopo vado a serializzare su file usando l'override degli operatori

Codice sorgente - presumibilmente C/C++

  1. QDataStream& operator << (QDataStream& s, const MappySaver::Tile& tile);
  2. QDataStream& operator >> (QDataStream& s, MappySaver::Tile& tile);



Che farebbe semplicemente questo sia in read che in write

Codice sorgente - presumibilmente C/C++

  1. QDataStream &operator>>(QDataStream &s, MappySaver::Tile& tile)
  2. {
  3.   s >> tile.h >> tile.ID >> tile.rect >> tile.w >> tile.x >> tile.y << tile.Tx << tile.Ty;
  4.   return s;
  5. }




Riguardo al personaggio, succede anche qui uguale perché hai confuso i parametri.
o semplicemente esegue l'incremento di X molto lentamente rispetto al frame che richiede un 32 per cambiare.

Personalmente, ho usato il resto di una divisione di 16

provo a scriverti qualcosa di comprensibile

Per far muovere il personaggio, premi ovviamente Su,Giu,Destra,Sinitra.
In questo caso aumenterà la variabile del movimento.

Ma ti insegno un bel trick.
Non andare ad aumentare direttamente la posizione del persionaggio.
Ma usa una variabile che permette man mano di far arrivare il personaggio alla destizione.

ad esempio

Premo Destra

Codice sorgente - presumibilmente C/C++

  1. int x =0;
  2. int destinazione = 0;
  3.  
  4.  
  5. //Premo Destra
  6. if(destinazione == 0)
  7. destinazione += 32;
  8.  
  9. //Premo Sinistra
  10. if(destinazione == 0)
  11. destinazione -= 32
  12.  
  13.  
  14.  
  15. //Loop
  16.  
  17. if(destinazione > 0 && Direzione == Destra )
  18. {
  19.   destinazione -=2;
  20.   x += 2;
  21.  
  22. }
  23.  
  24.  
  25. if(destinazione < 0 && Direzione == Sinistra)
  26. {
  27.    destinazione +=2;
  28.    x -= 2;
  29. }



in modo da simulare uno spostamento graduale fino a che la destinazione non si azzeri.
Una volta arrivato a 0 ovviamente il loop del movimento si ferma.

Per il frame come detto prima, io uso il resto di una divisione per il totale dei frame
Se ho uno sprite di cui un personaggio ha 16 frame.  

4 * riga
Fermo, Passo Sinistra, Passo centrale, Passo Destro  [ Guarda verso giu ]

ecc. ecc.

Codice sorgente - presumibilmente C/C++

  1. if(destinazione != 0)
  2.                {
  3.                 frame = (frame + 1) % 16;  //Anima il personaggio
  4.                }
  5.                else
  6.                {
  7.                 frame = 0;
  8.                }



La variabile Frame è relativa al SourceX dello sprite
mentre userai una variabile tipo Face  per il sourceY ovvero dove il personaggio sta guardando o camminando.
Di conseguenza il frame anima verso destra, mentre il Face per le varie direzioni.

Elimina tutto il restante che hai fatto

Codice sorgente - presumibilmente Plain Text

  1. playerObj.GetShader().setFloat("x_dir", (0.32 * a) * time ); //0.50



ed usa un metodo semplice come ti ho mostrato

alla fine otterrai qualcosa del genere


https://youtu.be/tgDJn-HnRIQ


Se vuoi osservare l'intero procedimento di come ho realizzato.
Il sorgente è in C# e trovi qui l'intera classe Player

https://github.com/MakingItalia/MMORpgmaker/blob/master/Cli ...



Ultima modifica effettuata da Thejuster il 10/01/2023 alle 20:39


PM Quote
Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 6:29
Mercoledì, 11/01/2023
grazie mille thejuster ora sto andando a lavoro appena torno oggi nel pomeriggio proverò e ti farò sapere :) cmq grazie veramente anche solo con queste spiegazioni mi hai fatto capire gia tante cose....cmq oggi proverò a fare un metodo per le tile e l'animazioni e t farò sapere come andrà :D

cmq veramente figo il video che mi hai mostrato...io vorrei fare qualcosa proprio così...anche l'ombra dietro *_*....vabbè piano piano capirò come fare :D....

Ultima modifica effettuata da Gemini il 11/01/2023 alle 6:34
PM Quote
Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 6:15
Venerdì, 13/01/2023
Buongiorno e rieccomi con una domanda forse stupidissima... in pratica Thejuster per le tile ho risolto cioè quasi risolto :D ho fatto come mi hai suggerito tu però invece di usare una struttura ho fatto una classe dove dal costruttore prendo tutte le info dell'immagine che mi servono e le salvo nelle variabili... non ho usato una lista al momento......
Codice sorgente - presumibilmente C++

  1. float x;
  2. float y;
  3. float image_width;
  4. float image_height;
  5. float sprite_width;
  6. float sprite_height;


ok fin qui ci siamo poi ai vertici delle coordinate delle texture gli passo queste info in questo modo

Codice sorgente - presumibilmente Plain Text

  1. std::vector<float>vertexTexture = {
  2.         (x * sprite_width) / image_width, (y * sprite_height) / image_height,
  3.         ((x + 1) * sprite_width) / image_width, ((y + 1) * sprite_height) / image_height,
  4.         (x * sprite_width) / image_width, ((y + 1) * sprite_height) / image_height,
  5.  
  6.         (x * sprite_width) / image_width, (y * sprite_height) / image_height,
  7.         ((x + 1) * sprite_width) / image_width, (y * sprite_height) / image_height,
  8.         ((x + 1) * sprite_width) / image_width, ((y + 1) * sprite_height) / image_height
  9.     };


Poi le carico nel buffer VBO e le renderizzo.

ora quando voglio renderizzare ad esempio il player in alto cambio semplicemente x e y....

Però mi domando qui io vado a modificare i vertici direttamente nel codice c++ ma non conviene farlo dallo shader cioè come facevo prima? mandando un uniform float allo shader cosi da far lavorare la gpu....
non so forse sto sbagliando o sto dicendo una stupidaggine però volevo capire meglio questa cosa...cosa mi conviene cambiare i vertici da c++ e ogni volta fare il bind del vbo per i nuovi vertici nel buffer oppure meglio usare un uniform float da mandare allo shader?



Ultima modifica effettuata da Gemini il 13/01/2023 alle 9:09
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2197
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 9:01
Venerdì, 13/01/2023
Non sò dirti quale metodo sia più conviente usare. ( Non performante )

Personalmente avevo creato un void che durante il render andava a bindare delle texture.
Cambiavo le TexCoord prima del Draw subito dopo al GlBegin
Avevo un pò diviso il tutto in void separati che richiamavo dal render per risparmiare tempo.

Dovrebbe esistere anche un metodo chiamato BlitFrameBuffer e GenFrameBuffer era qualcosa che rigenerava la texture nel fbo.

Tornando al discorso, il mio draw era semplicemente composto da 4 chiamate

da li andavo a richiamare successivamente ogni funzione dove avevo già pre-elaborato l'inizializzazione dei vertici
chiamando un void e passando argomenti come posizione, source ecc. ecc.

alla fine un semplice void per disegnare
Ti mostro il mio esempio in C# preso direttamente dal mio Mire Engine
In questo esempio disegnavo tutti i vari tiles della mappa Id per ID
Ma penso basti solo ottimizzare il codice per adattarlo al personaggio.

Ciclo per Disegnare i vari Layer come id della texture passo l'intera immagine
che poi va a suddividere tramite la lista con le relative posizioni X ,Y , SourceX, SourceY

Ho tagliato un bel pò di codice che era relativo al mio motore.
Spero di non aver tagliato l'utile essenziale :rotfl:


Main Loop
Codice sorgente - presumibilmente Plain Text

  1. GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
  2.             glMatrixMode(MatrixMode.Modelview);
  3.             glLoadIdentity();
  4.  
  5.             //TODO: Metodo Render qui per disegnare
  6.             UpdateRender();
  7.  
  8.             glEnd();
  9.             glControl1.SwapBuffers();
  10.             glControl1.Invalidate();
  11.             Update();






L'update Render, va ad aggiornare la griglia con i relativi sprite
Codice sorgente - presumibilmente C/C++

  1. private void UpdateRender()
  2.         {
  3.             for (int i = 0; i < Grid.GetLength(2); i++)
  4.             {
  5.                 DrawLayer(i);
  6.             }
  7.         }






Codice sorgente - presumibilmente C++

  1. private void DrawLayer(int layer)
  2.         {
  3.             for (int i = 0; i < Grid.GetLength(0); i++)
  4.             {
  5.                 for (int j = 0; j < Grid.GetLength(1); j++)
  6.                 {
  7.                     Tile t = Grid[i, j, layer];
  8.                     if (t.id == 0)
  9.                         continue;
  10.  
  11.                     DrawImage(t.id, new Rectangle(i * GridPixelSize, j * GridPixelSize, t.width, t.height));
  12.                 }
  13.             }
  14.         }






Disegno l'immagine

Codice sorgente - presumibilmente C++

  1. /// <summary>
  2.         /// Metodo Draw Image
  3.         /// </summary>
  4.         /// <param name="image">variabile INT contenente la Texture</param>
  5.         public static void DrawImage(int image, Rectangle pos)
  6.         {
  7.             GL.MatrixMode(MatrixMode.Projection);
  8.             GL.PushMatrix();
  9.             GL.LoadIdentity();
  10.  
  11.             GL.Ortho(0, MapSize.Width, 0, MapSize.Height, -1, 1); //Grandezza della Mappa di gioco
  12.  
  13.             GL.MatrixMode(MatrixMode.Modelview);
  14.             GL.PushMatrix();
  15.             GL.LoadIdentity();
  16.  
  17.             GL.Disable(EnableCap.Lighting);
  18.             GL.Enable(EnableCap.Blend);
  19.             GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
  20.             GL.Enable(EnableCap.Texture2D);
  21.  
  22.             //GL.Color4(0, 1, 1, 1);
  23.             GL.Color4(Color.FromArgb(64, 255, 255, 255));
  24.  
  25.  
  26.             GL.BindTexture(TextureTarget.Texture2D, image);
  27.  
  28.             GL.Begin(BeginMode.Quads);
  29.  
  30.             Rectangle spos = new Rectangle(pos.X, MapSize.Height - pos.Y, pos.Width, -pos.Height);
  31.  
  32.             GL.TexCoord2(0, 0);
  33.             GL.Vertex3(spos.X, spos.Y, 0);
  34.             GL.TexCoord2(1, 0);
  35.             GL.Vertex3(spos.X + spos.Width, spos.Y, 0);
  36.             GL.TexCoord2(1, 1);
  37.             GL.Vertex3(spos.X + spos.Width, spos.Y + spos.Height, 0);
  38.             GL.TexCoord2(0, 1);
  39.             GL.Vertex3(spos.X, spos.Y + spos.Height, 0);
  40.  
  41.             GL.End();
  42.  
  43.             GL.Disable(EnableCap.Blend);
  44.             GL.Disable(EnableCap.Texture2D);
  45.             GL.PopMatrix();
  46.  
  47.             GL.MatrixMode(MatrixMode.Projection);
  48.             GL.PopMatrix();
  49.  
  50.             GL.MatrixMode(MatrixMode.Modelview);
  51.         }



Poi ho preferito passare a MonoGame per semplicità ed efficienza senza andarmi a complicare la vita.
Cmq penso che ottimizzando bene le funzioni in void separati che eseguono la medesima funzione puoi ottenere qualcosa di facile e veloce come nel mio esempio.
Evitando di andarti a riscrivere ogni volta riposizionamenti dei vertici e bind delle texture.

Ti consiglio di implementare prima le liste e strutture
Cosa fondamentale e necessaria per un progetto del genere.

Se sei curioso di sapere a cosa serviva il tutto era per l'editor
https://www.youtube.com/watch?v=jDEU4szVJ9A

Ultima modifica effettuata da Thejuster il 13/01/2023 alle 9:15


PM Quote
Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 9:10
Venerdì, 13/01/2023
Ho provato a fare così ho modificato il fragment in questo modo
Codice sorgente - presumibilmente C#

  1. #version 450 core
  2. out vec4 Color;
  3.  
  4. uniform vec3 customColor;
  5.  
  6. in vec2 TexCoord;
  7. uniform sampler2D ourTexture;
  8.  
  9. uniform float nx_frame;
  10. uniform float ny_frame;
  11. uniform float uv_x;
  12. uniform float uv_y;
  13.  
  14.  
  15.  
  16. void main() {
  17.     float x = 1.0 / nx_frame;
  18.     float y = 1.0 / ny_frame;
  19.     Color = vec4(customColor, 1.0) * texture(ourTexture, vec2(TexCoord.x * x, TexCoord.y * y) + vec2(x * uv_x, y * uv_y));
  20. }



quando creo l'oggetto gli mando allo shader le info dell'atlas
Qui creo per la prima volta il player con la posizione iniziale
Codice sorgente - presumibilmente Plain Text

  1. boxObj.GetShader().Use();
  2.     boxObj.GetShader().setFloat("uv_x", 0.0);
  3.     boxObj.GetShader().setFloat("uv_y", 0.0);
  4.     boxObj.GetShader().setFloat("nx_frame", 3);
  5.     boxObj.GetShader().setFloat("ny_frame", 4);




e quando lo  renderizzo gli rimando le nuove coordinate allo shader
Codice sorgente - presumibilmente C++

  1. //Animation
  2.     float nx_frame = 3, ny_frame = 4;
  3.     float uv_x = 1.0f, uv_y = 1.0f;
  4.     float time = glfwGetTime();
  5.     float speed = 10.0;
  6.     float new_time = time * speed;
  7.     for(float a = 0.0; a < new_time; a++){
  8.         if(a > 1.0f){
  9.             uv_x += 1.0f;
  10.             boxObj.GetShader().Use();
  11.             boxObj.GetShader().setFloat("uv_x", uv_x);
  12.             boxObj.GetShader().setFloat("uv_y", uv_y);
  13.  
  14.             if(uv_x >= nx_frame){
  15.                 uv_x = 0.0f;
  16.                 boxObj.GetShader().Use();
  17.                 boxObj.GetShader().setFloat("uv_x", uv_x);
  18.                 boxObj.GetShader().setFloat("uv_y", uv_y);
  19.             }
  20.         }  
  21.  
  22.     }



ed ecco il risultato
https://files.fm/u/ym8gz9rjc

ovviamente è da migliorare sicuramente però funziona... ed e piu pulita come funzione.... poi non so se è il metodo migliore....
Io credo... (questo è un mio pensiero) che sia meglio mandare i parametri allo shader in modo che il lavoro lo fa lui e quindi da come ho capito, (interrompetemi se sbaglio!) lo shader usa la gpu e quindi penso che si abbia prestazioni migliori visto che la cpu manda solo la prima volta i vertici allo shader per le coordinate della texture e i vertici per il quad.....
ripeto è un mio pensiero questo... sicuramente starò dicendo cavolate... o magari no.... mi devo informare meglio su sta cosa cmq :yup:

Ultima modifica effettuata da Gemini il 13/01/2023 alle 9:17
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2197
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 9:21
Venerdì, 13/01/2023
No, hai perfettamente ragione.
La GPU e molto molto più veloce della CPU.

Il risultato è ottimo bravissimo :k:
l'animazione è perfetta.


PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo