VBO Normal



  • So wie es dort steht wird die Scene über eine Indextabelle abgespielt.

    Leider werden die Normals nicht gerendert, glDrawelements crasht. Kommentiere
    ich die bezüge auf Normale aus, geht wieder alles. Deaktiviere ich die VBO-
    Ansprechung, und dekommentiere die glVertice Pointer. Wird die Scene
    mit den Normals dargestellt, natürlich um Potenzen langsamer als mit VBO.

    Frage also, warum werden die Normalspeicher nicht von glDrawElemnts
    prozessiert, wenn es über Pointer und indexliste "ja" auch geht.

    Ein hintergedanke wäre das facenormale erwartet werden, doch dann müßte
    ich zwei unterschiedliche indextabellen vorhalten. Also rendere ich Vertice-
    Normals als TRIANGLE



  • Hab oben noch was editiert 😉

    Wenn du VBOs verwenden willst, solltest du dir vielleicht erstmal anschauen, wie die eigentlich genau funktionieren 😉



  • Oh nee da fehlt kein Zeiger, es sind VBO's man setzt alle Zeiger
    auf NULL da VBO ohne angabe von zeigern rendert.

    der code ist ausdrücklich so wie beschrieben lauffähig, die Zeiger
    ansprechnung ist dort deaktiviert und zeigt nur die Optionelle
    verwendung an, wenn ich den markierten VBO Block dekommentiere.
    (ich mach das seit 1976 ^^)

    Die VBO's wurden bereits initialisiert das steht da nicht.

    Geht wirklich nur darum, warum die Normals nicht via VBO gerendert werden.

    Und über Zeiger schon.

    void CTerrain::Render(void)
    {
    	 glEnable(GL_TEXTURE_2D); 
    	 glBindTexture(GL_TEXTURE_2D,m_texid);
    
    	 glEnableClientState(GL_INDEX_ARRAY);
    	 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    	 //glEnableClientState(GL_NORMAL_ARRAY);
    	 glEnableClientState(GL_VERTEX_ARRAY);	
    
    	 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,m_nVBOIdx);
              glBindBufferARB( GL_TEXTURE_BUFFER_ARB,m_nVBOTexCoords); 
    	 //glBindBufferARB( GL_ARRAY_BUFFER_ARB,m_nVBONormals);
    	 glBindBufferARB( GL_ARRAY_BUFFER_ARB,m_nVBOVertices);
    
    	 glDrawElements(GL_TRIANGLES,m_idsz, GL_UNSIGNED_INT, NULL); 
    
    	 glDisableClientState(GL_VERTEX_ARRAY);
    	 glDisableClientState(GL_NORMAL_ARRAY);
    	 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    	 glDisableClientState(GL_INDEX_ARRAY);
    
    	 glDisable(GL_TEXTURE_2D); 
    }
    

    Exact genau so , zeige ich 40 Millionen Dreiecke an. Auf zwei NVidea
    Tessla. Alles also gut soweit, nur wenn ich die Normale im obiger funktion
    dekommentiere geht glDrawElement "nach hause" wärend es mit glPointer
    funktioniert, aber x million mal langsamer 🙂



  • Die Initialisierung sieht so aus:

    bool CTerrain::Create(int Width, int Height, int Bpp)
    {
    	Delete();
    
    	m_texid   = -1;
    	m_pMapMem = m_dib.GetMapMem();
    	m_width   = Width;
    	m_height  = Height;
    	m_bpp     = Bpp;
    
    	glGenTextures(1, (unsigned int *)&m_texid);
    	//m_texid = CreateNullTexture(m_width,m_height);
    
    	m_size = m_width*m_height;
    	m_idsz = m_width*m_height*6;
    
    	if(!(m_pNorm  = (CVertex *)  new CVertex[m_size])) return false;memset(m_pNorm,0,(m_size)*sizeof(CVertex));
    	if(!(m_pVert  = (CVertex *)  new CVertex[m_size])) return false;memset(m_pVert,0,m_size*sizeof(CVertex));
    	if(!(m_pTVert = (CTexvert *) new CTexvert[m_size])) return false;memset(m_pTVert,0,m_size*sizeof(CTexvert));
    	if(!(m_pIdx   = (GLuint *)   new GLuint[m_idsz])) return false;memset(m_pIdx,0,m_idsz*sizeof(GLuint));
    
    	int bufferSize,needSize(((m_size*sizeof(CTexvert)) + (m_size*sizeof(CTexvert)) + (m_idsz*sizeof(GLuint)) + (m_width*m_height*(m_bpp>>3))));
    	glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &bufferSize);
    
    	TRACE("Try to alloc GFX of %0.4f MB from %0.4f\r\n",
    		(float)abs(bufferSize)/1024.0f/1024.0f,
    		(float)needSize/1024.0f/1024.0f);
    
    	MakeField();
    
    	glGenBuffersARB(1, &m_nVBOIdx );							
    	glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_nVBOIdx);
    	glIndexPointer(1, GL_UNSIGNED_INT, NULL);//must null! 
    	glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,(m_idsz*sizeof(GLuint)), m_pIdx, GL_STATIC_DRAW_ARB );
    	//glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, m_idsz*sizeof(GLuint),  m_pIdx);
    
    	glGenBuffersARB(1, &m_nVBOTexCoords );		
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOTexCoords );	
    	glTexCoordPointer(2,GL_FLOAT,0, NULL);//must null!
    	glBufferDataARB(GL_ARRAY_BUFFER_ARB, (m_size*sizeof(CTexvert)),m_pTVert, GL_STATIC_DRAW_ARB );
    	//glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, m_size*sizeof(CVertex), m_pTVert);
    
    	glGenBuffersARB(1, &m_nVBONormals );							
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBONormals);
    	glNormalPointer(3, GL_FLOAT, NULL);//must null! 
    	glBufferDataARB(GL_ARRAY_BUFFER_ARB,(m_size*sizeof(CVertex)), m_pNorm, GL_STATIC_DRAW_ARB );
    	//glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, m_idsz*sizeof(GLuint),  m_pIdx);
    
    	glGenBuffersARB(1, &m_nVBOVertices );		
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices);		
    	glVertexPointer(3, GL_FLOAT, 0, NULL);//must null! 
    	glBufferDataARB(GL_ARRAY_BUFFER_ARB,(m_size*sizeof(CVertex)), m_pVert, GL_STATIC_DRAW_ARB );
    	//glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, m_size*sizeof(CVertex), m_pVert);
    
    	UpdateField();
    
        glBindTexture(GL_TEXTURE_2D,m_texid);			
    	gluBuild2DMipmaps(GL_TEXTURE_2D,(m_bpp>>3), m_width, m_height,m_bpp != 8?GL_BGR_EXT:GL_LUMINANCE,GL_UNSIGNED_BYTE,m_pMapMem);
    	//glTexSubImage2D(GL_TEXTURE_2D, 0,0,0, m_width, m_height,(m_bpp != 8?GL_BGR_EXT:GL_LUMINANCE),GL_UNSIGNED_BYTE,(GLvoid *)m_pMapMem);
    
    	return true;
    }
    


  • Gut, dann hast du eh schon in Create() alles gebunden. Dann sollte ein einfaches glDrawElements() allein schon ausreichen. glIndexPointer() hat trotzdem nichts mit den Indices bei glDrawElements() zu tun. Und GL_INDEX_ARRAY auch nicht. Und GL_TEXTURE_COORD_ARRAY hat auch nichts mit VBOs zu tun, sondern mit Multitexturing. Du brauchst also nur GL_VERTEX_ARRAY enablen und zwar bevor du irgendein gl*Pointer() aufrufst. Wobei du das binden und Pointer setzen wohl besser nochmal machen solltest, wenn dus inzwischen mal disablest. Und ja, du brauchst bei VBOs natürlich keine Pointer auf irgendwelche Arrays, weil du ja VBOs benutzt. Aber du musst trotzdem gl*Pointer() aufrufen, um OpenGL zu sagen, dass es die Daten aus einem VBO holen soll.

    EDIT: Allerdings sind deine VBOs alle voller 0en, warum du dich also wunderst, dass du nichts siehst, ist mir ziemlich schleierhaft.



  • Du wenn ich keine texturcoords übertragen würde, könnte ich auch
    nicht meine Bitmap in der scene sehen, da sie auf einem terrain
    gerendert wird. Der Array Pointer, den auf null zu stellen ist nicht falsch.

    würde ich über zeiger rendern, geht alles hier die Zeiger Version die genau so funktioniert , wie das gegenstück VBO (leider ohne Normale nur dort).

    void CTerrain::Render(void)
    {
    	glEnable(GL_TEXTURE_2D); 
    	glBindTexture(GL_TEXTURE_2D,m_texid);
    
    	glEnableClientState(GL_INDEX_ARRAY);
    	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    	glEnableClientState(GL_NORMAL_ARRAY);
    	glEnableClientState(GL_VERTEX_ARRAY);	
    
    	glVertexPointer(3, GL_FLOAT, 0, m_pVert); 
    	glNormalPointer(GL_FLOAT, 0, m_pNorm); 
    	glTexCoordPointer(2, GL_FLOAT, 0, m_pTVert); 
    	glDrawElements(GL_TRIANGLES,m_idsz, GL_UNSIGNED_INT, m_pIdx); 	 
    
    	glDisableClientState(GL_VERTEX_ARRAY);
    	glDisableClientState(GL_NORMAL_ARRAY);
    	glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    	glDisableClientState(GL_INDEX_ARRAY);
    
    	glDisable(GL_TEXTURE_2D); 
    }
    

    Wunderbar auch die Normale werden gerendert, alles gut, warum
    also nicht mit VBO normale rendern ?

    Du die Daten stimmen, die buffer sind nicht null da liegen welten drinne 🙂

    ich fummel mal weiter, da ist doch was faul...

    (was für pointer ich kann meinen speicher löschen, alles in der Grafikkarte)



  • Sry GL_TEXTURE_COORD_ARRAY ist natürlich schon richtig. Aber GL_INDEX_ARRAY ist sinnlos. Dass die Array-Pointer auf 0 zu stellen falsch wär, hab ich nie behauptet. Im Gegenteil, es ist, wie gesagt, sogar notwendig, damit OpenGL weiß, dass es die Daten aus dem VBO holen soll. So sollte es aussehen:

    void CTerrain::Render(void)
    {
      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, m_texid);
    
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      glEnableClientState(GL_NORMAL_ARRAY);
      glEnableClientState(GL_VERTEX_ARRAY);
    
      glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOTexCoords);
      glTexCoordPointer(2, GL_FLOAT, 0, 0);
    
      glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBONormals);
      glNormalPointer(GL_FLOAT, 0, 0);
    
      glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices);
      glVertexPointer(3, GL_FLOAT, 0, 0);
    
      glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_nVBOIdx);
    
      glDrawElements(GL_TRIANGLES, m_idsz, GL_UNSIGNED_INT, 0);
    
      glDisableClientState(GL_VERTEX_ARRAY);
      glDisableClientState(GL_NORMAL_ARRAY);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    
      glDisable(GL_TEXTURE_2D);
    }
    


  • verrückt so gehts.. nun muß mal kurz überlegen,

    du meinst das Index enable ist für Color Arrays ?

    omg



  • Karsten Schulz schrieb:

    du meinst das Index enable ist für Color Arrays ?

    Das mein ich nicht nur seit ein paar Posts, das ist genau so 😉



  • Ja vielen Dank, da wäre ich nun nicht drauf gekommen, weiß auch nicht warum ich drauf kam , wohl automatismus sah passend aus ^^

    Danke Dir !

    http://www.visiongrid.de/terrain.jpg


Anmelden zum Antworten