├── .gitignore ├── LICENSE-FreeGlut.txt ├── LICENSE-Glew.txt ├── LICENSE.txt ├── README.md └── src ├── CS530Proj5.sln ├── StreamSurface ├── Activity.h ├── CudaHelper.h ├── CudaMathHelper.h ├── GlyphsActivity.h ├── SteamlinesLineActivity.h ├── StreamSurface.cu ├── StreamSurface.vcxproj ├── StreamSurface.vcxproj.filters ├── Utils.h ├── VectorField.h ├── VectorFieldInfo.h ├── main.cpp ├── stdafx.cpp └── stdafx.h ├── bin ├── StreamSurface-Release-x64.exe ├── freeglut.dll └── glew32.dll ├── include └── GL │ ├── freeglut.h │ ├── freeglut_ext.h │ ├── freeglut_std.h │ ├── glew.h │ ├── glut.h │ ├── glxew.h │ └── wglew.h └── libs ├── freeglut.lib └── glew32.lib /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | *.opensdf 4 | *.sdf 5 | *.suo 6 | *.user 7 | 8 | src/ipch 9 | **/x64 10 | 11 | # Windows rubbish 12 | Thumbs.db 13 | ehthumbs.db -------------------------------------------------------------------------------- /LICENSE-FreeGlut.txt: -------------------------------------------------------------------------------- 1 | 2 | Freeglut Copyright 3 | ------------------ 4 | 5 | Freeglut code without an explicit copyright is covered by the following 6 | copyright: 7 | 8 | Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies or substantial portions of the Software. 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | Except as contained in this notice, the name of Pawel W. Olszta shall not be 26 | used in advertising or otherwise to promote the sale, use or other dealings 27 | in this Software without prior written authorization from Pawel W. Olszta. 28 | -------------------------------------------------------------------------------- /LICENSE-Glew.txt: -------------------------------------------------------------------------------- 1 | The OpenGL Extension Wrangler Library 2 | Copyright (C) 2002-2007, Milan Ikits 3 | Copyright (C) 2002-2007, Marcelo E. Magallon 4 | Copyright (C) 2002, Lev Povalahev 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | * The name of the author may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 | THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | Mesa 3-D graphics library 32 | Version: 7.0 33 | 34 | Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a 37 | copy of this software and associated documentation files (the "Software"), 38 | to deal in the Software without restriction, including without limitation 39 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 40 | and/or sell copies of the Software, and to permit persons to whom the 41 | Software is furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included 44 | in all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 47 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 48 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 49 | BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 50 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 51 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 52 | 53 | 54 | Copyright (c) 2007 The Khronos Group Inc. 55 | 56 | Permission is hereby granted, free of charge, to any person obtaining a 57 | copy of this software and/or associated documentation files (the 58 | "Materials"), to deal in the Materials without restriction, including 59 | without limitation the rights to use, copy, modify, merge, publish, 60 | distribute, sublicense, and/or sell copies of the Materials, and to 61 | permit persons to whom the Materials are furnished to do so, subject to 62 | the following conditions: 63 | 64 | The above copyright notice and this permission notice shall be included 65 | in all copies or substantial portions of the Materials. 66 | 67 | THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 68 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 69 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 70 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 71 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 72 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 73 | MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. 74 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NightElfik/Vector-field-visualization-using-cuda/2a63c0cc567342ccc38176461521129b76a18e36/README.md -------------------------------------------------------------------------------- /src/CS530Proj5.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 2012 3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StreamSurface", "StreamSurface\StreamSurface.vcxproj", "{F000C410-F59F-402A-AACD-B0A6074EDAE7}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|x64 = Debug|x64 8 | Release|x64 = Release|x64 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {F000C410-F59F-402A-AACD-B0A6074EDAE7}.Debug|x64.ActiveCfg = Debug|x64 12 | {F000C410-F59F-402A-AACD-B0A6074EDAE7}.Debug|x64.Build.0 = Debug|x64 13 | {F000C410-F59F-402A-AACD-B0A6074EDAE7}.Release|x64.ActiveCfg = Release|x64 14 | {F000C410-F59F-402A-AACD-B0A6074EDAE7}.Release|x64.Build.0 = Release|x64 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /src/StreamSurface/Activity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace mf { 4 | 5 | template 6 | class TActivity { 7 | 8 | protected: 9 | float m_lastDuration; 10 | 11 | public: 12 | 13 | 14 | float getLastTimerDuration() { 15 | return m_lastDuration; 16 | } 17 | 18 | virtual void recompute() = 0; 19 | virtual void drawControls(float& i, float incI) = 0; 20 | virtual bool keyboardCallback(unsigned char key) = 0; 21 | virtual bool motionCallback(int x, int y, int dx, int dy, int screenWidth, int screenHeight, int mouseButtonsState) = 0; 22 | virtual void displayCallback() = 0; 23 | 24 | }; 25 | 26 | typedef TActivity<> Activity; 27 | 28 | } -------------------------------------------------------------------------------- /src/StreamSurface/CudaHelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace mf { 4 | 5 | // Macro for automatic checking of CUDA operations. 6 | #define checkCudaErrors(val) checkCudaResult((val), #val, __FILE__, __LINE__) 7 | 8 | 9 | template 10 | void checkCudaResult(T result, const char* const func, const char* const file, int line) { 11 | if (result) { 12 | std::stringstream ss; 13 | ss << "CUDA error at " << file << ":" << line << " code=" << static_cast(result) 14 | << " \"" << func << "\""; 15 | std::cerr << ss.str() << std::endl; 16 | } 17 | } 18 | 19 | 20 | inline void createVbo(GLuint* vbo, GLenum target, uint size) { 21 | // create buffer object 22 | glGenBuffers(1, vbo); 23 | glBindBuffer(target, *vbo); 24 | 25 | // initialize buffer 26 | glBufferData(target, size, 0, GL_DYNAMIC_DRAW); 27 | glBindBuffer(target, 0); 28 | 29 | glutReportErrors(); 30 | } 31 | 32 | inline cudaError_t createCudaSharedVbo(GLuint* vbo, GLenum target, uint size, cudaGraphicsResource** cudaResource) { 33 | createVbo(vbo, target, size); 34 | 35 | assert(*cudaResource == nullptr); 36 | return cudaGraphicsGLRegisterBuffer(cudaResource, *vbo, cudaGraphicsMapFlagsNone); 37 | } 38 | 39 | 40 | inline void deleteVbo(GLuint* vbo) { 41 | if (*vbo == 0) { 42 | return; 43 | } 44 | 45 | glBindBuffer(GL_ARRAY_BUFFER, *vbo); 46 | glDeleteBuffers(1, vbo); 47 | 48 | *vbo = 0; 49 | 50 | glutReportErrors(); 51 | } 52 | 53 | inline cudaError_t deleteCudaSharedVbo(GLuint* vbo, cudaGraphicsResource* cudaResource) { 54 | deleteVbo(vbo); 55 | 56 | if (cudaResource == nullptr) { 57 | return cudaSuccess; 58 | } 59 | return cudaGraphicsUnregisterResource(cudaResource); 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /src/StreamSurface/CudaMathHelper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 1993-2012 NVIDIA Corporation. All rights reserved. 3 | * 4 | * Please refer to the NVIDIA end user license agreement (EULA) associated 5 | * with this source code for terms and conditions that govern your use of 6 | * this software. Any use, reproduction, disclosure, or distribution of 7 | * this software and related documentation outside the terms of the EULA 8 | * is strictly prohibited. 9 | * 10 | */ 11 | 12 | /* 13 | * This file implements common mathematical operations on vector types 14 | * (float3, float4 etc.) since these are not provided as standard by CUDA. 15 | * 16 | * The syntax is modeled on the Cg standard library. 17 | * 18 | * This is part of the Helper library includes 19 | * 20 | * Thanks to Linh Hah for additions and fixes. 21 | */ 22 | 23 | #ifndef HELPER_MATH_H 24 | #define HELPER_MATH_H 25 | 26 | #include "cuda_runtime.h" 27 | 28 | typedef unsigned int uint; 29 | typedef unsigned short ushort; 30 | 31 | #ifndef __CUDACC__ 32 | #include 33 | 34 | //////////////////////////////////////////////////////////////////////////////// 35 | // host implementations of CUDA functions 36 | //////////////////////////////////////////////////////////////////////////////// 37 | 38 | inline float fminf(float a, float b) 39 | { 40 | return a < b ? a : b; 41 | } 42 | 43 | inline float fmaxf(float a, float b) 44 | { 45 | return a > b ? a : b; 46 | } 47 | 48 | inline int max(int a, int b) 49 | { 50 | return a > b ? a : b; 51 | } 52 | 53 | inline int min(int a, int b) 54 | { 55 | return a < b ? a : b; 56 | } 57 | 58 | inline float rsqrtf(float x) 59 | { 60 | return 1.0f / sqrtf(x); 61 | } 62 | #endif 63 | 64 | //////////////////////////////////////////////////////////////////////////////// 65 | // constructors 66 | //////////////////////////////////////////////////////////////////////////////// 67 | 68 | inline __host__ __device__ float2 make_float2(float s) 69 | { 70 | return make_float2(s, s); 71 | } 72 | inline __host__ __device__ float2 make_float2(float3 a) 73 | { 74 | return make_float2(a.x, a.y); 75 | } 76 | inline __host__ __device__ float2 make_float2(int2 a) 77 | { 78 | return make_float2(float(a.x), float(a.y)); 79 | } 80 | inline __host__ __device__ float2 make_float2(uint2 a) 81 | { 82 | return make_float2(float(a.x), float(a.y)); 83 | } 84 | 85 | inline __host__ __device__ int2 make_int2(int s) 86 | { 87 | return make_int2(s, s); 88 | } 89 | inline __host__ __device__ int2 make_int2(int3 a) 90 | { 91 | return make_int2(a.x, a.y); 92 | } 93 | inline __host__ __device__ int2 make_int2(uint2 a) 94 | { 95 | return make_int2(int(a.x), int(a.y)); 96 | } 97 | inline __host__ __device__ int2 make_int2(float2 a) 98 | { 99 | return make_int2(int(a.x), int(a.y)); 100 | } 101 | 102 | inline __host__ __device__ uint2 make_uint2(uint s) 103 | { 104 | return make_uint2(s, s); 105 | } 106 | inline __host__ __device__ uint2 make_uint2(uint3 a) 107 | { 108 | return make_uint2(a.x, a.y); 109 | } 110 | inline __host__ __device__ uint2 make_uint2(int2 a) 111 | { 112 | return make_uint2(uint(a.x), uint(a.y)); 113 | } 114 | 115 | inline __host__ __device__ float3 make_float3(float s) 116 | { 117 | return make_float3(s, s, s); 118 | } 119 | inline __host__ __device__ float3 make_float3(float2 a) 120 | { 121 | return make_float3(a.x, a.y, 0.0f); 122 | } 123 | inline __host__ __device__ float3 make_float3(float2 a, float s) 124 | { 125 | return make_float3(a.x, a.y, s); 126 | } 127 | inline __host__ __device__ float3 make_float3(float4 a) 128 | { 129 | return make_float3(a.x, a.y, a.z); 130 | } 131 | inline __host__ __device__ float3 make_float3(int3 a) 132 | { 133 | return make_float3(float(a.x), float(a.y), float(a.z)); 134 | } 135 | inline __host__ __device__ float3 make_float3(uint3 a) 136 | { 137 | return make_float3(float(a.x), float(a.y), float(a.z)); 138 | } 139 | 140 | inline __host__ __device__ int3 make_int3(int s) 141 | { 142 | return make_int3(s, s, s); 143 | } 144 | inline __host__ __device__ int3 make_int3(int2 a) 145 | { 146 | return make_int3(a.x, a.y, 0); 147 | } 148 | inline __host__ __device__ int3 make_int3(int2 a, int s) 149 | { 150 | return make_int3(a.x, a.y, s); 151 | } 152 | inline __host__ __device__ int3 make_int3(uint3 a) 153 | { 154 | return make_int3(int(a.x), int(a.y), int(a.z)); 155 | } 156 | inline __host__ __device__ int3 make_int3(float3 a) 157 | { 158 | return make_int3(int(a.x), int(a.y), int(a.z)); 159 | } 160 | 161 | inline __host__ __device__ uint3 make_uint3(uint s) 162 | { 163 | return make_uint3(s, s, s); 164 | } 165 | inline __host__ __device__ uint3 make_uint3(uint2 a) 166 | { 167 | return make_uint3(a.x, a.y, 0); 168 | } 169 | inline __host__ __device__ uint3 make_uint3(uint2 a, uint s) 170 | { 171 | return make_uint3(a.x, a.y, s); 172 | } 173 | inline __host__ __device__ uint3 make_uint3(uint4 a) 174 | { 175 | return make_uint3(a.x, a.y, a.z); 176 | } 177 | inline __host__ __device__ uint3 make_uint3(int3 a) 178 | { 179 | return make_uint3(uint(a.x), uint(a.y), uint(a.z)); 180 | } 181 | 182 | inline __host__ __device__ float4 make_float4(float s) 183 | { 184 | return make_float4(s, s, s, s); 185 | } 186 | inline __host__ __device__ float4 make_float4(float3 a) 187 | { 188 | return make_float4(a.x, a.y, a.z, 0.0f); 189 | } 190 | inline __host__ __device__ float4 make_float4(float3 a, float w) 191 | { 192 | return make_float4(a.x, a.y, a.z, w); 193 | } 194 | inline __host__ __device__ float4 make_float4(int4 a) 195 | { 196 | return make_float4(float(a.x), float(a.y), float(a.z), float(a.w)); 197 | } 198 | inline __host__ __device__ float4 make_float4(uint4 a) 199 | { 200 | return make_float4(float(a.x), float(a.y), float(a.z), float(a.w)); 201 | } 202 | 203 | inline __host__ __device__ int4 make_int4(int s) 204 | { 205 | return make_int4(s, s, s, s); 206 | } 207 | inline __host__ __device__ int4 make_int4(int3 a) 208 | { 209 | return make_int4(a.x, a.y, a.z, 0); 210 | } 211 | inline __host__ __device__ int4 make_int4(int3 a, int w) 212 | { 213 | return make_int4(a.x, a.y, a.z, w); 214 | } 215 | inline __host__ __device__ int4 make_int4(uint4 a) 216 | { 217 | return make_int4(int(a.x), int(a.y), int(a.z), int(a.w)); 218 | } 219 | inline __host__ __device__ int4 make_int4(float4 a) 220 | { 221 | return make_int4(int(a.x), int(a.y), int(a.z), int(a.w)); 222 | } 223 | 224 | 225 | inline __host__ __device__ uint4 make_uint4(uint s) 226 | { 227 | return make_uint4(s, s, s, s); 228 | } 229 | inline __host__ __device__ uint4 make_uint4(uint3 a) 230 | { 231 | return make_uint4(a.x, a.y, a.z, 0); 232 | } 233 | inline __host__ __device__ uint4 make_uint4(uint3 a, uint w) 234 | { 235 | return make_uint4(a.x, a.y, a.z, w); 236 | } 237 | inline __host__ __device__ uint4 make_uint4(int4 a) 238 | { 239 | return make_uint4(uint(a.x), uint(a.y), uint(a.z), uint(a.w)); 240 | } 241 | 242 | //////////////////////////////////////////////////////////////////////////////// 243 | // negate 244 | //////////////////////////////////////////////////////////////////////////////// 245 | 246 | inline __host__ __device__ float2 operator-(float2 &a) 247 | { 248 | return make_float2(-a.x, -a.y); 249 | } 250 | inline __host__ __device__ int2 operator-(int2 &a) 251 | { 252 | return make_int2(-a.x, -a.y); 253 | } 254 | inline __host__ __device__ float3 operator-(float3 &a) 255 | { 256 | return make_float3(-a.x, -a.y, -a.z); 257 | } 258 | inline __host__ __device__ int3 operator-(int3 &a) 259 | { 260 | return make_int3(-a.x, -a.y, -a.z); 261 | } 262 | inline __host__ __device__ float4 operator-(float4 &a) 263 | { 264 | return make_float4(-a.x, -a.y, -a.z, -a.w); 265 | } 266 | inline __host__ __device__ int4 operator-(int4 &a) 267 | { 268 | return make_int4(-a.x, -a.y, -a.z, -a.w); 269 | } 270 | 271 | //////////////////////////////////////////////////////////////////////////////// 272 | // addition 273 | //////////////////////////////////////////////////////////////////////////////// 274 | 275 | inline __host__ __device__ float2 operator+(float2 a, float2 b) 276 | { 277 | return make_float2(a.x + b.x, a.y + b.y); 278 | } 279 | inline __host__ __device__ void operator+=(float2 &a, float2 b) 280 | { 281 | a.x += b.x; 282 | a.y += b.y; 283 | } 284 | inline __host__ __device__ float2 operator+(float2 a, float b) 285 | { 286 | return make_float2(a.x + b, a.y + b); 287 | } 288 | inline __host__ __device__ float2 operator+(float b, float2 a) 289 | { 290 | return make_float2(a.x + b, a.y + b); 291 | } 292 | inline __host__ __device__ void operator+=(float2 &a, float b) 293 | { 294 | a.x += b; 295 | a.y += b; 296 | } 297 | 298 | inline __host__ __device__ int2 operator+(int2 a, int2 b) 299 | { 300 | return make_int2(a.x + b.x, a.y + b.y); 301 | } 302 | inline __host__ __device__ void operator+=(int2 &a, int2 b) 303 | { 304 | a.x += b.x; 305 | a.y += b.y; 306 | } 307 | inline __host__ __device__ int2 operator+(int2 a, int b) 308 | { 309 | return make_int2(a.x + b, a.y + b); 310 | } 311 | inline __host__ __device__ int2 operator+(int b, int2 a) 312 | { 313 | return make_int2(a.x + b, a.y + b); 314 | } 315 | inline __host__ __device__ void operator+=(int2 &a, int b) 316 | { 317 | a.x += b; 318 | a.y += b; 319 | } 320 | 321 | inline __host__ __device__ uint2 operator+(uint2 a, uint2 b) 322 | { 323 | return make_uint2(a.x + b.x, a.y + b.y); 324 | } 325 | inline __host__ __device__ void operator+=(uint2 &a, uint2 b) 326 | { 327 | a.x += b.x; 328 | a.y += b.y; 329 | } 330 | inline __host__ __device__ uint2 operator+(uint2 a, uint b) 331 | { 332 | return make_uint2(a.x + b, a.y + b); 333 | } 334 | inline __host__ __device__ uint2 operator+(uint b, uint2 a) 335 | { 336 | return make_uint2(a.x + b, a.y + b); 337 | } 338 | inline __host__ __device__ void operator+=(uint2 &a, uint b) 339 | { 340 | a.x += b; 341 | a.y += b; 342 | } 343 | 344 | 345 | inline __host__ __device__ float3 operator+(float3 a, float3 b) 346 | { 347 | return make_float3(a.x + b.x, a.y + b.y, a.z + b.z); 348 | } 349 | inline __host__ __device__ void operator+=(float3 &a, float3 b) 350 | { 351 | a.x += b.x; 352 | a.y += b.y; 353 | a.z += b.z; 354 | } 355 | inline __host__ __device__ float3 operator+(float3 a, float b) 356 | { 357 | return make_float3(a.x + b, a.y + b, a.z + b); 358 | } 359 | inline __host__ __device__ void operator+=(float3 &a, float b) 360 | { 361 | a.x += b; 362 | a.y += b; 363 | a.z += b; 364 | } 365 | 366 | inline __host__ __device__ int3 operator+(int3 a, int3 b) 367 | { 368 | return make_int3(a.x + b.x, a.y + b.y, a.z + b.z); 369 | } 370 | inline __host__ __device__ void operator+=(int3 &a, int3 b) 371 | { 372 | a.x += b.x; 373 | a.y += b.y; 374 | a.z += b.z; 375 | } 376 | inline __host__ __device__ int3 operator+(int3 a, int b) 377 | { 378 | return make_int3(a.x + b, a.y + b, a.z + b); 379 | } 380 | inline __host__ __device__ void operator+=(int3 &a, int b) 381 | { 382 | a.x += b; 383 | a.y += b; 384 | a.z += b; 385 | } 386 | 387 | inline __host__ __device__ uint3 operator+(uint3 a, uint3 b) 388 | { 389 | return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z); 390 | } 391 | inline __host__ __device__ void operator+=(uint3 &a, uint3 b) 392 | { 393 | a.x += b.x; 394 | a.y += b.y; 395 | a.z += b.z; 396 | } 397 | inline __host__ __device__ uint3 operator+(uint3 a, uint b) 398 | { 399 | return make_uint3(a.x + b, a.y + b, a.z + b); 400 | } 401 | inline __host__ __device__ void operator+=(uint3 &a, uint b) 402 | { 403 | a.x += b; 404 | a.y += b; 405 | a.z += b; 406 | } 407 | 408 | inline __host__ __device__ int3 operator+(int b, int3 a) 409 | { 410 | return make_int3(a.x + b, a.y + b, a.z + b); 411 | } 412 | inline __host__ __device__ uint3 operator+(uint b, uint3 a) 413 | { 414 | return make_uint3(a.x + b, a.y + b, a.z + b); 415 | } 416 | inline __host__ __device__ float3 operator+(float b, float3 a) 417 | { 418 | return make_float3(a.x + b, a.y + b, a.z + b); 419 | } 420 | 421 | inline __host__ __device__ float4 operator+(float4 a, float4 b) 422 | { 423 | return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); 424 | } 425 | inline __host__ __device__ void operator+=(float4 &a, float4 b) 426 | { 427 | a.x += b.x; 428 | a.y += b.y; 429 | a.z += b.z; 430 | a.w += b.w; 431 | } 432 | inline __host__ __device__ float4 operator+(float4 a, float b) 433 | { 434 | return make_float4(a.x + b, a.y + b, a.z + b, a.w + b); 435 | } 436 | inline __host__ __device__ float4 operator+(float b, float4 a) 437 | { 438 | return make_float4(a.x + b, a.y + b, a.z + b, a.w + b); 439 | } 440 | inline __host__ __device__ void operator+=(float4 &a, float b) 441 | { 442 | a.x += b; 443 | a.y += b; 444 | a.z += b; 445 | a.w += b; 446 | } 447 | 448 | inline __host__ __device__ int4 operator+(int4 a, int4 b) 449 | { 450 | return make_int4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); 451 | } 452 | inline __host__ __device__ void operator+=(int4 &a, int4 b) 453 | { 454 | a.x += b.x; 455 | a.y += b.y; 456 | a.z += b.z; 457 | a.w += b.w; 458 | } 459 | inline __host__ __device__ int4 operator+(int4 a, int b) 460 | { 461 | return make_int4(a.x + b, a.y + b, a.z + b, a.w + b); 462 | } 463 | inline __host__ __device__ int4 operator+(int b, int4 a) 464 | { 465 | return make_int4(a.x + b, a.y + b, a.z + b, a.w + b); 466 | } 467 | inline __host__ __device__ void operator+=(int4 &a, int b) 468 | { 469 | a.x += b; 470 | a.y += b; 471 | a.z += b; 472 | a.w += b; 473 | } 474 | 475 | inline __host__ __device__ uint4 operator+(uint4 a, uint4 b) 476 | { 477 | return make_uint4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); 478 | } 479 | inline __host__ __device__ void operator+=(uint4 &a, uint4 b) 480 | { 481 | a.x += b.x; 482 | a.y += b.y; 483 | a.z += b.z; 484 | a.w += b.w; 485 | } 486 | inline __host__ __device__ uint4 operator+(uint4 a, uint b) 487 | { 488 | return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b); 489 | } 490 | inline __host__ __device__ uint4 operator+(uint b, uint4 a) 491 | { 492 | return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b); 493 | } 494 | inline __host__ __device__ void operator+=(uint4 &a, uint b) 495 | { 496 | a.x += b; 497 | a.y += b; 498 | a.z += b; 499 | a.w += b; 500 | } 501 | 502 | //////////////////////////////////////////////////////////////////////////////// 503 | // subtract 504 | //////////////////////////////////////////////////////////////////////////////// 505 | 506 | inline __host__ __device__ float2 operator-(float2 a, float2 b) 507 | { 508 | return make_float2(a.x - b.x, a.y - b.y); 509 | } 510 | inline __host__ __device__ void operator-=(float2 &a, float2 b) 511 | { 512 | a.x -= b.x; 513 | a.y -= b.y; 514 | } 515 | inline __host__ __device__ float2 operator-(float2 a, float b) 516 | { 517 | return make_float2(a.x - b, a.y - b); 518 | } 519 | inline __host__ __device__ float2 operator-(float b, float2 a) 520 | { 521 | return make_float2(b - a.x, b - a.y); 522 | } 523 | inline __host__ __device__ void operator-=(float2 &a, float b) 524 | { 525 | a.x -= b; 526 | a.y -= b; 527 | } 528 | 529 | inline __host__ __device__ int2 operator-(int2 a, int2 b) 530 | { 531 | return make_int2(a.x - b.x, a.y - b.y); 532 | } 533 | inline __host__ __device__ void operator-=(int2 &a, int2 b) 534 | { 535 | a.x -= b.x; 536 | a.y -= b.y; 537 | } 538 | inline __host__ __device__ int2 operator-(int2 a, int b) 539 | { 540 | return make_int2(a.x - b, a.y - b); 541 | } 542 | inline __host__ __device__ int2 operator-(int b, int2 a) 543 | { 544 | return make_int2(b - a.x, b - a.y); 545 | } 546 | inline __host__ __device__ void operator-=(int2 &a, int b) 547 | { 548 | a.x -= b; 549 | a.y -= b; 550 | } 551 | 552 | inline __host__ __device__ uint2 operator-(uint2 a, uint2 b) 553 | { 554 | return make_uint2(a.x - b.x, a.y - b.y); 555 | } 556 | inline __host__ __device__ void operator-=(uint2 &a, uint2 b) 557 | { 558 | a.x -= b.x; 559 | a.y -= b.y; 560 | } 561 | inline __host__ __device__ uint2 operator-(uint2 a, uint b) 562 | { 563 | return make_uint2(a.x - b, a.y - b); 564 | } 565 | inline __host__ __device__ uint2 operator-(uint b, uint2 a) 566 | { 567 | return make_uint2(b - a.x, b - a.y); 568 | } 569 | inline __host__ __device__ void operator-=(uint2 &a, uint b) 570 | { 571 | a.x -= b; 572 | a.y -= b; 573 | } 574 | 575 | inline __host__ __device__ float3 operator-(float3 a, float3 b) 576 | { 577 | return make_float3(a.x - b.x, a.y - b.y, a.z - b.z); 578 | } 579 | inline __host__ __device__ void operator-=(float3 &a, float3 b) 580 | { 581 | a.x -= b.x; 582 | a.y -= b.y; 583 | a.z -= b.z; 584 | } 585 | inline __host__ __device__ float3 operator-(float3 a, float b) 586 | { 587 | return make_float3(a.x - b, a.y - b, a.z - b); 588 | } 589 | inline __host__ __device__ float3 operator-(float b, float3 a) 590 | { 591 | return make_float3(b - a.x, b - a.y, b - a.z); 592 | } 593 | inline __host__ __device__ void operator-=(float3 &a, float b) 594 | { 595 | a.x -= b; 596 | a.y -= b; 597 | a.z -= b; 598 | } 599 | 600 | inline __host__ __device__ int3 operator-(int3 a, int3 b) 601 | { 602 | return make_int3(a.x - b.x, a.y - b.y, a.z - b.z); 603 | } 604 | inline __host__ __device__ void operator-=(int3 &a, int3 b) 605 | { 606 | a.x -= b.x; 607 | a.y -= b.y; 608 | a.z -= b.z; 609 | } 610 | inline __host__ __device__ int3 operator-(int3 a, int b) 611 | { 612 | return make_int3(a.x - b, a.y - b, a.z - b); 613 | } 614 | inline __host__ __device__ int3 operator-(int b, int3 a) 615 | { 616 | return make_int3(b - a.x, b - a.y, b - a.z); 617 | } 618 | inline __host__ __device__ void operator-=(int3 &a, int b) 619 | { 620 | a.x -= b; 621 | a.y -= b; 622 | a.z -= b; 623 | } 624 | 625 | inline __host__ __device__ uint3 operator-(uint3 a, uint3 b) 626 | { 627 | return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z); 628 | } 629 | inline __host__ __device__ void operator-=(uint3 &a, uint3 b) 630 | { 631 | a.x -= b.x; 632 | a.y -= b.y; 633 | a.z -= b.z; 634 | } 635 | inline __host__ __device__ uint3 operator-(uint3 a, uint b) 636 | { 637 | return make_uint3(a.x - b, a.y - b, a.z - b); 638 | } 639 | inline __host__ __device__ uint3 operator-(uint b, uint3 a) 640 | { 641 | return make_uint3(b - a.x, b - a.y, b - a.z); 642 | } 643 | inline __host__ __device__ void operator-=(uint3 &a, uint b) 644 | { 645 | a.x -= b; 646 | a.y -= b; 647 | a.z -= b; 648 | } 649 | 650 | inline __host__ __device__ float4 operator-(float4 a, float4 b) 651 | { 652 | return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); 653 | } 654 | inline __host__ __device__ void operator-=(float4 &a, float4 b) 655 | { 656 | a.x -= b.x; 657 | a.y -= b.y; 658 | a.z -= b.z; 659 | a.w -= b.w; 660 | } 661 | inline __host__ __device__ float4 operator-(float4 a, float b) 662 | { 663 | return make_float4(a.x - b, a.y - b, a.z - b, a.w - b); 664 | } 665 | inline __host__ __device__ void operator-=(float4 &a, float b) 666 | { 667 | a.x -= b; 668 | a.y -= b; 669 | a.z -= b; 670 | a.w -= b; 671 | } 672 | 673 | inline __host__ __device__ int4 operator-(int4 a, int4 b) 674 | { 675 | return make_int4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); 676 | } 677 | inline __host__ __device__ void operator-=(int4 &a, int4 b) 678 | { 679 | a.x -= b.x; 680 | a.y -= b.y; 681 | a.z -= b.z; 682 | a.w -= b.w; 683 | } 684 | inline __host__ __device__ int4 operator-(int4 a, int b) 685 | { 686 | return make_int4(a.x - b, a.y - b, a.z - b, a.w - b); 687 | } 688 | inline __host__ __device__ int4 operator-(int b, int4 a) 689 | { 690 | return make_int4(b - a.x, b - a.y, b - a.z, b - a.w); 691 | } 692 | inline __host__ __device__ void operator-=(int4 &a, int b) 693 | { 694 | a.x -= b; 695 | a.y -= b; 696 | a.z -= b; 697 | a.w -= b; 698 | } 699 | 700 | inline __host__ __device__ uint4 operator-(uint4 a, uint4 b) 701 | { 702 | return make_uint4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); 703 | } 704 | inline __host__ __device__ void operator-=(uint4 &a, uint4 b) 705 | { 706 | a.x -= b.x; 707 | a.y -= b.y; 708 | a.z -= b.z; 709 | a.w -= b.w; 710 | } 711 | inline __host__ __device__ uint4 operator-(uint4 a, uint b) 712 | { 713 | return make_uint4(a.x - b, a.y - b, a.z - b, a.w - b); 714 | } 715 | inline __host__ __device__ uint4 operator-(uint b, uint4 a) 716 | { 717 | return make_uint4(b - a.x, b - a.y, b - a.z, b - a.w); 718 | } 719 | inline __host__ __device__ void operator-=(uint4 &a, uint b) 720 | { 721 | a.x -= b; 722 | a.y -= b; 723 | a.z -= b; 724 | a.w -= b; 725 | } 726 | 727 | //////////////////////////////////////////////////////////////////////////////// 728 | // multiply 729 | //////////////////////////////////////////////////////////////////////////////// 730 | 731 | inline __host__ __device__ float2 operator*(float2 a, float2 b) 732 | { 733 | return make_float2(a.x * b.x, a.y * b.y); 734 | } 735 | inline __host__ __device__ void operator*=(float2 &a, float2 b) 736 | { 737 | a.x *= b.x; 738 | a.y *= b.y; 739 | } 740 | inline __host__ __device__ float2 operator*(float2 a, float b) 741 | { 742 | return make_float2(a.x * b, a.y * b); 743 | } 744 | inline __host__ __device__ float2 operator*(float b, float2 a) 745 | { 746 | return make_float2(b * a.x, b * a.y); 747 | } 748 | inline __host__ __device__ void operator*=(float2 &a, float b) 749 | { 750 | a.x *= b; 751 | a.y *= b; 752 | } 753 | 754 | inline __host__ __device__ int2 operator*(int2 a, int2 b) 755 | { 756 | return make_int2(a.x * b.x, a.y * b.y); 757 | } 758 | inline __host__ __device__ void operator*=(int2 &a, int2 b) 759 | { 760 | a.x *= b.x; 761 | a.y *= b.y; 762 | } 763 | inline __host__ __device__ int2 operator*(int2 a, int b) 764 | { 765 | return make_int2(a.x * b, a.y * b); 766 | } 767 | inline __host__ __device__ int2 operator*(int b, int2 a) 768 | { 769 | return make_int2(b * a.x, b * a.y); 770 | } 771 | inline __host__ __device__ void operator*=(int2 &a, int b) 772 | { 773 | a.x *= b; 774 | a.y *= b; 775 | } 776 | 777 | inline __host__ __device__ uint2 operator*(uint2 a, uint2 b) 778 | { 779 | return make_uint2(a.x * b.x, a.y * b.y); 780 | } 781 | inline __host__ __device__ void operator*=(uint2 &a, uint2 b) 782 | { 783 | a.x *= b.x; 784 | a.y *= b.y; 785 | } 786 | inline __host__ __device__ uint2 operator*(uint2 a, uint b) 787 | { 788 | return make_uint2(a.x * b, a.y * b); 789 | } 790 | inline __host__ __device__ uint2 operator*(uint b, uint2 a) 791 | { 792 | return make_uint2(b * a.x, b * a.y); 793 | } 794 | inline __host__ __device__ void operator*=(uint2 &a, uint b) 795 | { 796 | a.x *= b; 797 | a.y *= b; 798 | } 799 | 800 | inline __host__ __device__ float3 operator*(float3 a, float3 b) 801 | { 802 | return make_float3(a.x * b.x, a.y * b.y, a.z * b.z); 803 | } 804 | inline __host__ __device__ void operator*=(float3 &a, float3 b) 805 | { 806 | a.x *= b.x; 807 | a.y *= b.y; 808 | a.z *= b.z; 809 | } 810 | inline __host__ __device__ float3 operator*(float3 a, float b) 811 | { 812 | return make_float3(a.x * b, a.y * b, a.z * b); 813 | } 814 | inline __host__ __device__ float3 operator*(float b, float3 a) 815 | { 816 | return make_float3(b * a.x, b * a.y, b * a.z); 817 | } 818 | inline __host__ __device__ void operator*=(float3 &a, float b) 819 | { 820 | a.x *= b; 821 | a.y *= b; 822 | a.z *= b; 823 | } 824 | 825 | inline __host__ __device__ int3 operator*(int3 a, int3 b) 826 | { 827 | return make_int3(a.x * b.x, a.y * b.y, a.z * b.z); 828 | } 829 | inline __host__ __device__ void operator*=(int3 &a, int3 b) 830 | { 831 | a.x *= b.x; 832 | a.y *= b.y; 833 | a.z *= b.z; 834 | } 835 | inline __host__ __device__ int3 operator*(int3 a, int b) 836 | { 837 | return make_int3(a.x * b, a.y * b, a.z * b); 838 | } 839 | inline __host__ __device__ int3 operator*(int b, int3 a) 840 | { 841 | return make_int3(b * a.x, b * a.y, b * a.z); 842 | } 843 | inline __host__ __device__ void operator*=(int3 &a, int b) 844 | { 845 | a.x *= b; 846 | a.y *= b; 847 | a.z *= b; 848 | } 849 | 850 | inline __host__ __device__ uint3 operator*(uint3 a, uint3 b) 851 | { 852 | return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z); 853 | } 854 | inline __host__ __device__ void operator*=(uint3 &a, uint3 b) 855 | { 856 | a.x *= b.x; 857 | a.y *= b.y; 858 | a.z *= b.z; 859 | } 860 | inline __host__ __device__ uint3 operator*(uint3 a, uint b) 861 | { 862 | return make_uint3(a.x * b, a.y * b, a.z * b); 863 | } 864 | inline __host__ __device__ uint3 operator*(uint b, uint3 a) 865 | { 866 | return make_uint3(b * a.x, b * a.y, b * a.z); 867 | } 868 | inline __host__ __device__ void operator*=(uint3 &a, uint b) 869 | { 870 | a.x *= b; 871 | a.y *= b; 872 | a.z *= b; 873 | } 874 | 875 | inline __host__ __device__ float4 operator*(float4 a, float4 b) 876 | { 877 | return make_float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); 878 | } 879 | inline __host__ __device__ void operator*=(float4 &a, float4 b) 880 | { 881 | a.x *= b.x; 882 | a.y *= b.y; 883 | a.z *= b.z; 884 | a.w *= b.w; 885 | } 886 | inline __host__ __device__ float4 operator*(float4 a, float b) 887 | { 888 | return make_float4(a.x * b, a.y * b, a.z * b, a.w * b); 889 | } 890 | inline __host__ __device__ float4 operator*(float b, float4 a) 891 | { 892 | return make_float4(b * a.x, b * a.y, b * a.z, b * a.w); 893 | } 894 | inline __host__ __device__ void operator*=(float4 &a, float b) 895 | { 896 | a.x *= b; 897 | a.y *= b; 898 | a.z *= b; 899 | a.w *= b; 900 | } 901 | 902 | inline __host__ __device__ int4 operator*(int4 a, int4 b) 903 | { 904 | return make_int4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); 905 | } 906 | inline __host__ __device__ void operator*=(int4 &a, int4 b) 907 | { 908 | a.x *= b.x; 909 | a.y *= b.y; 910 | a.z *= b.z; 911 | a.w *= b.w; 912 | } 913 | inline __host__ __device__ int4 operator*(int4 a, int b) 914 | { 915 | return make_int4(a.x * b, a.y * b, a.z * b, a.w * b); 916 | } 917 | inline __host__ __device__ int4 operator*(int b, int4 a) 918 | { 919 | return make_int4(b * a.x, b * a.y, b * a.z, b * a.w); 920 | } 921 | inline __host__ __device__ void operator*=(int4 &a, int b) 922 | { 923 | a.x *= b; 924 | a.y *= b; 925 | a.z *= b; 926 | a.w *= b; 927 | } 928 | 929 | inline __host__ __device__ uint4 operator*(uint4 a, uint4 b) 930 | { 931 | return make_uint4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); 932 | } 933 | inline __host__ __device__ void operator*=(uint4 &a, uint4 b) 934 | { 935 | a.x *= b.x; 936 | a.y *= b.y; 937 | a.z *= b.z; 938 | a.w *= b.w; 939 | } 940 | inline __host__ __device__ uint4 operator*(uint4 a, uint b) 941 | { 942 | return make_uint4(a.x * b, a.y * b, a.z * b, a.w * b); 943 | } 944 | inline __host__ __device__ uint4 operator*(uint b, uint4 a) 945 | { 946 | return make_uint4(b * a.x, b * a.y, b * a.z, b * a.w); 947 | } 948 | inline __host__ __device__ void operator*=(uint4 &a, uint b) 949 | { 950 | a.x *= b; 951 | a.y *= b; 952 | a.z *= b; 953 | a.w *= b; 954 | } 955 | 956 | //////////////////////////////////////////////////////////////////////////////// 957 | // divide 958 | //////////////////////////////////////////////////////////////////////////////// 959 | 960 | inline __host__ __device__ float2 operator/(float2 a, float2 b) 961 | { 962 | return make_float2(a.x / b.x, a.y / b.y); 963 | } 964 | inline __host__ __device__ void operator/=(float2 &a, float2 b) 965 | { 966 | a.x /= b.x; 967 | a.y /= b.y; 968 | } 969 | inline __host__ __device__ float2 operator/(float2 a, float b) 970 | { 971 | return make_float2(a.x / b, a.y / b); 972 | } 973 | inline __host__ __device__ void operator/=(float2 &a, float b) 974 | { 975 | a.x /= b; 976 | a.y /= b; 977 | } 978 | inline __host__ __device__ float2 operator/(float b, float2 a) 979 | { 980 | return make_float2(b / a.x, b / a.y); 981 | } 982 | 983 | inline __host__ __device__ float3 operator/(float3 a, float3 b) 984 | { 985 | return make_float3(a.x / b.x, a.y / b.y, a.z / b.z); 986 | } 987 | inline __host__ __device__ void operator/=(float3 &a, float3 b) 988 | { 989 | a.x /= b.x; 990 | a.y /= b.y; 991 | a.z /= b.z; 992 | } 993 | inline __host__ __device__ float3 operator/(float3 a, float b) 994 | { 995 | return make_float3(a.x / b, a.y / b, a.z / b); 996 | } 997 | inline __host__ __device__ void operator/=(float3 &a, float b) 998 | { 999 | a.x /= b; 1000 | a.y /= b; 1001 | a.z /= b; 1002 | } 1003 | inline __host__ __device__ float3 operator/(float b, float3 a) 1004 | { 1005 | return make_float3(b / a.x, b / a.y, b / a.z); 1006 | } 1007 | 1008 | inline __host__ __device__ float4 operator/(float4 a, float4 b) 1009 | { 1010 | return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); 1011 | } 1012 | inline __host__ __device__ void operator/=(float4 &a, float4 b) 1013 | { 1014 | a.x /= b.x; 1015 | a.y /= b.y; 1016 | a.z /= b.z; 1017 | a.w /= b.w; 1018 | } 1019 | inline __host__ __device__ float4 operator/(float4 a, float b) 1020 | { 1021 | return make_float4(a.x / b, a.y / b, a.z / b, a.w / b); 1022 | } 1023 | inline __host__ __device__ void operator/=(float4 &a, float b) 1024 | { 1025 | a.x /= b; 1026 | a.y /= b; 1027 | a.z /= b; 1028 | a.w /= b; 1029 | } 1030 | inline __host__ __device__ float4 operator/(float b, float4 a) 1031 | { 1032 | return make_float4(b / a.x, b / a.y, b / a.z, b / a.w); 1033 | } 1034 | 1035 | //////////////////////////////////////////////////////////////////////////////// 1036 | // min 1037 | //////////////////////////////////////////////////////////////////////////////// 1038 | 1039 | inline __host__ __device__ float2 fminf(float2 a, float2 b) 1040 | { 1041 | return make_float2(fminf(a.x,b.x), fminf(a.y,b.y)); 1042 | } 1043 | inline __host__ __device__ float3 fminf(float3 a, float3 b) 1044 | { 1045 | return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z)); 1046 | } 1047 | inline __host__ __device__ float4 fminf(float4 a, float4 b) 1048 | { 1049 | return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w)); 1050 | } 1051 | 1052 | inline __host__ __device__ int2 min(int2 a, int2 b) 1053 | { 1054 | return make_int2(min(a.x,b.x), min(a.y,b.y)); 1055 | } 1056 | inline __host__ __device__ int3 min(int3 a, int3 b) 1057 | { 1058 | return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); 1059 | } 1060 | inline __host__ __device__ int4 min(int4 a, int4 b) 1061 | { 1062 | return make_int4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w)); 1063 | } 1064 | 1065 | inline __host__ __device__ uint2 min(uint2 a, uint2 b) 1066 | { 1067 | return make_uint2(min(a.x,b.x), min(a.y,b.y)); 1068 | } 1069 | inline __host__ __device__ uint3 min(uint3 a, uint3 b) 1070 | { 1071 | return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z)); 1072 | } 1073 | inline __host__ __device__ uint4 min(uint4 a, uint4 b) 1074 | { 1075 | return make_uint4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w)); 1076 | } 1077 | 1078 | //////////////////////////////////////////////////////////////////////////////// 1079 | // max 1080 | //////////////////////////////////////////////////////////////////////////////// 1081 | 1082 | inline __host__ __device__ float2 fmaxf(float2 a, float2 b) 1083 | { 1084 | return make_float2(fmaxf(a.x,b.x), fmaxf(a.y,b.y)); 1085 | } 1086 | inline __host__ __device__ float3 fmaxf(float3 a, float3 b) 1087 | { 1088 | return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z)); 1089 | } 1090 | inline __host__ __device__ float4 fmaxf(float4 a, float4 b) 1091 | { 1092 | return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w)); 1093 | } 1094 | 1095 | inline __host__ __device__ int2 max(int2 a, int2 b) 1096 | { 1097 | return make_int2(max(a.x,b.x), max(a.y,b.y)); 1098 | } 1099 | inline __host__ __device__ int3 max(int3 a, int3 b) 1100 | { 1101 | return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); 1102 | } 1103 | inline __host__ __device__ int4 max(int4 a, int4 b) 1104 | { 1105 | return make_int4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w)); 1106 | } 1107 | 1108 | inline __host__ __device__ uint2 max(uint2 a, uint2 b) 1109 | { 1110 | return make_uint2(max(a.x,b.x), max(a.y,b.y)); 1111 | } 1112 | inline __host__ __device__ uint3 max(uint3 a, uint3 b) 1113 | { 1114 | return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z)); 1115 | } 1116 | inline __host__ __device__ uint4 max(uint4 a, uint4 b) 1117 | { 1118 | return make_uint4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w)); 1119 | } 1120 | 1121 | //////////////////////////////////////////////////////////////////////////////// 1122 | // lerp 1123 | // - linear interpolation between a and b, based on value t in [0, 1] range 1124 | //////////////////////////////////////////////////////////////////////////////// 1125 | 1126 | inline __device__ __host__ float lerp(float a, float b, float t) 1127 | { 1128 | return a + t*(b-a); 1129 | } 1130 | inline __device__ __host__ float2 lerp(float2 a, float2 b, float t) 1131 | { 1132 | return a + t*(b-a); 1133 | } 1134 | inline __device__ __host__ float3 lerp(float3 a, float3 b, float t) 1135 | { 1136 | return a + t*(b-a); 1137 | } 1138 | inline __device__ __host__ float4 lerp(float4 a, float4 b, float t) 1139 | { 1140 | return a + t*(b-a); 1141 | } 1142 | 1143 | //////////////////////////////////////////////////////////////////////////////// 1144 | // clamp 1145 | // - clamp the value v to be in the range [a, b] 1146 | //////////////////////////////////////////////////////////////////////////////// 1147 | 1148 | inline __device__ __host__ float clamp(float f, float a, float b) 1149 | { 1150 | return fmaxf(a, fminf(f, b)); 1151 | } 1152 | inline __device__ __host__ int clamp(int f, int a, int b) 1153 | { 1154 | return max(a, min(f, b)); 1155 | } 1156 | inline __device__ __host__ uint clamp(uint f, uint a, uint b) 1157 | { 1158 | return max(a, min(f, b)); 1159 | } 1160 | 1161 | inline __device__ __host__ float2 clamp(float2 v, float a, float b) 1162 | { 1163 | return make_float2(clamp(v.x, a, b), clamp(v.y, a, b)); 1164 | } 1165 | inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b) 1166 | { 1167 | return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); 1168 | } 1169 | inline __device__ __host__ float3 clamp(float3 v, float a, float b) 1170 | { 1171 | return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); 1172 | } 1173 | inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b) 1174 | { 1175 | return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); 1176 | } 1177 | inline __device__ __host__ float4 clamp(float4 v, float a, float b) 1178 | { 1179 | return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); 1180 | } 1181 | inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b) 1182 | { 1183 | return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); 1184 | } 1185 | 1186 | inline __device__ __host__ int2 clamp(int2 v, int a, int b) 1187 | { 1188 | return make_int2(clamp(v.x, a, b), clamp(v.y, a, b)); 1189 | } 1190 | inline __device__ __host__ int2 clamp(int2 v, int2 a, int2 b) 1191 | { 1192 | return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); 1193 | } 1194 | inline __device__ __host__ int3 clamp(int3 v, int a, int b) 1195 | { 1196 | return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); 1197 | } 1198 | inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b) 1199 | { 1200 | return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); 1201 | } 1202 | inline __device__ __host__ int4 clamp(int4 v, int a, int b) 1203 | { 1204 | return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); 1205 | } 1206 | inline __device__ __host__ int4 clamp(int4 v, int4 a, int4 b) 1207 | { 1208 | return make_int4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); 1209 | } 1210 | 1211 | inline __device__ __host__ uint2 clamp(uint2 v, uint a, uint b) 1212 | { 1213 | return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b)); 1214 | } 1215 | inline __device__ __host__ uint2 clamp(uint2 v, uint2 a, uint2 b) 1216 | { 1217 | return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y)); 1218 | } 1219 | inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b) 1220 | { 1221 | return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b)); 1222 | } 1223 | inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b) 1224 | { 1225 | return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z)); 1226 | } 1227 | inline __device__ __host__ uint4 clamp(uint4 v, uint a, uint b) 1228 | { 1229 | return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b)); 1230 | } 1231 | inline __device__ __host__ uint4 clamp(uint4 v, uint4 a, uint4 b) 1232 | { 1233 | return make_uint4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w)); 1234 | } 1235 | 1236 | //////////////////////////////////////////////////////////////////////////////// 1237 | // dot product 1238 | //////////////////////////////////////////////////////////////////////////////// 1239 | 1240 | inline __host__ __device__ float dot(float2 a, float2 b) 1241 | { 1242 | return a.x * b.x + a.y * b.y; 1243 | } 1244 | inline __host__ __device__ float dot(float3 a, float3 b) 1245 | { 1246 | return a.x * b.x + a.y * b.y + a.z * b.z; 1247 | } 1248 | inline __host__ __device__ float dot(float4 a, float4 b) 1249 | { 1250 | return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; 1251 | } 1252 | 1253 | inline __host__ __device__ int dot(int2 a, int2 b) 1254 | { 1255 | return a.x * b.x + a.y * b.y; 1256 | } 1257 | inline __host__ __device__ int dot(int3 a, int3 b) 1258 | { 1259 | return a.x * b.x + a.y * b.y + a.z * b.z; 1260 | } 1261 | inline __host__ __device__ int dot(int4 a, int4 b) 1262 | { 1263 | return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; 1264 | } 1265 | 1266 | inline __host__ __device__ uint dot(uint2 a, uint2 b) 1267 | { 1268 | return a.x * b.x + a.y * b.y; 1269 | } 1270 | inline __host__ __device__ uint dot(uint3 a, uint3 b) 1271 | { 1272 | return a.x * b.x + a.y * b.y + a.z * b.z; 1273 | } 1274 | inline __host__ __device__ uint dot(uint4 a, uint4 b) 1275 | { 1276 | return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; 1277 | } 1278 | 1279 | //////////////////////////////////////////////////////////////////////////////// 1280 | // length 1281 | //////////////////////////////////////////////////////////////////////////////// 1282 | 1283 | inline __host__ __device__ float length(float2 v) 1284 | { 1285 | return sqrtf(dot(v, v)); 1286 | } 1287 | inline __host__ __device__ float length(float3 v) 1288 | { 1289 | return sqrtf(dot(v, v)); 1290 | } 1291 | inline __host__ __device__ float length(float4 v) 1292 | { 1293 | return sqrtf(dot(v, v)); 1294 | } 1295 | 1296 | //////////////////////////////////////////////////////////////////////////////// 1297 | // normalize 1298 | //////////////////////////////////////////////////////////////////////////////// 1299 | 1300 | inline __host__ __device__ float2 normalize(float2 v) 1301 | { 1302 | float invLen = rsqrtf(dot(v, v)); 1303 | return v * invLen; 1304 | } 1305 | inline __host__ __device__ float3 normalize(float3 v) 1306 | { 1307 | float invLen = rsqrtf(dot(v, v)); 1308 | return v * invLen; 1309 | } 1310 | inline __host__ __device__ float4 normalize(float4 v) 1311 | { 1312 | float invLen = rsqrtf(dot(v, v)); 1313 | return v * invLen; 1314 | } 1315 | 1316 | //////////////////////////////////////////////////////////////////////////////// 1317 | // floor 1318 | //////////////////////////////////////////////////////////////////////////////// 1319 | 1320 | inline __host__ __device__ float2 floorf(float2 v) 1321 | { 1322 | return make_float2(floorf(v.x), floorf(v.y)); 1323 | } 1324 | inline __host__ __device__ float3 floorf(float3 v) 1325 | { 1326 | return make_float3(floorf(v.x), floorf(v.y), floorf(v.z)); 1327 | } 1328 | inline __host__ __device__ float4 floorf(float4 v) 1329 | { 1330 | return make_float4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w)); 1331 | } 1332 | 1333 | //////////////////////////////////////////////////////////////////////////////// 1334 | // frac - returns the fractional portion of a scalar or each vector component 1335 | //////////////////////////////////////////////////////////////////////////////// 1336 | 1337 | inline __host__ __device__ float fracf(float v) 1338 | { 1339 | return v - floorf(v); 1340 | } 1341 | inline __host__ __device__ float2 fracf(float2 v) 1342 | { 1343 | return make_float2(fracf(v.x), fracf(v.y)); 1344 | } 1345 | inline __host__ __device__ float3 fracf(float3 v) 1346 | { 1347 | return make_float3(fracf(v.x), fracf(v.y), fracf(v.z)); 1348 | } 1349 | inline __host__ __device__ float4 fracf(float4 v) 1350 | { 1351 | return make_float4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w)); 1352 | } 1353 | 1354 | //////////////////////////////////////////////////////////////////////////////// 1355 | // fmod 1356 | //////////////////////////////////////////////////////////////////////////////// 1357 | 1358 | inline __host__ __device__ float2 fmodf(float2 a, float2 b) 1359 | { 1360 | return make_float2(fmodf(a.x, b.x), fmodf(a.y, b.y)); 1361 | } 1362 | inline __host__ __device__ float3 fmodf(float3 a, float3 b) 1363 | { 1364 | return make_float3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z)); 1365 | } 1366 | inline __host__ __device__ float4 fmodf(float4 a, float4 b) 1367 | { 1368 | return make_float4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w)); 1369 | } 1370 | 1371 | //////////////////////////////////////////////////////////////////////////////// 1372 | // absolute value 1373 | //////////////////////////////////////////////////////////////////////////////// 1374 | 1375 | inline __host__ __device__ float2 fabs(float2 v) 1376 | { 1377 | return make_float2(fabs(v.x), fabs(v.y)); 1378 | } 1379 | inline __host__ __device__ float3 fabs(float3 v) 1380 | { 1381 | return make_float3(fabs(v.x), fabs(v.y), fabs(v.z)); 1382 | } 1383 | inline __host__ __device__ float4 fabs(float4 v) 1384 | { 1385 | return make_float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w)); 1386 | } 1387 | 1388 | inline __host__ __device__ int2 abs(int2 v) 1389 | { 1390 | return make_int2(abs(v.x), abs(v.y)); 1391 | } 1392 | inline __host__ __device__ int3 abs(int3 v) 1393 | { 1394 | return make_int3(abs(v.x), abs(v.y), abs(v.z)); 1395 | } 1396 | inline __host__ __device__ int4 abs(int4 v) 1397 | { 1398 | return make_int4(abs(v.x), abs(v.y), abs(v.z), abs(v.w)); 1399 | } 1400 | 1401 | //////////////////////////////////////////////////////////////////////////////// 1402 | // reflect 1403 | // - returns reflection of incident ray I around surface normal N 1404 | // - N should be normalized, reflected vector's length is equal to length of I 1405 | //////////////////////////////////////////////////////////////////////////////// 1406 | 1407 | inline __host__ __device__ float3 reflect(float3 i, float3 n) 1408 | { 1409 | return i - 2.0f * n * dot(n,i); 1410 | } 1411 | 1412 | //////////////////////////////////////////////////////////////////////////////// 1413 | // cross product 1414 | //////////////////////////////////////////////////////////////////////////////// 1415 | 1416 | inline __host__ __device__ float3 cross(float3 a, float3 b) 1417 | { 1418 | return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); 1419 | } 1420 | 1421 | //////////////////////////////////////////////////////////////////////////////// 1422 | // smoothstep 1423 | // - returns 0 if x < a 1424 | // - returns 1 if x > b 1425 | // - otherwise returns smooth interpolation between 0 and 1 based on x 1426 | //////////////////////////////////////////////////////////////////////////////// 1427 | 1428 | inline __device__ __host__ float smoothstep(float a, float b, float x) 1429 | { 1430 | float y = clamp((x - a) / (b - a), 0.0f, 1.0f); 1431 | return (y*y*(3.0f - (2.0f*y))); 1432 | } 1433 | inline __device__ __host__ float2 smoothstep(float2 a, float2 b, float2 x) 1434 | { 1435 | float2 y = clamp((x - a) / (b - a), 0.0f, 1.0f); 1436 | return (y*y*(make_float2(3.0f) - (make_float2(2.0f)*y))); 1437 | } 1438 | inline __device__ __host__ float3 smoothstep(float3 a, float3 b, float3 x) 1439 | { 1440 | float3 y = clamp((x - a) / (b - a), 0.0f, 1.0f); 1441 | return (y*y*(make_float3(3.0f) - (make_float3(2.0f)*y))); 1442 | } 1443 | inline __device__ __host__ float4 smoothstep(float4 a, float4 b, float4 x) 1444 | { 1445 | float4 y = clamp((x - a) / (b - a), 0.0f, 1.0f); 1446 | return (y*y*(make_float4(3.0f) - (make_float4(2.0f)*y))); 1447 | } 1448 | 1449 | #endif 1450 | -------------------------------------------------------------------------------- /src/StreamSurface/GlyphsActivity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Activity.h" 4 | #include "CudaHelper.h" 5 | #include "Utils.h" 6 | 7 | namespace mf { 8 | 9 | template 10 | class TGlyphsActivity : public Activity { 11 | 12 | protected: 13 | VectorFieldInfo m_vfInfo; 14 | bool m_allocated; 15 | float m_glyphsSpacing; 16 | uint2 m_glyphsCount; // counted by changeSpacing method 17 | float m_planeX; 18 | bool m_useLines; 19 | float m_glyphSize; 20 | 21 | static const uint m_verticesPerGlyph = 9; 22 | static const uint m_facesPerGlyph = 6; 23 | 24 | 25 | GLuint m_verticesVbo; 26 | cudaGraphicsResource* m_cudaVerticesVboResource; 27 | 28 | GLuint m_normalsVbo; 29 | cudaGraphicsResource* m_cudaNormalsVboResource; 30 | 31 | GLuint m_indicesVbo; 32 | cudaGraphicsResource* m_cudaIndicesVboResource; 33 | 34 | GLuint m_colorsVbo; 35 | cudaGraphicsResource* m_cudaColorsVboResource; 36 | 37 | public: 38 | TGlyphsActivity(const VectorFieldInfo& vfInfo) 39 | : m_vfInfo(vfInfo) 40 | , m_allocated(false) 41 | , m_glyphsSpacing(0) 42 | , m_glyphSize(4.0f) 43 | , m_planeX(0.0f) 44 | , m_useLines(false) 45 | , m_verticesVbo(NULL) 46 | , m_cudaVerticesVboResource(nullptr) 47 | , m_normalsVbo(NULL) 48 | , m_cudaNormalsVboResource(nullptr) 49 | , m_indicesVbo(NULL) 50 | , m_cudaIndicesVboResource(nullptr) 51 | , m_colorsVbo(NULL) 52 | , m_cudaColorsVboResource(nullptr) 53 | { 54 | changeSpacing(1.0); 55 | allocate(); 56 | recompute(); 57 | }; 58 | 59 | 60 | void changeSpacing(float newSpacingValue) { 61 | m_glyphsSpacing = newSpacingValue; 62 | m_glyphsCount.x = (int)(m_vfInfo.realSize.y / m_glyphsSpacing); 63 | m_glyphsCount.y = (int)(m_vfInfo.realSize.z / m_glyphsSpacing); 64 | allocate(); 65 | } 66 | 67 | virtual ~TGlyphsActivity() { 68 | free(); 69 | }; 70 | 71 | 72 | virtual void recompute() { 73 | assert(m_allocated); 74 | 75 | auto t1 = std::chrono::high_resolution_clock::now(); 76 | 77 | size_t bytesCount; 78 | float3* d_glyphs; 79 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaVerticesVboResource)); 80 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_glyphs, &bytesCount, m_cudaVerticesVboResource)); 81 | 82 | float3* d_colors; 83 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaColorsVboResource)); 84 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_colors, &bytesCount, m_cudaColorsVboResource)); 85 | 86 | if (m_useLines) { 87 | runGlyphLinesKernel(m_planeX, m_glyphsCount, make_float2(m_vfInfo.realSize.y, m_vfInfo.realSize.z), m_glyphSize, m_vfInfo.volumeCoordSpaceMult, 88 | d_glyphs, d_colors); 89 | } 90 | else { 91 | uint3* d_indices; 92 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaIndicesVboResource)); 93 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_indices, &bytesCount, m_cudaIndicesVboResource)); 94 | 95 | float3* d_normals; 96 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaNormalsVboResource)); 97 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_normals, &bytesCount, m_cudaNormalsVboResource)); 98 | 99 | runGlyphArrowsKernel(m_planeX, m_glyphsCount, make_float2(m_vfInfo.realSize.y, m_vfInfo.realSize.z), m_glyphSize, m_vfInfo.volumeCoordSpaceMult, 100 | d_glyphs, d_indices, d_normals, d_colors); 101 | 102 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaNormalsVboResource)); 103 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaIndicesVboResource)); 104 | } 105 | 106 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaColorsVboResource)); 107 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaVerticesVboResource)); 108 | 109 | auto t2 = std::chrono::high_resolution_clock::now(); 110 | m_lastDuration = std::chrono::duration_cast(t2 - t1).count() / 1000.0f; 111 | } 112 | 113 | virtual void drawControls(float& i, float incI) { 114 | 115 | std::stringstream ss; 116 | 117 | drawString(10, ++i * incI, 0, "Use right mouse for movement"); 118 | 119 | ss.str(""); 120 | ss << "[+] [-] Glyphs spacing: " << m_glyphsSpacing; 121 | drawString(10, ++i * incI, 0, ss.str()); 122 | 123 | ss.str(""); 124 | ss << " that's " << (m_glyphsCount.x * m_glyphsCount.y) << " glyphs"; 125 | drawString(10, ++i * incI, 0, ss.str()); 126 | 127 | ss.str(""); 128 | ss << "[q] [w] Glyph size: " << m_glyphSize; 129 | drawString(10, ++i * incI, 0, ss.str()); 130 | 131 | drawString(10, ++i * incI, 0, " [t] Toggle primitives"); 132 | 133 | } 134 | 135 | virtual bool keyboardCallback(unsigned char key) { 136 | switch (key) { 137 | case '+': 138 | changeSpacing(m_glyphsSpacing * 1.25f); 139 | break; 140 | case '-': 141 | changeSpacing(m_glyphsSpacing / 1.25f); 142 | break; 143 | case 'q': 144 | m_glyphSize *= 1.25f; 145 | break; 146 | case 'w': 147 | m_glyphSize /= 1.25f; 148 | break; 149 | case 't': 150 | m_useLines ^= true; 151 | break; 152 | default: 153 | return false; 154 | } 155 | 156 | recompute(); 157 | return true; 158 | } 159 | 160 | virtual bool motionCallback(int /*x*/, int y, int /*dx*/, int /*dy*/, int /*screenWidth*/, int screenHeight, int mouseButtonsState) { 161 | if (mouseButtonsState == (1 << GLUT_RIGHT_BUTTON)) { 162 | m_planeX = m_vfInfo.realSize.x - ((float)y / screenHeight) * m_vfInfo.realSize.x; 163 | recompute(); 164 | return true; 165 | } 166 | 167 | return false; 168 | } 169 | 170 | virtual void displayCallback() { 171 | assert(m_allocated); 172 | 173 | if (m_glyphsCount.x == 0 || m_glyphsCount.y == 0) { 174 | return; 175 | } 176 | 177 | glBindBuffer(GL_ARRAY_BUFFER, m_verticesVbo); 178 | glEnableClientState(GL_VERTEX_ARRAY); 179 | glVertexPointer(3, GL_FLOAT, 0, NULL); 180 | 181 | glBindBuffer(GL_ARRAY_BUFFER, m_colorsVbo); 182 | glEnableClientState(GL_COLOR_ARRAY); 183 | glColorPointer(3, GL_FLOAT, 0, NULL); 184 | 185 | if (!m_useLines) { 186 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indicesVbo); 187 | 188 | glBindBuffer(GL_ARRAY_BUFFER, m_normalsVbo); 189 | glEnableClientState(GL_NORMAL_ARRAY); 190 | glNormalPointer(GL_FLOAT, 0, NULL); 191 | } 192 | 193 | 194 | if (m_useLines) { 195 | glDrawArrays(GL_LINES, 0, 2 * m_glyphsCount.x * m_glyphsCount.y); 196 | } 197 | else { 198 | glEnable(GL_COLOR_MATERIAL); 199 | glEnable(GL_LIGHTING); 200 | 201 | glDrawElements(GL_TRIANGLES, 3 * m_facesPerGlyph * m_glyphsCount.x * m_glyphsCount.y, GL_UNSIGNED_INT, NULL); 202 | 203 | glDisable(GL_COLOR_MATERIAL); 204 | glDisable(GL_LIGHTING); 205 | } 206 | 207 | glBindBuffer(GL_ARRAY_BUFFER, 0); 208 | glDisableClientState(GL_NORMAL_ARRAY); 209 | glDisableClientState(GL_COLOR_ARRAY); 210 | glDisableClientState(GL_VERTEX_ARRAY); 211 | }; 212 | 213 | protected: 214 | 215 | void allocate() { 216 | if (m_allocated) { 217 | free(); 218 | } 219 | 220 | m_allocated = true; 221 | 222 | uint totalGlyphsCount = m_glyphsCount.x * m_glyphsCount.y; 223 | uint verticesCount = m_useLines ? 2 * totalGlyphsCount : m_verticesPerGlyph * totalGlyphsCount; 224 | 225 | checkCudaErrors(createCudaSharedVbo(&m_verticesVbo, GL_ARRAY_BUFFER, verticesCount * sizeof(float3), &m_cudaVerticesVboResource)); 226 | checkCudaErrors(createCudaSharedVbo(&m_colorsVbo, GL_ARRAY_BUFFER, verticesCount * sizeof(float3), &m_cudaColorsVboResource)); 227 | 228 | if (!m_useLines) { 229 | checkCudaErrors(createCudaSharedVbo(&m_normalsVbo, GL_ARRAY_BUFFER, verticesCount * sizeof(float3), &m_cudaNormalsVboResource)); 230 | uint facesCount = m_facesPerGlyph * totalGlyphsCount; 231 | checkCudaErrors(createCudaSharedVbo(&m_indicesVbo, GL_ELEMENT_ARRAY_BUFFER, 3 * facesCount * sizeof(uint3), &m_cudaIndicesVboResource)); 232 | 233 | } 234 | 235 | } 236 | 237 | void free() { 238 | if (!m_allocated) { 239 | return; 240 | } 241 | 242 | checkCudaErrors(deleteCudaSharedVbo(&m_verticesVbo, m_cudaVerticesVboResource)); 243 | m_verticesVbo = NULL; 244 | m_cudaVerticesVboResource = nullptr; 245 | 246 | checkCudaErrors(deleteCudaSharedVbo(&m_colorsVbo, m_cudaColorsVboResource)); 247 | m_colorsVbo = NULL; 248 | m_cudaColorsVboResource = nullptr; 249 | 250 | if (m_cudaNormalsVboResource != nullptr) { 251 | checkCudaErrors(deleteCudaSharedVbo(&m_normalsVbo, m_cudaNormalsVboResource)); 252 | m_normalsVbo = NULL; 253 | m_cudaNormalsVboResource = nullptr; 254 | } 255 | 256 | if (m_cudaIndicesVboResource != nullptr) { 257 | checkCudaErrors(deleteCudaSharedVbo(&m_indicesVbo, m_cudaIndicesVboResource)); 258 | m_indicesVbo = NULL; 259 | m_cudaIndicesVboResource = nullptr; 260 | } 261 | 262 | m_allocated = false; 263 | } 264 | 265 | }; 266 | 267 | typedef TGlyphsActivity<> GlyphsActivity; 268 | 269 | } -------------------------------------------------------------------------------- /src/StreamSurface/SteamlinesLineActivity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Activity.h" 3 | #include "CudaHelper.h" 4 | #include "Utils.h" 5 | #include "CudaMathHelper.h" 6 | 7 | namespace mf { 8 | 9 | template 10 | class TStreamlinesLineActivity : public Activity { 11 | 12 | protected: 13 | VectorFieldInfo m_vfInfo; 14 | bool m_allocated; 15 | bool m_useRk4; 16 | double m_dt; 17 | uint m_linesCount; 18 | uint m_linePairsCount; 19 | float3 m_startPt; 20 | float3 m_endPt; 21 | uint m_maxSamples; 22 | float m_lineWidth; 23 | bool m_useTubes; 24 | float m_tubeRadius; 25 | uint m_geometrySampling; 26 | uint m_maxGeometrySamples; 27 | bool m_oritentationX; 28 | bool m_adaptiveLinePositions; 29 | float m_maxAdaptiveDistance; 30 | uint m_maxAdaptiveSteps; 31 | bool m_streamSurface; 32 | bool m_streamSurfaceLines; 33 | uint m_stremasurfaceSlicesCount; 34 | bool m_wingLine; 35 | 36 | static const uint m_verticesPerTubeSlice = 5; 37 | static const uint m_facesPerTubeSegment = 5 * 2; 38 | 39 | 40 | GLuint m_verticesVbo; 41 | cudaGraphicsResource* m_cudaVerticesVboResource; 42 | 43 | GLuint m_normalsVbo; 44 | cudaGraphicsResource* m_cudaNormalsVboResource; 45 | 46 | GLuint m_indicesVbo; 47 | cudaGraphicsResource* m_cudaIndicesVboResource; 48 | 49 | GLuint m_colorsVbo; 50 | cudaGraphicsResource* m_cudaColorsVboResource; 51 | 52 | GLuint m_surfaceIndicesVbo; 53 | cudaGraphicsResource* m_cudaSurfaceIndicesVboResource; 54 | 55 | GLuint m_surfaceNormalsVbo; 56 | cudaGraphicsResource* m_cudaSurfaceNormalsVboResource; 57 | 58 | uint* m_d_surfaceFacesCounts; 59 | uint* m_h_surfaceFacesCounts; 60 | 61 | uint* m_d_ptCounts; 62 | uint* m_h_ptCounts; 63 | 64 | uint m_seedCount; 65 | float3* m_d_seeds; 66 | float3* m_h_seeds; 67 | 68 | uint2* h_linePairs; 69 | uint2* d_inLinePairs; 70 | uint2* d_outLinePairs; 71 | 72 | uint* d_outLinePairsIndex; 73 | uint* d_outLinesIndex; 74 | 75 | 76 | float3* d_vertices; 77 | uint3* d_indices; 78 | float3* d_normals; 79 | float3* d_colors; 80 | 81 | uint3* d_surfaceIndices; 82 | float3* d_surfaceNormals; 83 | 84 | 85 | public: 86 | TStreamlinesLineActivity(const VectorFieldInfo& vfInfo) 87 | : m_vfInfo(vfInfo) 88 | , m_allocated(false) 89 | , m_useRk4(true) 90 | , m_useTubes(false) 91 | , m_lineWidth(0.9f) 92 | , m_dt(1.0 / 256.0) 93 | , m_linesCount(256) 94 | , m_linePairsCount(0) 95 | , m_tubeRadius(1.0f) 96 | , m_geometrySampling(4) 97 | , m_oritentationX(true) 98 | , m_adaptiveLinePositions(false) 99 | , m_maxAdaptiveSteps(16) 100 | , m_maxAdaptiveDistance(10) 101 | , m_streamSurface(false) 102 | , m_streamSurfaceLines(true) 103 | , m_stremasurfaceSlicesCount(0) 104 | , m_startPt(make_float3(0, 0, 0)) 105 | , m_endPt(make_float3(0, vfInfo.realSize.y, 0)) 106 | , m_maxSamples(8192) 107 | , m_wingLine(false) 108 | , m_maxGeometrySamples((uint)-1) // will be properly initialized in ctor body 109 | , m_verticesVbo(NULL) 110 | , m_cudaVerticesVboResource(nullptr) 111 | , m_normalsVbo(NULL) 112 | , m_cudaNormalsVboResource(nullptr) 113 | , m_indicesVbo(NULL) 114 | , m_cudaIndicesVboResource(nullptr) 115 | , m_colorsVbo(NULL) 116 | , m_cudaColorsVboResource(nullptr) 117 | , m_surfaceIndicesVbo(NULL) 118 | , m_cudaSurfaceIndicesVboResource(nullptr) 119 | , m_surfaceNormalsVbo(NULL) 120 | , m_cudaSurfaceNormalsVboResource(nullptr) 121 | , m_d_surfaceFacesCounts(nullptr) 122 | , m_h_surfaceFacesCounts(nullptr) 123 | , m_d_ptCounts(nullptr) 124 | , m_h_ptCounts(nullptr) 125 | , m_seedCount(0) 126 | , m_d_seeds(nullptr) 127 | , m_h_seeds(nullptr) 128 | , h_linePairs(nullptr) 129 | , d_inLinePairs(nullptr) 130 | , d_outLinePairs(nullptr) 131 | , d_outLinePairsIndex(nullptr) 132 | , d_outLinesIndex(nullptr) 133 | , d_vertices(nullptr) 134 | , d_indices(nullptr) 135 | , d_normals(nullptr) 136 | , d_colors(nullptr) 137 | , d_surfaceIndices(nullptr) 138 | , d_surfaceNormals(nullptr) 139 | { 140 | applyGeometrySampling(); 141 | applyLineWidth(); 142 | allocate(); 143 | recompute(); 144 | } 145 | 146 | virtual ~TStreamlinesLineActivity() { 147 | free(); 148 | } 149 | 150 | 151 | 152 | virtual void recompute() { 153 | assert(m_allocated); 154 | 155 | auto t1 = std::chrono::high_resolution_clock::now(); 156 | 157 | size_t bytesCount; 158 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaVerticesVboResource)); 159 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_vertices, &bytesCount, m_cudaVerticesVboResource)); 160 | 161 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaColorsVboResource)); 162 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_colors, &bytesCount, m_cudaColorsVboResource)); 163 | 164 | if (!m_adaptiveLinePositions) { 165 | seedAsLine(m_linesCount); 166 | } 167 | 168 | if (m_useTubes) { 169 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaIndicesVboResource)); 170 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_indices, &bytesCount, m_cudaIndicesVboResource)); 171 | 172 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaNormalsVboResource)); 173 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_normals, &bytesCount, m_cudaNormalsVboResource)); 174 | } 175 | 176 | bool doComputeSurface = m_streamSurface && !m_useTubes; 177 | 178 | if (m_adaptiveLinePositions) { 179 | runAdaptiveLineEvaluation(); 180 | } 181 | else { 182 | runKernel(m_h_seeds, m_linesCount); 183 | if (doComputeSurface) { 184 | m_linePairsCount = m_linesCount - 1; 185 | for (uint i = 0; i < m_linePairsCount; ++i) { 186 | h_linePairs[i].x = i; 187 | h_linePairs[i].y = i + 1; 188 | } 189 | checkCudaErrors(cudaMemcpy(d_inLinePairs, h_linePairs, sizeof(uint2) * m_linePairsCount, cudaMemcpyHostToDevice)); 190 | } 191 | } 192 | 193 | if (doComputeSurface) { 194 | computeSurface(); 195 | } 196 | 197 | if (m_useTubes) { 198 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaNormalsVboResource)); 199 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaIndicesVboResource)); 200 | } 201 | 202 | 203 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaColorsVboResource)); 204 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaVerticesVboResource)); 205 | 206 | d_vertices = nullptr; 207 | d_indices = nullptr; 208 | d_normals = nullptr; 209 | d_colors = nullptr; 210 | 211 | auto t2 = std::chrono::high_resolution_clock::now(); 212 | m_lastDuration = std::chrono::duration_cast(t2 - t1).count() / 1000.0f; 213 | } 214 | 215 | virtual void drawControls(float& i, float incI) { 216 | 217 | std::stringstream ss; 218 | 219 | drawString(10, ++i * incI, 0, "Use right mouse for in x direction"); 220 | drawString(10, ++i * incI, 0, "Use right+left mouse for in z direction"); 221 | 222 | ss.str(""); 223 | ss << "[+] [-] Time step: " << m_dt; 224 | drawString(10, ++i * incI, 0, ss.str()); 225 | 226 | ss.str(""); 227 | ss << "[q] [w] Lines count: " << m_linesCount; 228 | drawString(10, ++i * incI, 0, ss.str()); 229 | 230 | ss.str(""); 231 | ss << "[a] [s] Max samples: " << m_maxSamples; 232 | drawString(10, ++i * incI, 0, ss.str()); 233 | 234 | ss.str(""); 235 | ss << "[z] [x] Line width: " << m_lineWidth; 236 | drawString(10, ++i * incI, 0, ss.str()); 237 | ss.str(""); 238 | ss << "[d] [f] Geometry sampling: " << m_geometrySampling; 239 | drawString(10, ++i * incI, 0, ss.str()); 240 | 241 | ss.str(""); 242 | ss << " [e] Use RK4: " << (m_useRk4 ? "true" : "false"); 243 | drawString(10, ++i * incI, 0, ss.str()); 244 | 245 | ss.str(""); 246 | ss << " [t] Use tubes: " << (m_useTubes ? "true" : "false"); 247 | drawString(10, ++i * incI, 0, ss.str()); 248 | 249 | if (m_useTubes) { 250 | ss.str(""); 251 | ss << "[c] [v] Tube radius: " << m_tubeRadius; 252 | drawString(10, ++i * incI, 0, ss.str()); 253 | } 254 | 255 | ss.str(""); 256 | ss << " [u] Toggle orientation"; 257 | drawString(10, ++i * incI, 0, ss.str()); 258 | 259 | ss.str(""); 260 | ss << " [j] Toggle wing line"; 261 | drawString(10, ++i * incI, 0, ss.str()); 262 | 263 | ss.str(""); 264 | ss << " [m] Toggle stream surface"; 265 | drawString(10, ++i * incI, 0, ss.str()); 266 | 267 | ss.str(""); 268 | ss << " [,] Toggle stream surface lines"; 269 | drawString(10, ++i * incI, 0, ss.str()); 270 | 271 | ss.str(""); 272 | ss << " [y] Adaptive line positions"; 273 | drawString(10, ++i * incI, 0, ss.str()); 274 | 275 | if (m_adaptiveLinePositions) { 276 | ss.str(""); 277 | ss << "[g] [h] Min adaptive distance: " << m_maxAdaptiveDistance; 278 | drawString(10, ++i * incI, 0, ss.str()); 279 | 280 | ss.str(""); 281 | ss << "[b] [n] Max adaptive steps: " << m_maxAdaptiveSteps; 282 | drawString(10, ++i * incI, 0, ss.str()); 283 | } 284 | } 285 | 286 | virtual bool keyboardCallback(unsigned char key) { 287 | 288 | switch (key) { 289 | case '+': 290 | m_dt *= 2; 291 | break; 292 | case '-': 293 | m_dt /= 2; 294 | break; 295 | case 'q': 296 | m_linesCount *= 2; 297 | allocate(); 298 | break; 299 | case 'w': 300 | if (m_linesCount > 2) { 301 | m_linesCount /= 2; 302 | allocate(); 303 | } 304 | break; 305 | case 'a': 306 | m_maxSamples *= 2; 307 | applyGeometrySampling(); 308 | allocate(); 309 | break; 310 | case 's': 311 | if (m_maxSamples > 2) { 312 | m_maxSamples /= 2; 313 | applyGeometrySampling(); 314 | allocate(); 315 | } 316 | break; 317 | case 'z': 318 | if (m_lineWidth < 1) { 319 | m_lineWidth *= 1.25; 320 | applyLineWidth(); 321 | } 322 | break; 323 | case 'x': 324 | m_lineWidth /= 1.25; 325 | applyLineWidth(); 326 | break; 327 | case 'c': 328 | m_tubeRadius *= 1.25; 329 | break; 330 | case 'v': 331 | m_tubeRadius /= 1.25; 332 | break; 333 | case 'd': 334 | ++m_geometrySampling; 335 | applyGeometrySampling(); 336 | allocate(); 337 | break; 338 | case 'f': 339 | if (m_geometrySampling > 1) { 340 | --m_geometrySampling; 341 | applyGeometrySampling(); 342 | allocate(); 343 | } 344 | break; 345 | case 'e': 346 | m_useRk4 ^= true; 347 | break; 348 | case 'y': 349 | m_adaptiveLinePositions ^= true; 350 | allocate(); 351 | break; 352 | case 't': 353 | m_useTubes ^= true; 354 | allocate(); 355 | break; 356 | case 'm': 357 | m_streamSurface ^= true; 358 | allocate(); 359 | break; 360 | case ',': 361 | m_streamSurfaceLines ^= true; 362 | break; 363 | case 'j': 364 | m_wingLine ^= true; 365 | if (m_wingLine) { 366 | m_startPt = make_float3((float)-m_vfInfo.realCoordMin.x, (float)-m_vfInfo.realCoordMin.y, (float)-m_vfInfo.realCoordMin.z); 367 | m_endPt = make_float3((float)-m_vfInfo.realCoordMin.x + 238, (float)-m_vfInfo.realCoordMin.y - 145, (float)-m_vfInfo.realCoordMin.z); 368 | } 369 | else { 370 | m_startPt = make_float3(0, 0, 0); 371 | m_endPt = make_float3(0, m_vfInfo.realSize.y, 0); 372 | } 373 | break; 374 | case 'u': 375 | m_oritentationX ^= true; 376 | if (m_oritentationX) { 377 | m_startPt = make_float3(0, 0, 0); 378 | m_endPt = make_float3(0, m_vfInfo.realSize.y, 0); 379 | } 380 | else { 381 | m_startPt = make_float3(0, m_vfInfo.realSize.y / 2, 0); 382 | m_endPt = make_float3(0, m_vfInfo.realSize.y / 2, m_vfInfo.realSize.z); 383 | } 384 | applyLineWidth(); 385 | break; 386 | case 'g': 387 | ++m_maxAdaptiveDistance; 388 | break; 389 | case 'h': 390 | if (m_maxAdaptiveDistance > 1) { 391 | --m_maxAdaptiveDistance; 392 | } 393 | break; 394 | case 'b': 395 | ++m_maxAdaptiveSteps; 396 | break; 397 | case 'n': 398 | if (m_maxAdaptiveSteps > 0) { 399 | --m_maxAdaptiveSteps; 400 | } 401 | break; 402 | default: 403 | return false; 404 | } 405 | 406 | recompute(); 407 | return true; 408 | } 409 | 410 | virtual bool motionCallback(int /*x*/, int y, int /*dx*/, int /*dy*/, int /*screenWidth*/, int screenHeight, int mouseButtonsState) { 411 | 412 | 413 | if (mouseButtonsState == (1 << GLUT_RIGHT_BUTTON)) { 414 | float ptX = m_oritentationX 415 | ? m_vfInfo.realSize.x - ((float)y / screenHeight) * m_vfInfo.realSize.x 416 | : (1.0f - ((float)y / screenHeight)) * m_vfInfo.realSize.x; 417 | if (m_wingLine) { 418 | float dx = ptX - m_startPt.x; 419 | m_startPt.x = ptX; 420 | m_endPt.x += dx; 421 | } 422 | else { 423 | m_startPt.x = ptX; 424 | m_endPt.x = ptX; 425 | } 426 | recompute(); 427 | return true; 428 | } 429 | else if (mouseButtonsState == ((1 << GLUT_LEFT_BUTTON) | (1 << GLUT_RIGHT_BUTTON))) { 430 | if (m_oritentationX) { 431 | float ptZ = (1.0f - ((float)y / screenHeight)) * m_vfInfo.realSize.z; 432 | m_startPt.z = ptZ; 433 | m_endPt.z = ptZ; 434 | } 435 | else { 436 | float ptY = ((float)y / screenHeight) * m_vfInfo.realSize.y; 437 | if (m_wingLine) { 438 | float dy = ptY - m_startPt.y; 439 | m_startPt.y = ptY; 440 | m_endPt.y += dy; 441 | } 442 | else { 443 | m_startPt.y = ptY; 444 | m_endPt.y = ptY; 445 | } 446 | } 447 | recompute(); 448 | return true; 449 | } 450 | 451 | return false; 452 | } 453 | 454 | virtual void displayCallback() { 455 | assert(m_allocated); 456 | 457 | if (m_linesCount == 0) { 458 | return; 459 | } 460 | 461 | glBindBuffer(GL_ARRAY_BUFFER, m_verticesVbo); 462 | glEnableClientState(GL_VERTEX_ARRAY); 463 | glVertexPointer(3, GL_FLOAT, 0, NULL); 464 | 465 | glBindBuffer(GL_ARRAY_BUFFER, m_colorsVbo); 466 | glEnableClientState(GL_COLOR_ARRAY); 467 | glColorPointer(3, GL_FLOAT, 0, NULL); 468 | 469 | //std::cout << "============================" << std::endl; 470 | 471 | if (m_useTubes) { 472 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indicesVbo); 473 | 474 | glBindBuffer(GL_ARRAY_BUFFER, m_normalsVbo); 475 | glEnableClientState(GL_NORMAL_ARRAY); 476 | glNormalPointer(GL_FLOAT, 0, NULL); 477 | 478 | glEnable(GL_COLOR_MATERIAL); 479 | glEnable(GL_LIGHTING); 480 | 481 | uint indicesPerTube = m_facesPerTubeSegment * (m_maxGeometrySamples - 1); 482 | for (size_t i = 0; i < m_linesCount; ++i) { 483 | if (m_h_ptCounts[i] >= 2) { 484 | assert(m_h_ptCounts[i] <= m_maxGeometrySamples); 485 | //std::cout << "Drawing tubes " << m_h_ptCounts[i] << std::endl; 486 | glDrawElements(GL_TRIANGLES, 3 * m_facesPerTubeSegment * (m_h_ptCounts[i] - 1), GL_UNSIGNED_INT, (void*)(i * indicesPerTube * 3 * sizeof(GLuint))); 487 | } 488 | } 489 | 490 | glDisable(GL_COLOR_MATERIAL); 491 | glDisable(GL_LIGHTING); 492 | 493 | glDisableClientState(GL_NORMAL_ARRAY); 494 | } 495 | else { 496 | 497 | if (m_streamSurface) { 498 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceIndicesVbo); 499 | 500 | glBindBuffer(GL_ARRAY_BUFFER, m_surfaceNormalsVbo); 501 | glEnableClientState(GL_NORMAL_ARRAY); 502 | glNormalPointer(GL_FLOAT, 0, NULL); 503 | 504 | glEnable(GL_COLOR_MATERIAL); 505 | glEnable(GL_LIGHTING); 506 | 507 | uint facesPerLine = 2 * m_maxGeometrySamples - 2; 508 | for (uint i = 0; i < m_stremasurfaceSlicesCount; ++i) { 509 | assert(m_h_surfaceFacesCounts[i] <= 2 * m_maxGeometrySamples - 2); 510 | if (m_h_surfaceFacesCounts[i] > 0) { 511 | glDrawElements(GL_TRIANGLES, 3 * m_h_surfaceFacesCounts[i], GL_UNSIGNED_INT, (void*)(i * facesPerLine * 3 * sizeof(GLuint))); 512 | } 513 | } 514 | 515 | glDisable(GL_COLOR_MATERIAL); 516 | glDisable(GL_LIGHTING); 517 | 518 | glDisableClientState(GL_NORMAL_ARRAY); 519 | //std::cout << "Drawing " << m_h_surfaceFacesCounts[0] << " faces" << std::endl; 520 | //glDrawElements(GL_TRIANGLES, 3 * m_h_surfaceFacesCounts[0], GL_UNSIGNED_INT, NULL/*(void*)(facesPerLine * 3 * sizeof(GLuint))*/); 521 | } 522 | 523 | if (!m_streamSurface || m_streamSurfaceLines) { 524 | for (uint i = 0; i < m_linesCount; ++i) { 525 | if (m_h_ptCounts[i] >= 2) { 526 | assert(m_h_ptCounts[i] <= m_maxGeometrySamples); 527 | //std::cout << "Drawing lines " << m_h_ptCounts[i] << std::endl; 528 | glDrawArrays(GL_LINE_STRIP, i * m_maxGeometrySamples, m_h_ptCounts[i]); 529 | } 530 | } 531 | } 532 | } 533 | 534 | glBindBuffer(GL_ARRAY_BUFFER, 0); 535 | glDisableClientState(GL_COLOR_ARRAY); 536 | glDisableClientState(GL_VERTEX_ARRAY); 537 | } 538 | 539 | 540 | protected: 541 | 542 | void applyGeometrySampling() { 543 | m_maxGeometrySamples = m_maxSamples / m_geometrySampling + 1; 544 | } 545 | 546 | void applyLineWidth() { 547 | 548 | if (m_wingLine) { 549 | float3 mid = (m_startPt + m_endPt) / 2.0f; 550 | float3 startVect = m_startPt - mid; 551 | float3 endVect = m_endPt - mid; 552 | 553 | m_startPt = mid + startVect * (m_lineWidth + 0.5f); 554 | m_endPt = mid + endVect * (m_lineWidth + 0.5f); 555 | return; 556 | } 557 | 558 | if (m_oritentationX) { 559 | m_startPt.y = (1.0f - m_lineWidth) * m_vfInfo.realSize.y / 2; 560 | m_endPt.y = m_lineWidth * m_vfInfo.realSize.y / 2 + m_vfInfo.realSize.y / 2; 561 | } 562 | else { 563 | m_startPt.z = (1.0f - m_lineWidth) * m_vfInfo.realSize.z / 2; 564 | m_endPt.z = m_lineWidth * m_vfInfo.realSize.z / 2 + m_vfInfo.realSize.z / 2; 565 | } 566 | } 567 | 568 | void seedAsLine(uint count) { 569 | 570 | float3 delta = (m_endPt - m_startPt) / (float)count; 571 | for (uint i = 0; i < count; ++i) { 572 | m_h_seeds[i] = m_startPt + (float)i * delta; 573 | } 574 | 575 | } 576 | 577 | 578 | void runKernel(float3* h_seeds, uint seedsCount, uint offsetLines = 0) { 579 | if (h_seeds != nullptr) { 580 | checkCudaErrors(cudaMemcpy(m_d_seeds + offsetLines, h_seeds + offsetLines, seedsCount * sizeof(float3), cudaMemcpyHostToDevice)); 581 | } 582 | 583 | if (m_useTubes) { 584 | uint verticesOffset = offsetLines * m_verticesPerTubeSlice * m_maxGeometrySamples; 585 | uint facesOffset = offsetLines * m_facesPerTubeSegment * (m_maxGeometrySamples - 1); 586 | runStreamtubesLineKernel(m_d_seeds + offsetLines, seedsCount, m_dt, m_maxSamples, m_vfInfo.cudaDataSize, m_vfInfo.volumeCoordSpaceMult, m_tubeRadius, m_useRk4, m_geometrySampling, 587 | d_vertices + verticesOffset, m_d_ptCounts + offsetLines, d_indices + facesOffset, d_normals + verticesOffset, d_colors + verticesOffset); 588 | } 589 | else { 590 | uint verticesOffset = offsetLines * m_maxGeometrySamples; 591 | runStreamlinesLineKernel(m_d_seeds + offsetLines, seedsCount, m_dt, m_maxSamples, m_vfInfo.cudaDataSize, m_vfInfo.volumeCoordSpaceMult, m_useRk4, m_geometrySampling, 592 | d_vertices + verticesOffset, m_d_ptCounts + offsetLines, d_colors + verticesOffset); 593 | } 594 | 595 | checkCudaErrors(cudaMemcpy(m_h_ptCounts + offsetLines, m_d_ptCounts + offsetLines, seedsCount * sizeof(uint), cudaMemcpyDeviceToHost)); 596 | } 597 | 598 | void runAdaptiveLineEvaluation() { 599 | 600 | for (size_t i = 0; i < m_linesCount; ++i) { 601 | m_h_ptCounts[i] = 0; 602 | } 603 | 604 | uint totalLinesCount = 0; 605 | uint linesToGenerate = 2; 606 | 607 | m_h_seeds[0] = m_startPt; 608 | m_h_seeds[1] = m_endPt; 609 | checkCudaErrors(cudaMemcpy(m_d_seeds, m_h_seeds, 2 * sizeof(float3), cudaMemcpyHostToDevice)); 610 | 611 | m_linePairsCount = 1; 612 | uint2 linePair = make_uint2(0, 1); 613 | checkCudaErrors(cudaMemcpy(d_inLinePairs, &linePair, sizeof(uint2), cudaMemcpyHostToDevice)); 614 | 615 | uint zero = 0; 616 | uint verticesPerSample = m_useTubes ? m_verticesPerTubeSlice : 1; 617 | uint verticesPerLine = verticesPerSample * m_maxGeometrySamples; 618 | 619 | runKernel(nullptr, linesToGenerate, totalLinesCount); 620 | totalLinesCount += linesToGenerate; 621 | 622 | for (uint adaptiveSteps = 0; adaptiveSteps < m_maxAdaptiveSteps; ++adaptiveSteps) { 623 | 624 | checkCudaErrors(cudaMemcpy(d_outLinesIndex, &totalLinesCount, sizeof(uint), cudaMemcpyHostToDevice)); 625 | checkCudaErrors(cudaMemcpy(d_outLinePairsIndex, &zero, sizeof(uint), cudaMemcpyHostToDevice)); 626 | 627 | runLineAdaptiveExtensionKernel(m_maxAdaptiveDistance, d_inLinePairs, m_linePairsCount, d_vertices, verticesPerLine, verticesPerSample, m_d_ptCounts, m_d_seeds, 628 | d_outLinePairs, d_outLinePairsIndex, d_outLinesIndex, m_linesCount); 629 | 630 | checkCudaErrors(cudaMemcpy(&m_linePairsCount, d_outLinePairsIndex, sizeof(uint), cudaMemcpyDeviceToHost)); 631 | //std::cout << "Pairs: " << pairsCount << std::endl; 632 | assert(m_linePairsCount <= m_linesCount); 633 | std::swap(d_inLinePairs, d_outLinePairs); 634 | 635 | uint newLinesCount; 636 | checkCudaErrors(cudaMemcpy(&newLinesCount, d_outLinesIndex, sizeof(uint), cudaMemcpyDeviceToHost)); 637 | 638 | linesToGenerate = newLinesCount - totalLinesCount; 639 | assert(totalLinesCount + linesToGenerate <= m_linesCount); 640 | 641 | if (linesToGenerate == 0) { 642 | break; 643 | } 644 | 645 | runKernel(nullptr, linesToGenerate, totalLinesCount); 646 | totalLinesCount += linesToGenerate; 647 | } 648 | } 649 | 650 | void computeSurface() { 651 | 652 | for (size_t i = 0; i < m_linesCount; ++i) { 653 | m_h_surfaceFacesCounts[i] = 0; 654 | } 655 | 656 | size_t bytesCount; 657 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaSurfaceIndicesVboResource)); 658 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_surfaceIndices, &bytesCount, m_cudaSurfaceIndicesVboResource)); 659 | 660 | checkCudaErrors(cudaGraphicsMapResources(1, &m_cudaSurfaceNormalsVboResource)); 661 | checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&d_surfaceNormals, &bytesCount, m_cudaSurfaceNormalsVboResource)); 662 | 663 | uint verticesPerSample = m_useTubes ? m_verticesPerTubeSlice : 1; 664 | uint verticesPerLine = verticesPerSample * m_maxGeometrySamples; 665 | 666 | //std::cout << "Running surface for " << pairsCount << " pairs" << std::endl; 667 | runLineStreamSurfaceKernel(d_inLinePairs, m_linePairsCount, d_vertices, verticesPerLine, m_d_ptCounts, d_surfaceIndices, m_d_surfaceFacesCounts, d_surfaceNormals); 668 | m_stremasurfaceSlicesCount = m_linePairsCount; 669 | 670 | checkCudaErrors(cudaMemcpy(m_h_surfaceFacesCounts, m_d_surfaceFacesCounts, m_linePairsCount * sizeof(uint), cudaMemcpyDeviceToHost)); 671 | 672 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaSurfaceNormalsVboResource)); 673 | checkCudaErrors(cudaGraphicsUnmapResources(1, &m_cudaSurfaceIndicesVboResource)); 674 | 675 | } 676 | 677 | void allocate() { 678 | if (m_allocated) { 679 | free(); 680 | } 681 | 682 | m_allocated = true; 683 | 684 | if (m_useTubes) { 685 | uint verticesCount = m_verticesPerTubeSlice * m_maxGeometrySamples * m_linesCount; 686 | checkCudaErrors(createCudaSharedVbo(&m_verticesVbo, GL_ARRAY_BUFFER, sizeof(float3) * verticesCount, &m_cudaVerticesVboResource)); 687 | checkCudaErrors(createCudaSharedVbo(&m_colorsVbo, GL_ARRAY_BUFFER, sizeof(float3) * verticesCount, &m_cudaColorsVboResource)); 688 | checkCudaErrors(createCudaSharedVbo(&m_normalsVbo, GL_ARRAY_BUFFER, sizeof(float3) * verticesCount, &m_cudaNormalsVboResource)); 689 | uint facesCount = m_facesPerTubeSegment * (m_maxGeometrySamples - 1) * m_linesCount; 690 | checkCudaErrors(createCudaSharedVbo(&m_indicesVbo, GL_ELEMENT_ARRAY_BUFFER, facesCount * sizeof(uint3), &m_cudaIndicesVboResource)); 691 | } 692 | else { 693 | checkCudaErrors(createCudaSharedVbo(&m_verticesVbo, GL_ARRAY_BUFFER, m_linesCount * m_maxGeometrySamples * sizeof(float3), &m_cudaVerticesVboResource)); 694 | checkCudaErrors(createCudaSharedVbo(&m_colorsVbo, GL_ARRAY_BUFFER, m_linesCount * m_maxGeometrySamples * sizeof(float3), &m_cudaColorsVboResource)); 695 | } 696 | 697 | if (m_adaptiveLinePositions) { 698 | checkCudaErrors(cudaMalloc((void**)&d_outLinePairs, sizeof(uint2) * m_linesCount)); 699 | 700 | checkCudaErrors(cudaMalloc((void**)&d_outLinePairsIndex, sizeof(uint2))); 701 | checkCudaErrors(cudaMalloc((void**)&d_outLinesIndex, sizeof(uint2))); 702 | } 703 | 704 | if (m_adaptiveLinePositions || m_streamSurface) { 705 | checkCudaErrors(cudaMalloc((void**)&d_inLinePairs, sizeof(uint2) * m_linesCount)); 706 | } 707 | 708 | if (m_streamSurface) { 709 | h_linePairs = new uint2[m_linesCount]; 710 | 711 | checkCudaErrors(createCudaSharedVbo(&m_surfaceIndicesVbo, GL_ELEMENT_ARRAY_BUFFER, m_linesCount * (2 * m_maxGeometrySamples - 2) * sizeof(uint3), &m_cudaSurfaceIndicesVboResource)); 712 | checkCudaErrors(createCudaSharedVbo(&m_surfaceNormalsVbo, GL_ELEMENT_ARRAY_BUFFER, m_linesCount * (2 * m_maxGeometrySamples - 2) * sizeof(float3), &m_cudaSurfaceNormalsVboResource)); 713 | 714 | checkCudaErrors(cudaMalloc((void**)&m_d_surfaceFacesCounts, sizeof(uint) * m_linesCount)); 715 | m_h_surfaceFacesCounts = new uint[m_linesCount]; 716 | for (size_t i = 0; i < m_linesCount; ++i) { 717 | m_h_surfaceFacesCounts[i] = 0; 718 | } 719 | 720 | m_stremasurfaceSlicesCount = 0; 721 | } 722 | 723 | checkCudaErrors(cudaMalloc((void**)&m_d_ptCounts, sizeof(uint) * m_linesCount)); 724 | m_h_ptCounts = new uint[m_linesCount]; 725 | for (size_t i = 0; i < m_linesCount; ++i) { 726 | m_h_ptCounts[i] = 0; 727 | } 728 | 729 | checkCudaErrors(cudaMalloc((void**)&m_d_seeds, sizeof(float3) * m_linesCount)); 730 | m_h_seeds = new float3[m_linesCount]; 731 | } 732 | 733 | void free() { 734 | if (!m_allocated) { 735 | return; 736 | } 737 | 738 | checkCudaErrors(deleteCudaSharedVbo(&m_verticesVbo, m_cudaVerticesVboResource)); 739 | m_verticesVbo = NULL; 740 | m_cudaVerticesVboResource = nullptr; 741 | 742 | checkCudaErrors(deleteCudaSharedVbo(&m_colorsVbo, m_cudaColorsVboResource)); 743 | m_colorsVbo = NULL; 744 | m_cudaColorsVboResource = nullptr; 745 | 746 | if (m_cudaNormalsVboResource != nullptr) { 747 | checkCudaErrors(deleteCudaSharedVbo(&m_normalsVbo, m_cudaNormalsVboResource)); 748 | m_normalsVbo = NULL; 749 | m_cudaNormalsVboResource = nullptr; 750 | } 751 | 752 | if (m_cudaIndicesVboResource != nullptr) { 753 | checkCudaErrors(deleteCudaSharedVbo(&m_indicesVbo, m_cudaIndicesVboResource)); 754 | m_indicesVbo = NULL; 755 | m_cudaIndicesVboResource = nullptr; 756 | } 757 | 758 | if (m_cudaSurfaceIndicesVboResource != nullptr) { 759 | checkCudaErrors(deleteCudaSharedVbo(&m_surfaceIndicesVbo, m_cudaSurfaceIndicesVboResource)); 760 | m_surfaceIndicesVbo = NULL; 761 | m_cudaSurfaceIndicesVboResource = nullptr; 762 | } 763 | 764 | if (m_cudaSurfaceNormalsVboResource != nullptr) { 765 | checkCudaErrors(deleteCudaSharedVbo(&m_surfaceNormalsVbo, m_cudaSurfaceNormalsVboResource)); 766 | m_surfaceNormalsVbo = NULL; 767 | m_cudaSurfaceNormalsVboResource = nullptr; 768 | } 769 | 770 | if (h_linePairs != nullptr) { 771 | delete[] h_linePairs; 772 | h_linePairs = nullptr; 773 | } 774 | 775 | if (d_inLinePairs != nullptr) { 776 | checkCudaErrors(cudaFree((void*)d_inLinePairs)); 777 | d_inLinePairs = nullptr; 778 | } 779 | 780 | if (d_outLinePairs != nullptr) { 781 | checkCudaErrors(cudaFree((void*)d_outLinePairs)); 782 | d_outLinePairs = nullptr; 783 | } 784 | 785 | if (d_outLinePairsIndex != nullptr) { 786 | checkCudaErrors(cudaFree((void*)d_outLinePairsIndex)); 787 | d_outLinePairsIndex = nullptr; 788 | } 789 | 790 | if (d_outLinesIndex != nullptr) { 791 | checkCudaErrors(cudaFree((void*)d_outLinesIndex)); 792 | d_outLinesIndex = nullptr; 793 | } 794 | 795 | if (m_d_surfaceFacesCounts) { 796 | checkCudaErrors(cudaFree((void*)m_d_surfaceFacesCounts)); 797 | m_d_surfaceFacesCounts = nullptr; 798 | delete[] m_h_surfaceFacesCounts; 799 | m_h_surfaceFacesCounts = nullptr; 800 | } 801 | 802 | checkCudaErrors(cudaFree((void*)m_d_ptCounts)); 803 | m_d_ptCounts = nullptr; 804 | delete[] m_h_ptCounts; 805 | m_h_ptCounts = nullptr; 806 | 807 | checkCudaErrors(cudaFree((void*)m_d_seeds)); 808 | m_d_seeds = nullptr; 809 | delete[] m_h_seeds; 810 | m_h_seeds = nullptr; 811 | 812 | m_allocated = false; 813 | } 814 | 815 | }; 816 | 817 | typedef TStreamlinesLineActivity<> StreamlinesLineActivity; 818 | 819 | } -------------------------------------------------------------------------------- /src/StreamSurface/StreamSurface.cu: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CudaHelper.h" 3 | #include "CudaMathHelper.h" 4 | 5 | namespace mf { 6 | 7 | texture vectorMangitudeCtfTex; // 1D texture for color transfer function. 8 | texture vectorFieldTex; // 3D texture for storing of volumetric vector field. 9 | 10 | cudaArray* d_volumeArray = nullptr; 11 | cudaArray* d_vectorMangitudeCtfData = nullptr; 12 | 13 | float vectorMangitudeCtfLength; 14 | float maxMangitude; 15 | 16 | extern "C" 17 | void initCuda(const float4* h_volume, cudaExtent volumeSize, const std::vector& vectorMangitudeCtf, float maxVectorMangitude) { 18 | 19 | { 20 | std::cout << "Initializing vector magnitude color transfer function." << std::endl; 21 | cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(); 22 | checkCudaErrors(cudaMallocArray(&d_vectorMangitudeCtfData, &channelDesc, vectorMangitudeCtf.size(), 1)); 23 | checkCudaErrors(cudaMemcpyToArray(d_vectorMangitudeCtfData, 0, 0, &vectorMangitudeCtf[0], sizeof(float4) * vectorMangitudeCtf.size(), cudaMemcpyHostToDevice)); 24 | vectorMangitudeCtfTex.normalized = false; 25 | vectorMangitudeCtfTex.filterMode = cudaFilterModeLinear; 26 | vectorMangitudeCtfTex.addressMode[0] = cudaAddressModeClamp; 27 | checkCudaErrors(cudaBindTextureToArray(vectorMangitudeCtfTex, d_vectorMangitudeCtfData, channelDesc)); 28 | vectorMangitudeCtfLength = (float)vectorMangitudeCtf.size(); 29 | maxMangitude = maxVectorMangitude; 30 | } 31 | 32 | 33 | { 34 | // allocate 3D array 35 | std::cout << "Allocating CUDA 3D array in device." << std::endl; 36 | cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(); 37 | checkCudaErrors(cudaMalloc3DArray(&d_volumeArray, &channelDesc, volumeSize)); 38 | 39 | // copy data to 3D array 40 | std::cout << "Copying data to device." << std::endl; 41 | cudaMemcpy3DParms copyParams = {0}; 42 | copyParams.srcPtr = make_cudaPitchedPtr((void*)h_volume, volumeSize.width * sizeof(float4), volumeSize.width, volumeSize.height); 43 | copyParams.dstArray = d_volumeArray; 44 | copyParams.extent = volumeSize; 45 | copyParams.kind = cudaMemcpyHostToDevice; 46 | checkCudaErrors(cudaMemcpy3D(©Params)); 47 | 48 | // set texture parameters 49 | vectorFieldTex.normalized = false; 50 | vectorFieldTex.filterMode = cudaFilterModeLinear; // linear interpolation 51 | vectorFieldTex.addressMode[0] = cudaAddressModeClamp; 52 | vectorFieldTex.addressMode[1] = cudaAddressModeClamp; 53 | vectorFieldTex.addressMode[2] = cudaAddressModeClamp; 54 | 55 | // bind array to 3D texture 56 | std::cout << "Binding 3D texture." << std::endl; 57 | checkCudaErrors(cudaBindTextureToArray(vectorFieldTex, d_volumeArray, channelDesc)); 58 | 59 | std::cout << "Volume data successfully copied to device." << std::endl; 60 | } 61 | 62 | checkCudaErrors(cudaDeviceSynchronize()); 63 | } 64 | 65 | 66 | 67 | __inline__ __device__ float3 findPerpendicular(float3 v) { 68 | /*float ax = abs(v.x); 69 | float ay = abs(v.y); 70 | float az = abs(v.z); 71 | 72 | if (ax >= az && ay >= az) { // ax, ay are dominant 73 | return make_float3(-v.y, v.x, 0.0f); 74 | } 75 | else if (ax >= ay && az >= ay) { // ax, az are dominant 76 | return make_float3(-v.z, 0.0f, v.x); 77 | } 78 | else { // ay, az are dominant 79 | return make_float3(0.0f, -v.z, v.y); 80 | }*/ 81 | return make_float3(-v.y, v.x, 0.0f); 82 | } 83 | 84 | 85 | __device__ double4 eulerIntegrate(double3 pos, double dt, float3 volumeCoordSpaceMult) { 86 | float4 v = tex3D(vectorFieldTex, (float)(pos.x * volumeCoordSpaceMult.x), (float)(pos.y * volumeCoordSpaceMult.y), (float)(pos.z * volumeCoordSpaceMult.z)); 87 | return make_double4(dt * v.x, dt * v.y, dt * v.z, v.w); 88 | } 89 | 90 | __device__ double4 rk4Integrate(double3 pos, double dt, float3 volumeCoordSpaceMult) { 91 | float4 k1 = tex3D(vectorFieldTex, (float)(pos.x * volumeCoordSpaceMult.x), (float)(pos.y * volumeCoordSpaceMult.y), (float)(pos.z * volumeCoordSpaceMult.z)); 92 | double dtHalf = dt * 0.5; 93 | float4 k2 = tex3D(vectorFieldTex, (float)((pos.x + dtHalf * k1.x) * volumeCoordSpaceMult.x), (float)((pos.y + dtHalf * k1.y) * volumeCoordSpaceMult.y), (float)((pos.z + dtHalf * k1.z) * volumeCoordSpaceMult.z)); 94 | float4 k3 = tex3D(vectorFieldTex, (float)((pos.x + dtHalf * k2.x) * volumeCoordSpaceMult.x), (float)((pos.y + dtHalf * k2.y) * volumeCoordSpaceMult.y), (float)((pos.z + dtHalf * k2.z) * volumeCoordSpaceMult.z)); 95 | float4 k4 = tex3D(vectorFieldTex, (float)((pos.x + dt * k3.x) * volumeCoordSpaceMult.x), (float)((pos.y + dt * k3.y) * volumeCoordSpaceMult.y), (float)((pos.z + dt * k3.z) * volumeCoordSpaceMult.z)); 96 | 97 | double dtSixth = dt / 6.0; 98 | return make_double4( 99 | dtSixth * ((double)k1.x + 2.0 * ((double)k2.x + (double)k3.x) + (double)k4.x), 100 | dtSixth * ((double)k1.y + 2.0 * ((double)k2.y + (double)k3.y) + (double)k4.y), 101 | dtSixth * ((double)k1.z + 2.0 * ((double)k2.z + (double)k3.z) + (double)k4.z), 102 | ((double)k1.w + 2.0 * ((double)k2.w + (double)k3.w) + (double)k4.w) / 6.0); 103 | } 104 | 105 | __global__ void computeStreamlinesLineKernel(float3* seeds, uint seedsCount, double dt, uint maxSteps, 106 | cudaExtent volumeSize, float3 volumeCoordSpaceMult, bool useRk4, uint geometrySampling, float mangitudeCtfNormalizeMult, 107 | float3* outputPts, uint* outComputedSteps, float3* outVertexColors) { 108 | 109 | uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; 110 | if (id >= seedsCount) { 111 | return; 112 | } 113 | 114 | uint outputPos = id * (maxSteps / geometrySampling + 1); 115 | double3 position = make_double3(seeds[id].x, seeds[id].y, seeds[id].z); 116 | 117 | //printf("[%i] Pos: %f %f %f\n", id, position.x, position.y, position.z); 118 | //printf("[%i] World: %i %i %i\n", id, volumeSize.width, volumeSize.height, volumeSize.depth); 119 | 120 | double3 maxWorld; 121 | maxWorld.x = (double)volumeSize.width / volumeCoordSpaceMult.x; 122 | maxWorld.y = (double)volumeSize.height / volumeCoordSpaceMult.y; 123 | maxWorld.z = (double)volumeSize.depth / volumeCoordSpaceMult.z; 124 | 125 | //printf("Start pos: %f %f %f\n", position.x, position.y, position.z); 126 | 127 | outputPts[outputPos].x = (float)position.x; 128 | outputPts[outputPos].y = (float)position.y; 129 | outputPts[outputPos].z = (float)position.z; 130 | ++outputPos; 131 | 132 | uint geometryStep = geometrySampling; 133 | uint step = 1; 134 | for (; step < maxSteps; ++step) { 135 | 136 | if (position.x < 0 || position.y < 0 || position.z < 0 || position.x > maxWorld.x || position.y > maxWorld.y || position.z > maxWorld.z) { 137 | //printf("Break at pos: %f %f %f\n", position.x, position.y, position.z); 138 | break; 139 | } 140 | 141 | double4 dv = useRk4 ? rk4Integrate(position, dt, volumeCoordSpaceMult) : eulerIntegrate(position, dt, volumeCoordSpaceMult); 142 | //printf("Vector: %f %f %f\n", dv.x, dv.y, dv.z); 143 | position.x += dv.x; 144 | position.y += dv.y; 145 | position.z += dv.z; 146 | 147 | --geometryStep; 148 | if (geometryStep == 0) { 149 | geometryStep = geometrySampling; 150 | 151 | outputPts[outputPos].x = (float)position.x; 152 | outputPts[outputPos].y = (float)position.y; 153 | outputPts[outputPos].z = (float)position.z; 154 | //printf("New pos: %f %f %f\n", position.x, position.y, position.z); 155 | 156 | float4 color = tex1D(vectorMangitudeCtfTex, (float)(dv.w * mangitudeCtfNormalizeMult)); 157 | //printf("Color (%f -> %f): %f %f %f\n", vector.w, vector.w * mangitudeCtfNormalizeMult, color.x, color.y, color.z); 158 | outVertexColors[outputPos - 1].x = color.x; 159 | outVertexColors[outputPos - 1].y = color.y; 160 | outVertexColors[outputPos - 1].z = color.z; 161 | ++outputPos; 162 | } 163 | } 164 | 165 | float4 vector = tex3D(vectorFieldTex, (float)(position.x * volumeCoordSpaceMult.x), (float)(position.y * volumeCoordSpaceMult.y), (float)(position.z * volumeCoordSpaceMult.z)); 166 | 167 | float4 color = tex1D(vectorMangitudeCtfTex, vector.w * mangitudeCtfNormalizeMult); 168 | outVertexColors[outputPos - 1].x = color.x; 169 | outVertexColors[outputPos - 1].y = color.y; 170 | outVertexColors[outputPos - 1].z = color.z; 171 | 172 | 173 | outComputedSteps[id] = step / geometrySampling; 174 | } 175 | 176 | extern "C" 177 | void runStreamlinesLineKernel(float3* seeds, uint seedsCount, double dt, uint maxSteps, 178 | cudaExtent volumeSize, float3 volumeCoordSpaceMult, bool useRk4, uint geometrySampling, 179 | float3* outputPts, uint* outComputedSteps, float3* outVertexColors) { 180 | 181 | ushort threadsCount = 32; 182 | uint requredBlocksCount = (seedsCount + threadsCount - 1) / threadsCount; 183 | if (requredBlocksCount > 1024) { 184 | threadsCount = 256; 185 | requredBlocksCount = (seedsCount + threadsCount - 1) / threadsCount; 186 | } 187 | assert(requredBlocksCount < 65536); 188 | ushort blocksCount = (ushort)requredBlocksCount; 189 | 190 | computeStreamlinesLineKernel<<>>(seeds, seedsCount, dt, maxSteps, volumeSize, volumeCoordSpaceMult, useRk4, geometrySampling, 191 | (vectorMangitudeCtfLength / maxMangitude), outputPts, outComputedSteps, outVertexColors); 192 | checkCudaErrors(cudaDeviceSynchronize()); 193 | } 194 | 195 | 196 | __device__ void createTubeBaseVertices(float3 pos, float3 v, float radius, uint baseIndex, float3 color, float3* outVetrices, float3* outNormals, float3* outColors) { 197 | float3 xAxis = normalize(findPerpendicular(v)); 198 | float3 yAxis = normalize(cross(v, xAxis)); 199 | 200 | //printf("vertices %i\n", baseIndex); 201 | 202 | outNormals[baseIndex] = xAxis; 203 | outVetrices[baseIndex] = pos + xAxis * radius; // x * cos(0) + y * sin (0) 204 | outColors[baseIndex] = color; 205 | ++baseIndex; 206 | 207 | v = 0.3090f * xAxis + 0.9511f * yAxis; 208 | outNormals[baseIndex] = v; 209 | outVetrices[baseIndex] = pos + v * radius; // x * cos(72) + y * sin (72) 210 | outColors[baseIndex] = color; 211 | ++baseIndex; 212 | 213 | v = -0.8090f * xAxis + 0.5878f * yAxis; 214 | outNormals[baseIndex] = v; 215 | outVetrices[baseIndex] = pos + v * radius; 216 | outColors[baseIndex] = color; 217 | ++baseIndex; 218 | 219 | v = -0.8090f * xAxis - 0.5878f * yAxis; 220 | outNormals[baseIndex] = v; 221 | outVetrices[baseIndex] = pos + v * radius; // x * cos(216) + y * sin (216) 222 | outColors[baseIndex] = color; 223 | ++baseIndex; 224 | 225 | v = 0.3090f * xAxis - 0.9511f * yAxis; 226 | outNormals[baseIndex] = v; 227 | outVetrices[baseIndex] = pos + v * radius; // x * cos(288) + y * sin (288) 228 | outColors[baseIndex] = color; 229 | } 230 | 231 | __device__ void createTubeIndices(uint vertexBaseId, uint baseFaceId, uint3* outFaces) { 232 | 233 | //printf("v %i, i %i \n", vertexBaseId, baseFaceId); 234 | for (uint i = 0; i < 5; ++i) { 235 | uint iNext = (i + 1) % 5; 236 | outFaces[baseFaceId++] = make_uint3(vertexBaseId + i, vertexBaseId + iNext, vertexBaseId - 5 + iNext); 237 | outFaces[baseFaceId++] = make_uint3(vertexBaseId + i, vertexBaseId - 5 + i, vertexBaseId - 5 + iNext); 238 | } 239 | 240 | } 241 | 242 | __global__ void computeStreamtubesLineKernel(float3* seeds, uint seedsCount, double dt, uint maxSteps, 243 | cudaExtent volumeSize, float3 volumeCoordSpaceMult, float radius, bool useRk4, uint geometrySampling, float mangitudeCtfNormalizeMult, 244 | float3* outVetrices, uint* outComputedSteps, uint3* outFaces, float3* outVertexNormals, float3* outVertexColors) { 245 | 246 | uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; 247 | if (id >= seedsCount) { 248 | return; 249 | } 250 | 251 | uint outputPos = id * (maxSteps / geometrySampling + 1) * 5; 252 | //printf("id: %i, maxSteps: %i, outPos: %i \n", id, maxSteps, outputPos); 253 | double3 position = make_double3(seeds[id].x, seeds[id].y, seeds[id].z); 254 | 255 | float4 vector = tex3D(vectorFieldTex, (float)(position.x * volumeCoordSpaceMult.x), (float)(position.y * volumeCoordSpaceMult.y), (float)(position.z * volumeCoordSpaceMult.z)); 256 | float4 color = tex1D(vectorMangitudeCtfTex, vector.w * mangitudeCtfNormalizeMult); 257 | createTubeBaseVertices(make_float3(position.x, position.y, position.z), make_float3(vector.x, vector.y, vector.z), radius, outputPos, make_float3(color.x, color.y, color.z), 258 | outVetrices, outVertexNormals, outVertexColors); 259 | outputPos += 5; 260 | 261 | double3 maxWorld; 262 | maxWorld.x = (double)volumeSize.width / volumeCoordSpaceMult.x; 263 | maxWorld.y = (double)volumeSize.height / volumeCoordSpaceMult.y; 264 | maxWorld.z = (double)volumeSize.depth / volumeCoordSpaceMult.z; 265 | 266 | uint geometryStep = geometrySampling; 267 | uint step = 1; 268 | for (; step < maxSteps; ++step) { 269 | 270 | if (position.x < 0 || position.y < 0 || position.z < 0 || position.x > maxWorld.x || position.y > maxWorld.y || position.z > maxWorld.z) { 271 | break; 272 | } 273 | 274 | double4 dv = useRk4 ? rk4Integrate(position, dt, volumeCoordSpaceMult) : eulerIntegrate(position, dt, volumeCoordSpaceMult); 275 | position.x += dv.x; 276 | position.y += dv.y; 277 | position.z += dv.z; 278 | 279 | --geometryStep; 280 | if (geometryStep == 0) { 281 | geometryStep = geometrySampling; 282 | 283 | color = tex1D(vectorMangitudeCtfTex, (float)(dv.w * mangitudeCtfNormalizeMult)); 284 | createTubeBaseVertices(make_float3(position.x, position.y, position.z), make_float3(dv.x, dv.y, dv.z), radius, outputPos, make_float3(color.x, color.y, color.z), 285 | outVetrices, outVertexNormals, outVertexColors); 286 | 287 | createTubeIndices(outputPos, (outputPos - 5 * id - 5) * 2, outFaces); 288 | outputPos += 5; 289 | } 290 | } 291 | 292 | outComputedSteps[id] = step / geometrySampling; 293 | } 294 | 295 | extern "C" 296 | void runStreamtubesLineKernel(float3* seeds, uint seedsCount, double dt, uint maxSteps, 297 | cudaExtent volumeSize, float3 volumeCoordSpaceMult, float tubeRadius, bool useRk4, uint geometrySampling, 298 | float3* outVetrices, uint* outComputedSteps, uint3* outFaces, float3* outVertexNormals, float3* outVertexColors) { 299 | 300 | ushort threadsCount = 64; 301 | uint requredBlocksCount = (seedsCount + threadsCount - 1) / threadsCount; 302 | if (requredBlocksCount > 1024) { 303 | threadsCount = 256; 304 | requredBlocksCount = (seedsCount + threadsCount - 1) / threadsCount; 305 | } 306 | assert(requredBlocksCount < 65536); 307 | ushort blocksCount = (ushort)requredBlocksCount; 308 | 309 | computeStreamtubesLineKernel<<>>(seeds, seedsCount, dt, maxSteps, volumeSize, volumeCoordSpaceMult, tubeRadius, useRk4, geometrySampling, 310 | (vectorMangitudeCtfLength / maxMangitude), outVetrices, outComputedSteps, outFaces, outVertexNormals, outVertexColors); 311 | checkCudaErrors(cudaDeviceSynchronize()); 312 | } 313 | 314 | __global__ void computeGlyphLinesKernel(float x, uint2 glyphsCount, float2 worldSize, float glyphLength, float3 volumeCoordSpaceMult, 315 | float3* outputPts, float mangitudeCtfNormalizeMult, float3* outVertexColors) { 316 | 317 | 318 | uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; 319 | uint totalCount = __umul24(glyphsCount.x, glyphsCount.y); 320 | if (id >= totalCount) { 321 | return; 322 | } 323 | 324 | uint col = id % glyphsCount.x; 325 | uint row = id / glyphsCount.x; 326 | 327 | float3 position = make_float3(x, col * (worldSize.x / glyphsCount.x), row * (worldSize.y / glyphsCount.y)); 328 | float4 vector = tex3D(vectorFieldTex, position.x * volumeCoordSpaceMult.x, position.y * volumeCoordSpaceMult.y, position.z * volumeCoordSpaceMult.z); 329 | 330 | id *= 2; 331 | outputPts[id] = position; 332 | outputPts[id + 1] = position + normalize(make_float3(vector.x, vector.y, vector.z)) * glyphLength * vector.w * mangitudeCtfNormalizeMult * 0.5; 333 | 334 | float4 color = tex1D(vectorMangitudeCtfTex, vector.w * mangitudeCtfNormalizeMult); 335 | outVertexColors[id].x = color.x; 336 | outVertexColors[id].y = color.y; 337 | outVertexColors[id].z = color.z; 338 | outVertexColors[id + 1].x = color.x; 339 | outVertexColors[id + 1].y = color.y; 340 | outVertexColors[id + 1].z = color.z; 341 | 342 | } 343 | 344 | extern "C" 345 | void runGlyphLinesKernel(float x, uint2 glyphsCount, float2 worldSize, float glyphLength, float3 volumeCoordSpaceMult, 346 | float3* outputPts, float3* outVertexColors) { 347 | 348 | ushort threadsCount = 256; 349 | uint requredBlocksCount = (glyphsCount.x * glyphsCount.y + threadsCount - 1) / threadsCount; 350 | assert(requredBlocksCount < 65536); 351 | ushort blocksCount = (ushort)requredBlocksCount; 352 | 353 | computeGlyphLinesKernel<<>>(x, glyphsCount, worldSize, glyphLength, volumeCoordSpaceMult, 354 | outputPts, (vectorMangitudeCtfLength / maxMangitude), outVertexColors); 355 | checkCudaErrors(cudaDeviceSynchronize()); 356 | 357 | } 358 | 359 | 360 | __global__ void computeGlyphArrowsKernel(float x, uint2 glyphsCount, float2 worldSize, float glyphLength, float3 volumeCoordSpaceMult, 361 | float mangitudeCtfNormalizeMult, float3* outVertices, uint3* outFaces, float3* outVertexNormals, float3* outVertexColors) { 362 | 363 | 364 | uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; 365 | uint totalCount = __umul24(glyphsCount.x, glyphsCount.y); 366 | if (id >= totalCount) { 367 | return; 368 | } 369 | 370 | uint col = id % glyphsCount.x; 371 | uint row = id / glyphsCount.x; 372 | 373 | float3 position = make_float3(x, col * (worldSize.x / glyphsCount.x), row * (worldSize.y / glyphsCount.y)); 374 | float4 vector = tex3D(vectorFieldTex, position.x * volumeCoordSpaceMult.x, position.y * volumeCoordSpaceMult.y, position.z * volumeCoordSpaceMult.z); 375 | 376 | float3 forward = normalize(make_float3(vector.x, vector.y, vector.z)); 377 | float3 xAxis = normalize(findPerpendicular(forward)); 378 | float3 yAxis = normalize(cross(forward, xAxis)); 379 | 380 | 381 | uint faceId = id * 6; 382 | uint vertexId = id * 9; 383 | 384 | outFaces[faceId] = make_uint3(vertexId, vertexId + 1, vertexId + 2); 385 | outFaces[faceId + 1] = make_uint3(vertexId, vertexId + 2, vertexId + 3); 386 | outFaces[faceId + 2] = make_uint3(vertexId, vertexId + 3, vertexId + 4); 387 | outFaces[faceId + 3] = make_uint3(vertexId, vertexId + 4, vertexId + 1); 388 | outFaces[faceId + 4] = make_uint3(vertexId + 5, vertexId + 6, vertexId +7); 389 | outFaces[faceId + 5] = make_uint3(vertexId + 5, vertexId + 7, vertexId + 8); 390 | 391 | id *= 9; 392 | outVertexNormals[id] = forward; 393 | outVertexNormals[id + 1] = xAxis; 394 | outVertexNormals[id + 2] = yAxis; 395 | outVertexNormals[id + 3] = -xAxis; 396 | outVertexNormals[id + 4] = -yAxis; 397 | forward *= -1; 398 | outVertexNormals[id + 5] = forward; 399 | outVertexNormals[id + 6] = forward; 400 | outVertexNormals[id + 7] = forward; 401 | outVertexNormals[id + 8] = forward; 402 | 403 | forward *= glyphLength * vector.w * mangitudeCtfNormalizeMult * 0.5; 404 | xAxis *= glyphLength * 0.1; 405 | yAxis *= glyphLength * 0.1; 406 | 407 | //printf("Pos: %f %f %f\n", xAxis.x, xAxis.y, xAxis.z); 408 | 409 | outVertices[id] = position - forward; // forward was multiplied by -1 410 | outVertices[id + 1] = position + xAxis; 411 | outVertices[id + 2] = position + yAxis; 412 | outVertices[id + 3] = position - xAxis; 413 | outVertices[id + 4] = position - yAxis; 414 | outVertices[id + 5] = position + xAxis; 415 | outVertices[id + 6] = position + yAxis; 416 | outVertices[id + 7] = position - xAxis; 417 | outVertices[id + 8] = position - yAxis; 418 | 419 | float4 color = tex1D(vectorMangitudeCtfTex, vector.w * mangitudeCtfNormalizeMult); 420 | float3 color3 = make_float3(color.x, color.y, color.z); 421 | outVertexColors[id] = color3; 422 | outVertexColors[id + 1] = color3; 423 | outVertexColors[id + 2] = color3; 424 | outVertexColors[id + 3] = color3; 425 | outVertexColors[id + 4] = color3; 426 | outVertexColors[id + 5] = color3; 427 | outVertexColors[id + 6] = color3; 428 | outVertexColors[id + 7] = color3; 429 | outVertexColors[id + 8] = color3; 430 | 431 | } 432 | 433 | extern "C" 434 | void runGlyphArrowsKernel(float x, uint2 glyphsCount, float2 worldSize, float glyphLength, float3 volumeCoordSpaceMult, 435 | float3* outVertices, uint3* outFaces, float3* outVertexNormals, float3* outVertexColors) { 436 | 437 | ushort threadsCount = 256; 438 | uint requredBlocksCount = (glyphsCount.x * glyphsCount.y + threadsCount - 1) / threadsCount; 439 | assert(requredBlocksCount < 65536); 440 | ushort blocksCount = (ushort)requredBlocksCount; 441 | 442 | computeGlyphArrowsKernel<<>>(x, glyphsCount, worldSize, glyphLength, volumeCoordSpaceMult, (vectorMangitudeCtfLength / maxMangitude), 443 | outVertices, outFaces, outVertexNormals, outVertexColors); 444 | checkCudaErrors(cudaDeviceSynchronize()); 445 | 446 | } 447 | 448 | 449 | __global__ void computeLineAdaptiveExtensionKernel(float maxAllowedLineDist, uint2* linePairs, uint linePairsCount, float3* lineVertices, uint verticesPerLine, uint verticesPerSample, uint* lineLengths, float3* seeds, 450 | uint2* outLinePairs, uint* outPairsIndex, uint* outLinesIndex, uint linesMaxCount) { 451 | 452 | uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; 453 | if (id >= linePairsCount) { 454 | return; 455 | } 456 | 457 | uint2 currPair = linePairs[id]; 458 | 459 | uint outPairIndex = atomicAdd(outPairsIndex, 1); 460 | // preserve original pair 461 | outLinePairs[outPairIndex].x = currPair.x; 462 | outLinePairs[outPairIndex].y = currPair.y; 463 | 464 | uint count = min(lineLengths[currPair.x], lineLengths[currPair.y]); 465 | if (count < 2) { 466 | return; 467 | } 468 | 469 | // test 32 samples 470 | float maxDist = 0; 471 | for (uint i = 0; i < count; i += count / 32) { 472 | float3 v1 = lineVertices[currPair.x * verticesPerLine + i * verticesPerSample]; 473 | float3 v2 = lineVertices[currPair.y * verticesPerLine + i * verticesPerSample]; 474 | maxDist = max(maxDist, length(v1 - v2)); 475 | } 476 | 477 | if (maxDist < maxAllowedLineDist) { 478 | return; 479 | } 480 | 481 | uint newLines = max(1.0f, sqrtf(maxDist / maxAllowedLineDist)); 482 | 483 | //printf("[%id] extending %i %i to %i new\n", id, currPair.x, currPair.y, newLines); 484 | 485 | if (newLines == 0) { 486 | return; 487 | } 488 | 489 | uint outLineIndex = atomicAdd(outLinesIndex, newLines); 490 | if ((outLineIndex + newLines) >= linesMaxCount) { 491 | atomicAdd(outLinesIndex, -newLines); 492 | return; 493 | } 494 | 495 | float3 seedStep = (seeds[currPair.y] - seeds[currPair.x]) / (newLines + 1); 496 | 497 | uint lastOutPairIndex = outPairIndex; 498 | for (uint i = 0; i < newLines; ++i) { 499 | seeds[outLineIndex + i] = seeds[currPair.x] + (i + 1) * seedStep; 500 | 501 | uint outPairIndex = atomicAdd(outPairsIndex, 1); 502 | outLinePairs[lastOutPairIndex].y = outLineIndex + i; 503 | outLinePairs[outPairIndex].x = outLineIndex + i; 504 | outLinePairs[outPairIndex].y = currPair.y; 505 | 506 | lastOutPairIndex = outPairIndex; 507 | } 508 | 509 | } 510 | 511 | extern "C" 512 | void runLineAdaptiveExtensionKernel(float maxAllowedLineDist, uint2* linePairs, uint linePairsCount, float3* lineVertices, uint verticesPerLine, uint verticesPerSample, uint* lineLengths, float3* seeds, 513 | uint2* outLinePairs, uint* outPairsIndex, uint* outLinesIndex, uint linesMaxCount) { 514 | 515 | ushort threadsCount = 32; 516 | uint requredBlocksCount = (linePairsCount + threadsCount - 1) / threadsCount; 517 | if (requredBlocksCount > 1024) { 518 | threadsCount = 256; 519 | requredBlocksCount = (linePairsCount + threadsCount - 1) / threadsCount; 520 | } 521 | assert(requredBlocksCount < 65536); 522 | ushort blocksCount = (ushort)requredBlocksCount; 523 | 524 | computeLineAdaptiveExtensionKernel<<>>(maxAllowedLineDist, linePairs, linePairsCount, lineVertices, verticesPerLine, verticesPerSample, lineLengths, seeds, 525 | outLinePairs, outPairsIndex, outLinesIndex, linesMaxCount); 526 | checkCudaErrors(cudaDeviceSynchronize()); 527 | } 528 | 529 | 530 | __global__ void computeStreamSurfaceKernel(uint2* linePairs, uint linePairsCount, float3* lineVertices, uint verticesPerLine, uint* lineLengths, 531 | uint3* outFaces, uint* outFacesCounts, float3* outNormals) { 532 | 533 | uint id = __umul24(blockIdx.x, blockDim.x) + threadIdx.x; 534 | if (id >= linePairsCount) { 535 | //printf("%i: too much\n", id); 536 | return; 537 | } 538 | 539 | uint2 currPair = linePairs[id]; 540 | uint2 lengths = make_uint2(lineLengths[currPair.x], lineLengths[currPair.y]); 541 | 542 | if (lengths.x < 2 || lengths.y < 2) { 543 | outFacesCounts[id] = 0; 544 | //printf("%i: too much\n", id); 545 | return; 546 | } 547 | 548 | //printf("%i: lines %i, %i; lengths: %i, %i\n", id, currPair.x, currPair.y, lengths.x ,lengths.y); 549 | 550 | uint line1Offset = currPair.x * verticesPerLine; 551 | uint line2Offset = currPair.y * verticesPerLine; 552 | 553 | //printf("[%i] vpl: %i\n", id, verticesPerLine); 554 | 555 | float3* line1 = lineVertices + line1Offset; 556 | float3* line2 = lineVertices + line2Offset; 557 | 558 | float3* normals1 = outNormals + line1Offset; 559 | float3* normals2 = outNormals + line2Offset; 560 | 561 | uint maxFaces = verticesPerLine * 2 - 2; 562 | uint3* faces = outFaces + id * maxFaces; 563 | 564 | uint2 currIndex = make_uint2(0, 0); 565 | 566 | //float totalMaxAllowedLineDist = max(1.0f, 8.0f * max(length(line1[0] - line2[0]), length(line1[0] - line2[1]))); 567 | //float maxAllowedLineDist = 2.0f * length(line1[0] - line2[0]);//length(line1[0] - line2[1]) + length(line2[0] - line1[1]); 568 | 569 | float lastMinDist = length(line1[0] - line2[0]); 570 | 571 | uint oneConnections = 0; 572 | uint twoConnections = 0; 573 | uint maxConnections = 8; 574 | 575 | uint faceId; 576 | for (faceId = 0; faceId < maxFaces; ++faceId) { 577 | 578 | if (currIndex.x + 1 >= lengths.x || currIndex.y + 1 >= lengths.y) { 579 | break; 580 | } 581 | 582 | float dist1 = (currIndex.x + 1 < lengths.x) ? length(line1[currIndex.x + 1] - line2[currIndex.y]) : (1.0f / 0.0f); 583 | float dist2 = (currIndex.y + 1 < lengths.y) ? length(line1[currIndex.x] - line2[currIndex.y + 1]) : (1.0f / 0.0f); 584 | 585 | uint newVertexIndex; 586 | float3 newVertex; 587 | uint2 nextIndex; 588 | float minDist; 589 | 590 | if (dist1 <= dist2) { 591 | if (oneConnections > maxConnections) { 592 | break; 593 | } 594 | ++oneConnections; 595 | twoConnections = 0; 596 | minDist = dist1; 597 | newVertexIndex = line1Offset + currIndex.x + 1; 598 | newVertex = line1[currIndex.x + 1]; 599 | nextIndex = make_uint2(currIndex.x + 1, currIndex.y); 600 | } 601 | else if (dist2 < dist1) { 602 | if (twoConnections > maxConnections) { 603 | break; 604 | } 605 | ++twoConnections; 606 | oneConnections = 0; 607 | minDist = dist2; 608 | newVertexIndex = line2Offset + currIndex.y + 1; 609 | newVertex = line2[currIndex.y + 1]; 610 | nextIndex = make_uint2(currIndex.x, currIndex.y + 1); 611 | } 612 | 613 | float lenDirect = length(line1[currIndex.x] - line2[currIndex.y]); 614 | minDist = min(minDist, lenDirect); 615 | //if (/*minDist > maxAllowedLineDist || */minDist > totalMaxAllowedLineDist) { 616 | // break; 617 | //} 618 | 619 | float distRatio = minDist / lastMinDist; 620 | if (distRatio > 1.5) { 621 | //printf("%i: dist ratio %f\n", id, distRatio); 622 | break; 623 | } 624 | 625 | //maxAllowedLineDist = (7.0f * maxAllowedLineDist + 2.0f * minDist) / 8.0f; 626 | 627 | faces[faceId] = make_uint3(line1Offset + currIndex.x, line2Offset + currIndex.y, newVertexIndex); 628 | //printf("%i: faceId %i [%i, %i, %i] (dist1: %f, dist2: %f)\n", id, faceId, faces[faceId].x, faces[faceId].y, faces[faceId].z, dist1, dist2); 629 | float3 normal = cross(line1[currIndex.x] - line2[currIndex.y], newVertex - line2[currIndex.y]); 630 | normal = normalize(normal); 631 | 632 | normals1[currIndex.x] = normal; 633 | normals2[currIndex.y] = normal; 634 | 635 | currIndex = nextIndex; 636 | lastMinDist = (3.0f * lastMinDist + minDist) / 4.0f; 637 | } 638 | 639 | //printf("[%i] faces: %i\n", id, faceId); 640 | 641 | outFacesCounts[id] = faceId; 642 | } 643 | 644 | extern "C" 645 | void runLineStreamSurfaceKernel(uint2* linePairs, uint linePairsCount, float3* lineVertices, uint verticesPerLine, uint* lineLengths, 646 | uint3* outFaces, uint* outFacesCounts, float3* outNormals) { 647 | 648 | ushort threadsCount = 32; 649 | uint requredBlocksCount = (linePairsCount + threadsCount - 1) / threadsCount; 650 | if (requredBlocksCount > 1024) { 651 | threadsCount = 256; 652 | requredBlocksCount = (linePairsCount + threadsCount - 1) / threadsCount; 653 | } 654 | assert(requredBlocksCount < 65536); 655 | ushort blocksCount = (ushort)requredBlocksCount; 656 | 657 | computeStreamSurfaceKernel<<>>(linePairs, linePairsCount, lineVertices, verticesPerLine, lineLengths, 658 | outFaces, outFacesCounts, outNormals); 659 | checkCudaErrors(cudaDeviceSynchronize()); 660 | } 661 | 662 | } -------------------------------------------------------------------------------- /src/StreamSurface/StreamSurface.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {F000C410-F59F-402A-AACD-B0A6074EDAE7} 15 | Win32Proj 16 | StreamSurface 17 | 18 | 19 | 20 | 21 | 22 | Application 23 | true 24 | v110 25 | Unicode 26 | 27 | 28 | Application 29 | false 30 | v110 31 | true 32 | Unicode 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | 48 | 49 | false 50 | 51 | 52 | 53 | Use 54 | Level4 55 | Disabled 56 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 57 | true 58 | $(SolutionDir)\include\;%(AdditionalIncludeDirectories) 59 | 60 | 61 | Console 62 | true 63 | $(CUDA_PATH)\lib\$(PlatformName);$(SolutionDir)\libs\ 64 | cudart.lib;freeglut.lib;glew32.lib;%(AdditionalDependencies) 65 | 66 | 67 | compute_20,sm_20 68 | 64 69 | 70 | 71 | 72 | 73 | Level4 74 | Use 75 | MaxSpeed 76 | true 77 | true 78 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 79 | $(SolutionDir)\include\;%(AdditionalIncludeDirectories) 80 | true 81 | 82 | 83 | Console 84 | true 85 | true 86 | true 87 | $(CUDA_PATH)\lib\$(PlatformName);$(SolutionDir)\libs\ 88 | cudart.lib;freeglut.lib;glew32.lib;%(AdditionalDependencies) 89 | 90 | 91 | 64 92 | compute_20,sm_20 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Create 110 | Create 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/StreamSurface/StreamSurface.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Header Files 16 | 17 | 18 | Header Files 19 | 20 | 21 | Header Files 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | 43 | 44 | Source Files 45 | 46 | 47 | Source Files 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/StreamSurface/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace mf { 5 | 6 | inline void drawString(float x, float y, float z, const std::string& text) { 7 | glRasterPos3f(x, y, z); 8 | for (size_t i = 0; i < text.size(); i++) { 9 | glutBitmapCharacter(GLUT_BITMAP_8_BY_13, text[i]); 10 | } 11 | } 12 | 13 | inline void ltrim(std::string& s) { 14 | s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); 15 | } 16 | 17 | inline void rtrim(std::string& s) { 18 | s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); 19 | } 20 | 21 | inline void trim(std::string& s) { 22 | ltrim(s); 23 | rtrim(s); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/StreamSurface/VectorField.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "VectorFieldInfo.h" 3 | 4 | namespace mf { 5 | 6 | template 7 | class TVectorField { 8 | 9 | public: 10 | float4* data; 11 | 12 | /// step size per axis 13 | float3 spacings; 14 | 15 | /// dimension of vector field 16 | uint3 sizes; 17 | 18 | /// start points of axis 19 | int3 mins; 20 | 21 | float maxMangitude; 22 | 23 | public: 24 | TVectorField() 25 | : data(nullptr) 26 | , spacings(make_float3(0, 0, 0)) 27 | , sizes(make_uint3(0, 0, 0)) 28 | , mins(make_int3(0, 0, 0)) 29 | , maxMangitude(0) { 30 | 31 | } 32 | 33 | virtual ~TVectorField() { 34 | if (data != nullptr) { 35 | delete[] data; 36 | data = nullptr; 37 | } 38 | } 39 | 40 | 41 | size_t totalSize() const { return (size_t)sizes.x * (size_t)sizes.y * (size_t)sizes.z; } 42 | 43 | float3 realSize() const { return make_float3(sizes.x * spacings.x, sizes.y * spacings.y, sizes.z * spacings.z); } 44 | 45 | void fetchInfo(VectorFieldInfo& vfInfo) { 46 | vfInfo.cudaDataSize = make_cudaExtent(sizes.x, sizes.y, sizes.z); 47 | vfInfo.dataSize = sizes; 48 | vfInfo.realSize = realSize(); 49 | vfInfo.realCoordMin = mins; 50 | vfInfo.volumeCoordSpaceMult = make_float3(1.0f / spacings.x, 1.0f / spacings.y, 1.0f / spacings.z); 51 | } 52 | 53 | bool loadFromFile(const std::string& filePath) { 54 | 55 | std::cout << "Loading data from '" << filePath << "'..." << std::endl; 56 | 57 | std::ifstream inputStream(filePath, std::ios::binary); 58 | assert(inputStream.good()); 59 | 60 | bool sizeSet = false; 61 | spacings = make_float3(1, 1, 1); 62 | mins = make_int3(0, 0, 0); 63 | //bool littleEndian = false; 64 | 65 | // reading of header 66 | for (;;) { 67 | std::string line; 68 | std::getline(inputStream, line); 69 | trim(line); 70 | 71 | if (line.length() == 0) { 72 | break; // header ended 73 | } 74 | 75 | size_t colonPos = line.find(':'); 76 | if (colonPos == std::string::npos) { 77 | continue; // unknown non-empty line 78 | } 79 | 80 | std::string key = line.substr(0, colonPos); // key is word before colon 81 | std::string value = line.substr(colonPos + 1); 82 | trim(key); 83 | trim(value); 84 | 85 | if (key == "type") { 86 | if (value != "float") { 87 | std::cerr << "Data type expected to be 'float', but it is '" << value << "'." << std::endl; 88 | return false; 89 | } 90 | std::cout << "Data type: " << value << std::endl; 91 | } 92 | else if (key == "dimension") { 93 | if (value != "4") { 94 | std::cerr << "Dimension expected to be '4', but it is '" << value << "'." << std::endl; 95 | return false; 96 | } 97 | std::cout << "Dimension: " << value << std::endl; 98 | } 99 | else if (key == "sizes") { 100 | std::stringstream ss; 101 | ss << value; 102 | int size; 103 | ss >> size; 104 | ss >> sizes.x; 105 | ss >> sizes.y; 106 | ss >> sizes.z; 107 | if (!ss || !ss.eof()) { 108 | std::cerr << "Failed to read sizes from string: '" << value << "'." << std::endl; 109 | return false; 110 | } 111 | if (size != 3) { 112 | std::cerr << "Size of the first component expected to be '3' but it is '" << size << "'." << std::endl; 113 | return false; 114 | } 115 | if (sizes.x < 0 || sizes.y < 0 || sizes.y < 0) { 116 | std::cerr << "Read sizes are weird: " << sizes.x << ", " << sizes.y << ", " << sizes.z << "'." << std::endl; 117 | return false; 118 | } 119 | std::cout << "Size: " << sizes.x << "x" << sizes.y << "x" << sizes.z << std::endl; 120 | sizeSet = true; 121 | } 122 | else if (key == "spacings") { 123 | std::stringstream ss; 124 | ss << value; 125 | std::string ignoreValue; 126 | ss >> ignoreValue; // not interesting value 127 | ss >> spacings.x; 128 | ss >> spacings.y; 129 | ss >> spacings.z; 130 | if (!ss || !ss.eof()) { 131 | std::cerr << "Failed to read spacings from string: '" << value << "'." << std::endl; 132 | return false; 133 | } 134 | if (spacings.x < 0 || spacings.y < 0 || spacings.y < 0) { 135 | std::cerr << "Read spacings are weird: " << spacings.x << ", " << spacings.y << ", " << spacings.z << "'." << std::endl; 136 | return false; 137 | } 138 | std::cout << "Spacings: " << spacings.x << ", " << spacings.y << ", " << spacings.z << std::endl; 139 | } 140 | else if (key == "axis mins") { 141 | std::stringstream ss; 142 | ss << value; 143 | std::string ignoreValue; 144 | ss >> ignoreValue; // not interesting value 145 | ss >> mins.x; 146 | ss >> mins.y; 147 | ss >> mins.z; 148 | if (!ss || !ss.eof()) { 149 | std::cerr << "Failed to read mins from string: '" << value << "'." << std::endl; 150 | return false; 151 | } 152 | std::cout << "Minimums: " << mins.x << ", " << mins.y << ", " << mins.z << std::endl; 153 | } 154 | else if (key == "encoding") { 155 | if (value != "raw") { 156 | std::cerr << "Encoding expected to be 'raw' but it is '" << value << "'." << std::endl; 157 | return false; 158 | } 159 | std::cout << "Encoding: " << value << std::endl; 160 | } 161 | //else if (key == "endian") { 162 | // if (value == "little") { 163 | // littleEndian = true; 164 | // } 165 | // else if (value == "big") { 166 | // littleEndian = false; 167 | // } 168 | // else { 169 | // std::cerr << "Unknown value of edianess '" << value << "'." << std::endl; 170 | // return false; 171 | // } 172 | // std::cout << "Endian: " << (littleEndian ? "little" : "big") << std::endl; 173 | //} 174 | else { 175 | std::cout << "Ignoring: " << line << std::endl; 176 | } 177 | } 178 | 179 | std::cout << "Header information loaded loaded." << std::endl; 180 | 181 | if (!sizeSet) { 182 | std::cerr << "Size information was not found in the file." << std::endl; 183 | return false; 184 | } 185 | 186 | size_t totSize = totalSize(); 187 | size_t sizeInBytes = totSize * sizeof(float4); 188 | 189 | 190 | std::cout << "Allocating data (" << (sizeInBytes >> 20) << " MB)" << std::endl; 191 | data = new float4[totSize]; 192 | 193 | std::cout << "Reading binary data..." << std::endl; 194 | 195 | maxMangitude = 0; 196 | //float3 min = make_float3(1e10f, 1e10f, 1e10f); 197 | //float3 max = make_float3(-1e10f, -1e10f, -1e10f); 198 | 199 | for (size_t i = 0; i < totSize; ++i) { 200 | float4* curr = &(data[i]); 201 | // read x, y, z 202 | inputStream.read((char*)curr, sizeof(float3)); 203 | 204 | //min.x = std::min(min.x, curr->x); 205 | //min.y = std::min(min.y, curr->y); 206 | //min.z = std::min(min.z, curr->z); 207 | 208 | //max.x = std::max(max.x, curr->x); 209 | //max.y = std::max(max.y, curr->y); 210 | //max.z = std::max(max.z, curr->z); 211 | 212 | // compute w 213 | curr->w = std::sqrtf(curr->x * curr->x + curr->y * curr->y + curr->z * curr->z); 214 | 215 | maxMangitude = std::max(maxMangitude, curr->w); 216 | } 217 | 218 | std::cout << "Data successfully loaded." << std::endl; 219 | 220 | //for (size_t i = 0; i < 4; ++i) { 221 | // std::cout << data[i].x << ", " << data[i].y << ", " << data[i].z << " (" << data[i].w << ")" << std::endl; 222 | //} 223 | 224 | //std::cout << "Data min: " << min.x << ", " << min.y << ", " << min.z << std::endl; 225 | //std::cout << "Data max: " << max.x << ", " << max.y << ", " << max.z << std::endl; 226 | 227 | return true; 228 | } 229 | 230 | }; 231 | 232 | typedef TVectorField<> VectorField; 233 | 234 | } -------------------------------------------------------------------------------- /src/StreamSurface/VectorFieldInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace mf { 4 | 5 | template 6 | struct TVectorFieldInfo { 7 | 8 | cudaExtent cudaDataSize; 9 | uint3 dataSize; 10 | 11 | float3 realSize; 12 | int3 realCoordMin; 13 | 14 | /// multiplier to transform real coordinates to data coordinates 15 | float3 volumeCoordSpaceMult; 16 | 17 | }; 18 | 19 | typedef TVectorFieldInfo<> VectorFieldInfo; 20 | 21 | } -------------------------------------------------------------------------------- /src/StreamSurface/main.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "CudaHelper.h" 3 | #include "Utils.h" 4 | #include "VectorField.h" 5 | #include "Activity.h" 6 | #include "VectorFieldInfo.h" 7 | 8 | #include "SteamlinesLineActivity.h" 9 | #include "GlyphsActivity.h" 10 | 11 | 12 | namespace mf { 13 | 14 | // UI window stuff 15 | int screenWidth = 1024; 16 | int screenHeight = 768; 17 | 18 | bool wireframe = false; 19 | bool menuVisible = true; 20 | bool showWing = false; 21 | bool showBb = true; 22 | 23 | // mouse controls 24 | int2 mouseOld; 25 | int mouseButtons = 0; 26 | float3 rotate = make_float3(0, 0, 0); 27 | float2 translate = make_float2(0, 0); 28 | float zoom = 500; 29 | 30 | // vector field 31 | VectorFieldInfo vectorFieldInfo; 32 | 33 | 34 | Activity* currentActivity; 35 | 36 | 37 | 38 | extern "C" void initCuda(const float4* h_volume, cudaExtent volumeSize, const std::vector& vectorMangitudeCtf, float maxVectorMangitude); 39 | 40 | extern "C" void runStreamlinesLineKernel(float3* seeds, uint seedsCount, double dt, uint maxSteps, 41 | cudaExtent volumeSize, float3 volumeCoordSpaceMult, bool useRk4, uint geometrySampling, 42 | float3* outputPts, uint* outComputedSteps, float3* outVertexColors); 43 | 44 | extern "C" void runStreamtubesLineKernel(float3* seeds, uint seedsCount, double dt, uint maxSteps, 45 | cudaExtent volumeSize, float3 volumeCoordSpaceMult, float tubeRadius, bool useRk4, uint geometrySampling, 46 | float3* outVetrices, uint* outComputedSteps, uint3* outFaces, float3* outVertexNormals, float3* outVertexColors); 47 | 48 | extern "C" void runGlyphLinesKernel(float x, uint2 glyphsCount, float2 worldSize, float glyphLength, float3 volumeCoordSpaceMult, 49 | float3* outputPts, float3* outVertexColors); 50 | extern "C" void runGlyphArrowsKernel(float x, uint2 glyphsCount, float2 worldSize, float glyphLength, float3 volumeCoordSpaceMult, 51 | float3* outVertices, uint3* outFaces, float3* outVertexNormals, float3* outVertexColors); 52 | 53 | extern "C" void runLineAdaptiveExtensionKernel(float maxAllowedLineDist, uint2* linePairs, uint linePairsCount, float3* lineVertices, 54 | uint verticesPerLine, uint verticesPerSample, uint* lineLengths, float3* seeds, uint2* outLinePairs, uint* outPairsIndex, uint* outLinesIndex, uint linesMaxCount); 55 | 56 | extern "C" void runLineStreamSurfaceKernel(uint2* linePairs, uint linePairsCount, float3* lineVertices, uint verticesPerLine, uint* lineLengths, 57 | uint3* outFaces, uint* outFacesCounts, float3* outNormals); 58 | 59 | 60 | void drawControls() { 61 | float i = 1; 62 | float incI = 14; 63 | std::stringstream ss; 64 | 65 | drawString(10, ++i * incI, 0, " [i] Toggle wing"); 66 | drawString(10, ++i * incI, 0, " [o] Toggle wireframe"); 67 | drawString(10, ++i * incI, 0, " [l] Toggle bounding box"); 68 | drawString(10, ++i * incI, 0, " [p] Hide/show this menu"); 69 | 70 | drawString(10, ++i * incI, 0, ""); 71 | 72 | drawString(10, ++i * incI, 0, "Switch activity to:"); 73 | drawString(10, ++i * incI, 0, " [1] Streamlines line"); 74 | drawString(10, ++i * incI, 0, " [2] Glyphs plane"); 75 | 76 | drawString(10, ++i * incI, 0, ""); 77 | 78 | if (currentActivity != nullptr) { 79 | currentActivity->drawControls(i, incI); 80 | } 81 | 82 | i = screenHeight / incI - 2.5f; 83 | 84 | if (currentActivity != nullptr) { 85 | ss.str(""); 86 | ss << "Last process time: " << currentActivity->getLastTimerDuration() << " ms"; 87 | drawString(10, ++i * incI, 0, ss.str()); 88 | } 89 | } 90 | 91 | void drawVolumeBb() { 92 | glPushMatrix(); 93 | 94 | glScalef(vectorFieldInfo.realSize.x, vectorFieldInfo.realSize.y, vectorFieldInfo.realSize.z); 95 | glTranslatef(0.5f, 0.5f, 0.5f); 96 | 97 | glColor3f(0.2f, 0.2f, 0.2f); 98 | glutWireCube(1); 99 | 100 | glPopMatrix(); 101 | } 102 | 103 | void drawWing() { 104 | glBegin(GL_TRIANGLES); 105 | 106 | glColor3f(0.8f, 0.8f, 0.8f); 107 | 108 | float xMin = (float)-vectorFieldInfo.realCoordMin.x; 109 | float xMax = (float)-vectorFieldInfo.realCoordMin.x + 238; 110 | float yMin = (float)-vectorFieldInfo.realCoordMin.y - 145; 111 | float yMid = (float)-vectorFieldInfo.realCoordMin.y; 112 | float yMax = (float)-vectorFieldInfo.realCoordMin.y + 145; 113 | float z = (float)-vectorFieldInfo.realCoordMin.z; 114 | glNormal3f(0, 0, 1); 115 | glVertex3f(xMin, yMid, z); 116 | glVertex3f(xMax, yMin, z); 117 | glVertex3f(xMax, yMax, z); 118 | 119 | glEnd(); 120 | } 121 | 122 | void displayCallback() { 123 | 124 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 125 | 126 | // set view matrix 127 | glMatrixMode(GL_MODELVIEW); 128 | glPushMatrix(); 129 | glTranslatef(zoom, translate.x, translate.y); 130 | glRotatef(rotate.x, 0.0, 1.0, 0.0); 131 | glRotatef(rotate.y, 0.0, 0.0, 1.0); 132 | glTranslatef(vectorFieldInfo.realSize.x / -2.0f, vectorFieldInfo.realSize.y / -2.0f, vectorFieldInfo.realSize.z / -2.0f); 133 | 134 | 135 | glPolygonMode(GL_FRONT_AND_BACK, wireframe? GL_LINE : GL_FILL); 136 | glEnable(GL_DEPTH_TEST); 137 | 138 | if (showBb) { 139 | drawVolumeBb(); 140 | } 141 | if (showWing){ 142 | drawWing(); 143 | } 144 | 145 | if (currentActivity != nullptr) { 146 | currentActivity->displayCallback(); 147 | } 148 | 149 | if (menuVisible) { 150 | // setup orthogonal projection for text 151 | glMatrixMode(GL_PROJECTION); 152 | glPushMatrix(); 153 | glLoadIdentity(); 154 | glOrtho(0, screenWidth, screenHeight - 5, -5, -100, 100); 155 | 156 | glMatrixMode(GL_MODELVIEW); 157 | glPushMatrix(); 158 | glLoadIdentity(); 159 | 160 | glDisable(GL_DEPTH_TEST); 161 | 162 | glColor3f(0.8f, 0.8f, 0.8f); 163 | drawControls(); 164 | glTranslatef(-1, -1, 0); 165 | glColor3f(0, 0, 0); 166 | drawControls(); 167 | 168 | glMatrixMode(GL_MODELVIEW); 169 | glPopMatrix(); 170 | 171 | glMatrixMode(GL_PROJECTION); 172 | glPopMatrix(); 173 | } 174 | 175 | glMatrixMode(GL_MODELVIEW); 176 | glPopMatrix(); 177 | glutSwapBuffers(); 178 | glutReportErrors(); 179 | } 180 | 181 | void keyboardCallback(unsigned char key, int /*x*/, int /*y*/) { 182 | 183 | bool handled = false; 184 | if (currentActivity != nullptr) { 185 | handled = currentActivity->keyboardCallback(key); 186 | } 187 | 188 | if (!handled) { 189 | switch (key) { 190 | case 27: 191 | exit(EXIT_SUCCESS); 192 | break; 193 | case 'p': 194 | menuVisible ^= true; 195 | break; 196 | case 'o': 197 | wireframe ^= true; 198 | break; 199 | case 'i': 200 | showWing ^= true; 201 | break; 202 | case 'l': 203 | showBb ^= true; 204 | break; 205 | case ' ': 206 | if (currentActivity != nullptr) { 207 | currentActivity->recompute(); 208 | } 209 | break; 210 | case '1': 211 | if (currentActivity != nullptr) { 212 | delete currentActivity; 213 | } 214 | currentActivity = new StreamlinesLineActivity(vectorFieldInfo); 215 | break; 216 | case '2': 217 | if (currentActivity != nullptr) { 218 | delete currentActivity; 219 | } 220 | currentActivity = new GlyphsActivity(vectorFieldInfo); 221 | break; 222 | } 223 | } 224 | 225 | glutPostRedisplay(); 226 | } 227 | 228 | void mouseCallback(int button, int state, int x, int y) { 229 | 230 | if (button == 3 || button == 4) { // stroll a wheel event 231 | // Each wheel event reports like a button click, GLUT_DOWN then GLUT_UP 232 | if (state == GLUT_UP) { 233 | return; // Disregard redundant GLUT_UP events 234 | } 235 | zoom *= (button == 3) ? 1/1.05f : 1.05f; 236 | 237 | glutPostRedisplay(); 238 | return; 239 | } 240 | 241 | if (state == GLUT_DOWN) { 242 | mouseButtons |= 1 << button; 243 | } 244 | else if (state == GLUT_UP) { 245 | mouseButtons &= ~(1 << button); 246 | } 247 | 248 | mouseOld.x = x; 249 | mouseOld.y = y; 250 | 251 | glutPostRedisplay(); 252 | } 253 | 254 | void motionCallback(int x, int y) { 255 | int dx = x - mouseOld.x; 256 | int dy = y - mouseOld.y; 257 | 258 | bool handled = false; 259 | if (currentActivity != nullptr) { 260 | handled = currentActivity->motionCallback(x, y, dx, dy, screenWidth, screenHeight, mouseButtons); 261 | } 262 | 263 | if (!handled) { 264 | if (mouseButtons == (1 << GLUT_LEFT_BUTTON)) { 265 | rotate.x -= dy * 0.2f; 266 | rotate.y += dx * 0.2f; 267 | } 268 | else if (mouseButtons == (1 << GLUT_MIDDLE_BUTTON)) { 269 | translate.x -= dx * 0.2f; 270 | translate.y -= dy * 0.2f; 271 | } 272 | } 273 | 274 | 275 | mouseOld.x = x; 276 | mouseOld.y = y; 277 | 278 | glutPostRedisplay(); 279 | } 280 | 281 | void reshapeCallback(int w, int h) { 282 | screenWidth = w; 283 | screenHeight = h; 284 | 285 | glViewport(0, 0, screenWidth, screenHeight); 286 | 287 | glMatrixMode(GL_PROJECTION); 288 | glLoadIdentity(); 289 | gluPerspective(60.0, (GLdouble)screenWidth / (GLdouble)screenHeight, 1, 10000.0); 290 | 291 | glMatrixMode(GL_MODELVIEW); 292 | glLoadIdentity(); 293 | gluLookAt(-1, 0, 0, 0, 0, 0, 0, 0, 1); 294 | } 295 | 296 | 297 | bool loadVectorField(int argc, const char* const argv[]) { 298 | if (argc != 2) { 299 | std::cerr << "Expected one argument as a file path for data in binary NRRD format." << std::endl; 300 | return false; 301 | } 302 | 303 | 304 | VectorField vectorField; 305 | if (!vectorField.loadFromFile(argv[1])) { 306 | return false; 307 | } 308 | 309 | vectorField.fetchInfo(vectorFieldInfo); 310 | 311 | std::cout << std::endl; 312 | 313 | std::vector vectMagnitudeCtf; 314 | vectMagnitudeCtf.push_back(make_float4(0.4f, 0.6f, 0.9f, 0)); 315 | vectMagnitudeCtf.push_back(make_float4(0, 1, 0, 0)); 316 | vectMagnitudeCtf.push_back(make_float4(0.9f, 0.9f, 0, 0)); 317 | vectMagnitudeCtf.push_back(make_float4(1, 0, 0, 0)); 318 | 319 | initCuda(vectorField.data, vectorFieldInfo.cudaDataSize, vectMagnitudeCtf, vectorField.maxMangitude); 320 | 321 | std::cout << "Freeing volume data from computer RAM." << std::endl; 322 | return true; 323 | } 324 | 325 | 326 | bool initGL(int* argc, char* argv[]) { 327 | glutInit(argc, argv); // Create GL context 328 | glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); 329 | glutInitWindowSize(screenWidth, screenHeight); 330 | glutCreateWindow("CS 530 - Stream surfaces by Marek Fiser"); 331 | 332 | std::cout << "Open GL version: " << (char*)glGetString(GL_VERSION) << std::endl; 333 | std::cout << "Open GL vendor: " << (char*)glGetString(GL_VENDOR) << std::endl; 334 | 335 | glewInit(); 336 | 337 | if (!glewIsSupported("GL_VERSION_2_0")) { 338 | std::cerr << "ERROR: Support for necessary OpenGL extensions missing." << std::endl; 339 | return false; 340 | } 341 | 342 | std::cout << "Using GLEW Version: " << glewGetString(GLEW_VERSION) << std::endl; 343 | 344 | glEnable(GL_MULTISAMPLE); 345 | glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 346 | 347 | glShadeModel (GL_SMOOTH); 348 | glEnable(GL_LINE_SMOOTH); 349 | glDepthMask(GL_TRUE); 350 | glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); 351 | 352 | // good old-fashioned fixed function lighting 353 | float black[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 354 | float white[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 355 | float ambient[] = { 0.1f, 0.1f, 0.1f, 1.0f }; 356 | float lightPos[] = { 0.0f, 300.0f, 600.0f, 0.0f }; 357 | 358 | glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); 359 | //glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); -- comes from color 360 | glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black); 361 | 362 | glLightfv(GL_LIGHT0, GL_AMBIENT, white); 363 | //glLightfv(GL_LIGHT0, GL_DIFFUSE, white); 364 | glLightfv(GL_LIGHT0, GL_SPECULAR, white); 365 | glLightfv(GL_LIGHT0, GL_POSITION, lightPos); 366 | 367 | glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black); 368 | //glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, black); 369 | //glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); 370 | 371 | glEnable(GL_LIGHT0); 372 | glEnable(GL_NORMALIZE); 373 | 374 | glutReportErrors(); 375 | 376 | std::cout << "Open GL initialized." << std::endl << std::endl; 377 | return true; 378 | } 379 | 380 | void runGui(int argc, char* argv[]) { 381 | 382 | if (!initGL(&argc, argv)) { 383 | std::cerr << "Failed to initialize OpenGL." << std::endl; 384 | exit(EXIT_FAILURE); 385 | } 386 | 387 | checkCudaErrors(cudaGLSetGLDevice(0)); 388 | 389 | // register callbacks 390 | glutDisplayFunc(displayCallback); 391 | glutKeyboardFunc(keyboardCallback); 392 | glutMouseFunc(mouseCallback); 393 | glutMotionFunc(motionCallback); 394 | glutReshapeFunc(reshapeCallback); 395 | 396 | //argv[1] = "..\\Data\\tdelta-high.nrrd"; 397 | //argv[1] = "..\\Data\\tdelta-bigsmall.nrrd"; 398 | //argv[1] = "..\\Data\\tdelta-bigbig.nrrd"; 399 | 400 | if (!loadVectorField(argc, argv)) { 401 | std::cerr << "Failed to load input file." << std::endl; 402 | exit(EXIT_FAILURE); 403 | } 404 | 405 | std::cout << std::endl << "Application initialized successfully!" << std::endl << std::endl; 406 | 407 | //currentActivity = new StreamlinesLineActivity(vectorFieldInfo); 408 | //currentActivity = new GlyphsActivity(vectorFieldInfo); 409 | 410 | // start app loop - blocking op 411 | glutMainLoop(); 412 | } 413 | } 414 | 415 | 416 | int main(int argc, char* argv[]) { 417 | mf::runGui(argc, argv); 418 | return EXIT_SUCCESS; 419 | } 420 | 421 | -------------------------------------------------------------------------------- /src/StreamSurface/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /src/StreamSurface/stdafx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | typedef unsigned int uint; 28 | typedef unsigned short ushort; 29 | 30 | -------------------------------------------------------------------------------- /src/bin/StreamSurface-Release-x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NightElfik/Vector-field-visualization-using-cuda/2a63c0cc567342ccc38176461521129b76a18e36/src/bin/StreamSurface-Release-x64.exe -------------------------------------------------------------------------------- /src/bin/freeglut.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NightElfik/Vector-field-visualization-using-cuda/2a63c0cc567342ccc38176461521129b76a18e36/src/bin/freeglut.dll -------------------------------------------------------------------------------- /src/bin/glew32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NightElfik/Vector-field-visualization-using-cuda/2a63c0cc567342ccc38176461521129b76a18e36/src/bin/glew32.dll -------------------------------------------------------------------------------- /src/include/GL/freeglut.h: -------------------------------------------------------------------------------- 1 | #ifndef __FREEGLUT_H__ 2 | #define __FREEGLUT_H__ 3 | 4 | /* 5 | * freeglut.h 6 | * 7 | * The freeglut library include file 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 12 | * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | #include "freeglut_std.h" 18 | #include "freeglut_ext.h" 19 | 20 | /*** END OF FILE ***/ 21 | 22 | #endif /* __FREEGLUT_H__ */ 23 | -------------------------------------------------------------------------------- /src/include/GL/freeglut_ext.h: -------------------------------------------------------------------------------- 1 | #ifndef __FREEGLUT_EXT_H__ 2 | #define __FREEGLUT_EXT_H__ 3 | 4 | /* 5 | * freeglut_ext.h 6 | * 7 | * The non-GLUT-compatible extensions to the freeglut library include file 8 | * 9 | * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. 10 | * Written by Pawel W. Olszta, 11 | * Creation date: Thu Dec 2 1999 12 | * 13 | * Permission is hereby granted, free of charge, to any person obtaining a 14 | * copy of this software and associated documentation files (the "Software"), 15 | * to deal in the Software without restriction, including without limitation 16 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 | * and/or sell copies of the Software, and to permit persons to whom the 18 | * Software is furnished to do so, subject to the following conditions: 19 | * 20 | * The above copyright notice and this permission notice shall be included 21 | * in all copies or substantial portions of the Software. 22 | * 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 24 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 26 | * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 27 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /* 36 | * Additional GLUT Key definitions for the Special key function 37 | */ 38 | #define GLUT_KEY_NUM_LOCK 0x006D 39 | #define GLUT_KEY_BEGIN 0x006E 40 | #define GLUT_KEY_DELETE 0x006F 41 | #define GLUT_KEY_SHIFT_L 0x0070 42 | #define GLUT_KEY_SHIFT_R 0x0071 43 | #define GLUT_KEY_CTRL_L 0x0072 44 | #define GLUT_KEY_CTRL_R 0x0073 45 | #define GLUT_KEY_ALT_L 0x0074 46 | #define GLUT_KEY_ALT_R 0x0075 47 | 48 | /* 49 | * GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window 50 | */ 51 | #define GLUT_ACTION_EXIT 0 52 | #define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1 53 | #define GLUT_ACTION_CONTINUE_EXECUTION 2 54 | 55 | /* 56 | * Create a new rendering context when the user opens a new window? 57 | */ 58 | #define GLUT_CREATE_NEW_CONTEXT 0 59 | #define GLUT_USE_CURRENT_CONTEXT 1 60 | 61 | /* 62 | * Direct/Indirect rendering context options (has meaning only in Unix/X11) 63 | */ 64 | #define GLUT_FORCE_INDIRECT_CONTEXT 0 65 | #define GLUT_ALLOW_DIRECT_CONTEXT 1 66 | #define GLUT_TRY_DIRECT_CONTEXT 2 67 | #define GLUT_FORCE_DIRECT_CONTEXT 3 68 | 69 | /* 70 | * GLUT API Extension macro definitions -- the glutGet parameters 71 | */ 72 | #define GLUT_INIT_STATE 0x007C 73 | 74 | #define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9 75 | 76 | #define GLUT_WINDOW_BORDER_WIDTH 0x01FA 77 | #define GLUT_WINDOW_BORDER_HEIGHT 0x01FB 78 | #define GLUT_WINDOW_HEADER_HEIGHT 0x01FB /* Docs say it should always have been GLUT_WINDOW_BORDER_HEIGHT, keep this for backward compatibility */ 79 | 80 | #define GLUT_VERSION 0x01FC 81 | 82 | #define GLUT_RENDERING_CONTEXT 0x01FD 83 | #define GLUT_DIRECT_RENDERING 0x01FE 84 | 85 | #define GLUT_FULL_SCREEN 0x01FF 86 | 87 | #define GLUT_SKIP_STALE_MOTION_EVENTS 0x0204 88 | 89 | /* 90 | * New tokens for glutInitDisplayMode. 91 | * Only one GLUT_AUXn bit may be used at a time. 92 | * Value 0x0400 is defined in OpenGLUT. 93 | */ 94 | #define GLUT_AUX 0x1000 95 | 96 | #define GLUT_AUX1 0x1000 97 | #define GLUT_AUX2 0x2000 98 | #define GLUT_AUX3 0x4000 99 | #define GLUT_AUX4 0x8000 100 | 101 | /* 102 | * Context-related flags, see freeglut_state.c 103 | */ 104 | #define GLUT_INIT_MAJOR_VERSION 0x0200 105 | #define GLUT_INIT_MINOR_VERSION 0x0201 106 | #define GLUT_INIT_FLAGS 0x0202 107 | #define GLUT_INIT_PROFILE 0x0203 108 | 109 | /* 110 | * Flags for glutInitContextFlags, see freeglut_init.c 111 | */ 112 | #define GLUT_DEBUG 0x0001 113 | #define GLUT_FORWARD_COMPATIBLE 0x0002 114 | 115 | 116 | /* 117 | * Flags for glutInitContextProfile, see freeglut_init.c 118 | */ 119 | #define GLUT_CORE_PROFILE 0x0001 120 | #define GLUT_COMPATIBILITY_PROFILE 0x0002 121 | 122 | /* 123 | * Process loop function, see freeglut_main.c 124 | */ 125 | FGAPI void FGAPIENTRY glutMainLoopEvent( void ); 126 | FGAPI void FGAPIENTRY glutLeaveMainLoop( void ); 127 | FGAPI void FGAPIENTRY glutExit ( void ); 128 | 129 | /* 130 | * Window management functions, see freeglut_window.c 131 | */ 132 | FGAPI void FGAPIENTRY glutFullScreenToggle( void ); 133 | FGAPI void FGAPIENTRY glutLeaveFullScreen( void ); 134 | 135 | /* 136 | * Window-specific callback functions, see freeglut_callbacks.c 137 | */ 138 | FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) ); 139 | FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) ); 140 | FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) ); 141 | /* A. Donev: Also a destruction callback for menus */ 142 | FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) ); 143 | 144 | /* 145 | * State setting and retrieval functions, see freeglut_state.c 146 | */ 147 | FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value ); 148 | FGAPI int * FGAPIENTRY glutGetModeValues(GLenum mode, int * size); 149 | /* A.Donev: User-data manipulation */ 150 | FGAPI void* FGAPIENTRY glutGetWindowData( void ); 151 | FGAPI void FGAPIENTRY glutSetWindowData(void* data); 152 | FGAPI void* FGAPIENTRY glutGetMenuData( void ); 153 | FGAPI void FGAPIENTRY glutSetMenuData(void* data); 154 | 155 | /* 156 | * Font stuff, see freeglut_font.c 157 | */ 158 | FGAPI int FGAPIENTRY glutBitmapHeight( void* font ); 159 | FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font ); 160 | FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string ); 161 | FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string ); 162 | 163 | /* 164 | * Geometry functions, see freeglut_geometry.c 165 | */ 166 | FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void ); 167 | FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void ); 168 | FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ); 169 | FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale ); 170 | FGAPI void FGAPIENTRY glutWireCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks); 171 | FGAPI void FGAPIENTRY glutSolidCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks); 172 | 173 | /* 174 | * Extension functions, see freeglut_ext.c 175 | */ 176 | typedef void (*GLUTproc)(); 177 | FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName ); 178 | 179 | /* 180 | * Multi-touch/multi-pointer extensions 181 | */ 182 | 183 | #define GLUT_HAS_MULTI 1 184 | 185 | FGAPI void FGAPIENTRY glutMultiEntryFunc( void (* callback)( int, int ) ); 186 | FGAPI void FGAPIENTRY glutMultiButtonFunc( void (* callback)( int, int, int, int, int ) ); 187 | FGAPI void FGAPIENTRY glutMultiMotionFunc( void (* callback)( int, int, int ) ); 188 | FGAPI void FGAPIENTRY glutMultiPassiveFunc( void (* callback)( int, int, int ) ); 189 | 190 | /* 191 | * Joystick functions, see freeglut_joystick.c 192 | */ 193 | /* USE OF THESE FUNCTIONS IS DEPRECATED !!!!! */ 194 | /* If you have a serious need for these functions in your application, please either 195 | * contact the "freeglut" developer community at freeglut-developer@lists.sourceforge.net, 196 | * switch to the OpenGLUT library, or else port your joystick functionality over to PLIB's 197 | * "js" library. 198 | */ 199 | int glutJoystickGetNumAxes( int ident ); 200 | int glutJoystickGetNumButtons( int ident ); 201 | int glutJoystickNotWorking( int ident ); 202 | float glutJoystickGetDeadBand( int ident, int axis ); 203 | void glutJoystickSetDeadBand( int ident, int axis, float db ); 204 | float glutJoystickGetSaturation( int ident, int axis ); 205 | void glutJoystickSetSaturation( int ident, int axis, float st ); 206 | void glutJoystickSetMinRange( int ident, float *axes ); 207 | void glutJoystickSetMaxRange( int ident, float *axes ); 208 | void glutJoystickSetCenter( int ident, float *axes ); 209 | void glutJoystickGetMinRange( int ident, float *axes ); 210 | void glutJoystickGetMaxRange( int ident, float *axes ); 211 | void glutJoystickGetCenter( int ident, float *axes ); 212 | 213 | /* 214 | * Initialization functions, see freeglut_init.c 215 | */ 216 | FGAPI void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion ); 217 | FGAPI void FGAPIENTRY glutInitContextFlags( int flags ); 218 | FGAPI void FGAPIENTRY glutInitContextProfile( int profile ); 219 | 220 | /* to get the typedef for va_list */ 221 | #include 222 | 223 | FGAPI void FGAPIENTRY glutInitErrorFunc( void (* vError)( const char *fmt, va_list ap ) ); 224 | FGAPI void FGAPIENTRY glutInitWarningFunc( void (* vWarning)( const char *fmt, va_list ap ) ); 225 | 226 | /* 227 | * GLUT API macro definitions -- the display mode definitions 228 | */ 229 | #define GLUT_CAPTIONLESS 0x0400 230 | #define GLUT_BORDERLESS 0x0800 231 | #define GLUT_SRGB 0x1000 232 | 233 | #ifdef __cplusplus 234 | } 235 | #endif 236 | 237 | /*** END OF FILE ***/ 238 | 239 | #endif /* __FREEGLUT_EXT_H__ */ 240 | -------------------------------------------------------------------------------- /src/include/GL/freeglut_std.h: -------------------------------------------------------------------------------- 1 | #ifndef __FREEGLUT_STD_H__ 2 | #define __FREEGLUT_STD_H__ 3 | 4 | /* 5 | * freeglut_std.h 6 | * 7 | * The GLUT-compatible part of the freeglut library include file 8 | * 9 | * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. 10 | * Written by Pawel W. Olszta, 11 | * Creation date: Thu Dec 2 1999 12 | * 13 | * Permission is hereby granted, free of charge, to any person obtaining a 14 | * copy of this software and associated documentation files (the "Software"), 15 | * to deal in the Software without restriction, including without limitation 16 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 17 | * and/or sell copies of the Software, and to permit persons to whom the 18 | * Software is furnished to do so, subject to the following conditions: 19 | * 20 | * The above copyright notice and this permission notice shall be included 21 | * in all copies or substantial portions of the Software. 22 | * 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 24 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 26 | * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 27 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 28 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | /* 36 | * Under windows, we have to differentiate between static and dynamic libraries 37 | */ 38 | #ifdef _WIN32 39 | /* #pragma may not be supported by some compilers. 40 | * Discussion by FreeGLUT developers suggests that 41 | * Visual C++ specific code involving pragmas may 42 | * need to move to a separate header. 24th Dec 2003 43 | */ 44 | 45 | /* Define FREEGLUT_LIB_PRAGMAS to 1 to include library 46 | * pragmas or to 0 to exclude library pragmas. 47 | * The default behavior depends on the compiler/platform. 48 | */ 49 | # ifndef FREEGLUT_LIB_PRAGMAS 50 | # if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(_WIN32_WCE) 51 | # define FREEGLUT_LIB_PRAGMAS 1 52 | # else 53 | # define FREEGLUT_LIB_PRAGMAS 0 54 | # endif 55 | # endif 56 | 57 | # ifndef WIN32_LEAN_AND_MEAN 58 | # define WIN32_LEAN_AND_MEAN 1 59 | # endif 60 | # ifndef NOMINMAX 61 | # define NOMINMAX 62 | # endif 63 | # include 64 | 65 | /* Windows static library */ 66 | # ifdef FREEGLUT_STATIC 67 | 68 | # define FGAPI 69 | # define FGAPIENTRY 70 | 71 | /* Link with Win32 static freeglut lib */ 72 | # if FREEGLUT_LIB_PRAGMAS 73 | # pragma comment (lib, "freeglut_static.lib") 74 | # endif 75 | 76 | /* Windows shared library (DLL) */ 77 | # else 78 | 79 | # define FGAPIENTRY __stdcall 80 | # if defined(FREEGLUT_EXPORTS) 81 | # define FGAPI __declspec(dllexport) 82 | # else 83 | # define FGAPI __declspec(dllimport) 84 | 85 | /* Link with Win32 shared freeglut lib */ 86 | # if FREEGLUT_LIB_PRAGMAS 87 | # pragma comment (lib, "freeglut.lib") 88 | # endif 89 | 90 | # endif 91 | 92 | # endif 93 | 94 | /* Drag in other Windows libraries as required by FreeGLUT */ 95 | # if FREEGLUT_LIB_PRAGMAS 96 | # pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */ 97 | # pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */ 98 | # pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */ 99 | # pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */ 100 | # pragma comment (lib, "user32.lib") /* link Windows user lib */ 101 | # endif 102 | 103 | #else 104 | 105 | /* Non-Windows definition of FGAPI and FGAPIENTRY */ 106 | # define FGAPI 107 | # define FGAPIENTRY 108 | 109 | #endif 110 | 111 | /* 112 | * The freeglut and GLUT API versions 113 | */ 114 | #define FREEGLUT 1 115 | #define GLUT_API_VERSION 4 116 | #define GLUT_XLIB_IMPLEMENTATION 13 117 | /* Deprecated: 118 | cf. http://sourceforge.net/mailarchive/forum.php?thread_name=CABcAi1hw7cr4xtigckaGXB5X8wddLfMcbA_rZ3NAuwMrX_zmsw%40mail.gmail.com&forum_name=freeglut-developer */ 119 | #define FREEGLUT_VERSION_2_0 1 120 | 121 | /* 122 | * Always include OpenGL and GLU headers 123 | */ 124 | #if __APPLE__ 125 | # include 126 | # include 127 | #else 128 | # include 129 | # include 130 | #endif 131 | 132 | /* 133 | * GLUT API macro definitions -- the special key codes: 134 | */ 135 | #define GLUT_KEY_F1 0x0001 136 | #define GLUT_KEY_F2 0x0002 137 | #define GLUT_KEY_F3 0x0003 138 | #define GLUT_KEY_F4 0x0004 139 | #define GLUT_KEY_F5 0x0005 140 | #define GLUT_KEY_F6 0x0006 141 | #define GLUT_KEY_F7 0x0007 142 | #define GLUT_KEY_F8 0x0008 143 | #define GLUT_KEY_F9 0x0009 144 | #define GLUT_KEY_F10 0x000A 145 | #define GLUT_KEY_F11 0x000B 146 | #define GLUT_KEY_F12 0x000C 147 | #define GLUT_KEY_LEFT 0x0064 148 | #define GLUT_KEY_UP 0x0065 149 | #define GLUT_KEY_RIGHT 0x0066 150 | #define GLUT_KEY_DOWN 0x0067 151 | #define GLUT_KEY_PAGE_UP 0x0068 152 | #define GLUT_KEY_PAGE_DOWN 0x0069 153 | #define GLUT_KEY_HOME 0x006A 154 | #define GLUT_KEY_END 0x006B 155 | #define GLUT_KEY_INSERT 0x006C 156 | 157 | /* 158 | * GLUT API macro definitions -- mouse state definitions 159 | */ 160 | #define GLUT_LEFT_BUTTON 0x0000 161 | #define GLUT_MIDDLE_BUTTON 0x0001 162 | #define GLUT_RIGHT_BUTTON 0x0002 163 | #define GLUT_DOWN 0x0000 164 | #define GLUT_UP 0x0001 165 | #define GLUT_LEFT 0x0000 166 | #define GLUT_ENTERED 0x0001 167 | 168 | /* 169 | * GLUT API macro definitions -- the display mode definitions 170 | */ 171 | #define GLUT_RGB 0x0000 172 | #define GLUT_RGBA 0x0000 173 | #define GLUT_INDEX 0x0001 174 | #define GLUT_SINGLE 0x0000 175 | #define GLUT_DOUBLE 0x0002 176 | #define GLUT_ACCUM 0x0004 177 | #define GLUT_ALPHA 0x0008 178 | #define GLUT_DEPTH 0x0010 179 | #define GLUT_STENCIL 0x0020 180 | #define GLUT_MULTISAMPLE 0x0080 181 | #define GLUT_STEREO 0x0100 182 | #define GLUT_LUMINANCE 0x0200 183 | 184 | /* 185 | * GLUT API macro definitions -- windows and menu related definitions 186 | */ 187 | #define GLUT_MENU_NOT_IN_USE 0x0000 188 | #define GLUT_MENU_IN_USE 0x0001 189 | #define GLUT_NOT_VISIBLE 0x0000 190 | #define GLUT_VISIBLE 0x0001 191 | #define GLUT_HIDDEN 0x0000 192 | #define GLUT_FULLY_RETAINED 0x0001 193 | #define GLUT_PARTIALLY_RETAINED 0x0002 194 | #define GLUT_FULLY_COVERED 0x0003 195 | 196 | /* 197 | * GLUT API macro definitions -- fonts definitions 198 | * 199 | * Steve Baker suggested to make it binary compatible with GLUT: 200 | */ 201 | #if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WATCOMC__) 202 | # define GLUT_STROKE_ROMAN ((void *)0x0000) 203 | # define GLUT_STROKE_MONO_ROMAN ((void *)0x0001) 204 | # define GLUT_BITMAP_9_BY_15 ((void *)0x0002) 205 | # define GLUT_BITMAP_8_BY_13 ((void *)0x0003) 206 | # define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004) 207 | # define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005) 208 | # define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006) 209 | # define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007) 210 | # define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008) 211 | #else 212 | /* 213 | * I don't really know if it's a good idea... But here it goes: 214 | */ 215 | extern void* glutStrokeRoman; 216 | extern void* glutStrokeMonoRoman; 217 | extern void* glutBitmap9By15; 218 | extern void* glutBitmap8By13; 219 | extern void* glutBitmapTimesRoman10; 220 | extern void* glutBitmapTimesRoman24; 221 | extern void* glutBitmapHelvetica10; 222 | extern void* glutBitmapHelvetica12; 223 | extern void* glutBitmapHelvetica18; 224 | 225 | /* 226 | * Those pointers will be used by following definitions: 227 | */ 228 | # define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman) 229 | # define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman) 230 | # define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15) 231 | # define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13) 232 | # define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10) 233 | # define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24) 234 | # define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10) 235 | # define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12) 236 | # define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18) 237 | #endif 238 | 239 | /* 240 | * GLUT API macro definitions -- the glutGet parameters 241 | */ 242 | #define GLUT_WINDOW_X 0x0064 243 | #define GLUT_WINDOW_Y 0x0065 244 | #define GLUT_WINDOW_WIDTH 0x0066 245 | #define GLUT_WINDOW_HEIGHT 0x0067 246 | #define GLUT_WINDOW_BUFFER_SIZE 0x0068 247 | #define GLUT_WINDOW_STENCIL_SIZE 0x0069 248 | #define GLUT_WINDOW_DEPTH_SIZE 0x006A 249 | #define GLUT_WINDOW_RED_SIZE 0x006B 250 | #define GLUT_WINDOW_GREEN_SIZE 0x006C 251 | #define GLUT_WINDOW_BLUE_SIZE 0x006D 252 | #define GLUT_WINDOW_ALPHA_SIZE 0x006E 253 | #define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F 254 | #define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070 255 | #define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071 256 | #define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072 257 | #define GLUT_WINDOW_DOUBLEBUFFER 0x0073 258 | #define GLUT_WINDOW_RGBA 0x0074 259 | #define GLUT_WINDOW_PARENT 0x0075 260 | #define GLUT_WINDOW_NUM_CHILDREN 0x0076 261 | #define GLUT_WINDOW_COLORMAP_SIZE 0x0077 262 | #define GLUT_WINDOW_NUM_SAMPLES 0x0078 263 | #define GLUT_WINDOW_STEREO 0x0079 264 | #define GLUT_WINDOW_CURSOR 0x007A 265 | 266 | #define GLUT_SCREEN_WIDTH 0x00C8 267 | #define GLUT_SCREEN_HEIGHT 0x00C9 268 | #define GLUT_SCREEN_WIDTH_MM 0x00CA 269 | #define GLUT_SCREEN_HEIGHT_MM 0x00CB 270 | #define GLUT_MENU_NUM_ITEMS 0x012C 271 | #define GLUT_DISPLAY_MODE_POSSIBLE 0x0190 272 | #define GLUT_INIT_WINDOW_X 0x01F4 273 | #define GLUT_INIT_WINDOW_Y 0x01F5 274 | #define GLUT_INIT_WINDOW_WIDTH 0x01F6 275 | #define GLUT_INIT_WINDOW_HEIGHT 0x01F7 276 | #define GLUT_INIT_DISPLAY_MODE 0x01F8 277 | #define GLUT_ELAPSED_TIME 0x02BC 278 | #define GLUT_WINDOW_FORMAT_ID 0x007B 279 | 280 | /* 281 | * GLUT API macro definitions -- the glutDeviceGet parameters 282 | */ 283 | #define GLUT_HAS_KEYBOARD 0x0258 284 | #define GLUT_HAS_MOUSE 0x0259 285 | #define GLUT_HAS_SPACEBALL 0x025A 286 | #define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B 287 | #define GLUT_HAS_TABLET 0x025C 288 | #define GLUT_NUM_MOUSE_BUTTONS 0x025D 289 | #define GLUT_NUM_SPACEBALL_BUTTONS 0x025E 290 | #define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F 291 | #define GLUT_NUM_DIALS 0x0260 292 | #define GLUT_NUM_TABLET_BUTTONS 0x0261 293 | #define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262 294 | #define GLUT_DEVICE_KEY_REPEAT 0x0263 295 | #define GLUT_HAS_JOYSTICK 0x0264 296 | #define GLUT_OWNS_JOYSTICK 0x0265 297 | #define GLUT_JOYSTICK_BUTTONS 0x0266 298 | #define GLUT_JOYSTICK_AXES 0x0267 299 | #define GLUT_JOYSTICK_POLL_RATE 0x0268 300 | 301 | /* 302 | * GLUT API macro definitions -- the glutLayerGet parameters 303 | */ 304 | #define GLUT_OVERLAY_POSSIBLE 0x0320 305 | #define GLUT_LAYER_IN_USE 0x0321 306 | #define GLUT_HAS_OVERLAY 0x0322 307 | #define GLUT_TRANSPARENT_INDEX 0x0323 308 | #define GLUT_NORMAL_DAMAGED 0x0324 309 | #define GLUT_OVERLAY_DAMAGED 0x0325 310 | 311 | /* 312 | * GLUT API macro definitions -- the glutVideoResizeGet parameters 313 | */ 314 | #define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384 315 | #define GLUT_VIDEO_RESIZE_IN_USE 0x0385 316 | #define GLUT_VIDEO_RESIZE_X_DELTA 0x0386 317 | #define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387 318 | #define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388 319 | #define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389 320 | #define GLUT_VIDEO_RESIZE_X 0x038A 321 | #define GLUT_VIDEO_RESIZE_Y 0x038B 322 | #define GLUT_VIDEO_RESIZE_WIDTH 0x038C 323 | #define GLUT_VIDEO_RESIZE_HEIGHT 0x038D 324 | 325 | /* 326 | * GLUT API macro definitions -- the glutUseLayer parameters 327 | */ 328 | #define GLUT_NORMAL 0x0000 329 | #define GLUT_OVERLAY 0x0001 330 | 331 | /* 332 | * GLUT API macro definitions -- the glutGetModifiers parameters 333 | */ 334 | #define GLUT_ACTIVE_SHIFT 0x0001 335 | #define GLUT_ACTIVE_CTRL 0x0002 336 | #define GLUT_ACTIVE_ALT 0x0004 337 | 338 | /* 339 | * GLUT API macro definitions -- the glutSetCursor parameters 340 | */ 341 | #define GLUT_CURSOR_RIGHT_ARROW 0x0000 342 | #define GLUT_CURSOR_LEFT_ARROW 0x0001 343 | #define GLUT_CURSOR_INFO 0x0002 344 | #define GLUT_CURSOR_DESTROY 0x0003 345 | #define GLUT_CURSOR_HELP 0x0004 346 | #define GLUT_CURSOR_CYCLE 0x0005 347 | #define GLUT_CURSOR_SPRAY 0x0006 348 | #define GLUT_CURSOR_WAIT 0x0007 349 | #define GLUT_CURSOR_TEXT 0x0008 350 | #define GLUT_CURSOR_CROSSHAIR 0x0009 351 | #define GLUT_CURSOR_UP_DOWN 0x000A 352 | #define GLUT_CURSOR_LEFT_RIGHT 0x000B 353 | #define GLUT_CURSOR_TOP_SIDE 0x000C 354 | #define GLUT_CURSOR_BOTTOM_SIDE 0x000D 355 | #define GLUT_CURSOR_LEFT_SIDE 0x000E 356 | #define GLUT_CURSOR_RIGHT_SIDE 0x000F 357 | #define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010 358 | #define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011 359 | #define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012 360 | #define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013 361 | #define GLUT_CURSOR_INHERIT 0x0064 362 | #define GLUT_CURSOR_NONE 0x0065 363 | #define GLUT_CURSOR_FULL_CROSSHAIR 0x0066 364 | 365 | /* 366 | * GLUT API macro definitions -- RGB color component specification definitions 367 | */ 368 | #define GLUT_RED 0x0000 369 | #define GLUT_GREEN 0x0001 370 | #define GLUT_BLUE 0x0002 371 | 372 | /* 373 | * GLUT API macro definitions -- additional keyboard and joystick definitions 374 | */ 375 | #define GLUT_KEY_REPEAT_OFF 0x0000 376 | #define GLUT_KEY_REPEAT_ON 0x0001 377 | #define GLUT_KEY_REPEAT_DEFAULT 0x0002 378 | 379 | #define GLUT_JOYSTICK_BUTTON_A 0x0001 380 | #define GLUT_JOYSTICK_BUTTON_B 0x0002 381 | #define GLUT_JOYSTICK_BUTTON_C 0x0004 382 | #define GLUT_JOYSTICK_BUTTON_D 0x0008 383 | 384 | /* 385 | * GLUT API macro definitions -- game mode definitions 386 | */ 387 | #define GLUT_GAME_MODE_ACTIVE 0x0000 388 | #define GLUT_GAME_MODE_POSSIBLE 0x0001 389 | #define GLUT_GAME_MODE_WIDTH 0x0002 390 | #define GLUT_GAME_MODE_HEIGHT 0x0003 391 | #define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004 392 | #define GLUT_GAME_MODE_REFRESH_RATE 0x0005 393 | #define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006 394 | 395 | /* 396 | * Initialization functions, see fglut_init.c 397 | */ 398 | FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv ); 399 | FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y ); 400 | FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height ); 401 | FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode ); 402 | FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode ); 403 | 404 | /* 405 | * Process loop function, see freeglut_main.c 406 | */ 407 | FGAPI void FGAPIENTRY glutMainLoop( void ); 408 | 409 | /* 410 | * Window management functions, see freeglut_window.c 411 | */ 412 | FGAPI int FGAPIENTRY glutCreateWindow( const char* title ); 413 | FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height ); 414 | FGAPI void FGAPIENTRY glutDestroyWindow( int window ); 415 | FGAPI void FGAPIENTRY glutSetWindow( int window ); 416 | FGAPI int FGAPIENTRY glutGetWindow( void ); 417 | FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title ); 418 | FGAPI void FGAPIENTRY glutSetIconTitle( const char* title ); 419 | FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height ); 420 | FGAPI void FGAPIENTRY glutPositionWindow( int x, int y ); 421 | FGAPI void FGAPIENTRY glutShowWindow( void ); 422 | FGAPI void FGAPIENTRY glutHideWindow( void ); 423 | FGAPI void FGAPIENTRY glutIconifyWindow( void ); 424 | FGAPI void FGAPIENTRY glutPushWindow( void ); 425 | FGAPI void FGAPIENTRY glutPopWindow( void ); 426 | FGAPI void FGAPIENTRY glutFullScreen( void ); 427 | 428 | /* 429 | * Display-connected functions, see freeglut_display.c 430 | */ 431 | FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window ); 432 | FGAPI void FGAPIENTRY glutPostRedisplay( void ); 433 | FGAPI void FGAPIENTRY glutSwapBuffers( void ); 434 | 435 | /* 436 | * Mouse cursor functions, see freeglut_cursor.c 437 | */ 438 | FGAPI void FGAPIENTRY glutWarpPointer( int x, int y ); 439 | FGAPI void FGAPIENTRY glutSetCursor( int cursor ); 440 | 441 | /* 442 | * Overlay stuff, see freeglut_overlay.c 443 | */ 444 | FGAPI void FGAPIENTRY glutEstablishOverlay( void ); 445 | FGAPI void FGAPIENTRY glutRemoveOverlay( void ); 446 | FGAPI void FGAPIENTRY glutUseLayer( GLenum layer ); 447 | FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void ); 448 | FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window ); 449 | FGAPI void FGAPIENTRY glutShowOverlay( void ); 450 | FGAPI void FGAPIENTRY glutHideOverlay( void ); 451 | 452 | /* 453 | * Menu stuff, see freeglut_menu.c 454 | */ 455 | FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) ); 456 | FGAPI void FGAPIENTRY glutDestroyMenu( int menu ); 457 | FGAPI int FGAPIENTRY glutGetMenu( void ); 458 | FGAPI void FGAPIENTRY glutSetMenu( int menu ); 459 | FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value ); 460 | FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu ); 461 | FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value ); 462 | FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value ); 463 | FGAPI void FGAPIENTRY glutRemoveMenuItem( int item ); 464 | FGAPI void FGAPIENTRY glutAttachMenu( int button ); 465 | FGAPI void FGAPIENTRY glutDetachMenu( int button ); 466 | 467 | /* 468 | * Global callback functions, see freeglut_callbacks.c 469 | */ 470 | FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value ); 471 | FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) ); 472 | 473 | /* 474 | * Window-specific callback functions, see freeglut_callbacks.c 475 | */ 476 | FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) ); 477 | FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) ); 478 | FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) ); 479 | FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) ); 480 | FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) ); 481 | FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) ); 482 | FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) ); 483 | FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) ); 484 | FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) ); 485 | 486 | FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) ); 487 | FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) ); 488 | FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval ); 489 | FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) ); 490 | FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) ); 491 | FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) ); 492 | FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) ); 493 | 494 | FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) ); 495 | FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) ); 496 | FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) ); 497 | FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) ); 498 | FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) ); 499 | FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) ); 500 | FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) ); 501 | 502 | /* 503 | * State setting and retrieval functions, see freeglut_state.c 504 | */ 505 | FGAPI int FGAPIENTRY glutGet( GLenum query ); 506 | FGAPI int FGAPIENTRY glutDeviceGet( GLenum query ); 507 | FGAPI int FGAPIENTRY glutGetModifiers( void ); 508 | FGAPI int FGAPIENTRY glutLayerGet( GLenum query ); 509 | 510 | /* 511 | * Font stuff, see freeglut_font.c 512 | */ 513 | FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character ); 514 | FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character ); 515 | FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character ); 516 | FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character ); 517 | FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string ); 518 | FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string ); 519 | 520 | /* 521 | * Geometry functions, see freeglut_geometry.c 522 | */ 523 | FGAPI void FGAPIENTRY glutWireCube( GLdouble size ); 524 | FGAPI void FGAPIENTRY glutSolidCube( GLdouble size ); 525 | FGAPI void FGAPIENTRY glutWireSphere( GLdouble radius, GLint slices, GLint stacks ); 526 | FGAPI void FGAPIENTRY glutSolidSphere( GLdouble radius, GLint slices, GLint stacks ); 527 | FGAPI void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ); 528 | FGAPI void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks ); 529 | 530 | FGAPI void FGAPIENTRY glutWireTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings ); 531 | FGAPI void FGAPIENTRY glutSolidTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings ); 532 | FGAPI void FGAPIENTRY glutWireDodecahedron( void ); 533 | FGAPI void FGAPIENTRY glutSolidDodecahedron( void ); 534 | FGAPI void FGAPIENTRY glutWireOctahedron( void ); 535 | FGAPI void FGAPIENTRY glutSolidOctahedron( void ); 536 | FGAPI void FGAPIENTRY glutWireTetrahedron( void ); 537 | FGAPI void FGAPIENTRY glutSolidTetrahedron( void ); 538 | FGAPI void FGAPIENTRY glutWireIcosahedron( void ); 539 | FGAPI void FGAPIENTRY glutSolidIcosahedron( void ); 540 | 541 | /* 542 | * Teapot rendering functions, found in freeglut_teapot.c 543 | * NB: front facing polygons have clockwise winding, not counter clockwise 544 | */ 545 | FGAPI void FGAPIENTRY glutWireTeapot( GLdouble size ); 546 | FGAPI void FGAPIENTRY glutSolidTeapot( GLdouble size ); 547 | 548 | /* 549 | * Game mode functions, see freeglut_gamemode.c 550 | */ 551 | FGAPI void FGAPIENTRY glutGameModeString( const char* string ); 552 | FGAPI int FGAPIENTRY glutEnterGameMode( void ); 553 | FGAPI void FGAPIENTRY glutLeaveGameMode( void ); 554 | FGAPI int FGAPIENTRY glutGameModeGet( GLenum query ); 555 | 556 | /* 557 | * Video resize functions, see freeglut_videoresize.c 558 | */ 559 | FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query ); 560 | FGAPI void FGAPIENTRY glutSetupVideoResizing( void ); 561 | FGAPI void FGAPIENTRY glutStopVideoResizing( void ); 562 | FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height ); 563 | FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height ); 564 | 565 | /* 566 | * Colormap functions, see freeglut_misc.c 567 | */ 568 | FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue ); 569 | FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component ); 570 | FGAPI void FGAPIENTRY glutCopyColormap( int window ); 571 | 572 | /* 573 | * Misc keyboard and joystick functions, see freeglut_misc.c 574 | */ 575 | FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore ); 576 | FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode ); 577 | FGAPI void FGAPIENTRY glutForceJoystickFunc( void ); 578 | 579 | /* 580 | * Misc functions, see freeglut_misc.c 581 | */ 582 | FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension ); 583 | FGAPI void FGAPIENTRY glutReportErrors( void ); 584 | 585 | /* Comment from glut.h of classic GLUT: 586 | 587 | Win32 has an annoying issue where there are multiple C run-time 588 | libraries (CRTs). If the executable is linked with a different CRT 589 | from the GLUT DLL, the GLUT DLL will not share the same CRT static 590 | data seen by the executable. In particular, atexit callbacks registered 591 | in the executable will not be called if GLUT calls its (different) 592 | exit routine). GLUT is typically built with the 593 | "/MD" option (the CRT with multithreading DLL support), but the Visual 594 | C++ linker default is "/ML" (the single threaded CRT). 595 | 596 | One workaround to this issue is requiring users to always link with 597 | the same CRT as GLUT is compiled with. That requires users supply a 598 | non-standard option. GLUT 3.7 has its own built-in workaround where 599 | the executable's "exit" function pointer is covertly passed to GLUT. 600 | GLUT then calls the executable's exit function pointer to ensure that 601 | any "atexit" calls registered by the application are called if GLUT 602 | needs to exit. 603 | 604 | Note that the __glut*WithExit routines should NEVER be called directly. 605 | To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ 606 | 607 | /* to get the prototype for exit() */ 608 | #include 609 | 610 | #if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__) 611 | FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); 612 | FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); 613 | FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int)); 614 | #ifndef FREEGLUT_BUILDING_LIB 615 | #if defined(__GNUC__) 616 | #define FGUNUSED __attribute__((unused)) 617 | #else 618 | #define FGUNUSED 619 | #endif 620 | static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } 621 | #define glutInit glutInit_ATEXIT_HACK 622 | static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } 623 | #define glutCreateWindow glutCreateWindow_ATEXIT_HACK 624 | static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); } 625 | #define glutCreateMenu glutCreateMenu_ATEXIT_HACK 626 | #endif 627 | #endif 628 | 629 | #ifdef __cplusplus 630 | } 631 | #endif 632 | 633 | /*** END OF FILE ***/ 634 | 635 | #endif /* __FREEGLUT_STD_H__ */ 636 | 637 | -------------------------------------------------------------------------------- /src/include/GL/glut.h: -------------------------------------------------------------------------------- 1 | #ifndef __GLUT_H__ 2 | #define __GLUT_H__ 3 | 4 | /* 5 | * glut.h 6 | * 7 | * The freeglut library include file 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 12 | * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | */ 16 | 17 | #include "freeglut_std.h" 18 | 19 | /*** END OF FILE ***/ 20 | 21 | #endif /* __GLUT_H__ */ 22 | -------------------------------------------------------------------------------- /src/libs/freeglut.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NightElfik/Vector-field-visualization-using-cuda/2a63c0cc567342ccc38176461521129b76a18e36/src/libs/freeglut.lib -------------------------------------------------------------------------------- /src/libs/glew32.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NightElfik/Vector-field-visualization-using-cuda/2a63c0cc567342ccc38176461521129b76a18e36/src/libs/glew32.lib --------------------------------------------------------------------------------