- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
<分区>
首先,我想为我在下面提供的代码量道歉,我不确定,但我可能会违反发布规则。
我正在尝试修改 nvidia 的 cuda 示例 fluidsGL(可以在此处看到示例 https://www.youtube.com/watch?v=jU9wgSu4_zw),这样我就可以加载自定义图像(例如 PNG),然后在其上应用流体解算器,而不是修改随机像素,以类似流体的方式有效地扭曲它。
在尝试了许多不同的实现之后,我发现使用两个 vbo 可能是可能的,一个用于将被发送到流体求解器内核的 float2 粒子,另一个用于颜色,我用来自图像的 RGBA 信息。
虽然我在 glDrawArrays 中遇到了访问冲突,但我仍然没有弄清楚为什么,在早期的尝试中,我尝试使用一个带有名为 vertex_data 的结构的 vbo,它包含一个 float2 和一个 uchar4,通过 glbufferdata 发送它并让内核计算它的 float2 部分,但也发生了访问冲突异常。
如果有人愿意帮助我,我将不胜感激
typedef unsigned char ubyte;
#define DEVICE __device__
#define GLOBAL __global__
#define MAX(a,b) ((a > b) ? a : b)
#define DIM 512
#define DS DIM*DIM
glm::mat4 m_mat;
// CUFFT plan handle
cufftHandle planr2c;
cufftHandle planc2r;
static float2 *vxfield = NULL;
static float2 *vyfield = NULL;
float2 *hvfield = NULL;
float2 *dvfield = NULL;
static int wWidth = MAX(512, DIM);
static int wHeight = MAX(512, DIM);
/*-----CUSTOM STRUCT-----------------------------------------------------*/
struct GLTexture
{
GLuint id;
int width;
int height;
};
vertex_data data[DS];
//c linkage
/*--------------------------------------------------------------------------------------------------------------------------------*/
extern "C" void addForces(float2 *v, int dx, int dy, int spx, int spy, float fx, float fy, int r);
extern "C" void advectVelocity(float2 *v, float *vx, float *vy, int dx, int pdx, int dy, float dt);
extern "C" void diffuseProject(float2 *vx, float2 *vy, int dx, int dy, float dt, float visc);
extern "C" void updateVelocity(float2 *v, float *vx, float *vy, int dx, int pdx, int dy);
extern "C" void advectParticles(GLuint vbo, float2 *v, int dx, int dy, float dt);
/*--------------------------------------------------------------------------------------------------------------------------------*/
GLSLProgram prog;
IOManager m_manager;
GLTexture m_tex;
std::vector<ubyte> in_img;
std::vector<ubyte> out_img;
vertex_data vData[6];
GLuint positionsVBO;
GLuint colorsVBO;
cudaGraphicsResource* positionsVBO_CUDA;
float2 *particles = NULL;
float2 *part_cuda = NULL;
int lastx = 0, lasty = 0;
int clicked = 0;
size_t tPitch = 0;
float myrand(void)
{
return rand() / (float)RAND_MAX;
}
void initParticles(float2 *p, int dx, int dy)
{
int i, j;
for (i = 0; i < dy; i++)
{
for (j = 0; j < dx; j++)
{
p[i*dx + j].x = (j + 0.5f + (myrand() - 0.5f)) / dx;
p[i*dx + j].y = (i + 0.5f + (myrand() - 0.5f)) / dy;
}
}
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
glutDestroyWindow(glutGetWindow());
exit(0);
return;
default:
break;
}
}
void click(int button, int updown, int x, int y)
{
lastx = x;
lasty = y;
clicked = !clicked;
}
void motion(int x, int y)
{
// Convert motion coordinates to domain
float fx = (lastx / (float)wWidth);
float fy = (lasty / (float)wHeight);
int nx = (int)(fx * DIM);
int ny = (int)(fy * DIM);
if (clicked && nx < DIM - FR && nx > FR - 1 && ny < DIM - FR && ny > FR - 1)
{
int ddx = x - lastx;
int ddy = y - lasty;
fx = ddx / (float)wWidth;
fy = ddy / (float)wHeight;
int spy = ny - FR;
int spx = nx - FR;
addForces(dvfield, DIM, DIM, spx, spy, FORCE * DT * fx, FORCE * DT * fy, FR);
lastx = x;
lasty = y;
}
glutPostRedisplay();
}
void cleanup(void)
{
cudaGraphicsUnregisterResource(positionsVBO_CUDA);
unbindTexture();
deleteTexture();
// Free all host and device resources
free(hvfield);
free(particles);
cudaFree(dvfield);
cudaFree(vxfield);
cudaFree(vyfield);
cufftDestroy(planr2c);
cufftDestroy(planc2r);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glDeleteBuffersARB(1, &positionsVBO);
}
void run_simulation(void){
//Execute kernel
advectVelocity(dvfield, (float *)vxfield, (float *)vyfield, DIM, RPADW, DIM, DT);
diffuseProject(vxfield, vyfield, CPADW, DIM, DT, VIS);
updateVelocity(dvfield, (float *)vxfield, (float *)vyfield, DIM, RPADW, DIM);
advectParticles(positionsVBO, dvfield, DIM, DIM, DT);
}
void initShaders(){
prog.compileShaders("vShader.vertex", "fShader.frag");
prog.addAttribute("vertexPos");
prog.addAttribute("vertexColor");
prog.linkShaders();
}
void pre_display()
{
glViewport(0, 0, 512, 512);
glutPostRedisplay();
}
void display()
{
pre_display();
// render points from vertex buffer
glClear(GL_COLOR_BUFFER_BIT);
initShaders();
run_simulation();
prog.use();
//GLint textureUniform = prog.getUniformLocation("mySampler");
//glUniform1i(textureUniform, 0);
//glActiveTexture(GL_TEXTURE0);
GLint pUniform = prog.getUniformLocation("P");
glUniformMatrix4fv(pUniform, 1, GL_FALSE, &m_mat[0][0]);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, positionsVBO);
glPointSize(1);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glEnableVertexAttribArray(0); tried to manually enable the arrays
//glEnableVertexAttribArray(1);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_TRUE, sizeof(float2), 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); //dont need this but access violaton persists without it anyway
glBindBufferARB(GL_ARRAY_BUFFER_ARB, colorsVBO);
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertex_data) ,(void*)(offsetof(vertex_data, col)));
glDrawArrays(GL_POINTS, 0, DS);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
prog.unuse();
glDisable(GL_TEXTURE_2D); //from nvidia's probably linked to the cudaarray_t
// Swap buffers
glutSwapBuffers();
}
void initGL()
{
int foo = 1;
char *bar = "bar";
glutInit(&foo, &bar);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(DIM, DIM);
glutCreateWindow("mate21");
glClearColor(0.0, 0.0, 0.0, 1.0);
glutKeyboardFunc(keyboard);
glutMouseFunc(click);
glutMotionFunc(motion);
glutDisplayFunc(display);
glewInit();
}
void setGLDevice(){
cudaDeviceProp prop;
int dev;
memset(&prop, 0, sizeof(cudaDeviceProp));
prop.major = 1;
prop.minor = 0;
cudaChooseDevice(&dev, &prop);
cudaGLSetGLDevice(dev);
}
void createVBO(){
//reading rgba information from image to out_img
unsigned long width, height;
IOManager::readFileToBuffer("jojo_test.png", in_img);
decodePNG(out_img, width, height, &(in_img[0]), in_img.size());
//data.resize(DS); data used to be a vector, gave up on that
for (int i = 0; i < DS; ++i){
//data[i].pos = particles[i]; edited vertex_data struct for rgba only
data[i].col.x = out_img[i * 4 + 0];
data[i].col.y = out_img[i * 4 + 1];
data[i].col.z = out_img[i * 4 + 2];
data[i].col.w = out_img[i * 4 + 3];
}
glGenBuffers(1, &positionsVBO);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, positionsVBO);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(float2)*DS, particles , GL_DYNAMIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
cudaGraphicsGLRegisterBuffer(&positionsVBO_CUDA, positionsVBO, cudaGraphicsMapFlagsNone);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glGenBuffers(1, &colorsVBO);
glBindBuffer(GL_ARRAY_BUFFER_ARB, colorsVBO);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertex_data)*DS, data, GL_DYNAMIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
int main()
{
setGLDevice();
initGL();
//orthogonal view matrix with glm
m_mat = glm::ortho(0, 1, 1, 0, 0, 1);
hvfield = (float2 *)malloc(sizeof(float2) * DS);
memset(hvfield, 0, sizeof(float2) * DS);
// Allocate and initialize device data
cudaMallocPitch((void **)&dvfield, &tPitch, sizeof(float2)*DIM, DIM);
cudaMemcpy(dvfield, hvfield, sizeof(float2) * DS,
cudaMemcpyHostToDevice);
// Temporary complex velocity field data
cudaMalloc((void **)&vxfield, sizeof(float2) * PDS);
cudaMalloc((void **)&vyfield, sizeof(float2) * PDS);
setupTexture(DIM, DIM);
bindTexture();
// Create particle array
particles = (float2 *)malloc(sizeof(float2) * DS);
memset(particles, 0, sizeof(float2) * DS);
initParticles(particles, DIM, DIM);
// Create CUFFT transform plan configuration
cufftPlan2d(&planr2c, DIM, DIM, CUFFT_R2C);
cufftPlan2d(&planc2r, DIM, DIM, CUFFT_C2R);
cufftSetCompatibilityMode(planr2c, CUFFT_COMPATIBILITY_FFTW_PADDING);
cufftSetCompatibilityMode(planc2r, CUFFT_COMPATIBILITY_FFTW_PADDING);
createVBO();
//cleanup
glutCloseFunc(cleanup);
//Launch rendering loop
glutMainLoop();
}
这是对 float2 粒子有效模拟流体的相关内核
extern "C"
void advectParticles(GLuint vbo, float2 *v, int dx, int dy, float dt)
{
dim3 grid((dx/TILEX)+(!(dx%TILEX)?0:1), (dy/TILEY)+(!(dy%TILEY)?0:1));
dim3 tids(TIDSX, TIDSY);
float2 *p;
cudaGraphicsMapResources(1, &positionsVBO_CUDA, 0);
size_t num_bytes;
cudaGraphicsResourceGetMappedPointer((void **)&p, &num_bytes,positionsVBO_CUDA);
advectParticles_k<<<grid, tids>>>(p, v, dx, dy, dt, TILEY/TIDSY, tPitch);
cudaGraphicsUnmapResources(1, &positionsVBO_CUDA, 0);
}
和 advectParticles_k:
__global__ void
advectParticles_k(float2 *part, float2 *v, int dx, int dy,
float dt, int lb, size_t pitch)
{
int gtidx = blockIdx.x * blockDim.x + threadIdx.x;
int gtidy = blockIdx.y * (lb * blockDim.y) + threadIdx.y * lb;
int p;
// gtidx is the domain location in x for this thread
float2 pterm, vterm;
if (gtidx < dx)
{
for (p = 0; p < lb; p++)
{
// fi is the domain location in y for this thread
int fi = gtidy + p;
if (fi < dy)
{
int fj = fi * dx + gtidx;
pterm = part[fj];
int xvi = ((int)(pterm.x * dx));
int yvi = ((int)(pterm.y * dy));
vterm = *((float2 *)((char *)v + yvi * pitch) + xvi);
pterm.x += dt * vterm.x;
pterm.x = pterm.x - (int)pterm.x;
pterm.x += 1.f;
pterm.x = pterm.x - (int)pterm.x;
pterm.y += dt * vterm.y;
pterm.y = pterm.y - (int)pterm.y;
pterm.y += 1.f;
pterm.y = pterm.y - (int)pterm.y;
part[fj] = pterm;
}
} // If this thread is inside the domain in Y
} // If this thread is inside the domain in X
}
谢谢
在 OpenGL/ES 中,在实现渲染到纹理功能时,您必须小心,不要引起反馈循环(从正在写入的同一纹理中读取像素)。由于显而易见的原因,当您读取和写入纹理的相同像素时,行为是未定义的。但是,如果您正在
正如我们最终都知道的那样,规范是一回事,实现是另一回事。大多数错误是我们自己造成的,但有时情况并非如此。 我相信列出以下内容会很有用: GPU 驱动程序中当前已知的与最新版本的 OpenGL 和 GL
很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。为了帮助澄清这个问题以便可以重新打开它,visit the help center
我正在学习 OpenGL,非常想知道与显卡的交互如何。 我觉得了解它是如何在图形驱动程序中实现的,会让我了解 opengl 的完整内部结构(通过这个我可以知道哪些阶段/因素影响我对 opengl 性能
我正在尝试绘制到大于屏幕尺寸(即 320x480)的渲染缓冲区 (512x512)。 执行 glReadPixels 后,图像看起来是正确的,除非图像的尺寸超过屏幕尺寸——在本例中,超过 320 水平
我正在 Windows 中制作一个 3D 小行星游戏(使用 OpenGL 和 GLUT),您可以在其中穿过一堆障碍物在太空中移动并生存下来。我正在寻找一种方法来针对无聊的 bg 颜色选项设置图像背景。
如果我想要一个包含 100 个 10*10 像素 Sprite 的 Sprite 表,是否可以将它们全部排成一排来制作 1,000*10 像素纹理?还是 GPU 对不那么窄的纹理表现更好?这对性能有什
这个问题在这里已经有了答案: Rendering 2D sprites in a 3D world? (7 个答案) 关闭 6 年前。 我如何概念化让图像始终面对相机。我尝试将三角函数与 arcta
是否可以在 OpenGL 中增加缓冲区? 假设我想使用实例化渲染。每次在世界上生成一个新对象时,我都必须用实例化数据更新缓冲区。 在这种情况下,我有一个 3 个 float 的缓冲区 std::v
有人可以向我解释为什么下面的代码没有绘制任何东西,但如果我使用 GL_LINE_LOOP 它确实形成了一个闭环吗? glBegin(GL_POLYGON); for(int i = 0; i <= N
正如标题所说,OpenGL 中的渲染目标是什么?我对 OpenGL 很陌生,我看到的所有网站都让我很困惑。 它只是一个缓冲区,我在其中放置稍后将用于渲染的东西吗? 如果您能提供一个很好的引用来阅读它,
当使用 OpenGL 1.4 固定功能多纹理时,每个纹理阶段的输出在传递到下一个阶段之前是否都固定在 [0, 1]? spec说(第 153 页): If the value of TEXTURE_E
我比较了 2 个函数 openGL ES 和 openGL gvec4 texelFetchOffset(gsampler2DArray sampler, ivec3 P, int lod, ivec
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
那么当你调用opengl函数时,比如glDraw或者gLBufferData,是否会导致程序线程停止等待GL完成调用呢? 如果不是,那么 GL 如何处理调用像 glDraw 这样的重要函数,然后立即更
我正在尝试实现级联阴影贴图,当我想访问我的视锥体的每个分区的相应深度纹理时,我遇到了一个错误。 更具体地说,当我想选择正确的阴影纹理时会出现我的问题,如果我尝试下面的代码,我会得到一个像 this 中
我想为OpenGL ES和OpenGL(Windows)使用相同的着色器源。为此,我想定义自定义数据类型并仅使用OpenGL ES函数。 一种方法是定义: #define highp #define
我尝试用 6 个位图映射立方体以实现天空盒效果。我的问题是一个纹理映射到立方体的每个面。我已经检查了 gDEBugger,在立方体纹理内存中我只有一个 图像(因为我尝试加载六个图像)。 代码准备纹理:
在 OpenGL 中偏移深度的最佳方法是什么?我目前每个多边形都有索引顶点属性,我将其传递给 OpenGL 中的顶点着色器。我的目标是在深度上偏移多边形,其中最高索引始终位于较低索引的前面。我目前有这
我是一名优秀的程序员,十分优秀!