1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
#include <cuda_runtime.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
extern "C" {
void updateTorusVerticesCUDA(float* vertices, int numVertices, float time, float majorRadius, float minorRadius);
void updateTorusColorsCUDA(float* colors, int numVertices, float time);
int initCUDA();
void cleanupCUDA();
}
// CUDA kernel for updating torus vertex positions
__global__ void torusVertexKernel(float* vertices, int numVertices, float time, float majorRadius, float minorRadius) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < numVertices) {
// Calculate vertex index for position data (6 floats per vertex: x,y,z,r,g,b)
int vertexOffset = idx * 6;
// Generate torus parameters
int segments = (int)sqrt((float)numVertices);
int rings = segments;
int u = idx % segments;
int v = idx / segments;
if (v >= rings) return;
float theta = 2.0f * M_PI * u / segments;
float phi = 2.0f * M_PI * v / rings;
// Add rotation animation
theta += time * 0.5f;
phi += time * 0.3f;
// Calculate torus coordinates
float cosTheta = cosf(theta);
float sinTheta = sinf(theta);
float cosPhi = cosf(phi);
float sinPhi = sinf(phi);
// Torus parametric equations
float x = (majorRadius + minorRadius * cosPhi) * cosTheta;
float y = (majorRadius + minorRadius * cosPhi) * sinTheta;
float z = minorRadius * sinPhi;
// Update vertex positions
vertices[vertexOffset + 0] = x;
vertices[vertexOffset + 1] = y;
vertices[vertexOffset + 2] = z;
}
}
// CUDA kernel for updating torus vertex colors with dynamic effects
__global__ void torusColorKernel(float* vertices, int numVertices, float time) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < numVertices) {
// Calculate vertex index for color data (6 floats per vertex: x,y,z,r,g,b)
int vertexOffset = idx * 6;
// Get vertex position
float x = vertices[vertexOffset + 0];
float y = vertices[vertexOffset + 1];
float z = vertices[vertexOffset + 2];
// Calculate distance from center for color effect
float distance = sqrtf(x*x + y*y + z*z);
// Create pulsating color effect based on distance and time
float pulse = sinf(time * 2.0f + distance * 0.5f) * 0.5f + 0.5f;
float wave = sinf(time + idx * 0.1f) * 0.3f + 0.7f;
// Generate RGB colors
float r = pulse * wave;
float g = sinf(time * 1.5f + distance * 0.3f) * 0.4f + 0.6f;
float b = cosf(time * 0.8f + distance * 0.7f) * 0.5f + 0.5f;
// Update vertex colors
vertices[vertexOffset + 3] = r;
vertices[vertexOffset + 4] = g;
vertices[vertexOffset + 5] = b;
}
}
// Host function to update torus vertices
void updateTorusVerticesCUDA(float* vertices, int numVertices, float time, float majorRadius, float minorRadius) {
float* d_vertices;
size_t size = numVertices * 6 * sizeof(float); // 6 floats per vertex (x,y,z,r,g,b)
// Allocate GPU memory
cudaMalloc(&d_vertices, size);
// Copy data to GPU
cudaMemcpy(d_vertices, vertices, size, cudaMemcpyHostToDevice);
// Launch kernel
int threadsPerBlock = 256;
int blocksPerGrid = (numVertices + threadsPerBlock - 1) / threadsPerBlock;
torusVertexKernel<<<blocksPerGrid, threadsPerBlock>>>(d_vertices, numVertices, time, majorRadius, minorRadius);
// Wait for kernel to complete
cudaDeviceSynchronize();
// Copy result back to host
cudaMemcpy(vertices, d_vertices, size, cudaMemcpyDeviceToHost);
// Free GPU memory
cudaFree(d_vertices);
}
// Host function to update torus colors
void updateTorusColorsCUDA(float* vertices, int numVertices, float time) {
float* d_vertices;
size_t size = numVertices * 6 * sizeof(float); // 6 floats per vertex (x,y,z,r,g,b)
// Allocate GPU memory
cudaMalloc(&d_vertices, size);
// Copy data to GPU
cudaMemcpy(d_vertices, vertices, size, cudaMemcpyHostToDevice);
// Launch kernel
int threadsPerBlock = 256;
int blocksPerGrid = (numVertices + threadsPerBlock - 1) / threadsPerBlock;
torusColorKernel<<<blocksPerGrid, threadsPerBlock>>>(d_vertices, numVertices, time);
// Wait for kernel to complete
cudaDeviceSynchronize();
// Copy result back to host
cudaMemcpy(vertices, d_vertices, size, cudaMemcpyDeviceToHost);
// Free GPU memory
cudaFree(d_vertices);
}
// Initialize CUDA
int initCUDA() {
int deviceCount;
cudaError_t error = cudaGetDeviceCount(&deviceCount);
if (error != cudaSuccess) {
return 0; // CUDA not available
}
if (deviceCount == 0) {
return 0; // No CUDA devices
}
// Set device 0 as default
cudaSetDevice(0);
return 1; // Success
}
// Cleanup CUDA resources
void cleanupCUDA() {
cudaDeviceReset();
}
|