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
|
#include <cuda_runtime.h>
#include <math.h>
#include <stdio.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
__global__ void torusVertexKernel(float* vertices, int numVertices, float time, float majorRadius, float minorRadius) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < numVertices) {
int vertexOffset = idx * 6;
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;
theta += time * 0.5f;
phi += time * 0.3f;
float cosTheta = cosf(theta);
float sinTheta = sinf(theta);
float cosPhi = cosf(phi);
float sinPhi = sinf(phi);
float x = (majorRadius + minorRadius * cosPhi) * cosTheta;
float y = (majorRadius + minorRadius * cosPhi) * sinTheta;
float z = minorRadius * sinPhi;
vertices[vertexOffset + 0] = x;
vertices[vertexOffset + 1] = y;
vertices[vertexOffset + 2] = z;
}
}
__global__ void torusColorKernel(float* colors, int numVertices, float time) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < numVertices) {
int colorOffset = idx * 3;
float phase = time * 2.0f + idx * 0.1f;
colors[colorOffset + 0] = 0.5f + 0.5f * sinf(phase);
colors[colorOffset + 1] = 0.5f + 0.5f * sinf(phase + 2.1f);
colors[colorOffset + 2] = 0.5f + 0.5f * sinf(phase + 4.2f);
}
}
static float* d_vertices = nullptr;
static float* d_colors = nullptr;
static int maxVertices = 0;
static bool cudaInitialized = false;
extern "C" {
int initCUDA() {
if (cudaInitialized) return 1;
cudaError_t error = cudaSetDevice(0);
if (error != cudaSuccess) {
printf("CUDA Error: %s\n", cudaGetErrorString(error));
return 0;
}
cudaInitialized = true;
return 1;
}
void cleanupCUDA() {
if (!cudaInitialized) return;
if (d_vertices) { cudaFree(d_vertices); d_vertices = nullptr; }
if (d_colors) { cudaFree(d_colors); d_colors = nullptr; }
maxVertices = 0;
cudaInitialized = false;
cudaDeviceReset();
}
int ensureDeviceMemory(int numVertices) {
if (!cudaInitialized) return 0;
if (numVertices > maxVertices) {
if (d_vertices) cudaFree(d_vertices);
if (d_colors) cudaFree(d_colors);
size_t vertexSize = numVertices * 6 * sizeof(float);
size_t colorSize = numVertices * 3 * sizeof(float);
if (cudaMalloc(&d_vertices, vertexSize) != cudaSuccess) return 0;
if (cudaMalloc(&d_colors, colorSize) != cudaSuccess) return 0;
maxVertices = numVertices;
}
return 1;
}
void updateTorusVerticesCUDA(float* vertices, int numVertices, float time, float majorRadius, float minorRadius) {
if (!cudaInitialized || !ensureDeviceMemory(numVertices)) return;
size_t vertexSize = numVertices * 6 * sizeof(float);
if (cudaMemcpy(d_vertices, vertices, vertexSize, cudaMemcpyHostToDevice) != cudaSuccess) return;
int blockSize = 256;
int gridSize = (numVertices + blockSize - 1) / blockSize;
torusVertexKernel<<<gridSize, blockSize>>>(d_vertices, numVertices, time, majorRadius, minorRadius);
if (cudaDeviceSynchronize() != cudaSuccess) return;
cudaMemcpy(vertices, d_vertices, vertexSize, cudaMemcpyDeviceToHost);
}
void updateTorusColorsCUDA(float* colors, int numVertices, float time) {
if (!cudaInitialized || !ensureDeviceMemory(numVertices)) return;
size_t colorSize = numVertices * 3 * sizeof(float);
if (cudaMemcpy(d_colors, colors, colorSize, cudaMemcpyHostToDevice) != cudaSuccess) return;
int blockSize = 256;
int gridSize = (numVertices + blockSize - 1) / blockSize;
torusColorKernel<<<gridSize, blockSize>>>(d_colors, numVertices, time);
if (cudaDeviceSynchronize() != cudaSuccess) return;
cudaMemcpy(colors, d_colors, colorSize, cudaMemcpyDeviceToHost);
}
} // extern "C"
|