| 619 | // *********************************************************************** |
| 620 | |
| 621 | void EndObject3D() { |
| 622 | if (pRenderState->mode == ERenderMode::None) // TODO Call errors when this is incorrect |
| 623 | return; |
| 624 | |
| 625 | DrawCommand cmd; |
| 626 | |
| 627 | i32 numIndices; |
| 628 | cmd.type = pRenderState->typeState; |
| 629 | cmd.cullMode = pRenderState->cullMode; |
| 630 | bool buffersFilled = false; |
| 631 | switch (pRenderState->typeState) { |
| 632 | case EPrimitiveType::Points: |
| 633 | case EPrimitiveType::Lines: |
| 634 | case EPrimitiveType::LineStrip: |
| 635 | break; |
| 636 | case EPrimitiveType::Triangles: { |
| 637 | if (pRenderState->normalsModeState == ENormalsMode::Flat) { |
| 638 | for (i64 i = 0; i < pRenderState->vertexState.count; i += 3) { |
| 639 | Vec3f v1 = pRenderState->vertexState[i + 1].pos - pRenderState->vertexState[i].pos; |
| 640 | Vec3f v2 = pRenderState->vertexState[i + 2].pos - pRenderState->vertexState[i].pos; |
| 641 | Vec3f faceNormal = Vec3f::Cross(v1, v2).GetNormalized(); |
| 642 | |
| 643 | pRenderState->vertexState[i].norm = faceNormal; |
| 644 | pRenderState->vertexState[i + 1].norm = faceNormal; |
| 645 | pRenderState->vertexState[i + 2].norm = faceNormal; |
| 646 | } |
| 647 | |
| 648 | u32 numVertices = (u32)pRenderState->vertexState.count; |
| 649 | VertexData* pDestBuffer = pRenderState->perFrameVertexBuffer.pData + pRenderState->perFrameVertexBuffer.count; |
| 650 | if (pRenderState->perFrameVertexBuffer.count + numVertices > MAX_VERTICES_PER_FRAME) |
| 651 | return; |
| 652 | memcpy(pDestBuffer, pRenderState->vertexState.pData, numVertices * sizeof(VertexData)); |
| 653 | |
| 654 | cmd.vertexBufferOffset = (i32)pRenderState->perFrameVertexBuffer.count * sizeof(VertexData); |
| 655 | cmd.numElements = numVertices; |
| 656 | pRenderState->perFrameVertexBuffer.count += numVertices; |
| 657 | buffersFilled = true; |
| 658 | } else if (pRenderState->normalsModeState == ENormalsMode::Smooth) { |
| 659 | // the purpose of this is to make same vertices share the same normal vector that gets averaged from the nearby polygons |
| 660 | // Convert to indexed list, loop through, saving verts into vector, each new one you search for in vector, if you find it, save index in index list. |
| 661 | |
| 662 | ResizableArray<VertexData> uniqueVerts(g_pArenaFrame); |
| 663 | ResizableArray<u16> indices(g_pArenaFrame); |
| 664 | for (i64 i = 0; i < pRenderState->vertexState.count; i++) { |
| 665 | VertexData* pVertData = uniqueVerts.Find(pRenderState->vertexState[i]); |
| 666 | if (pVertData == uniqueVerts.end()) { |
| 667 | // New vertex |
| 668 | uniqueVerts.PushBack(pRenderState->vertexState[i]); |
| 669 | indices.PushBack((u16)uniqueVerts.count - 1); |
| 670 | } else { |
| 671 | indices.PushBack((u16)uniqueVerts.IndexFromPointer(pVertData)); |
| 672 | } |
| 673 | } |
| 674 | |
| 675 | // Then run your flat shading algo on the list of vertices looping through index list. If you have a new normal for a vert, then average with the existing one |
| 676 | for (i64 i = 0; i < indices.count; i += 3) { |
| 677 | Vec3f v1 = uniqueVerts[indices[i + 1]].pos - uniqueVerts[indices[i]].pos; |
| 678 | Vec3f v2 = uniqueVerts[indices[i + 2]].pos - uniqueVerts[indices[i]].pos; |
no outgoing calls
no test coverage detected