// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Grid.cpp
// Function: gaps::R3Grid::DrawSlice(int, int) const
void R3Grid::
DrawSlice(RNDimension dim, int coord) const
{
  // Check coordinates
  if ((dim < 0) || (dim > 2)) return;
  if ((coord < 0) || (coord >= Resolution(dim))) return;

  // Get useful variables
  RNDimension dim1 = (dim+1) % 3;
  RNDimension dim2 = (dim+2) % 3;
  int width = Resolution(dim1);
  int height = Resolution(dim2);
  const int max_resolution = 1024;
  if (width > max_resolution) width = max_resolution;
  if (height > max_resolution) height = max_resolution;

  // Define slice texture
  static const R3Grid *previous_grid[3] = { NULL, NULL, NULL };
  static int previous_coord[3] = { -1, -1, -1 };
  static GLuint texture_id[3] = { 0, 0, 0 };
  if ((this != previous_grid[dim]) || (coord != previous_coord[dim])) {
    if (texture_id[dim] != 0) glDeleteTextures(1, &texture_id[dim]);
    glGenTextures(1, &texture_id[dim]);
    glBindTexture(GL_TEXTURE_2D, texture_id[dim]);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    static GLfloat pixels[max_resolution * max_resolution];
    RNInterval range = Range();
    if (range.Diameter() <= 0) range = RNunit_interval;
    GLfloat *pixelsp = pixels;
    for (int j = 0; j < height; j++) {
      for (int i = 0; i < width; i++) {
        RNCoord p[3];
        p[dim] = coord;
        p[dim1] = (i+0.5) * Resolution(dim1) / width;
        p[dim2] = (j+0.5) * Resolution(dim2) / height;
        RNScalar value = GridValue(p[0], p[1], p[2]);
        *(pixelsp++) = (GLfloat) ((value - range.Min()) / range.Diameter());
      }
    }
    glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0, GL_LUMINANCE, GL_FLOAT, pixels);
    previous_coord[dim] = coord;
    previous_grid[dim] = this;
  }

  // Set OpenGL modes
  assert(texture_id[dim]);
  glBindTexture(GL_TEXTURE_2D, texture_id[dim]);
  glEnable(GL_TEXTURE_2D);

  // Create quad
  R3Point p0, p1, p2, p3;
  p0[dim] = coord; p0[dim1] = 0;                  p0[dim2] = 0;
  p1[dim] = coord; p1[dim1] = Resolution(dim1)-1; p1[dim2] = 0;
  p2[dim] = coord; p2[dim1] = Resolution(dim1)-1; p2[dim2] = Resolution(dim2)-1;
  p3[dim] = coord; p3[dim1] = 0;                  p3[dim2] = Resolution(dim2)-1;

  // Draw quad 
  RNScalar one = 1.0;
  RNScalar zero = 0;
  R3BeginPolygon();
  R3LoadTextureCoords(zero, zero);
  R3LoadPoint(p0[0], p0[1], p0[2]);
  R3LoadTextureCoords(one, zero);
  R3LoadPoint(p1[0], p1[1], p1[2]);
  R3LoadTextureCoords(one, one);
  R3LoadPoint(p2[0], p2[1], p2[2]);
  R3LoadTextureCoords(zero, one);
  R3LoadPoint(p3[0], p3[1], p3[2]);
  R3EndPolygon();

  // Reset OpenGL modes
  glDisable(GL_TEXTURE_2D);
}

// Assembly:
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdi, 0x1a0(%rsp)
movl %esi, 0x19c(%rsp)
movl %edx, 0x198(%rsp)
movq 0x1a0(%rsp), %rax
movq %rax, 0xc0(%rsp)
cmpl $0x0, 0x19c(%rsp)
jl 0x6ac31
cmpl $0x2, 0x19c(%rsp)
jle 0x6ac36
jmp 0x6b568
cmpl $0x0, 0x198(%rsp)
jl 0x6ac6f
movq 0xc0(%rsp), %rdi
movl 0x198(%rsp), %eax
movl %eax, 0xbc(%rsp)
movl 0x19c(%rsp), %esi
callq 0x6bdc0
movl %eax, %ecx
movl 0xbc(%rsp), %eax
cmpl %ecx, %eax
jl 0x6ac74
jmp 0x6b568
movq 0xc0(%rsp), %rdi
movl 0x19c(%rsp), %eax
addl $0x1, %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %edx, 0x194(%rsp)
movl 0x19c(%rsp), %eax
addl $0x2, %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %edx, 0x190(%rsp)
movl 0x194(%rsp), %esi
callq 0x6bdc0
movq 0xc0(%rsp), %rdi
movl %eax, 0x18c(%rsp)
movl 0x190(%rsp), %esi
callq 0x6bdc0
movl %eax, 0x188(%rsp)
movl $0x400, 0x184(%rsp) # imm = 0x400
cmpl $0x400, 0x18c(%rsp) # imm = 0x400
jle 0x6acff
movl $0x400, 0x18c(%rsp) # imm = 0x400
cmpl $0x400, 0x188(%rsp) # imm = 0x400
jle 0x6ad17
movl $0x400, 0x188(%rsp) # imm = 0x400
movq 0xc0(%rsp), %rax
movslq 0x19c(%rsp), %rdx
leaq 0x10e382(%rip), %rcx    # 0x1790b0
cmpq (%rcx,%rdx,8), %rax
jne 0x6ad53
movl 0x198(%rsp), %eax
movslq 0x19c(%rsp), %rdx
leaq 0x10912e(%rip), %rcx    # 0x173e78
cmpl (%rcx,%rdx,4), %eax
je 0x6b0e3
movslq 0x19c(%rsp), %rcx
leaq 0x10e366(%rip), %rax    # 0x1790c8
cmpl $0x0, (%rax,%rcx,4)
je 0x6ad88
movslq 0x19c(%rsp), %rax
leaq 0x10e351(%rip), %rsi    # 0x1790c8
shlq $0x2, %rax
addq %rax, %rsi
movl $0x1, %edi
callq 0xf6c0
movslq 0x19c(%rsp), %rax
leaq 0x10e331(%rip), %rsi    # 0x1790c8
shlq $0x2, %rax
addq %rax, %rsi
movl $0x1, %edi
callq 0xf6f0
movslq 0x19c(%rsp), %rcx
leaq 0x10e311(%rip), %rax    # 0x1790c8
movl (%rax,%rcx,4), %esi
movl $0xde1, %edi            # imm = 0xDE1
callq 0xf630
movl $0x2300, %edi           # imm = 0x2300
movl $0x2200, %esi           # imm = 0x2200
movl $0x2100, %edx           # imm = 0x2100
callq 0xf5a0
movl $0xde1, %edi            # imm = 0xDE1
movl $0x2802, %esi           # imm = 0x2802
movl $0x2900, %edx           # imm = 0x2900
callq 0xf6d0
movl $0xde1, %edi            # imm = 0xDE1
movl $0x2803, %esi           # imm = 0x2803
movl $0x2900, %edx           # imm = 0x2900
callq 0xf6d0
movl $0xde1, %edi            # imm = 0xDE1
movl $0x2801, %esi           # imm = 0x2801
movl $0x2601, %edx           # imm = 0x2601
callq 0xf6d0
movl $0xde1, %edi            # imm = 0xDE1
movl $0x2800, %esi           # imm = 0x2800
movl $0x2601, %edx           # imm = 0x2601
callq 0xf6d0
movq 0xc0(%rsp), %rsi
leaq 0x170(%rsp), %rdi
callq 0x56bc0
leaq 0x170(%rsp), %rdi
callq 0x6bf70
movaps %xmm0, %xmm1
xorps %xmm0, %xmm0
ucomisd %xmm1, %xmm0
jb 0x6ae74
leaq 0x5105f3(%rip), %rax    # 0x57b450
movq (%rax), %rcx
movq %rcx, 0x170(%rsp)
movq 0x8(%rax), %rax
movq %rax, 0x178(%rsp)
leaq 0x10e265(%rip), %rax    # 0x1790e0
movq %rax, 0x168(%rsp)
movl $0x0, 0x164(%rsp)
movl 0x164(%rsp), %eax
cmpl 0x188(%rsp), %eax
jge 0x6b070
movl $0x0, 0x160(%rsp)
movl 0x160(%rsp), %eax
cmpl 0x18c(%rsp), %eax
jge 0x6b058
movq 0xc0(%rsp), %rdi
cvtsi2sdl 0x198(%rsp), %xmm0
movslq 0x19c(%rsp), %rax
movsd %xmm0, 0x140(%rsp,%rax,8)
cvtsi2sdl 0x160(%rsp), %xmm0
movsd 0xc811c(%rip), %xmm1    # 0x133010
addsd %xmm1, %xmm0
movsd %xmm0, 0x98(%rsp)
movl 0x194(%rsp), %esi
callq 0x6bdc0
movsd 0x98(%rsp), %xmm0
movq 0xc0(%rsp), %rdi
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
cvtsi2sdl 0x18c(%rsp), %xmm1
divsd %xmm1, %xmm0
movslq 0x194(%rsp), %rax
movsd %xmm0, 0x140(%rsp,%rax,8)
cvtsi2sdl 0x164(%rsp), %xmm0
movsd 0xc80bb(%rip), %xmm1    # 0x133010
addsd %xmm1, %xmm0
movsd %xmm0, 0xa0(%rsp)
movl 0x190(%rsp), %esi
callq 0x6bdc0
movsd 0xa0(%rsp), %xmm0
movq 0xc0(%rsp), %rdi
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
cvtsi2sdl 0x188(%rsp), %xmm1
divsd %xmm1, %xmm0
movslq 0x190(%rsp), %rax
movsd %xmm0, 0x140(%rsp,%rax,8)
movsd 0x140(%rsp), %xmm0
movsd 0x148(%rsp), %xmm1
movsd 0x150(%rsp), %xmm2
callq 0x56e50
movsd %xmm0, 0x138(%rsp)
movsd 0x138(%rsp), %xmm0
movsd %xmm0, 0xa8(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x13960
movaps %xmm0, %xmm1
movsd 0xa8(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0xb0(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x6bf70
movaps %xmm0, %xmm1
movsd 0xb0(%rsp), %xmm0
divsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movq 0x168(%rsp), %rax
movq %rax, %rcx
addq $0x4, %rcx
movq %rcx, 0x168(%rsp)
movss %xmm0, (%rax)
movl 0x160(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x160(%rsp)
jmp 0x6aead
jmp 0x6b05a
movl 0x164(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x164(%rsp)
jmp 0x6ae8e
movl 0x18c(%rsp), %ecx
movl 0x188(%rsp), %r8d
movl $0xde1, %edi            # imm = 0xDE1
xorl %r9d, %r9d
movl $0x1, %edx
leaq 0x10e04d(%rip), %rax    # 0x1790e0
movl %r9d, %esi
movl $0x1909, (%rsp)         # imm = 0x1909
movl $0x1406, 0x8(%rsp)      # imm = 0x1406
movq %rax, 0x10(%rsp)
callq 0xf1c0
movq 0xc0(%rsp), %rdx
movl 0x198(%rsp), %esi
movslq 0x19c(%rsp), %rcx
leaq 0x108dab(%rip), %rax    # 0x173e78
movl %esi, (%rax,%rcx,4)
movslq 0x19c(%rsp), %rcx
leaq 0x10dfd1(%rip), %rax    # 0x1790b0
movq %rdx, (%rax,%rcx,8)
movslq 0x19c(%rsp), %rcx
leaq 0x10dfd6(%rip), %rax    # 0x1790c8
movl (%rax,%rcx,4), %esi
movl $0xde1, %edi            # imm = 0xDE1
callq 0xf630
movl $0xde1, %edi            # imm = 0xDE1
callq 0xf460
leaq 0x120(%rsp), %rdi
callq 0x6eb40
leaq 0x108(%rsp), %rdi
callq 0x6eb40
leaq 0xf0(%rsp), %rdi
callq 0x6eb40
leaq 0xd8(%rsp), %rdi
callq 0x6eb40
cvtsi2sdl 0x198(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movl 0x19c(%rsp), %esi
leaq 0x120(%rsp), %rdi
callq 0x36be0
movsd 0x18(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x194(%rsp), %esi
leaq 0x120(%rsp), %rdi
callq 0x36be0
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl 0x190(%rsp), %esi
leaq 0x120(%rsp), %rdi
callq 0x36be0
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
cvtsi2sdl 0x198(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movl 0x19c(%rsp), %esi
leaq 0x108(%rsp), %rdi
callq 0x36be0
movsd 0x20(%rsp), %xmm0
movq 0xc0(%rsp), %rdi
movsd %xmm0, (%rax)
movl 0x194(%rsp), %esi
callq 0x6bdc0
subl $0x1, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x28(%rsp)
movl 0x194(%rsp), %esi
leaq 0x108(%rsp), %rdi
callq 0x36be0
movsd 0x28(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x190(%rsp), %esi
leaq 0x108(%rsp), %rdi
callq 0x36be0
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
cvtsi2sdl 0x198(%rsp), %xmm0
movsd %xmm0, 0x30(%rsp)
movl 0x19c(%rsp), %esi
leaq 0xf0(%rsp), %rdi
callq 0x36be0
movsd 0x30(%rsp), %xmm0
movq 0xc0(%rsp), %rdi
movsd %xmm0, (%rax)
movl 0x194(%rsp), %esi
callq 0x6bdc0
subl $0x1, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x38(%rsp)
movl 0x194(%rsp), %esi
leaq 0xf0(%rsp), %rdi
callq 0x36be0
movsd 0x38(%rsp), %xmm0
movq 0xc0(%rsp), %rdi
movsd %xmm0, (%rax)
movl 0x190(%rsp), %esi
callq 0x6bdc0
subl $0x1, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x40(%rsp)
movl 0x190(%rsp), %esi
leaq 0xf0(%rsp), %rdi
callq 0x36be0
movsd 0x40(%rsp), %xmm0
movsd %xmm0, (%rax)
cvtsi2sdl 0x198(%rsp), %xmm0
movsd %xmm0, 0x48(%rsp)
movl 0x19c(%rsp), %esi
leaq 0xd8(%rsp), %rdi
callq 0x36be0
movsd 0x48(%rsp), %xmm0
movsd %xmm0, (%rax)
movl 0x194(%rsp), %esi
leaq 0xd8(%rsp), %rdi
callq 0x36be0
movq 0xc0(%rsp), %rdi
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl 0x190(%rsp), %esi
callq 0x6bdc0
subl $0x1, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x50(%rsp)
movl 0x190(%rsp), %esi
leaq 0xd8(%rsp), %rdi
callq 0x36be0
movsd 0x50(%rsp), %xmm0
movsd %xmm0, (%rax)
movsd 0xc7ca7(%rip), %xmm0    # 0x133008
movsd %xmm0, 0xd0(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0xc8(%rsp)
callq 0x38e90
movsd 0xc8(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm1
callq 0x6bf90
leaq 0x120(%rsp), %rdi
xorl %esi, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x58(%rsp)
leaq 0x120(%rsp), %rdi
movl $0x1, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x60(%rsp)
leaq 0x120(%rsp), %rdi
movl $0x2, %esi
callq 0x36be0
movsd 0x58(%rsp), %xmm0
movsd 0x60(%rsp), %xmm1
movsd (%rax), %xmm2
callq 0x6bfc0
movsd 0xd0(%rsp), %xmm0
movsd 0xc8(%rsp), %xmm1
callq 0x6bf90
leaq 0x108(%rsp), %rdi
xorl %esi, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x68(%rsp)
leaq 0x108(%rsp), %rdi
movl $0x1, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x70(%rsp)
leaq 0x108(%rsp), %rdi
movl $0x2, %esi
callq 0x36be0
movsd 0x68(%rsp), %xmm0
movsd 0x70(%rsp), %xmm1
movsd (%rax), %xmm2
callq 0x6bfc0
movsd 0xd0(%rsp), %xmm0
movsd 0xd0(%rsp), %xmm1
callq 0x6bf90
leaq 0xf0(%rsp), %rdi
xorl %esi, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x78(%rsp)
leaq 0xf0(%rsp), %rdi
movl $0x1, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x80(%rsp)
leaq 0xf0(%rsp), %rdi
movl $0x2, %esi
callq 0x36be0
movsd 0x78(%rsp), %xmm0
movsd 0x80(%rsp), %xmm1
movsd (%rax), %xmm2
callq 0x6bfc0
movsd 0xc8(%rsp), %xmm0
movsd 0xd0(%rsp), %xmm1
callq 0x6bf90
leaq 0xd8(%rsp), %rdi
xorl %esi, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x88(%rsp)
leaq 0xd8(%rsp), %rdi
movl $0x1, %esi
callq 0x36be0
movsd (%rax), %xmm0
movsd %xmm0, 0x90(%rsp)
leaq 0xd8(%rsp), %rdi
movl $0x2, %esi
callq 0x36be0
movsd 0x88(%rsp), %xmm0
movsd 0x90(%rsp), %xmm1
movsd (%rax), %xmm2
callq 0x6bfc0
callq 0x38ec0
movl $0xde1, %edi            # imm = 0xDE1
callq 0xf150
addq $0x1a8, %rsp            # imm = 0x1A8
retq