Source

kinect-viewer / KVRenderer.m

Cliff Biffle 0351b52 


















Cliff Biffle 0ea4300 
Cliff Biffle 0351b52 






Cliff Biffle 0ea4300 
Cliff Biffle 0351b52 














Cliff Biffle 0ea4300 




Cliff Biffle 0351b52 
















Cliff Biffle 8c83874 




Cliff Biffle 0351b52 









Cliff Biffle 8c83874 
Cliff Biffle 0351b52 




















Cliff Biffle e529285 
Cliff Biffle 0351b52 


Cliff Biffle 0ea4300 



Cliff Biffle 9aeccac 
Cliff Biffle 0351b52 




































Cliff Biffle 27fef0a 

Cliff Biffle 82cb6cd 
Cliff Biffle 0351b52 



/*
 * Copyright 2010 Cliff L. Biffle.  All Rights Reserved.
 * Use of this source code is governed by the Apache License 2.0,
 * which can be found in the LICENSE file.
 */

#import "KVRenderer.h"
#import "utility.h"

@interface KVRenderer ()
- (void) fillStaticComponents;

@property(assign, nonatomic) double rayCastingTotal;
@property(assign, nonatomic) NSUInteger rayCastingCount;

@property(assign, nonatomic) double vertexPlacementTotal;
@property(assign, nonatomic) NSUInteger vertexPlacementCount;

@property GLuint depthTexture;
@property GLuint colorTexture;

- (void) renderAsPointsWithOptions: (NSDictionary *) options;
@end

@implementation KVRenderer

@synthesize rayCastingCount, rayCastingTotal, vertexPlacementCount, vertexPlacementTotal;
@synthesize depthTexture, colorTexture;

- init {
  if ((self = [super init])) {
    [self fillStaticComponents];
  }
  return self;
}

#pragma mark --- Implementation of KVSpaceModel

- (void) initGL {
  glGenTextures(1, &depthTexture);
  glBindTexture(GL_TEXTURE_2D, depthTexture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  glGenTextures(1, &colorTexture);
  glBindTexture(GL_TEXTURE_2D, colorTexture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

- (void) setDepthSamples: (NSData *)data {
  NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
  
  const uint16_t *sample = [data bytes];
  memcpy(&depthImage, sample, sizeof depthImage);
  
  // gcc 4.2.1 is not clever enough to turn raster two-dimensional
  // subscripting (e.g. ray[y][x]) into a single incremented induction
  // variable -- we wind up doing integer multiplications on every
  // use!  So, we do it by hand: thus |vidx|.
  int vidx = 0;
  
  // Cast them rays
  for (int y = 0; y < 480 - 1; y++) {
    for (int x = 0; x < 640 - 1; x++, vidx++) {
      vec3f_t here = {
        rays[vidx].x,
        rays[vidx].y,
        sample[vidx],
      };
      vec3f_t right = {
        rays[vidx + 1].x,
        rays[vidx + 1].y,
        sample[vidx + 1],
      };
      vec3f_t down = {
        rays[vidx + 640].x,
        rays[vidx + 640].y,
        sample[vidx + 640],
      };
      normals[vidx] = compute_normal(here, down, right);
    }
  }
  
  NSTimeInterval end = [NSDate timeIntervalSinceReferenceDate];
  rayCastingCount++;
  rayCastingTotal += end - start;
  
  if ((rayCastingCount & 0xF) == 0) {
    NSLog(@"Raycasting: latest %.03fµs mean %.03fµs",
          (end - start) * 1000000.,
          (rayCastingTotal / rayCastingCount) * 1000000.);
  }
}

- (void) setColorSamples: (NSData *)data {
  memcpy(&colorImage, [data bytes], sizeof colorImage);
}

- (void) drawInCurrentOpenGLContextWithOptions: (NSDictionary *) options {
  NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];

  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, depthTexture);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, 640, 480, 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, &depthImage);
  
  glActiveTexture(GL_TEXTURE1);
  glBindTexture(GL_TEXTURE_2D, colorTexture);
  glTexImage2D(GL_TEXTURE_2D, 0, 3, 640, 480, 0, GL_RGB, GL_UNSIGNED_BYTE, &colorImage);
  
  [self renderAsPointsWithOptions: options];
  
  NSTimeInterval end = [NSDate timeIntervalSinceReferenceDate];
  vertexPlacementCount++;
  vertexPlacementTotal += end - start;
  
  if ((vertexPlacementCount & 0xF) == 0) {
    NSLog(@"Vertex placement: latest %.03fµs mean %.03fµs",
          (end - start) * 1000000.,
          (vertexPlacementTotal / vertexPlacementCount) * 1000000.);
  }
  
}

#pragma mark --- Internals

- (void) renderAsPointsWithOptions: (NSDictionary *) options {
  glColor3f(1, 1, 1);
  glNormal3f(0, 0, -1);
  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3, GL_FLOAT, 0, &rays);

  glEnableClientState(GL_NORMAL_ARRAY);
  glNormalPointer(GL_FLOAT, 0, &normals);
  
  glDrawArrays(GL_POINTS, 0, 640 * 480);
  
  glDisableClientState(GL_NORMAL_ARRAY);
  glDisableClientState(GL_VERTEX_ARRAY);
}

// We pre-fill the X and Y components with distance from the center of
// the image.  These values never make it to the rasterizer: they are
// merely input to the vertex shader that performs perspective correction.
- (void) fillStaticComponents {
  int vidx = 0;
  for (int y = 0; y < 480; y++) {
    for (int x = 0; x < 640; x++, vidx++) {
      rays[vidx].x = (x / 640.f);
      rays[vidx].y = (y / 480.f);
      rays[vidx].z = 4;
    }
  }
}

@end