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