现代OpenGL中如何实现每次按键回调生成不同的随机位置?
问题根源
你遇到的问题核心是随机数种子初始化逻辑错误:
srand((unsigned)time(NULL))被放在了randomPositions()函数内部,每次生成随机数都会重新执行播种操作time(NULL)的精度仅为秒级,同一秒内所有播种操作使用的种子完全相同,后续rand()返回的数值也会完全一致,最终生成的所有随机位置都相同- 若多次启动程序的间隔小于1秒,播种的种子也会一致,每次运行得到的随机序列完全相同
修复方案
方案1:最小改动兼容原有逻辑
仅需要把srand()的调用移动到程序全局初始化阶段,全局仅调用1次即可,不要放在随机数生成函数中重复执行:
- 修改随机数生成函数:
float randomPositions() { return (float)rand() / RAND_MAX; }
- 在
main函数中执行一次播种:
int main() { // GLFW、窗口初始化等前置逻辑 srand((unsigned)time(NULL)); // 全局仅执行一次播种 // 进入渲染循环 }
附加优化建议:你当前的positions数组每次触发按键回调都会重新生成,如果你不需要每次按键都刷新所有随机位置,可以将positions声明为static静态变量或者全局变量,程序启动时仅生成一次即可,减少不必要的重复计算。
另外注意你的pos变量递增时没有判断边界,positions数组只有10个元素,pos超过9会触发数组越界崩溃,可以添加取模逻辑避免:
if (key == GLFW_KEY_E && action == GLFW_PRESS) { pos = (pos + 1) % 10; // 循环取值,避免越界 trans = glm::translate(glm::mat4(1.0f), positions[pos]); }
方案2:推荐方案:使用C++11 库
rand()原生存在分布不均匀、低位随机性差的缺陷,C++标准库的<random>模块可以生成质量更高的随机数,更适合图形学场景使用,实现如下:
#include <random> // 全局初始化一次即可,无需手动管理播种 std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<float> dist(0.0f, 1.0f); float randomPositions() { return dist(gen); }
该方案通过std::random_device从硬件熵源获取随机种子,每次程序运行的随机序列完全独立,生成的0~1区间浮点数分布均匀,没有rand()的固有缺陷。
内容的提问来源于stack exchange,提问作者Nour Jandali
相关产品推荐
相关产品推荐

