// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3TriangleArray.cpp
// Function: gaps::R3TriangleArray::UpdateVBO()
void R3TriangleArray::
UpdateVBO(void)
{
#if (RN_3D_GRFX == RN_OPENGL)
  // Check if VBO is uptodate
  if (vbo_size > 0) return;
  
  // Check triangle array
  if (NVertices() == 0) return;
  if (NTriangles() == 0) return;

  // Allocate buffer data
  static const unsigned int vertex_size = 12 * sizeof(GLfloat);
  unsigned int buffer_size = 3 * NTriangles() * vertex_size;
  GLfloat *buffer_data = new GLfloat [ buffer_size ];
  if (!buffer_data) return;
  
  // Fill vertex data 
  GLfloat *buffer_datap = buffer_data;
  for (int i = 0; i < NTriangles(); i++) {
    R3Triangle *triangle = Triangle(i);
    int dim = triangle->Normal().MaxDimension();
    int dim1 = (dim + 1) % 3;
    int dim2 = (dim + 2) % 3;
    for (int j = 0; j < 3; j++) {
      R3TriangleVertex *vertex = triangle->Vertex(j);

      // Load position
      *(buffer_datap++) = vertex->Position().X();
      *(buffer_datap++) = vertex->Position().Y();
      *(buffer_datap++) = vertex->Position().Z();

      // Load normal
      if (triangle->HasNormals() && vertex->HasNormal()) {
        R3Vector normal = vertex->Normal();
        RNScalar dot = normal.Dot(triangle->Normal());
        if (dot < -0.25) normal = -normal;
        else if (dot < 0.25) normal = triangle->Normal();
        *(buffer_datap++) = normal.X();
        *(buffer_datap++) = normal.Y();
        *(buffer_datap++) = normal.Z();
      }
      else {
        *(buffer_datap++) = triangle->Normal().X();
        *(buffer_datap++) = triangle->Normal().Y();
        *(buffer_datap++) = triangle->Normal().Z();
      }

      // Load color      
      if (triangle->HasColors() && vertex->HasColor()) {
        *(buffer_datap++) = vertex->Color().R();
        *(buffer_datap++) = vertex->Color().G();
        *(buffer_datap++) = vertex->Color().B();
      }
      else {
        *(buffer_datap++) = 0.5;
        *(buffer_datap++) = 0.5;
        *(buffer_datap++) = 0.5;
      }

      // Load texture coordinates
      if (triangle->HasTextureCoords() && vertex->HasTextureCoords()) {
        *(buffer_datap++) = vertex->TextureCoords().X();
        *(buffer_datap++) = vertex->TextureCoords().Y();
        *(buffer_datap++) = 0;
      }
      else {
        *(buffer_datap++) = vertex->Position()[dim1];
        *(buffer_datap++) = vertex->Position()[dim2];
        *(buffer_datap++) = 0;
      }
    }
  }

  // Just checking
  assert((long int) (buffer_datap - buffer_data) == (long int) (buffer_size / sizeof(GLfloat)));

  // Generate VBO buffer (first time only)
  if (vbo_id == 0) glGenBuffers(1, &vbo_id);

  // Load VBO buffer
  if (vbo_id && buffer_data && buffer_size) {
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
    glBufferData(GL_ARRAY_BUFFER, buffer_size, buffer_data, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    vbo_size = buffer_size;
  }

  // Delete in-memory data
  if (buffer_data) delete [] buffer_data;
#endif
}

// Assembly:
cmpl $0x0, 0x6c(%rdi)
jne 0x53276
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdi, %r15
cmpl $0x0, 0x14(%rdi)
je 0x53268
movl 0x24(%r15), %ebx
testl %ebx, %ebx
je 0x53268
movl %ebx, %eax
shll $0x4, %eax
leal (%rax,%rax,8), %eax
movq %rax, 0x10(%rsp)
leaq (,%rax,4), %rdi
callq 0xe030
movq %rax, 0x8(%rsp)
testl %ebx, %ebx
jle 0x531f3
xorl %ecx, %ecx
movq 0x8(%rsp), %r14
movq %r15, 0x18(%rsp)
movq 0x18(%r15), %rax
movq %rcx, 0x20(%rsp)
movq (%rax,%rcx,8), %rbx
leaq 0x20(%rbx), %r15
movq %r15, %rdi
callq 0x3d14e
leaq 0x40(%rsp), %r13
movsd 0x56164(%rip), %xmm1    # 0xa9160
leal 0x1(%rax), %ecx
movslq %ecx, %rcx
imulq $0x55555556, %rcx, %rcx # imm = 0x55555556
movq %rcx, %rdx
shrq $0x3f, %rdx
shrq $0x20, %rcx
addl %edx, %ecx
leal (%rcx,%rcx,2), %ecx
negl %ecx
addl %eax, %ecx
incl %ecx
movl %eax, %edx
addl $0x2, %edx
movslq %edx, %rdx
imulq $0x55555556, %rdx, %rdx # imm = 0x55555556
movq %rdx, %rsi
shrq $0x3f, %rsi
shrq $0x20, %rdx
addl %esi, %edx
leal (%rdx,%rdx,2), %edx
negl %edx
addl %edx, %eax
addl $0x2, %eax
movslq %ecx, %rcx
movslq %eax, %rdx
movq 0x78(%rbx), %rax
movl $0x1, %r12d
movq %r15, 0x28(%rsp)
movq %rcx, 0x38(%rsp)
movq %rdx, 0x30(%rsp)
movq (%rbx,%r12,8), %rbp
movupd (%rbp), %xmm0
cvtpd2ps %xmm0, %xmm0
movlpd %xmm0, (%r14)
xorps %xmm0, %xmm0
cvtsd2ss 0x10(%rbp), %xmm0
movss %xmm0, 0x8(%r14)
btl $0x8, %eax
jae 0x53090
testb $0x1, 0x59(%rbp)
jne 0x530b2
movupd 0x20(%rbx), %xmm0
cvtpd2ps %xmm0, %xmm0
movlpd %xmm0, 0xc(%r14)
xorps %xmm0, %xmm0
cvtsd2ss 0x30(%rbx), %xmm0
movss %xmm0, 0x14(%r14)
jmp 0x53145
leaq 0x18(%rbp), %rsi
movq %r13, %rdi
callq 0x3cfd6
movq %r13, %rdi
movq %r15, %rsi
callq 0x3d252
movsd 0x55dbf(%rip), %xmm1    # 0xa8e90
ucomisd %xmm0, %xmm1
jbe 0x530f4
leaq 0x60(%rsp), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x3dc00
movq %r13, %rdi
movq %r15, %rsi
movq 0x28(%rsp), %r15
jmp 0x5310a
movsd 0x4fcb4(%rip), %xmm1    # 0xa2db0
ucomisd %xmm0, %xmm1
jbe 0x5310f
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x3d752
cvtpd2ps 0x40(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtsd2ss 0x50(%rsp), %xmm1
movlpd %xmm0, 0xc(%r14)
movss %xmm1, 0x14(%r14)
movq 0x78(%rbx), %rax
movsd 0x5602a(%rip), %xmm1    # 0xa9160
leaq 0x40(%rsp), %r13
movq 0x38(%rsp), %rcx
movq 0x30(%rsp), %rdx
btl $0xa, %eax
jae 0x53151
testb $0x4, 0x59(%rbp)
jne 0x53161
movsd %xmm1, 0x18(%r14)
movl $0x3f000000, 0x20(%r14) # imm = 0x3F000000
jmp 0x5317e
movupd 0x30(%rbp), %xmm0
cvtpd2ps %xmm0, %xmm0
movlpd %xmm0, 0x18(%r14)
xorps %xmm0, %xmm0
cvtsd2ss 0x40(%rbp), %xmm0
movss %xmm0, 0x20(%r14)
btl $0x9, %eax
jae 0x5318a
testb $0x2, 0x59(%rbp)
jne 0x531a0
xorps %xmm0, %xmm0
cvtsd2ss (%rbp,%rcx,8), %xmm0
movss %xmm0, 0x24(%r14)
leaq (%rbp,%rdx,8), %rbp
jmp 0x531b2
xorps %xmm0, %xmm0
cvtsd2ss 0x48(%rbp), %xmm0
movss %xmm0, 0x24(%r14)
addq $0x50, %rbp
xorps %xmm0, %xmm0
cvtsd2ss (%rbp), %xmm0
movss %xmm0, 0x28(%r14)
movl $0x0, 0x2c(%r14)
addq $0x30, %r14
incq %r12
cmpq $0x4, %r12
jne 0x53064
movq 0x20(%rsp), %rcx
incq %rcx
movq 0x18(%rsp), %r15
movslq 0x24(%r15), %rax
cmpq %rax, %rcx
jl 0x52fd6
movl 0x68(%r15), %esi
testl %esi, %esi
jne 0x53214
leaq 0x68(%r15), %r12
movq 0x91d82(%rip), %rax     # 0xe4f88
movl $0x1, %edi
movq %r12, %rsi
callq *(%rax)
movl (%r12), %esi
testl %esi, %esi
sete %al
movq 0x10(%rsp), %r14
testl %r14d, %r14d
sete %cl
orb %al, %cl
jne 0x5325e
movq 0x91d79(%rip), %rbx     # 0xe4fa8
movl $0x8892, %edi           # imm = 0x8892
callq *(%rbx)
movq 0x91d83(%rip), %rax     # 0xe4fc0
movl $0x8892, %edi           # imm = 0x8892
movq %r14, %rsi
movq 0x8(%rsp), %rdx
movl $0x88e4, %ecx           # imm = 0x88E4
callq *(%rax)
movl $0x8892, %edi           # imm = 0x8892
xorl %esi, %esi
callq *(%rbx)
movl %r14d, 0x6c(%r15)
movq 0x8(%rsp), %rdi
callq 0xe5b0
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop