├── .gitignore ├── img └── cornell_box_0001.png ├── cuda ├── CMakeLists.txt ├── FindOptiX.cmake ├── FindCUDA.cmake ├── ptx.cmake ├── random.cuh └── pathtracer.cu ├── Cargo.toml ├── README.md ├── src ├── gl_util.rs └── main.rs └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | -------------------------------------------------------------------------------- /img/cornell_box_0001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anderslanglands/optix-rs-pathtracer-example/master/img/cornell_box_0001.png -------------------------------------------------------------------------------- /cuda/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | project(optix-rs) 3 | 4 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) 5 | find_package(OptiX) 6 | find_package(CUDA) 7 | include(ptx) 8 | 9 | compile_optix_ptx(pathtracer.cu) 10 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | cargo-features = ["edition"] 2 | 3 | [package] 4 | name = "optix-pathtracer-example" 5 | version = "0.1.0" 6 | authors = ["Anders Langlands "] 7 | edition = "2018" 8 | 9 | [dependencies] 10 | optix = "0.1" 11 | config = "0.9" 12 | gl = "0.10" 13 | glfw = "0.23" 14 | crossbeam-channel = "0.2" 15 | 16 | [build-dependencies] 17 | config= "0.9" 18 | cmake = "0.1" -------------------------------------------------------------------------------- /cuda/FindOptiX.cmake: -------------------------------------------------------------------------------- 1 | include(FindPackageHandleStandardArgs) 2 | message("Trying to find OptiX at OPTIX_ROOT: $ENV{OPTIX_ROOT}") 3 | 4 | find_path(OptiX_INCLUDE_DIR 5 | NAMES optix.h 6 | PATHS ${OPTIX_ROOT}/include $ENV{OPTIX_ROOT}/include) 7 | 8 | find_library(OptiX_optix_LIBRARY 9 | NAMES optix 10 | PATHS ${OPTIX_ROOT}/lib64 $ENV{OPTIX_ROOT}/lib64 ${OPTIX_ROOT}/lib $ENV{OPTIX_ROOT}/lib 11 | ) 12 | 13 | add_library(OptiX::optix SHARED IMPORTED) 14 | set_target_properties(OptiX::optix PROPERTIES 15 | INTERFACE_INCLUDE_DIRECTORIES ${OptiX_INCLUDE_DIR} 16 | IMPORTED_LOCATION ${OptiX_optix_LIBRARY} 17 | IMPORTED_LINK_INTERFACE_LIBRARIES "CUDA::cudart" 18 | ) 19 | 20 | find_package_handle_standard_args(OptiX 21 | REQUIRED_VARS OptiX_INCLUDE_DIR OptiX_optix_LIBRARY 22 | FAIL_MESSAGE "Set OPTIX_ROOT to point to your OptiX installation\n" 23 | ) 24 | -------------------------------------------------------------------------------- /cuda/FindCUDA.cmake: -------------------------------------------------------------------------------- 1 | include(FindPackageHandleStandardArgs) 2 | message("Trying to find CUDA at CUDA_ROOT: $ENV{CUDA_ROOT}") 3 | 4 | find_path(CUDA_INCLUDE_DIR 5 | NAMES cuda.h 6 | PATHS ${CUDA_ROOT}/include $ENV{CUDA_ROOT}/include) 7 | 8 | find_library(CUDA_cudart_LIBRARY 9 | NAMES cudart 10 | PATHS ${CUDA_ROOT}/lib64 $ENV{CUDA_ROOT}/lib64 ${CUDA_ROOT}/lib $ENV{CUDA_ROOT}/lib 11 | ) 12 | 13 | find_program(CUDA_NVCC_EXECUTABLE 14 | NAMES nvcc 15 | PATHS ${CUDA_ROOT}/bin $ENV{CUDA_ROOT}/bin 16 | ) 17 | 18 | add_library(CUDA::cudart SHARED IMPORTED) 19 | set_target_properties(CUDA::cudart PROPERTIES 20 | INTERFACE_INCLUDE_DIRECTORIES ${CUDA_INCLUDE_DIR} 21 | IMPORTED_LOCATION ${CUDA_cudart_LIBRARY} 22 | ) 23 | 24 | find_package_handle_standard_args(CUDA 25 | REQUIRED_VARS CUDA_INCLUDE_DIR CUDA_cudart_LIBRARY CUDA_NVCC_EXECUTABLE 26 | FAIL_MESSAGE "Set CUDA_ROOT to point to your CUDA installation\n" 27 | ) 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # optix-rs-pathtracer-example 2 | ![alt text](https://github.com/anderslanglands/optix-rs-pathtracer-example/blob/master/img/cornell_box_0001.png "Cornell Box") 3 | 4 | Minimal example showing how to use optix-rs. This is a companion to https://github.com/anderslanglands/optix-rs - it is simply the pathtracer example from that crate factored out into its own repository to show how to set up the build for a project that depends on optix-rs. 5 | 6 | # Dependencies 7 | - optix-rs 8 | - OptiX (tested on 5.0 and 5.1) 9 | - CUDA (tested on 9.0-9.2) 10 | - CMake (tested on 3.5 and above) 11 | 12 | # Key things to note: 13 | - the build.rs requires optix_root and cuda_root to be set either as environment variables or in a build-settings.toml file in order to be able to compile any ptx files and link to liboptix 14 | - Add cuda programs to cuda/CMakeLists.txt to have them compiled by the build script. Edit cuda/ptx.cmake to tweak compile options. 15 | - If you're on macOS, you'll need to add OPTIX_ROOT/lib64 to your DYLD_LIBRARY_PATH as Cargo doesn't currently support setting the rpath programatically. 16 | 17 | -------------------------------------------------------------------------------- /cuda/ptx.cmake: -------------------------------------------------------------------------------- 1 | # Generate PTX files 2 | function(nvcuda_compile_ptx) 3 | set(options "") 4 | set(oneValueArgs TARGET_PATH GENERATED_FILES) 5 | set(multiValueArgs NVCC_OPTIONS SOURCES) 6 | cmake_parse_arguments(NVCUDA_COMPILE_PTX "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 7 | 8 | # Custom build rule to generate ptx files from cuda files 9 | foreach(input ${NVCUDA_COMPILE_PTX_SOURCES} ) 10 | get_filename_component(input_we ${input} NAME_WE ) 11 | 12 | # generate the *.ptx files inside "ptx" folder inside the executable's output directory. 13 | set(output "${CMAKE_CURRENT_BINARY_DIR}/${input_we}.ptx" ) 14 | 15 | list(APPEND PTX_FILES ${output} ) 16 | 17 | add_custom_command( 18 | OUTPUT ${output} 19 | DEPENDS ${input} 20 | COMMAND ${CUDA_NVCC_EXECUTABLE} --machine=64 --ptx ${NVCUDA_COMPILE_PTX_NVCC_OPTIONS} ${input} -o ${output} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 21 | ) 22 | endforeach( ) 23 | 24 | set(${NVCUDA_COMPILE_PTX_GENERATED_FILES} ${PTX_FILES} PARENT_SCOPE) 25 | endfunction() 26 | 27 | macro(compile_optix_ptx SOURCES) 28 | get_target_property(OPTIX_INCLUDE_DIR OptiX::optix INTERFACE_INCLUDE_DIRECTORIES) 29 | nvcuda_compile_ptx( 30 | SOURCES ${SOURCES} 31 | TARGET_PATH ${CMAKE_CURRENT_DIR} 32 | GENERATED_FILES PTX_SOURCES 33 | NVCC_OPTIONS 34 | -arch=sm_30 35 | # --use_fast_math 36 | --relocatable-device-code=true 37 | -std=c++14 38 | -I${OPTIX_INCLUDE_DIR} 39 | ) 40 | 41 | get_filename_component(src_file ${SOURCES} NAME_WE) 42 | 43 | add_custom_target("${src_file}_ptx" ALL DEPENDS ${PTX_SOURCES}) 44 | install(FILES ${PTX_SOURCES} DESTINATION ptx) 45 | endmacro() 46 | 47 | 48 | -------------------------------------------------------------------------------- /cuda/random.cuh: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of NVIDIA CORPORATION nor the names of its 13 | * contributors may be used to endorse or promote products derived 14 | * from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 24 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #pragma once 30 | #include 31 | 32 | template 33 | static __host__ __device__ __inline__ unsigned int tea( unsigned int val0, unsigned int val1 ) 34 | { 35 | unsigned int v0 = val0; 36 | unsigned int v1 = val1; 37 | unsigned int s0 = 0; 38 | 39 | for( unsigned int n = 0; n < N; n++ ) 40 | { 41 | s0 += 0x9e3779b9; 42 | v0 += ((v1<<4)+0xa341316c)^(v1+s0)^((v1>>5)+0xc8013ea4); 43 | v1 += ((v0<<4)+0xad90777d)^(v0+s0)^((v0>>5)+0x7e95761e); 44 | } 45 | 46 | return v0; 47 | } 48 | 49 | // Generate random unsigned int in [0, 2^24) 50 | static __host__ __device__ __inline__ unsigned int lcg(unsigned int &prev) 51 | { 52 | const unsigned int LCG_A = 1664525u; 53 | const unsigned int LCG_C = 1013904223u; 54 | prev = (LCG_A * prev + LCG_C); 55 | return prev & 0x00FFFFFF; 56 | } 57 | 58 | static __host__ __device__ __inline__ unsigned int lcg2(unsigned int &prev) 59 | { 60 | prev = (prev*8121 + 28411) % 134456; 61 | return prev; 62 | } 63 | 64 | // Generate random float in [0, 1) 65 | static __host__ __device__ __inline__ float rnd(unsigned int &prev) 66 | { 67 | return ((float) lcg(prev) / (float) 0x01000000); 68 | } 69 | 70 | // Multiply with carry 71 | static __host__ __inline__ unsigned int mwc() 72 | { 73 | static unsigned long long r[4]; 74 | static unsigned long long carry; 75 | static bool init = false; 76 | if( !init ) { 77 | init = true; 78 | unsigned int seed = 7654321u, seed0, seed1, seed2, seed3; 79 | r[0] = seed0 = lcg2(seed); 80 | r[1] = seed1 = lcg2(seed0); 81 | r[2] = seed2 = lcg2(seed1); 82 | r[3] = seed3 = lcg2(seed2); 83 | carry = lcg2(seed3); 84 | } 85 | 86 | unsigned long long sum = 2111111111ull * r[3] + 87 | 1492ull * r[2] + 88 | 1776ull * r[1] + 89 | 5115ull * r[0] + 90 | 1ull * carry; 91 | r[3] = r[2]; 92 | r[2] = r[1]; 93 | r[1] = r[0]; 94 | r[0] = static_cast(sum); // lower half 95 | carry = static_cast(sum >> 32); // upper half 96 | return static_cast(r[0]); 97 | } 98 | 99 | static __host__ __inline__ unsigned int random1u() 100 | { 101 | #if 0 102 | return rand(); 103 | #else 104 | return mwc(); 105 | #endif 106 | } 107 | 108 | static __host__ __inline__ optix::uint2 random2u() 109 | { 110 | return optix::make_uint2(random1u(), random1u()); 111 | } 112 | 113 | static __host__ __inline__ void fillRandBuffer( unsigned int *seeds, unsigned int N ) 114 | { 115 | for( unsigned int i=0; i 5 | #include 6 | #include "random.cuh" 7 | 8 | using namespace optix; 9 | 10 | struct PerRayData_radiance 11 | { 12 | optix::float3 L_e; 13 | bool done; 14 | int depth; 15 | float z; 16 | uint seed; 17 | float3 p; 18 | float3 w; 19 | float3 f; 20 | float g_c; 21 | float g_nee; 22 | }; 23 | 24 | struct PerRayData_shadow 25 | { 26 | optix::float3 attenuation; 27 | }; 28 | 29 | rtDeclareVariable(uint2, launch_index, rtLaunchIndex, ); 30 | rtDeclareVariable(uint2, launch_dim, rtLaunchDim, ); 31 | rtDeclareVariable(rtObject, scene_root, , ); 32 | rtBuffer result_buffer; 33 | 34 | rtDeclareVariable(Matrix4x4, camera_to_world, , ); 35 | rtDeclareVariable(Matrix4x4, raster_to_camera, , ); 36 | 37 | rtDeclareVariable(unsigned int, progression, , ); 38 | 39 | // a simple screen generator 40 | RT_PROGRAM void generate_ray() { 41 | PerRayData_radiance prd; 42 | prd.z = 1000.0f; 43 | // prd.pixel = launch_index; 44 | prd.seed = tea<16>(launch_index.y * launch_dim.x + launch_index.x, progression); 45 | float u0 = rnd(prd.seed); 46 | float u1 = rnd(prd.seed); 47 | 48 | float x = float(launch_index.x) + u0; 49 | float y = float(launch_index.y) + u1; 50 | 51 | float3 result = make_float3(0.0f); 52 | 53 | float4 Pras4 = make_float4(x, y, 0.0f, 1.0f); 54 | float4 Pcam4 = raster_to_camera * Pras4; 55 | float4 Dcam4 = make_float4(Pcam4.x, Pcam4.y, -1 * Pcam4.z, 0.0f); 56 | float4 P_origin_cam = make_float4(0.0f, 0.0f, 0.0f, 1.0f); 57 | float4 P_origin_world = camera_to_world * P_origin_cam; 58 | float4 D_world = camera_to_world * Dcam4; 59 | float4 P_world = camera_to_world * Pcam4; 60 | auto origin = make_float3(P_origin_world); 61 | auto direction = normalize(make_float3(Pcam4)); 62 | auto throughput = make_float3(1.0f); 63 | 64 | for (int i = 0; i < 32; ++i) { 65 | optix::Ray ray = optix::make_Ray(origin, direction, 0, 1e-5f, RT_DEFAULT_MAX); 66 | prd.depth = 0; 67 | prd.done = false; 68 | prd.L_e = make_float3(0.0f); 69 | rtTrace(scene_root, ray, prd); 70 | 71 | throughput *= prd.f; 72 | result += prd.L_e * throughput * prd.g_nee; 73 | throughput *= prd.g_c; 74 | 75 | if (i > 2) { 76 | float p = fmaxf(throughput); 77 | if (rnd(prd.seed) >= p) { 78 | break; 79 | } else { 80 | throughput /= p; 81 | } 82 | } 83 | 84 | if (prd.done) { 85 | break; 86 | } 87 | 88 | origin = prd.p; 89 | direction = prd.w; 90 | } 91 | float alpha = prd.depth > 0 ? 1.0f : 0.0f; 92 | 93 | result_buffer[launch_index] = make_float4(result, alpha); 94 | } 95 | 96 | rtDeclareVariable(PerRayData_radiance, prd_radiance, rtPayload, ); 97 | rtDeclareVariable(PerRayData_shadow, prd_shadow, rtPayload, ); 98 | 99 | RT_PROGRAM void miss() { 100 | prd_radiance.L_e = make_float3(0.f); 101 | } 102 | 103 | RT_PROGRAM void miss_shadow() { prd_shadow.attenuation = make_float3(1); } 104 | 105 | 106 | rtDeclareVariable(float3, texcoord, attribute texcoord, ); 107 | rtDeclareVariable(float3, geometric_normal, attribute geometric_normal, ); 108 | rtDeclareVariable(float3, shading_normal, attribute shading_normal, ); 109 | 110 | rtDeclareVariable(optix::Ray, ray, rtCurrentRay, ); 111 | rtDeclareVariable(float, t_hit, rtIntersectionDistance, ); 112 | 113 | rtDeclareVariable(float3, in_diffuse_albedo, , ); 114 | // Diffuse surface 115 | RT_PROGRAM void mtl_ch_diffuse() { 116 | float3 n = 117 | normalize(rtTransformNormal(RT_OBJECT_TO_WORLD, shading_normal)); 118 | 119 | float3 hit_point = ray.origin + ray.direction * t_hit; 120 | 121 | float3 light_center = make_float3(277.5, 554, -277.5); 122 | float3 light_dim = make_float3(100.0f, 0.0f, 100.0f); 123 | float3 light_min = light_center - light_dim / 2; 124 | 125 | float3 light_origin = light_min + light_dim * make_float3( 126 | rnd(prd_radiance.seed), 0.0f, rnd(prd_radiance.seed) 127 | ); 128 | float3 light_normal = make_float3(0.0f, -1.0f, 0.0f); 129 | 130 | 131 | float3 w_o = -ray.direction; 132 | float3 W_i = light_origin - hit_point; 133 | float d2 = dot(W_i, W_i); 134 | float3 w_i = normalize(W_i); 135 | 136 | float geo_l = max(0.0f, dot(w_i, n)); 137 | 138 | PerRayData_shadow prd_shadow; 139 | prd_shadow.attenuation = make_float3(1.0f); 140 | if (geo_l > 0) { 141 | float d = sqrtf(d2); 142 | auto epsilon = 2.0e-5f * t_hit; 143 | Ray ray_shadow = make_Ray(hit_point, w_i, 1, epsilon, d - epsilon); 144 | rtTrace(scene_root, ray_shadow, prd_shadow); 145 | } 146 | 147 | prd_radiance.L_e = 148 | make_float3(1.0f) 149 | * prd_shadow.attenuation; 150 | prd_radiance.g_nee = geo_l; 151 | 152 | prd_radiance.z = t_hit; 153 | prd_radiance.depth = 1; 154 | 155 | optix::Onb onb(n); 156 | auto u0 = rnd(prd_radiance.seed); 157 | auto u1 = rnd(prd_radiance.seed); 158 | float3 w; 159 | cosine_sample_hemisphere(u0, u1, w); 160 | onb.inverse_transform(w); 161 | prd_radiance.w = w; 162 | prd_radiance.p = hit_point; 163 | prd_radiance.f = in_diffuse_albedo; 164 | prd_radiance.g_c = dot(w, n); 165 | } 166 | 167 | RT_PROGRAM void mtl_ah_shadow() { 168 | prd_shadow.attenuation = optix::make_float3(0.0f); 169 | rtTerminateRay(); 170 | } 171 | 172 | RT_PROGRAM void mtl_ch_emission() { 173 | prd_radiance.L_e = make_float3(3.0f); 174 | prd_radiance.f = make_float3(1.0f); 175 | prd_radiance.done = true; 176 | } 177 | 178 | // intersection 179 | rtBuffer vertex_buffer; 180 | rtBuffer normal_buffer; 181 | rtBuffer texcoord_buffer; 182 | rtBuffer index_buffer; 183 | rtBuffer material_buffer; 184 | 185 | RT_PROGRAM void mesh_intersect(int primIdx) { 186 | const int3 v_idx = index_buffer[primIdx]; 187 | 188 | const float3 p0 = vertex_buffer[v_idx.x]; 189 | const float3 p1 = vertex_buffer[v_idx.y]; 190 | const float3 p2 = vertex_buffer[v_idx.z]; 191 | 192 | // Intersect ray with triangle 193 | float3 n; 194 | float t, beta, gamma; 195 | 196 | if (intersect_triangle(ray, p0, p1, p2, n, t, beta, gamma)) { 197 | if (rtPotentialIntersection(t)) { 198 | 199 | shading_normal = geometric_normal = normalize(n); 200 | rtReportIntersection(0); 201 | } 202 | } 203 | } 204 | 205 | RT_PROGRAM void bound(int primIdx, float result[6]) { 206 | const int3 v_idx = index_buffer[primIdx]; 207 | 208 | const float3 v0 = vertex_buffer[v_idx.x]; 209 | const float3 v1 = vertex_buffer[v_idx.y]; 210 | const float3 v2 = vertex_buffer[v_idx.z]; 211 | const float area = length(cross(v1 - v0, v2 - v0)); 212 | 213 | optix::Aabb* aabb = (optix::Aabb*)result; 214 | 215 | if (area > 0.0f && !isinf(area)) { 216 | aabb->m_min = fminf(fminf(v0, v1), v2); 217 | aabb->m_max = fmaxf(fmaxf(v0, v1), v2); 218 | } else { 219 | aabb->invalidate(); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/gl_util.rs: -------------------------------------------------------------------------------- 1 | use gl; 2 | use gl::types::{GLchar, GLenum, GLint, GLsizeiptr, GLuint, GLvoid}; 3 | use std::ffi::{CStr, CString}; 4 | 5 | pub struct Shader { 6 | id: GLuint, 7 | } 8 | 9 | impl Shader { 10 | pub fn from_source( 11 | source: &CStr, 12 | shader_type: GLenum, 13 | ) -> Result { 14 | let id = unsafe { gl::CreateShader(shader_type) }; 15 | 16 | unsafe { 17 | gl::ShaderSource(id, 1, &source.as_ptr(), std::ptr::null()); 18 | gl::CompileShader(id); 19 | } 20 | 21 | let mut success: GLint = 1; 22 | unsafe { 23 | gl::GetShaderiv(id, gl::COMPILE_STATUS, &mut success); 24 | } 25 | 26 | if success == 0 { 27 | let mut len: GLint = 0; 28 | unsafe { 29 | gl::GetShaderiv(id, gl::INFO_LOG_LENGTH, &mut len); 30 | } 31 | let error = create_whitespace_cstring(len as usize); 32 | unsafe { 33 | gl::GetShaderInfoLog( 34 | id, 35 | len, 36 | std::ptr::null_mut(), 37 | error.as_ptr() as *mut GLchar, 38 | ); 39 | } 40 | Err(error.to_string_lossy().into_owned()) 41 | } else { 42 | Ok(Shader { id }) 43 | } 44 | } 45 | 46 | pub fn vertex_from_source(source: &CStr) -> Result { 47 | Shader::from_source(source, gl::VERTEX_SHADER) 48 | } 49 | 50 | pub fn fragment_from_source(source: &CStr) -> Result { 51 | Shader::from_source(source, gl::FRAGMENT_SHADER) 52 | } 53 | 54 | pub fn id(&self) -> GLuint { 55 | self.id 56 | } 57 | } 58 | 59 | impl Drop for Shader { 60 | fn drop(&mut self) { 61 | unsafe { gl::DeleteShader(self.id) }; 62 | } 63 | } 64 | 65 | pub struct Program { 66 | id: GLuint, 67 | } 68 | 69 | impl Program { 70 | pub fn from_shaders(shaders: &[Shader]) -> Result { 71 | let id = unsafe { gl::CreateProgram() }; 72 | 73 | for shader in shaders { 74 | unsafe { gl::AttachShader(id, shader.id()) }; 75 | } 76 | 77 | unsafe { gl::LinkProgram(id) }; 78 | 79 | let mut success: GLint = 1; 80 | unsafe { 81 | gl::GetProgramiv(id, gl::LINK_STATUS, &mut success); 82 | } 83 | 84 | if success == 0 { 85 | let mut len: GLint = 0; 86 | unsafe { 87 | gl::GetProgramiv(id, gl::INFO_LOG_LENGTH, &mut len); 88 | } 89 | let error = create_whitespace_cstring(len as usize); 90 | unsafe { 91 | gl::GetProgramInfoLog( 92 | id, 93 | len, 94 | std::ptr::null_mut(), 95 | error.as_ptr() as *mut GLchar, 96 | ); 97 | } 98 | return Err(error.to_string_lossy().into_owned()); 99 | } 100 | 101 | for shader in shaders { 102 | unsafe { gl::DetachShader(id, shader.id()) } 103 | } 104 | 105 | Ok(Program { id }) 106 | } 107 | 108 | pub fn id(&self) -> GLuint { 109 | self.id 110 | } 111 | 112 | pub fn use_program(&self) { 113 | unsafe { 114 | gl::UseProgram(self.id); 115 | } 116 | } 117 | 118 | pub fn get_location(&self, name: &str) -> Result { 119 | let cname = CString::new(name).unwrap(); 120 | let loc = unsafe { 121 | gl::GetUniformLocation(self.id, cname.as_ptr() as *mut GLchar) 122 | }; 123 | 124 | if loc != 0 { 125 | Ok(loc) 126 | } else { 127 | Err("Could not get location".to_owned()) 128 | } 129 | } 130 | 131 | pub fn set_uniform(&self, loc: GLint, v: i32) { 132 | unsafe {gl::ProgramUniform1i(self.id, loc, v);} 133 | } 134 | } 135 | 136 | fn create_whitespace_cstring(len: usize) -> CString { 137 | let mut buffer: Vec = Vec::with_capacity(len as usize + 1); 138 | buffer.extend([b' '].iter().cycle().take(len as usize)); 139 | unsafe { CString::from_vec_unchecked(buffer) } 140 | } 141 | 142 | #[repr(u32)] 143 | #[derive(Copy, Clone)] 144 | pub enum BufferType { 145 | ArrayBuffer = gl::ARRAY_BUFFER, 146 | } 147 | 148 | #[repr(u32)] 149 | #[derive(Copy, Clone)] 150 | pub enum BufferUsage { 151 | StaticDraw = gl::STATIC_DRAW, 152 | StreamDraw = gl::STREAM_DRAW, 153 | } 154 | 155 | pub struct Buffer { 156 | id: GLuint, 157 | buffer_type: BufferType, 158 | _phantom: std::marker::PhantomData, 159 | } 160 | 161 | impl Buffer { 162 | pub fn new(buffer_type: BufferType) -> Buffer { 163 | let mut id: GLuint = 0; 164 | unsafe { 165 | gl::GenBuffers(1, &mut id); 166 | } 167 | Buffer { 168 | id, 169 | buffer_type, 170 | _phantom: std::marker::PhantomData, 171 | } 172 | } 173 | 174 | pub fn id(&self) -> GLuint { 175 | self.id 176 | } 177 | 178 | pub fn buffer_data(&self, data: &[T], usage: BufferUsage) { 179 | unsafe { 180 | gl::BindBuffer(self.buffer_type as GLuint, self.id); 181 | gl::BufferData( 182 | self.buffer_type as GLuint, 183 | (data.len() * std::mem::size_of::()) as GLsizeiptr, 184 | data.as_ptr() as *const GLvoid, 185 | usage as GLenum, 186 | ); 187 | gl::BindBuffer(self.buffer_type as GLuint, 0); 188 | } 189 | } 190 | 191 | pub fn bind(&self) { 192 | unsafe { 193 | gl::BindBuffer(self.buffer_type as GLuint, self.id); 194 | } 195 | } 196 | 197 | pub fn unbind(&self) { 198 | unsafe { 199 | gl::BindBuffer(self.buffer_type as GLuint, 0); 200 | } 201 | } 202 | } 203 | 204 | impl Drop for Buffer { 205 | fn drop(&mut self) { 206 | unsafe { 207 | gl::DeleteBuffers(1, &self.id as *const GLuint); 208 | } 209 | } 210 | } 211 | 212 | pub struct VertexArray { 213 | id: GLuint, 214 | } 215 | 216 | impl VertexArray { 217 | pub fn new() -> VertexArray { 218 | let mut id: GLuint = 0; 219 | unsafe { 220 | gl::GenVertexArrays(1, &mut id); 221 | } 222 | 223 | VertexArray { id } 224 | } 225 | 226 | pub fn id(&self) -> GLuint { 227 | self.id 228 | } 229 | 230 | pub fn bind(&self) { 231 | unsafe { 232 | gl::BindVertexArray(self.id); 233 | } 234 | } 235 | 236 | pub fn unbind(&self) { 237 | unsafe { 238 | gl::BindVertexArray(0); 239 | } 240 | } 241 | } 242 | 243 | impl Drop for VertexArray { 244 | fn drop(&mut self) { 245 | unsafe { 246 | gl::DeleteVertexArrays(1, &self.id as *const GLuint); 247 | } 248 | } 249 | } 250 | 251 | #[allow(non_camel_case_types)] 252 | #[repr(C, packed)] 253 | #[derive(Copy, Clone, Debug)] 254 | pub struct f32x2 { 255 | x: f32, 256 | y: f32, 257 | } 258 | 259 | impl f32x2 { 260 | pub fn new(x: f32, y: f32) -> f32x2 { 261 | f32x2 { x, y } 262 | } 263 | 264 | pub fn num_components() -> usize { 265 | 2 266 | } 267 | } 268 | 269 | #[allow(non_camel_case_types)] 270 | #[repr(C, packed)] 271 | #[derive(Copy, Clone, Debug)] 272 | pub struct f32x3 { 273 | x: f32, 274 | y: f32, 275 | z: f32, 276 | } 277 | 278 | impl f32x3 { 279 | pub fn new(x: f32, y: f32, z: f32) -> f32x3 { 280 | f32x3 { x, y, z } 281 | } 282 | 283 | pub fn num_components() -> usize { 284 | 3 285 | } 286 | } 287 | 288 | #[allow(non_camel_case_types)] 289 | #[repr(C, packed)] 290 | #[derive(Copy, Clone, Debug)] 291 | pub struct f32x4 { 292 | x: f32, 293 | y: f32, 294 | z: f32, 295 | w: f32, 296 | } 297 | 298 | impl f32x4 { 299 | pub fn new(x: f32, y: f32, z: f32, w: f32) -> f32x4 { 300 | f32x4 { x, y, z, w } 301 | } 302 | 303 | pub fn zero() -> f32x4 { 304 | f32x4::new(0.0, 0.0, 0.0, 0.0) 305 | } 306 | 307 | pub fn set(&mut self, x: f32, y: f32, z: f32, w: f32) { 308 | self.x = x; 309 | self.y = y; 310 | self.z = z; 311 | self.w = w; 312 | } 313 | 314 | pub fn num_components() -> usize { 315 | 4 316 | } 317 | } 318 | 319 | #[derive(Copy, Clone, Debug)] 320 | #[repr(C, packed)] 321 | pub struct Vertex { 322 | p: f32x3, 323 | st: f32x2, 324 | } 325 | impl Vertex { 326 | pub fn new(p: f32x3, st: f32x2) -> Vertex { 327 | Vertex { p, st } 328 | } 329 | 330 | unsafe fn vertex_attrib_pointer( 331 | num_components: usize, 332 | stride: usize, 333 | location: usize, 334 | offset: usize, 335 | ) { 336 | gl::EnableVertexAttribArray(location as gl::types::GLuint); // location(0) 337 | gl::VertexAttribPointer( 338 | location as gl::types::GLuint, // index of the vertex attribute 339 | num_components as gl::types::GLint, /* number of components per 340 | * vertex attrib */ 341 | gl::FLOAT, 342 | gl::FALSE, // normalized (int-to-float conversion), 343 | stride as gl::types::GLint, /* byte stride between 344 | * successive elements */ 345 | offset as *const gl::types::GLvoid, /* offset of the first 346 | * element */ 347 | ); 348 | } 349 | 350 | pub fn vertex_attrib_pointers() { 351 | let stride = std::mem::size_of::(); 352 | 353 | let location = 0; 354 | let offset = 0; 355 | 356 | // and configure the vertex array 357 | unsafe { 358 | Vertex::vertex_attrib_pointer( 359 | f32x3::num_components(), 360 | stride, 361 | location, 362 | offset, 363 | ); 364 | } 365 | 366 | let location = location + 1; 367 | let offset = offset + std::mem::size_of::(); 368 | 369 | // and configure the st array 370 | unsafe { 371 | Vertex::vertex_attrib_pointer( 372 | f32x2::num_components(), 373 | stride, 374 | location, 375 | offset, 376 | ); 377 | } 378 | } 379 | } 380 | 381 | pub struct FullscreenQuad { 382 | width: u32, 383 | height: u32, 384 | vertex_buffer: Buffer, 385 | vertex_array: VertexArray, 386 | program: Program, 387 | texture_id: GLuint, 388 | loc_progression: GLint, 389 | } 390 | 391 | impl FullscreenQuad { 392 | pub fn new(width: u32, height: u32) -> Result { 393 | let vert_shader = Shader::vertex_from_source( 394 | CStr::from_bytes_with_nul( 395 | b" 396 | #version 330 core 397 | layout (location = 0) in vec3 _p; 398 | layout (location = 1) in vec2 _st; 399 | out vec2 st; 400 | void main() { 401 | gl_Position = vec4(_p, 1.0); 402 | st = _st; 403 | } 404 | \0", 405 | ).unwrap(), 406 | )?; 407 | 408 | let frag_shader = Shader::fragment_from_source( 409 | CStr::from_bytes_with_nul( 410 | b" 411 | #version 330 core 412 | in vec2 st; 413 | out vec4 Color; 414 | 415 | uniform sampler2D smp2d_0; 416 | uniform int progression; 417 | 418 | void main() { 419 | vec4 col = texture(smp2d_0, st); 420 | col.r = pow(col.r / progression, 1/2.2); 421 | col.g = pow(col.g / progression, 1/2.2); 422 | col.b = pow(col.b / progression, 1/2.2); 423 | Color = col; 424 | } 425 | \0", 426 | ).unwrap(), 427 | )?; 428 | 429 | let program = Program::from_shaders(&[vert_shader, frag_shader])?; 430 | program.use_program(); 431 | let loc_progression = program.get_location("progression")?; 432 | 433 | let vertices: Vec = vec![ 434 | Vertex::new(f32x3::new(-1.0, -1.0, 0.0), f32x2::new(0.0, 0.0)), 435 | Vertex::new(f32x3::new(1.0, -1.0, 0.0), f32x2::new(1.0, 0.0)), 436 | Vertex::new(f32x3::new(1.0, 1.0, 0.0), f32x2::new(1.0, 1.0)), 437 | Vertex::new(f32x3::new(-1.0, -1.0, 0.0), f32x2::new(0.0, 0.0)), 438 | Vertex::new(f32x3::new(1.0, 1.0, 0.0), f32x2::new(1.0, 1.0)), 439 | Vertex::new(f32x3::new(-1.0, 1.0, 0.0), f32x2::new(0.0, 1.0)), 440 | ]; 441 | let vertex_buffer = Buffer::::new(BufferType::ArrayBuffer); 442 | vertex_buffer.buffer_data(&vertices, BufferUsage::StaticDraw); 443 | 444 | // Generate and bind the VAO 445 | let vertex_array = VertexArray::new(); 446 | 447 | vertex_array.bind(); 448 | // Re-bind the VBO to associate the two. We could just have left it 449 | // bound earlier and let the association happen when we 450 | // configure the VAO but this way at least makes the connection 451 | // between the two seem more explicit, despite the magical 452 | // state machine hiding in OpenGL 453 | vertex_buffer.bind(); 454 | 455 | // Set up the vertex attribute pointers for all locations 456 | Vertex::vertex_attrib_pointers(); 457 | 458 | // now unbind both the vbo and vao to keep everything cleaner 459 | vertex_buffer.unbind(); 460 | vertex_array.unbind(); 461 | 462 | // generate test texture data using the image width rather than the 463 | // framebuffer width 464 | let mut tex_data = Vec::with_capacity((width * height) as usize); 465 | for y in 0..height { 466 | for x in 0..width { 467 | tex_data.push(f32x4::new( 468 | (x as f32) / width as f32, 469 | (y as f32) / height as f32, 470 | 1.0, 471 | 0.0, 472 | )); 473 | } 474 | } 475 | 476 | // generate the texture for the quad 477 | let mut texture_id: gl::types::GLuint = 0; 478 | unsafe { 479 | gl::GenTextures(1, &mut texture_id); 480 | gl::ActiveTexture(gl::TEXTURE0); 481 | gl::Enable(gl::TEXTURE_2D); 482 | gl::BindTexture(gl::TEXTURE_2D, texture_id); 483 | gl::TexParameteri( 484 | gl::TEXTURE_2D, 485 | gl::TEXTURE_WRAP_S, 486 | gl::CLAMP_TO_BORDER as gl::types::GLint, 487 | ); 488 | gl::TexParameteri( 489 | gl::TEXTURE_2D, 490 | gl::TEXTURE_WRAP_T, 491 | gl::CLAMP_TO_BORDER as gl::types::GLint, 492 | ); 493 | gl::TexParameteri( 494 | gl::TEXTURE_2D, 495 | gl::TEXTURE_MIN_FILTER, 496 | gl::NEAREST as gl::types::GLint, 497 | ); 498 | gl::TexParameteri( 499 | gl::TEXTURE_2D, 500 | gl::TEXTURE_MAG_FILTER, 501 | gl::NEAREST as gl::types::GLint, 502 | ); 503 | gl::TexImage2D( 504 | gl::TEXTURE_2D, 505 | 0, 506 | gl::RGBA32F as gl::types::GLint, 507 | width as gl::types::GLint, 508 | height as gl::types::GLint, 509 | 0, 510 | gl::RGBA, 511 | gl::FLOAT, 512 | tex_data.as_ptr() as *const gl::types::GLvoid, 513 | ); 514 | } 515 | 516 | Ok(FullscreenQuad { 517 | width, 518 | height, 519 | vertex_buffer, 520 | vertex_array, 521 | program, 522 | texture_id, 523 | loc_progression, 524 | }) 525 | } 526 | 527 | pub fn draw(&self) { 528 | self.program.use_program(); 529 | self.vertex_array.bind(); 530 | unsafe { 531 | gl::DrawArrays( 532 | gl::TRIANGLES, 533 | 0, // starting index in the enabled array 534 | 6, // number of indices to draw 535 | ) 536 | } 537 | self.vertex_array.unbind(); 538 | } 539 | 540 | pub fn update_texture(&self, data: &[optix::math::V4f32]) { 541 | unsafe { 542 | gl::BindTexture(gl::TEXTURE_2D, self.texture_id); 543 | gl::TexSubImage2D( 544 | gl::TEXTURE_2D, 545 | 0, 546 | 0, 547 | 0, 548 | self.width as GLint, 549 | self.height as GLint, 550 | gl::RGBA, 551 | gl::FLOAT, 552 | data.as_ptr() as *const GLvoid, 553 | ); 554 | } 555 | } 556 | 557 | pub fn set_progression(&self, progression: i32) { 558 | self.program.set_uniform(self.loc_progression, progression); 559 | } 560 | } 561 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | // This example shows how to use the crate to generate a simple, progressive, 2 | // Cornell box. 3 | use crossbeam_channel as channel; 4 | use glfw::{Action, Context, Key}; 5 | use std::collections::HashMap; 6 | use std::sync::atomic::{AtomicUsize, Ordering}; 7 | use std::sync::{Arc, Mutex}; 8 | use std::thread; 9 | 10 | pub mod gl_util; 11 | use crate::gl_util::*; 12 | 13 | use optix as rt; 14 | use optix::math::*; 15 | 16 | fn main() -> Result<(), String> { 17 | let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); 18 | glfw.window_hint(glfw::WindowHint::ContextVersion(4, 1)); 19 | glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true)); 20 | glfw.window_hint(glfw::WindowHint::OpenGlProfile( 21 | glfw::OpenGlProfileHint::Core, 22 | )); 23 | 24 | let width = 512; 25 | let height = 512; 26 | 27 | let (mut window, events) = glfw 28 | .create_window( 29 | width, 30 | height, 31 | "path tracer example", 32 | glfw::WindowMode::Windowed, 33 | ).expect("failed to create glfw window"); 34 | 35 | window.set_key_polling(true); 36 | window.make_current(); 37 | 38 | // retina displays will return a higher res for the framebuffer 39 | // which we need to use for the viewport 40 | let (fb_width, fb_height) = window.get_framebuffer_size(); 41 | 42 | let gl = gl::load_with(|s| { 43 | glfw.get_proc_address_raw(s) as *const std::os::raw::c_void 44 | }); 45 | 46 | let fsq = FullscreenQuad::new(width, height)?; 47 | 48 | let image_data = vec![v4f(0.0, 0.0, 0.0, 0.0); (width * height) as usize]; 49 | 50 | unsafe { 51 | gl::Viewport(0, 0, fb_width, fb_height); 52 | }; 53 | 54 | let (ctx, entry_point) = create_context(width, height).unwrap(); 55 | 56 | // We'll create a second, render thread and pass messages to it in order to 57 | // control rendering, sharing an image buffer for the rendered frames and 58 | // using an atomic counter to signal when the context has finished each 59 | // render progression. 60 | let (tx_render, rx_render) = channel::unbounded(); 61 | let main_progression_counter = Arc::new(AtomicUsize::new(0)); 62 | let render_progression_counter = Arc::clone(&main_progression_counter); 63 | let mut last_progression = 0; 64 | let mtx_image_data = Arc::new(Mutex::new(image_data)); 65 | let mtx_image_data_render = Arc::clone(&mtx_image_data); 66 | let render_thread = thread::spawn(move || { 67 | 'outer: loop { 68 | let mut time_min = std::time::Duration::from_secs(99999999); 69 | let mut time_max = std::time::Duration::from_secs(0); 70 | let mut time_total = std::time::Duration::from_secs(0); 71 | let mut time_samples = 0; 72 | 73 | // block until we receive a command message 74 | match rx_render.recv() { 75 | Some(MsgMaster::StartRender(mut ctx, entry_point)) => { 76 | let result_buffer = ctx 77 | .buffer_create_2d::( 78 | width as usize, 79 | height as usize, 80 | rt::BufferType::OUTPUT, 81 | rt::BufferFlag::NONE, 82 | ).expect("Could not create result buffer"); 83 | 84 | ctx.set_variable( 85 | "result_buffer", 86 | rt::ObjectHandle::Buffer2d(result_buffer), 87 | ).expect("Setting buffer2d variable failed"); 88 | 89 | let mut progression = 0u32; 90 | 91 | 'inner: loop { 92 | let now = std::time::Instant::now(); 93 | match rx_render.try_recv() { 94 | Some(MsgMaster::StartRender(_, _)) => { 95 | println!( 96 | "ERROR: request to start an in-progress render" 97 | ); 98 | break 'outer; 99 | } 100 | Some(MsgMaster::StopRender) => { 101 | time_total /= time_samples; 102 | println!( 103 | "Min : {}s {}ms", 104 | time_min.as_secs(), 105 | time_min.subsec_millis() 106 | ); 107 | println!( 108 | "Max : {}s {}ms", 109 | time_max.as_secs(), 110 | time_max.subsec_nanos() 111 | ); 112 | println!( 113 | "Mean: {}s {}ms", 114 | time_total.as_secs(), 115 | time_total.subsec_nanos() 116 | ); 117 | break 'outer; 118 | } 119 | None => (), 120 | } 121 | 122 | ctx.set_variable("progression", progression).unwrap(); 123 | progression += 1; 124 | 125 | match ctx.launch_2d( 126 | entry_point, 127 | width as usize, 128 | height as usize, 129 | ) { 130 | Ok(()) => (), 131 | Err(rt::Error::Optix(e)) => { 132 | println!("[Optix ERROR]: {}", e.1); 133 | } 134 | Err(_) => { 135 | println!("ERROR!!!!!!!!"); 136 | } 137 | } 138 | 139 | // update the shared buffer 140 | { 141 | let buffer_map = ctx 142 | .buffer_map_2d::(result_buffer) 143 | .unwrap(); 144 | let mut output = 145 | mtx_image_data_render.lock().unwrap(); 146 | 147 | // output.clone_from_slice(buffer_map.as_slice()); 148 | for i in 0..output.len() { 149 | output[i] += buffer_map.as_slice()[i]; 150 | } 151 | } 152 | // let the ui thread know there's new image data to 153 | // display 154 | render_progression_counter 155 | .fetch_add(1, Ordering::SeqCst); 156 | 157 | let duration = now.elapsed(); 158 | if duration < time_min { 159 | time_min = duration; 160 | } 161 | if duration > time_max { 162 | time_max = duration; 163 | } 164 | time_total += duration; 165 | time_samples += 1; 166 | } 167 | } 168 | Some(MsgMaster::StopRender) => break 'outer, 169 | _ => (), 170 | } 171 | } 172 | }); 173 | 174 | tx_render.send(MsgMaster::StartRender(ctx, entry_point)); 175 | 176 | while !window.should_close() { 177 | glfw.poll_events(); 178 | for (_, event) in glfw::flush_messages(&events) { 179 | handle_window_event(&mut window, event); 180 | } 181 | 182 | // If the render thread has progressed since we last updated our display, 183 | // synchronize and update the display 184 | let current_progression = 185 | main_progression_counter.load(Ordering::SeqCst); 186 | if current_progression > last_progression { 187 | last_progression = current_progression; 188 | { 189 | let buffer = mtx_image_data.lock().unwrap(); 190 | fsq.update_texture(&buffer); 191 | } 192 | fsq.set_progression(current_progression as i32); 193 | } 194 | 195 | // draw the quad 196 | fsq.draw(); 197 | 198 | window.swap_buffers(); 199 | } 200 | // user requested close. Shutdown the render thread and exit 201 | tx_render.send(MsgMaster::StopRender); 202 | render_thread.join().unwrap(); 203 | 204 | Ok(()) 205 | } 206 | 207 | enum MsgMaster { 208 | StartRender(rt::Context, rt::EntryPointHandle), 209 | StopRender, 210 | } 211 | 212 | fn create_context( 213 | width: u32, 214 | height: u32, 215 | ) -> Result<(rt::Context, rt::EntryPointHandle), rt::Error> { 216 | // The context owns everything 217 | let mut ctx = rt::Context::new(); 218 | 219 | // The search path is used for finding ptx files. In this case the path to 220 | // the generated ptx is known by the build script, which outputs a config 221 | // file for us so we know where to look... 222 | ctx.set_search_path(rt::SearchPath::from_config_file( 223 | "ptx_path", "ptx_path", 224 | )); 225 | 226 | let prg_cam_screen = 227 | ctx.program_create_from_ptx_file("pathtracer.ptx", "generate_ray")?; 228 | let prg_miss = 229 | ctx.program_create_from_ptx_file("pathtracer.ptx", "miss")?; 230 | 231 | // generate camera matrices 232 | let swn = v2f(-1.0, -1.0); 233 | let swx = v2f(1.0, 1.0); 234 | let mtx_screen_to_raster = m4f_scaling(width as f32, height as f32, 1.0) 235 | * m4f_scaling(1.0 / (swx.x - swn.x), 1.0 / (swx.y - swn.y), 1.0) 236 | * m4f_translation(-swn.x, -swn.y, 0.0); 237 | let mtx_raster_to_screen = mtx_screen_to_raster.try_inverse().unwrap(); 238 | let mtx_camera_to_screen = M4f32::new_perspective( 239 | (width as f32) / (height as f32), 240 | 34.0f32.to_radians(), 241 | 0.1, 242 | 1.0e7, 243 | ); 244 | let mtx_screen_to_camera = mtx_camera_to_screen.try_inverse().unwrap(); 245 | let mtx_camera_to_world = m4f_translation(275.0, 275.0, 900.0); 246 | let mtx_raster_to_camera = mtx_screen_to_camera * mtx_raster_to_screen; 247 | ctx.program_set_variable( 248 | prg_cam_screen, 249 | "raster_to_camera", 250 | rt::MatrixFormat::ColumnMajor(mtx_raster_to_camera), 251 | )?; 252 | 253 | ctx.program_set_variable( 254 | prg_cam_screen, 255 | "camera_to_world", 256 | rt::MatrixFormat::ColumnMajor(mtx_camera_to_world), 257 | )?; 258 | 259 | let prg_mesh_intersect = 260 | ctx.program_create_from_ptx_file("pathtracer.ptx", "mesh_intersect")?; 261 | let prg_mesh_bound = 262 | ctx.program_create_from_ptx_file("pathtracer.ptx", "bound")?; 263 | let prg_material_constant_closest = 264 | ctx.program_create_from_ptx_file("pathtracer.ptx", "mtl_ch_diffuse")?; 265 | let prg_material_constant_any = 266 | ctx.program_create_from_ptx_file("pathtracer.ptx", "mtl_ah_shadow")?; 267 | 268 | let prg_material_emission = 269 | ctx.program_create_from_ptx_file("pathtracer.ptx", "mtl_ch_emission")?; 270 | 271 | let raytype_camera = ctx.set_ray_type(0, "camera")?; 272 | let raytype_shadow = ctx.set_ray_type(1, "shadow")?; 273 | ctx.set_miss_program(raytype_camera, prg_miss)?; 274 | 275 | let mut map_mtl_camera_programs = HashMap::new(); 276 | map_mtl_camera_programs.insert( 277 | raytype_camera, 278 | rt::MaterialProgram { 279 | closest: Some(prg_material_constant_closest), 280 | any: None, 281 | }, 282 | ); 283 | map_mtl_camera_programs.insert( 284 | raytype_shadow, 285 | rt::MaterialProgram { 286 | closest: None, 287 | any: Some(prg_material_constant_any), 288 | }, 289 | ); 290 | 291 | let mtl_constant = ctx.material_create(map_mtl_camera_programs)?; 292 | 293 | let mut map_mtl_emission = HashMap::new(); 294 | map_mtl_emission.insert( 295 | raytype_camera, 296 | rt::MaterialProgram { 297 | closest: Some(prg_material_emission), 298 | any: None, 299 | }, 300 | ); 301 | map_mtl_emission.insert( 302 | raytype_shadow, 303 | rt::MaterialProgram { 304 | closest: None, 305 | any: Some(prg_material_constant_any), 306 | }, 307 | ); 308 | let mtl_emission = ctx.material_create(map_mtl_emission)?; 309 | 310 | let materials = vec![0]; 311 | let buf_material = ctx.buffer_create_from_slice_1d( 312 | &materials, 313 | rt::BufferType::INPUT, 314 | rt::BufferFlag::NONE, 315 | )?; 316 | 317 | let geo_floor = create_quad( 318 | &mut ctx, 319 | [ 320 | v3f(0.0, 0.0, 0.0), 321 | v3f(555.0, 0.0, 0.0), 322 | v3f(555.0, 0.0, -555.0), 323 | v3f(0.0, 0.0, -555.0), 324 | ], 325 | prg_mesh_bound, 326 | prg_mesh_intersect, 327 | )?; 328 | let geo_ceiling = create_quad( 329 | &mut ctx, 330 | [ 331 | v3f(0.0, 555.0, -555.0), 332 | v3f(555.0, 555.0, -555.0), 333 | v3f(555.0, 555.0, 0.0), 334 | v3f(0.0, 555.0, 0.0), 335 | ], 336 | prg_mesh_bound, 337 | prg_mesh_intersect, 338 | )?; 339 | let geo_wall_back = create_quad( 340 | &mut ctx, 341 | [ 342 | v3f(0.0, 0.0, -555.0), 343 | v3f(555.0, 0.0, -555.0), 344 | v3f(555.0, 555.0, -555.0), 345 | v3f(0.0, 555.0, -555.0), 346 | ], 347 | prg_mesh_bound, 348 | prg_mesh_intersect, 349 | )?; 350 | let geo_wall_left = create_quad( 351 | &mut ctx, 352 | [ 353 | v3f(0.0, 0.0, 0.0), 354 | v3f(0.0, 0.0, -555.0), 355 | v3f(0.0, 555.0, -555.0), 356 | v3f(0.0, 555.0, 0.0), 357 | ], 358 | prg_mesh_bound, 359 | prg_mesh_intersect, 360 | )?; 361 | let geo_wall_right = create_quad( 362 | &mut ctx, 363 | [ 364 | v3f(555.0, 0.0, -555.0), 365 | v3f(555.0, 0.0, 0.0), 366 | v3f(555.0, 555.0, 0.0), 367 | v3f(555.0, 555.0, -555.0), 368 | ], 369 | prg_mesh_bound, 370 | prg_mesh_intersect, 371 | )?; 372 | 373 | let light_center = v3f(277.5, 554.0, -277.5); 374 | let light_dim = v3f(100.0, 0.0, 100.0); 375 | let light_min = light_center - light_dim / 2.0f32; 376 | let light_max = light_min + light_dim; 377 | let geo_light = create_quad( 378 | &mut ctx, 379 | [ 380 | v3f(light_min.x, light_min.y, light_min.z), 381 | v3f(light_max.x, light_min.y, light_min.z), 382 | v3f(light_max.x, light_min.y, light_max.z), 383 | v3f(light_min.x, light_min.y, light_max.z), 384 | ], 385 | prg_mesh_bound, 386 | prg_mesh_intersect, 387 | )?; 388 | 389 | let geo_tall_box = create_box( 390 | &mut ctx, 391 | v3f(0.0, 0.0, 0.0), 392 | v3f(165.0, 330.0, 165.0), 393 | prg_mesh_bound, 394 | prg_mesh_intersect, 395 | )?; 396 | let geo_short_box = create_box( 397 | &mut ctx, 398 | v3f(0.0, 0.0, 0.0), 399 | v3f(165.0, 165.0, 165.0), 400 | prg_mesh_bound, 401 | prg_mesh_intersect, 402 | )?; 403 | 404 | ctx.geometry_set_variable( 405 | geo_floor, 406 | "material_buffer", 407 | rt::ObjectHandle::Buffer1d(buf_material), 408 | )?; 409 | ctx.geometry_set_variable( 410 | geo_ceiling, 411 | "material_buffer", 412 | rt::ObjectHandle::Buffer1d(buf_material), 413 | )?; 414 | ctx.geometry_set_variable( 415 | geo_wall_back, 416 | "material_buffer", 417 | rt::ObjectHandle::Buffer1d(buf_material), 418 | )?; 419 | ctx.geometry_set_variable( 420 | geo_wall_left, 421 | "material_buffer", 422 | rt::ObjectHandle::Buffer1d(buf_material), 423 | )?; 424 | ctx.geometry_set_variable( 425 | geo_wall_right, 426 | "material_buffer", 427 | rt::ObjectHandle::Buffer1d(buf_material), 428 | )?; 429 | ctx.geometry_set_variable( 430 | geo_tall_box, 431 | "material_buffer", 432 | rt::ObjectHandle::Buffer1d(buf_material), 433 | )?; 434 | ctx.geometry_set_variable( 435 | geo_short_box, 436 | "material_buffer", 437 | rt::ObjectHandle::Buffer1d(buf_material), 438 | )?; 439 | 440 | ctx.geometry_set_variable( 441 | geo_light, 442 | "material_buffer", 443 | rt::ObjectHandle::Buffer1d(buf_material), 444 | )?; 445 | 446 | let geo_inst_floor = ctx.geometry_instance_create( 447 | rt::GeometryType::Geometry(geo_floor), 448 | vec![mtl_constant], 449 | )?; 450 | let geo_inst_ceiling = ctx.geometry_instance_create( 451 | rt::GeometryType::Geometry(geo_ceiling), 452 | vec![mtl_constant], 453 | )?; 454 | let geo_inst_wall_back = ctx.geometry_instance_create( 455 | rt::GeometryType::Geometry(geo_wall_back), 456 | vec![mtl_constant], 457 | )?; 458 | let geo_inst_wall_left = ctx.geometry_instance_create( 459 | rt::GeometryType::Geometry(geo_wall_left), 460 | vec![mtl_constant], 461 | )?; 462 | let geo_inst_wall_right = ctx.geometry_instance_create( 463 | rt::GeometryType::Geometry(geo_wall_right), 464 | vec![mtl_constant], 465 | )?; 466 | let geo_inst_tall_box = ctx.geometry_instance_create( 467 | rt::GeometryType::Geometry(geo_tall_box), 468 | vec![mtl_constant], 469 | )?; 470 | let geo_inst_short_box = ctx.geometry_instance_create( 471 | rt::GeometryType::Geometry(geo_short_box), 472 | vec![mtl_constant], 473 | )?; 474 | 475 | let geo_inst_light = ctx.geometry_instance_create( 476 | rt::GeometryType::Geometry(geo_light), 477 | vec![mtl_emission], 478 | )?; 479 | 480 | let col_white = v3f(0.76, 0.75, 0.5); 481 | let col_red = v3f(0.63, 0.06, 0.04); 482 | let col_green = v3f(0.15, 0.48, 0.09); 483 | 484 | ctx.geometry_instance_set_variable( 485 | geo_inst_floor, 486 | "in_diffuse_albedo", 487 | col_white, 488 | )?; 489 | ctx.geometry_instance_set_variable( 490 | geo_inst_ceiling, 491 | "in_diffuse_albedo", 492 | col_white, 493 | )?; 494 | ctx.geometry_instance_set_variable( 495 | geo_inst_wall_back, 496 | "in_diffuse_albedo", 497 | col_white, 498 | )?; 499 | ctx.geometry_instance_set_variable( 500 | geo_inst_wall_left, 501 | "in_diffuse_albedo", 502 | col_red, 503 | )?; 504 | ctx.geometry_instance_set_variable( 505 | geo_inst_wall_right, 506 | "in_diffuse_albedo", 507 | col_green, 508 | )?; 509 | ctx.geometry_instance_set_variable( 510 | geo_inst_tall_box, 511 | "in_diffuse_albedo", 512 | col_white, 513 | )?; 514 | ctx.geometry_instance_set_variable( 515 | geo_inst_short_box, 516 | "in_diffuse_albedo", 517 | col_white, 518 | )?; 519 | 520 | let acc_main_box = ctx.acceleration_create(rt::Builder::Trbvh)?; 521 | 522 | let geo_group = ctx.geometry_group_create( 523 | acc_main_box, 524 | vec![ 525 | geo_inst_floor, 526 | geo_inst_ceiling, 527 | geo_inst_wall_back, 528 | geo_inst_wall_left, 529 | geo_inst_wall_right, 530 | geo_inst_light, 531 | ], 532 | )?; 533 | 534 | let acc_tb = ctx.acceleration_create(rt::Builder::NoAccel)?; 535 | let geo_group_tall_box = 536 | ctx.geometry_group_create(acc_tb, vec![geo_inst_tall_box])?; 537 | 538 | let acc_sb = ctx.acceleration_create(rt::Builder::NoAccel)?; 539 | let geo_group_short_box = 540 | ctx.geometry_group_create(acc_sb, vec![geo_inst_short_box])?; 541 | 542 | let mtx_tall_box = m4f_translation(70.0, 0.0, -385.0) 543 | * m4f_rotation(v3f(0.0, 1.0, 0.0), 0.3925); 544 | let mtx_short_box = m4f_translation(320.0, 0.0, -255.0) 545 | * m4f_rotation(v3f(0.0, 1.0, 0.0), -0.314); 546 | 547 | let xform_tall_box = ctx.transform_create( 548 | rt::MatrixFormat::ColumnMajor(mtx_tall_box), 549 | rt::TransformChild::GeometryGroup(geo_group_tall_box), 550 | )?; 551 | let xform_short_box = ctx.transform_create( 552 | rt::MatrixFormat::ColumnMajor(mtx_short_box), 553 | rt::TransformChild::GeometryGroup(geo_group_short_box), 554 | )?; 555 | 556 | let mtx = M4f32::identity(); 557 | 558 | let xform = ctx.transform_create( 559 | rt::MatrixFormat::ColumnMajor(mtx), 560 | rt::TransformChild::GeometryGroup(geo_group), 561 | )?; 562 | 563 | let acc_grp = ctx.acceleration_create(rt::Builder::NoAccel)?; 564 | let grp_all = ctx.group_create( 565 | acc_grp, 566 | vec![ 567 | rt::GroupChild::Transform(xform), 568 | rt::GroupChild::Transform(xform_tall_box), 569 | rt::GroupChild::Transform(xform_short_box), 570 | ], 571 | )?; 572 | 573 | ctx.set_variable("scene_root", rt::ObjectHandle::Group(grp_all))?; 574 | 575 | let entry_point = ctx.add_entry_point(prg_cam_screen, None)?; 576 | 577 | ctx.set_print_enabled(false)?; 578 | 579 | Ok((ctx, entry_point)) 580 | } 581 | 582 | pub fn create_box( 583 | ctx: &mut rt::Context, 584 | min: V3f32, 585 | max: V3f32, 586 | prg_mesh_bound: rt::ProgramHandle, 587 | prg_mesh_intersect: rt::ProgramHandle, 588 | ) -> Result { 589 | let buf_vertex = ctx.buffer_create_from_slice_1d( 590 | &[ 591 | // BLF - 0 592 | v3f(min.x, min.y, min.z), 593 | // BRF - 1 594 | v3f(max.x, min.y, min.z), 595 | // TRF - 2 596 | v3f(max.x, max.y, min.z), 597 | // TLF - 3 598 | v3f(min.x, max.y, min.z), 599 | // BLB - 4 600 | v3f(min.x, min.y, max.z), 601 | // BRB - 5 602 | v3f(max.x, min.y, max.z), 603 | // TRB - 6 604 | v3f(max.x, max.y, max.z), 605 | // TLB - 7 606 | v3f(min.x, max.y, max.z), 607 | ], 608 | rt::BufferType::INPUT, 609 | rt::BufferFlag::NONE, 610 | )?; 611 | 612 | let indices = [ 613 | // FRONT 614 | v3i(2, 1, 0), 615 | v3i(3, 2, 0), 616 | // BACK 617 | v3i(4, 5, 6), 618 | v3i(4, 6, 7), 619 | // LEFT 620 | v3i(0, 4, 7), 621 | v3i(0, 7, 3), 622 | // RIGHT 623 | v3i(5, 1, 2), 624 | v3i(5, 2, 6), 625 | // TOP 626 | v3i(6, 2, 3), 627 | v3i(7, 6, 3), 628 | // BOTTOM 629 | v3i(1, 5, 4), 630 | v3i(0, 1, 4), 631 | ]; 632 | 633 | let buf_indices = ctx.buffer_create_from_slice_1d( 634 | &indices, 635 | rt::BufferType::INPUT, 636 | rt::BufferFlag::NONE, 637 | )?; 638 | 639 | let buf_normal = ctx.buffer_create_1d::( 640 | 0, 641 | rt::BufferType::INPUT, 642 | rt::BufferFlag::NONE, 643 | )?; 644 | 645 | let buf_texcoord = ctx.buffer_create_1d::( 646 | 0, 647 | rt::BufferType::INPUT, 648 | rt::BufferFlag::NONE, 649 | )?; 650 | 651 | let geo_box = ctx.geometry_create(prg_mesh_bound, prg_mesh_intersect)?; 652 | ctx.geometry_set_primitive_count(geo_box, indices.len() as u32)?; 653 | ctx.geometry_set_variable( 654 | geo_box, 655 | "vertex_buffer", 656 | rt::ObjectHandle::Buffer1d(buf_vertex), 657 | )?; 658 | ctx.geometry_set_variable( 659 | geo_box, 660 | "index_buffer", 661 | rt::ObjectHandle::Buffer1d(buf_indices), 662 | )?; 663 | ctx.geometry_set_variable( 664 | geo_box, 665 | "normal_buffer", 666 | rt::ObjectHandle::Buffer1d(buf_normal), 667 | )?; 668 | ctx.geometry_set_variable( 669 | geo_box, 670 | "texcoord_buffer", 671 | rt::ObjectHandle::Buffer1d(buf_texcoord), 672 | )?; 673 | 674 | Ok(geo_box) 675 | } 676 | 677 | pub fn create_quad( 678 | ctx: &mut rt::Context, 679 | vertices: [V3f32; 4], 680 | prg_mesh_bound: rt::ProgramHandle, 681 | prg_mesh_intersect: rt::ProgramHandle, 682 | ) -> Result { 683 | let buf_vertex = ctx.buffer_create_from_slice_1d( 684 | &vertices, 685 | rt::BufferType::INPUT, 686 | rt::BufferFlag::NONE, 687 | )?; 688 | let indices = [v3i(0, 1, 2), v3i(0, 2, 3)]; 689 | let buf_indices = ctx.buffer_create_from_slice_1d( 690 | &indices, 691 | rt::BufferType::INPUT, 692 | rt::BufferFlag::NONE, 693 | )?; 694 | let buf_normal = ctx.buffer_create_1d::( 695 | 0, 696 | rt::BufferType::INPUT, 697 | rt::BufferFlag::NONE, 698 | )?; 699 | let buf_texcoord = ctx.buffer_create_1d::( 700 | 0, 701 | rt::BufferType::INPUT, 702 | rt::BufferFlag::NONE, 703 | )?; 704 | let geo_triangle = 705 | ctx.geometry_create(prg_mesh_bound, prg_mesh_intersect)?; 706 | ctx.geometry_set_primitive_count(geo_triangle, indices.len() as u32)?; 707 | ctx.geometry_set_variable( 708 | geo_triangle, 709 | "vertex_buffer", 710 | rt::ObjectHandle::Buffer1d(buf_vertex), 711 | )?; 712 | ctx.geometry_set_variable( 713 | geo_triangle, 714 | "index_buffer", 715 | rt::ObjectHandle::Buffer1d(buf_indices), 716 | )?; 717 | ctx.geometry_set_variable( 718 | geo_triangle, 719 | "normal_buffer", 720 | rt::ObjectHandle::Buffer1d(buf_normal), 721 | )?; 722 | ctx.geometry_set_variable( 723 | geo_triangle, 724 | "texcoord_buffer", 725 | rt::ObjectHandle::Buffer1d(buf_texcoord), 726 | )?; 727 | 728 | Ok(geo_triangle) 729 | } 730 | 731 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 732 | match event { 733 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => { 734 | window.set_should_close(true) 735 | } 736 | _ => {} 737 | } 738 | } 739 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "aho-corasick" 3 | version = "0.6.8" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | dependencies = [ 6 | "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 7 | ] 8 | 9 | [[package]] 10 | name = "alga" 11 | version = "0.7.2" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | dependencies = [ 14 | "approx 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 15 | "libm 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 17 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 18 | ] 19 | 20 | [[package]] 21 | name = "ansi_term" 22 | version = "0.11.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | dependencies = [ 25 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 26 | ] 27 | 28 | [[package]] 29 | name = "approx" 30 | version = "0.3.0" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | dependencies = [ 33 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 34 | ] 35 | 36 | [[package]] 37 | name = "arrayvec" 38 | version = "0.4.7" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | dependencies = [ 41 | "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 42 | ] 43 | 44 | [[package]] 45 | name = "atty" 46 | version = "0.2.11" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | dependencies = [ 49 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 50 | "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 51 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 52 | ] 53 | 54 | [[package]] 55 | name = "bindgen" 56 | version = "0.41.0" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | dependencies = [ 59 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 60 | "cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 61 | "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 62 | "clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", 63 | "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", 64 | "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", 65 | "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 66 | "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 67 | "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 68 | "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 69 | "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 70 | "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 71 | "which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 72 | ] 73 | 74 | [[package]] 75 | name = "bitflags" 76 | version = "1.0.4" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | 79 | [[package]] 80 | name = "cc" 81 | version = "1.0.25" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | 84 | [[package]] 85 | name = "cexpr" 86 | version = "0.2.3" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | dependencies = [ 89 | "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 90 | ] 91 | 92 | [[package]] 93 | name = "cfg-if" 94 | version = "0.1.5" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | 97 | [[package]] 98 | name = "clang-sys" 99 | version = "0.23.0" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | dependencies = [ 102 | "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 103 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 104 | "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 105 | ] 106 | 107 | [[package]] 108 | name = "clap" 109 | version = "2.32.0" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | dependencies = [ 112 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 114 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 115 | "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 116 | "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 117 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 118 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 119 | ] 120 | 121 | [[package]] 122 | name = "cloudabi" 123 | version = "0.0.3" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | dependencies = [ 126 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 127 | ] 128 | 129 | [[package]] 130 | name = "cmake" 131 | version = "0.1.35" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | dependencies = [ 134 | "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 135 | ] 136 | 137 | [[package]] 138 | name = "config" 139 | version = "0.9.1" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | dependencies = [ 142 | "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 143 | "nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 144 | "rust-ini 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", 145 | "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", 146 | "serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 147 | "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", 148 | "toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 149 | "yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 150 | ] 151 | 152 | [[package]] 153 | name = "crossbeam-channel" 154 | version = "0.2.6" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | dependencies = [ 157 | "crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 158 | "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 159 | "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", 160 | "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 161 | "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 162 | ] 163 | 164 | [[package]] 165 | name = "crossbeam-epoch" 166 | version = "0.6.0" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | dependencies = [ 169 | "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", 170 | "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 171 | "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", 172 | "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 173 | "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 174 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 175 | ] 176 | 177 | [[package]] 178 | name = "crossbeam-utils" 179 | version = "0.5.0" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | 182 | [[package]] 183 | name = "enum_primitive" 184 | version = "0.1.1" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | dependencies = [ 187 | "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 188 | ] 189 | 190 | [[package]] 191 | name = "env_logger" 192 | version = "0.5.13" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | dependencies = [ 195 | "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 196 | "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 197 | "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 198 | "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 199 | "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 200 | ] 201 | 202 | [[package]] 203 | name = "fuchsia-zircon" 204 | version = "0.3.3" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | dependencies = [ 207 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 208 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 209 | ] 210 | 211 | [[package]] 212 | name = "fuchsia-zircon-sys" 213 | version = "0.3.3" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | 216 | [[package]] 217 | name = "generic-array" 218 | version = "0.11.1" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | dependencies = [ 221 | "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 222 | ] 223 | 224 | [[package]] 225 | name = "gl" 226 | version = "0.10.0" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | dependencies = [ 229 | "gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 230 | ] 231 | 232 | [[package]] 233 | name = "gl_generator" 234 | version = "0.9.0" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | dependencies = [ 237 | "khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 238 | "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 239 | "xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 240 | ] 241 | 242 | [[package]] 243 | name = "glfw" 244 | version = "0.23.0" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | dependencies = [ 247 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 248 | "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 249 | "glfw-sys 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 250 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 251 | "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 252 | "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 253 | "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 254 | ] 255 | 256 | [[package]] 257 | name = "glfw-sys" 258 | version = "3.2.2" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | dependencies = [ 261 | "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 262 | ] 263 | 264 | [[package]] 265 | name = "glob" 266 | version = "0.2.11" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | 269 | [[package]] 270 | name = "humantime" 271 | version = "1.1.1" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | dependencies = [ 274 | "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 275 | ] 276 | 277 | [[package]] 278 | name = "itoa" 279 | version = "0.4.3" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | 282 | [[package]] 283 | name = "khronos_api" 284 | version = "2.2.0" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | 287 | [[package]] 288 | name = "lazy_static" 289 | version = "0.2.11" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | 292 | [[package]] 293 | name = "lazy_static" 294 | version = "1.1.0" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | dependencies = [ 297 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 298 | ] 299 | 300 | [[package]] 301 | name = "libc" 302 | version = "0.2.43" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | 305 | [[package]] 306 | name = "libloading" 307 | version = "0.5.0" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | dependencies = [ 310 | "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 311 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 312 | ] 313 | 314 | [[package]] 315 | name = "libm" 316 | version = "0.1.2" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | 319 | [[package]] 320 | name = "linked-hash-map" 321 | version = "0.3.0" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | dependencies = [ 324 | "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 325 | "serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 326 | ] 327 | 328 | [[package]] 329 | name = "linked-hash-map" 330 | version = "0.5.1" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | 333 | [[package]] 334 | name = "lock_api" 335 | version = "0.1.4" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | dependencies = [ 338 | "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 339 | "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 340 | ] 341 | 342 | [[package]] 343 | name = "log" 344 | version = "0.4.5" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | dependencies = [ 347 | "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 348 | ] 349 | 350 | [[package]] 351 | name = "matrixmultiply" 352 | version = "0.1.14" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | dependencies = [ 355 | "rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 356 | ] 357 | 358 | [[package]] 359 | name = "memchr" 360 | version = "1.0.2" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | dependencies = [ 363 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 364 | ] 365 | 366 | [[package]] 367 | name = "memchr" 368 | version = "2.1.0" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | dependencies = [ 371 | "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 373 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 374 | ] 375 | 376 | [[package]] 377 | name = "memoffset" 378 | version = "0.2.1" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | 381 | [[package]] 382 | name = "nalgebra" 383 | version = "0.16.5" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | dependencies = [ 386 | "alga 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 387 | "approx 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 388 | "generic-array 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", 389 | "matrixmultiply 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 390 | "num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 391 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 392 | "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 393 | "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 394 | ] 395 | 396 | [[package]] 397 | name = "nodrop" 398 | version = "0.1.12" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | 401 | [[package]] 402 | name = "nom" 403 | version = "1.2.4" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | 406 | [[package]] 407 | name = "nom" 408 | version = "3.2.1" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | dependencies = [ 411 | "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 412 | ] 413 | 414 | [[package]] 415 | name = "nom" 416 | version = "4.1.1" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | dependencies = [ 419 | "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 420 | ] 421 | 422 | [[package]] 423 | name = "num" 424 | version = "0.1.42" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | dependencies = [ 427 | "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", 428 | "num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 429 | "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 430 | "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 431 | "num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 432 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 433 | ] 434 | 435 | [[package]] 436 | name = "num-bigint" 437 | version = "0.1.44" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | dependencies = [ 440 | "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 441 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 442 | "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 443 | "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", 444 | ] 445 | 446 | [[package]] 447 | name = "num-complex" 448 | version = "0.1.43" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | dependencies = [ 451 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 452 | "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", 453 | ] 454 | 455 | [[package]] 456 | name = "num-complex" 457 | version = "0.2.1" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | dependencies = [ 460 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 461 | ] 462 | 463 | [[package]] 464 | name = "num-integer" 465 | version = "0.1.39" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | dependencies = [ 468 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 469 | ] 470 | 471 | [[package]] 472 | name = "num-iter" 473 | version = "0.1.37" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | dependencies = [ 476 | "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 477 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 478 | ] 479 | 480 | [[package]] 481 | name = "num-rational" 482 | version = "0.1.42" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | dependencies = [ 485 | "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", 486 | "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", 487 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 488 | "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", 489 | ] 490 | 491 | [[package]] 492 | name = "num-traits" 493 | version = "0.1.43" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | dependencies = [ 496 | "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 497 | ] 498 | 499 | [[package]] 500 | name = "num-traits" 501 | version = "0.2.6" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | 504 | [[package]] 505 | name = "optix" 506 | version = "0.1.0" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | dependencies = [ 509 | "bindgen 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", 510 | "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 511 | "config 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 512 | "nalgebra 0.16.5 (registry+https://github.com/rust-lang/crates.io-index)", 513 | ] 514 | 515 | [[package]] 516 | name = "optix-pathtracer-example" 517 | version = "0.1.0" 518 | dependencies = [ 519 | "cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", 520 | "config 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 521 | "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 522 | "gl 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 523 | "glfw 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", 524 | "optix 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 525 | ] 526 | 527 | [[package]] 528 | name = "owning_ref" 529 | version = "0.3.3" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | dependencies = [ 532 | "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 533 | ] 534 | 535 | [[package]] 536 | name = "parking_lot" 537 | version = "0.6.4" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | dependencies = [ 540 | "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 541 | "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 542 | ] 543 | 544 | [[package]] 545 | name = "parking_lot_core" 546 | version = "0.3.1" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | dependencies = [ 549 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 550 | "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 551 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 552 | "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 553 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 554 | ] 555 | 556 | [[package]] 557 | name = "peeking_take_while" 558 | version = "0.1.2" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | 561 | [[package]] 562 | name = "proc-macro2" 563 | version = "0.3.5" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | dependencies = [ 566 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 567 | ] 568 | 569 | [[package]] 570 | name = "quick-error" 571 | version = "1.2.2" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | 574 | [[package]] 575 | name = "quote" 576 | version = "0.5.2" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | dependencies = [ 579 | "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 580 | ] 581 | 582 | [[package]] 583 | name = "rand" 584 | version = "0.4.3" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | dependencies = [ 587 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 588 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 589 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 590 | ] 591 | 592 | [[package]] 593 | name = "rand" 594 | version = "0.5.5" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | dependencies = [ 597 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 598 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 599 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 600 | "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 601 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 602 | ] 603 | 604 | [[package]] 605 | name = "rand_core" 606 | version = "0.2.2" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | dependencies = [ 609 | "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 610 | ] 611 | 612 | [[package]] 613 | name = "rand_core" 614 | version = "0.3.0" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | 617 | [[package]] 618 | name = "rawpointer" 619 | version = "0.1.0" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | 622 | [[package]] 623 | name = "redox_syscall" 624 | version = "0.1.40" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | 627 | [[package]] 628 | name = "redox_termios" 629 | version = "0.1.1" 630 | source = "registry+https://github.com/rust-lang/crates.io-index" 631 | dependencies = [ 632 | "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 633 | ] 634 | 635 | [[package]] 636 | name = "regex" 637 | version = "1.0.5" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | dependencies = [ 640 | "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", 641 | "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 642 | "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 643 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 644 | "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 645 | ] 646 | 647 | [[package]] 648 | name = "regex-syntax" 649 | version = "0.6.2" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | dependencies = [ 652 | "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 653 | ] 654 | 655 | [[package]] 656 | name = "rust-ini" 657 | version = "0.12.2" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | 660 | [[package]] 661 | name = "rustc-serialize" 662 | version = "0.3.24" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | 665 | [[package]] 666 | name = "rustc_version" 667 | version = "0.2.3" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | dependencies = [ 670 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 671 | ] 672 | 673 | [[package]] 674 | name = "ryu" 675 | version = "0.2.6" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | 678 | [[package]] 679 | name = "scopeguard" 680 | version = "0.3.3" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | 683 | [[package]] 684 | name = "semver" 685 | version = "0.2.3" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | dependencies = [ 688 | "nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 689 | ] 690 | 691 | [[package]] 692 | name = "semver" 693 | version = "0.9.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | dependencies = [ 696 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 697 | ] 698 | 699 | [[package]] 700 | name = "semver-parser" 701 | version = "0.7.0" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | 704 | [[package]] 705 | name = "serde" 706 | version = "0.8.23" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | 709 | [[package]] 710 | name = "serde" 711 | version = "1.0.80" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | 714 | [[package]] 715 | name = "serde-hjson" 716 | version = "0.8.2" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | dependencies = [ 719 | "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 720 | "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 721 | "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 722 | "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 723 | "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 724 | ] 725 | 726 | [[package]] 727 | name = "serde_json" 728 | version = "1.0.32" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | dependencies = [ 731 | "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 732 | "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 733 | "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", 734 | ] 735 | 736 | [[package]] 737 | name = "serde_test" 738 | version = "0.8.23" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | dependencies = [ 741 | "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 742 | ] 743 | 744 | [[package]] 745 | name = "smallvec" 746 | version = "0.6.5" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | dependencies = [ 749 | "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 750 | ] 751 | 752 | [[package]] 753 | name = "stable_deref_trait" 754 | version = "1.1.1" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | 757 | [[package]] 758 | name = "strsim" 759 | version = "0.7.0" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | 762 | [[package]] 763 | name = "termcolor" 764 | version = "1.0.4" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | dependencies = [ 767 | "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 768 | ] 769 | 770 | [[package]] 771 | name = "termion" 772 | version = "1.5.1" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | dependencies = [ 775 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 776 | "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", 777 | "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 778 | ] 779 | 780 | [[package]] 781 | name = "textwrap" 782 | version = "0.10.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | dependencies = [ 785 | "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 786 | ] 787 | 788 | [[package]] 789 | name = "thread_local" 790 | version = "0.3.6" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | dependencies = [ 793 | "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 794 | ] 795 | 796 | [[package]] 797 | name = "toml" 798 | version = "0.4.8" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | dependencies = [ 801 | "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", 802 | ] 803 | 804 | [[package]] 805 | name = "typenum" 806 | version = "1.10.0" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | 809 | [[package]] 810 | name = "ucd-util" 811 | version = "0.1.1" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | 814 | [[package]] 815 | name = "unicode-width" 816 | version = "0.1.5" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | 819 | [[package]] 820 | name = "unicode-xid" 821 | version = "0.1.0" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | 824 | [[package]] 825 | name = "unreachable" 826 | version = "1.0.0" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | dependencies = [ 829 | "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 830 | ] 831 | 832 | [[package]] 833 | name = "utf8-ranges" 834 | version = "1.0.1" 835 | source = "registry+https://github.com/rust-lang/crates.io-index" 836 | 837 | [[package]] 838 | name = "vec_map" 839 | version = "0.8.1" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | 842 | [[package]] 843 | name = "version_check" 844 | version = "0.1.5" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | 847 | [[package]] 848 | name = "void" 849 | version = "1.0.2" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | 852 | [[package]] 853 | name = "which" 854 | version = "1.0.5" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | dependencies = [ 857 | "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", 858 | ] 859 | 860 | [[package]] 861 | name = "winapi" 862 | version = "0.3.6" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | dependencies = [ 865 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 866 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 867 | ] 868 | 869 | [[package]] 870 | name = "winapi-i686-pc-windows-gnu" 871 | version = "0.4.0" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | 874 | [[package]] 875 | name = "winapi-util" 876 | version = "0.1.1" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | dependencies = [ 879 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 880 | ] 881 | 882 | [[package]] 883 | name = "winapi-x86_64-pc-windows-gnu" 884 | version = "0.4.0" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | 887 | [[package]] 888 | name = "wincolor" 889 | version = "1.0.1" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | dependencies = [ 892 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 893 | "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 894 | ] 895 | 896 | [[package]] 897 | name = "xml-rs" 898 | version = "0.7.0" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | dependencies = [ 901 | "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 902 | ] 903 | 904 | [[package]] 905 | name = "yaml-rust" 906 | version = "0.4.2" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | dependencies = [ 909 | "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 910 | ] 911 | 912 | [metadata] 913 | "checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" 914 | "checksum alga 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24bb00eeca59f2986c747b8c2f271d52310ce446be27428fc34705138b155778" 915 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 916 | "checksum approx 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f71f10b5c4946a64aad7b8cf65e3406cd3da22fc448595991d22423cf6db67b4" 917 | "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" 918 | "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" 919 | "checksum bindgen 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64eeb92e16bd21d6c95738458f80b2c95bad56cc8eeef7fdfaaf70268c56fe3" 920 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" 921 | "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" 922 | "checksum cexpr 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42aac45e9567d97474a834efdee3081b3c942b2205be932092f53354ce503d6c" 923 | "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" 924 | "checksum clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7f7c04e52c35222fffcc3a115b5daf5f7e2bfb71c13c4e2321afe1fc71859c2" 925 | "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" 926 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 927 | "checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a" 928 | "checksum config 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13490293b8a84cc82cd531da41adeae82cd9eaa40e926ac18865aa361f9c9f60" 929 | "checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" 930 | "checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416" 931 | "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" 932 | "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" 933 | "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" 934 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 935 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 936 | "checksum generic-array 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8107dafa78c80c848b71b60133954b4a58609a3a1a5f9af037ecc7f67280f369" 937 | "checksum gl 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81457bb802910ad5b535eb48541c51830a761804aa5b7087adbc9d049aa57aca" 938 | "checksum gl_generator 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a795170cbd85b5a7baa58d6d7525cae6a03e486859860c220f7ebbbdd379d0a" 939 | "checksum glfw 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be0e1e2f834ed535c3e3d0e3f8b339187b1da7ff829ddf98757d0b2752a7b945" 940 | "checksum glfw-sys 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f72bb86276679c5370276224546eef2dce99b23da2f364fd8b097c79db310b39" 941 | "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 942 | "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" 943 | "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" 944 | "checksum khronos_api 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "037ab472c33f67b5fbd3e9163a2645319e5356fcd355efa6d4eb7fff4bbcb554" 945 | "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" 946 | "checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" 947 | "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" 948 | "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" 949 | "checksum libm 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "03c0bb6d5ce1b5cc6fd0578ec1cbc18c9d88b5b591a5c7c1d6c6175e266a0819" 950 | "checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" 951 | "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" 952 | "checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" 953 | "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" 954 | "checksum matrixmultiply 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cac1a66eab356036af85ea093101a14223dc6e3f4c02a59b7d572e5b93270bf7" 955 | "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" 956 | "checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" 957 | "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" 958 | "checksum nalgebra 0.16.5 (registry+https://github.com/rust-lang/crates.io-index)" = "cc782b799c55698d80b61b43458f0c1a1379900bfd5b26d14a1241967b4e35e0" 959 | "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" 960 | "checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce" 961 | "checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b" 962 | "checksum nom 4.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c349f68f25f596b9f44cf0e7c69752a5c633b0550c3ff849518bfba0233774a" 963 | "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" 964 | "checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" 965 | "checksum num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" 966 | "checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8" 967 | "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" 968 | "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" 969 | "checksum num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" 970 | "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" 971 | "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" 972 | "checksum optix 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881549c4599144b2bd738f399f5bd13a8593c0775e9858efed4a34184733a863" 973 | "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" 974 | "checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" 975 | "checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" 976 | "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 977 | "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" 978 | "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" 979 | "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" 980 | "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" 981 | "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" 982 | "checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" 983 | "checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" 984 | "checksum rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019" 985 | "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" 986 | "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" 987 | "checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" 988 | "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" 989 | "checksum rust-ini 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ac66e816614e124a692b6ac1b8437237a518c9155a3aacab83a373982630c715" 990 | "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" 991 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 992 | "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" 993 | "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 994 | "checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" 995 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 996 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 997 | "checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" 998 | "checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" 999 | "checksum serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b833c5ad67d52ced5f5938b2980f32a9c1c5ef047f0b4fb3127e7a423c76153" 1000 | "checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" 1001 | "checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" 1002 | "checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" 1003 | "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" 1004 | "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" 1005 | "checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" 1006 | "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" 1007 | "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" 1008 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 1009 | "checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65" 1010 | "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" 1011 | "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" 1012 | "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" 1013 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1014 | "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" 1015 | "checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" 1016 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" 1017 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 1018 | "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1019 | "checksum which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e84a603e7e0b1ce1aa1ee2b109c7be00155ce52df5081590d1ffb93f4f515cb2" 1020 | "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" 1021 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1022 | "checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" 1023 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1024 | "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" 1025 | "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" 1026 | "checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e" 1027 | --------------------------------------------------------------------------------