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.pngvoid 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 }
-
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.
-
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