heightmap via normals beleuchten:



  • Am besten Du machst mal 'nen Screenshot...



  • ich weis nicht ob das so sein muss oder nicht, aber es muss doch ne möglichkeit geben, weichere übergänge zu schaffen: das ist der code bei stepsize = 2; es sieht nicht groß anders aus, als wenn ich mit der geposteten funktion von oben die normals pro quad mit lediglich 3 punkten berechne.

    http://img76.imageshack.us/img76/5161/bildschirmphoto9xt2.th.png
    http://img399.imageshack.us/img399/6480/bildschirmphoto10tg5.th.png

    void Map::drawMap(int iStepSize, bool bRenderQuads)
    {
    	if(!bHMapLoaded)
    		return;
    
    	// Lichter setzen
    	if(bStaticLightsLoaded) {
    		glLightfv(GL_LIGHT1, GL_AMBIENT, fLightAmbient);
    		glLightfv(GL_LIGHT1, GL_DIFFUSE, fLightDiffuse);
    		glLightfv(GL_LIGHT1, GL_POSITION,fLightPosition);
    		glEnable(GL_LIGHT1);
    	}
    
    	float x, y, z;
    	GLint w, h;
    
            st3KOVec svP1, svP2, svP3, svP4;
            st3KOVec svNorm;
    // 	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    	for ( int Y = 0; Y < (iLengthMap-iStepSize); Y += iStepSize ) {
    		for ( int X = 0; X < (iWidthMap-iStepSize); X += iStepSize )
    		{
    			// wenn Textur initialisiert wurde ^_^ sonst würdes abstürzen
    			if(gHMapTextures[Y][X] > 0) {
    				glBindTexture(GL_TEXTURE_2D, gHMapTextures[Y][X]);
    // 				glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
    // 				glGetTexLevelParameteriv (GL_TEXTURE_2D, 0,GL_TEXTURE_HEIGHT, &h);
    			}
    
                            // Punkte der Fläche berechnen:
                            // Get The (X, Y, Z) Value For The Bottom Left Vertex
                            svP1.x = X; svP1.y = fHeightMap[Y][X]; svP1.z = -Y;
                            // Get The (X, Y, Z) Value For The Top Left Vertex
                            svP2.x = X; svP2.y = fHeightMap[Y+iStepSize][X]; svP2.z = -Y - iStepSize; 
                            // Get The (X, Y, Z) Value For The Top Right Vertex
                            svP3.x = X + iStepSize; svP3.y = fHeightMap[Y+iStepSize][X+iStepSize]; svP3.z = -Y - iStepSize; 
                            // Get The (X, Y, Z) Value For The Bottom Right Vertex
                            svP4.x = X + iStepSize; svP4.y = fHeightMap[Y][X+iStepSize]; svP4.z = -Y;
    
                            // Normals berechnen und festsetzen
                            svNorm = CalcNormalInQuad(svP1, svP2, svP3, svP4);
    //                         svNorm = CalcNormal(svP1, svP2, svP3);
                            glNormal3f(svNorm.x, svNorm.y, svNorm.z);
    
                            if(bRenderQuads)               // What We Want To Render
                                     glBegin( GL_QUADS );  // Render Polygons
                            else 
                                     glBegin( GL_LINE_LOOP );  // Render Lines Instead
    			// Get The (X, Y, Z) Value For The Bottom Left Vertex
    			if(gHMapTextures[Y][X] > 0) glTexCoord2f(0.0f, 1.0f); glVertex3i(svP1.x, svP1.y, svP1.z);// Send This Vertex To OpenGL To Be Rendered
    			// Get The (X, Y, Z) Value For The Top Left Vertex
    			if(gHMapTextures[Y][X] > 0) glTexCoord2f(0.0f, 0.0f); glVertex3i(svP2.x, svP2.y, svP2.z);// Send This Vertex To OpenGL To Be Rendered
    			// Get The (X, Y, Z) Value For The Top Right Vertex
    			if(gHMapTextures[Y][X] > 0) glTexCoord2f(1.0f, 0.0f); glVertex3i(svP3.x, svP3.y, svP3.z);// Send This Vertex To OpenGL To Be Rendered
    			// Get The (X, Y, Z) Value For The Bottom Right Vertex
    			if(gHMapTextures[Y][X] > 0) glTexCoord2f(1.0f, 1.0f); glVertex3i(svP4.x, svP4.y, svP4.z);// Send This Vertex To OpenGL To Be Rendered
    
    	                glEnd();
    		}
    	}
    
    	// Zeichne nun die Modelle
    	for(int i = 0; i < vStaticModels.size(); i++)
    		vStaticModels.at(i)->draw();
    
    	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);// reset the color to white
    }
    

  • Mod

    eventuell

    glShadeModel
    mit
    gl_smooth
    😉



  • int display::initGL()
    {
    	glViewport(0, 0, screenWidth, screenHeight);
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);		// This Will Clear The Background Color To Black
    	glClearDepth(1.0);				// Enables Clearing Of The Depth Buffer
    	glDepthFunc(GL_LESS);				// The Type Of Depth Test To Do
    
    	glShadeModel(GL_SMOOTH);			// Enables Smooth Color Shading
    
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();				// Reset The Projection Matrix
    
    	gluPerspective(45.0f,(GLfloat)screenWidth/(GLfloat)screenHeight,0.1f,5000.0f);	// Calculate The Aspect Ratio Of The Window
    
    	glMatrixMode(GL_MODELVIEW);
    
    	glEnable(GL_VERTEX_ARRAY);
    	glEnable(GL_DEPTH_TEST);			// Enables Depth Testing
    	glEnable(GL_TEXTURE_2D);			// Enable Texture Mapping
    	glEnable(GL_TEXTURE_COORD_ARRAY);
    	glEnable(GL_LIGHTING);
    
    	return 1;
    }
    


  • Du musst jedem Eckpunkt eine eigene Normale mitgeben anstatt eine einzige pro Polygon zu setzen.


  • Mod

    du nimmst die 4punkte die ein quad aufziehen und berechnest fuer sie eine normale. entsprechend hast du pro face eine normale.
    alternative waere die 4 nachbarpunkte von einem vertex zu nehmen und daraus die normale zu mitteln.

    also statt

    +-+
    | |
    +-+
    

    eher

    +
      |
    +-+-+
      |
      +
    


  • Das was auf den Bildern zu sehen ist, sieht aus wie flat Schading 😉
    Ich habe jetzt nicht die andere Antworten gelsesen und es kann sein , das dies schon gesagt wurde. Es ist wichtig, das du für jeden Vertex eine Normale berechnest(und mit angibst), diese wiederum möglichst als Mittelwert von den benachbarten Normalen.



  • also, ich habe jetzt eine funktion gemacht die nun die normalen berechnet, ich hoffe das die nun richtig ist:

    (die inline funktionen habe ich auch angepasst)
    die normals in ein array zu packen hat auch den vorteil, dass es schneller ist, weil die nicht jedesmal neu berechnet werden müssen, wenn was gemalt werden soll. ist viel schneller als vorher!!!

    void Map::calcNormals(int iStepSize) {
       st3KOVec svPup, svPdown, svPleft, svPright, svPcenter;
       st3KOVec result;
       for ( int Y = iStepSize; Y < (iLengthMap-iStepSize); Y += iStepSize ) {
          for ( int X = iStepSize; X < (iWidthMap-iStepSize); X += iStepSize )
          {
             // Punkte der Fläche berechnen:
             svPcenter.x = X; svPcenter.y = fHeightMap[Y][X]; svPcenter.z = -Y;
             svPup.x = X; svPup.y = fHeightMap[Y+iStepSize][X]; svPup.z = -Y - iStepSize; 
             svPdown.x = X; svPdown.y = fHeightMap[Y-iStepSize][X]; svPdown.z = -Y + iStepSize; 
             svPleft.x = X - iStepSize; svPleft.y = fHeightMap[Y][X-iStepSize]; svPleft.z = -Y;
             svPright.x = X + iStepSize; svPright.y = fHeightMap[Y][X+iStepSize]; svPright.z = -Y;
    
             result = CalcNormalInQuad(svPright, svPleft, svPup, svPdown, svPcenter);
             vNormals[Y][X] = result;
          }
       }
    }
    

    aber die beleuchtung scheint realistischer zu sein!!! aber leider kriege ich kein smooth shading hin, kurios.



  • Tust Du so?

    glBegin(GL_QUADS);
    
                glTexCoord2f(0.0f, 1.0f);
                glNormal3f( ... );
                glVertex3i(svP1.x, svP1.y, svP1.z);
    
                glTexCoord2f(0.0f, 0.0f);
                glNormal3f( ... );
                glVertex3i(svP2.x, svP2.y, svP2.z);
    
                glTexCoord2f(1.0f, 0.0f);
                glNormal3f( ... );
                glVertex3i(svP3.x, svP3.y, svP3.z);
    
                glTexCoord2f(1.0f, 1.0f); 
                glNormal3f( ... );
                glVertex3i(svP4.x, svP4.y, svP4.z);
    
                glEnd();
    


  • hast recht, habs endlich geschafft


Anmelden zum Antworten