| 679 | 5. Calculate vertex normals by averaging nearby faces normals that are calculated with |
| 680 | [http://www.opengl.org/wiki/Calculating_a_Surface_Normal cross product]. We need to add normal array |
| 681 | as a global variable |
| 682 | {{{ |
| 683 | #!c |
| 684 | float normal[MaxVertices*3]; |
| 685 | }}} |
| 686 | and add [http://www.opengl.org/sdk/docs/man2/xhtml/glNormalPointer.xml glNormalPointer] with [http://www.opengl.org/sdk/docs/man2/xhtml/glEnableClientState.xml glEnableClientState(GL_NORMAL_ARRAY)] to the last part of `display()` that now reads: |
| 687 | {{{ |
| 688 | #!c |
| 689 | //glutSolidTeapot(0.6); |
| 690 | glNormalPointer(GL_FLOAT, 0, normal); |
| 691 | glVertexPointer(3, GL_FLOAT, 0, vertex); |
| 692 | glEnableClientState(GL_VERTEX_ARRAY); |
| 693 | glEnableClientState(GL_NORMAL_ARRAY); |
| 694 | glDrawElements(GL_TRIANGLES, faces*3, GL_UNSIGNED_INT, face); |
| 695 | glDisableClientState(GL_VERTEX_ARRAY); |
| 696 | glDisableClientState(GL_NORMAL_ARRAY); |
| 697 | }}} |
| 698 | For calculation of normals we quickly invent the following subroutine: |
| 699 | [[Image(motorbike-shadow.png,right)]] |
| 700 | {{{ |
| 701 | #!c |
| 702 | void calculate_normals() |
| 703 | { |
| 704 | int i; |
| 705 | for(i = 0; i < vertices*3; ++i) |
| 706 | normal[i] = 0.0; |
| 707 | for(i = 0; i < faces; ++i) |
| 708 | { |
| 709 | int p1 = face[i*3]*3; |
| 710 | int p2 = face[i*3+1]*3; |
| 711 | int p3 = face[i*3+2]*3; |
| 712 | float ux = vertex[p3]-vertex[p1]; |
| 713 | float uy = vertex[p3+1]-vertex[p1+1]; |
| 714 | float uz = vertex[p3+2]-vertex[p1+2]; |
| 715 | float vx = vertex[p2]-vertex[p1]; |
| 716 | float vy = vertex[p2+1]-vertex[p1+1]; |
| 717 | float vz = vertex[p2+2]-vertex[p1+2]; |
| 718 | float nx = uy*vz - uz*vy; |
| 719 | float ny = uz*vx - ux*vz; |
| 720 | float nz = ux*vy - uy*vx; |
| 721 | float length = sqrt(nx*nx+ny*ny+nz*nz); |
| 722 | normal[p1] += nx/length; |
| 723 | normal[p1+1] += ny/length; |
| 724 | normal[p1+2] += nz/length; |
| 725 | normal[p2] += nx/length; |
| 726 | normal[p2+1] += ny/length; |
| 727 | normal[p2+2] += nz/length; |
| 728 | normal[p3] += nx/length; |
| 729 | normal[p3+1] += ny/length; |
| 730 | normal[p3+2] += nz/length; |
| 731 | } |
| 732 | } |
| 733 | }}} |
| 734 | called in `main()` right after `read_wavefront("motorBike.obj");`. Now mistery occurs with garbled part of motorbike. Where the problem is? Possible suggestions: pointer problems, normal calculation, OpenGL bug, shader, data, ... Hint: Observe number of triangles versus number of vertices. |