当前位置: 首页 > 知识库问答 >
问题:

c cuda opengl不渲染vbo

翟俊
2023-03-14

我试图在屏幕上画一堆点。我使用CUDA生成数据(位置和颜色),并用OpenGL绘制它。我试图让CUDA更新一个VBO,然后用OpenGL来绘制它,但是我得到了一个空白的屏幕。我不确定CUDA是否无法更新缓冲区,或者缓冲区绘制不正确。我的GPU是GTX 1080,我正在尝试使用OpenGL 4.0。颜色也由CUDA指定。如果我的问题是我需要一个着色器,我如何添加它,但仍然通过CUDA指定颜色?

更新:问题似乎是openGL。更新了使用三角形的代码,以便添加新问题。为什么不渲染我的VBO?

下面是代码:

格普曼。cuh:

#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/remove.h>
#include <curand.h>
#include <GL/glew.h>
#include <SDL_opengl.h>
#include <cuda_gl_interop.h>

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

//ver: x, y, z, r, g, b, a
struct ver {

    // x, y, z pos
    GLuint x, y, z;

    // r, g, b, a color
    GLubyte r, g, b, a;

};

class GPU {

public:



    static int nParticles;

    static GLuint vboid;

    static cudaGraphicsResource *CGR;

    //collection of vertices to be simulated and rendered
    static thrust::device_vector<ver> rverts;

    static void init(int w, int h);

    static void compute();

    static void render();

    static void GPUmain();

    static void free();

};

格普曼。铜:

#include "GPUmain.cuh"

__global__ void uploadVerts(ver *vv, ver *vb) {
    int id = threadIdx.x + (blockDim.x * blockIdx.x);
    vb[id] = vv[id];
    vb[id].x = vv[id].x;
    vb[id].y = vv[id].y;
    vb[id].z = vv[id].z;
    vb[id].r = vv[id].r;
    vb[id].g = vv[id].g;
    vb[id].b = vv[id].b;
    vb[id].a = vv[id].a;
}

__global__ void genGrid(ver *v) {
    int i = threadIdx.x + (blockDim.x * blockIdx.x);
    float x = (float)(i % ((int)1080));
    float y = (float)(i / ((int)1920));

    v[i].x = x;
    v[i].y = y;
    v[i].z = 1;

    v[i].r = 255;
    v[i].g = 0;
    v[i].b = 0;
    v[i].a = 0;
}

int GPU::nParticles;

GLuint GPU::vboid;

cudaGraphicsResource *GPU::CGR;

//collection of vertices to be simulated and rendered
thrust::device_vector<ver> GPU::rverts;

void GPU::init(int w, int h)
{   
    nParticles = w * h;
    /*rverts.resize(nParticles, ver{0,0,0,0,0,0,0});
    genGrid<<<nParticles/1024,1024>>>(thrust::raw_pointer_cast(&rverts[0]));*/

    ver e[3] = { 
        ver{1024,200,2,255,0,0,255},
        ver{499,288,173,0,255,0,255},
        ver{462,1674,8,0,0,255,255} 
    };

    glGenBuffers(1,&vboid);
    glBindBuffer(GL_ARRAY_BUFFER,vboid);
    glBufferData(GL_ARRAY_BUFFER,3*sizeof(ver),e,GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    /*cudaGraphicsGLRegisterBuffer(&CGR,vboid,cudaGraphicsMapFlagsWriteDiscard);*/


}

void GPU::compute()
{

}

void GPU::render()
{

/*ver *verts;
size_t size;
cudaGraphicsMapResources(1, &CGR, 0);
cudaGraphicsResourceGetMappedPointer((void**)&verts, &size, CGR);
uploadVerts<<<nParticles/1024, 1024>>>(thrust::raw_pointer_cast(&rverts[0]), verts);
cudaGraphicsUnmapResources(1, &CGR, 0);
cudaDeviceSynchronize();*/

glClearColor(0, 0, 0, 0); // we clear the screen with black (else, frames would overlay...)
glClear(GL_COLOR_BUFFER_BIT); // clear the buffer

glBindBuffer(GL_ARRAY_BUFFER, vboid);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glVertexPointer(3, GL_INT, 4 * sizeof(GLubyte), 0);
glColorPointer(4, GL_BYTE, 3 * sizeof(GLuint), BUFFER_OFFSET(3 * sizeof(GLuint)));

glDrawArrays(GL_TRIANGLES, 0, 3);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void GPU::GPUmain()
{

    compute();

    render();

}

void GPU::free()
{
    cudaGraphicsUnregisterResource(CGR);
    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glDeleteBuffers(1, &vboid);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    rverts.clear();
    thrust::device_vector<ver>().swap(rverts);
}

window.cpp的相关部分(包含OpenGL代码):

bool Window::init()
{
    //initialize SDL
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {

        log << "Failed to initialize SDL!\n";
        return false;

    }

    //set window atributes
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);

    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);


    //creat window
    window = SDL_CreateWindow(
        name.c_str(),
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        width,
        height,
        SDL_WINDOW_OPENGL

    );

    //create opengl context in the window
    glcontext = SDL_GL_CreateContext(window);

    SDL_GL_SetSwapInterval(1);

    //check if the window was created
    if (window == nullptr) {

        log << "Failed to create window!\n";
        return false;

    }

    //turn on experimental features
    glewExperimental = GL_TRUE;

    //initiallize glew
    if (glewInit() != GLEW_OK) {

        log << "Failed to Init GLEW";

        return false;

    }



    //set drawing parameters
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, width, 0, height, 0, 255);
    glPointSize(1);
    glEnable(GL_BLEND);                                // Allow Transparency
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  // how transparency acts

    std::cout << sizeof(ver);

    GPU::init(width, height);

    return true;
}

void Window::renderFrame()
{

    GPU::render();

    SDL_GL_SwapWindow(window); //swap buffers
}

共有1个答案

郎嘉树
2023-03-14

如果您使用固定函数属性和客户端功能,那么您必须使用兼容性配置文件上下文。
请参见固定函数管道和遗留OpenGL。如果你想使用核心配置文件,那么你必须使用顶点数组对象和着色器:

SDL\u GL\u SetAttribute(SDL\u GL\u CONTEXT\u PROFILE\u掩码、SDL\u GL\u CONTEXT\u PROFILE\u核心)

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);

以下几何学

ver e[3] = { 
     //     x    y    z      r    g    b    a       
     ver{1024, 200,   2,   255,   0,   0, 255},
     ver{ 499, 288, 173,     0, 255,   0, 255},
     ver{462,  1674,  8,     0,   0, 255, 255} 
};

被正交投影的近平面剪裁。注意,在视图空间中,z轴指向视口之外
更改正交投影(或反转几何体的z坐标):

glOrtho(0,宽,0,高,0,255);

glOrtho(0, width, 0, height, -255, 0);

glVertexPointer的步长参数分别为glColorPointer连续属性之间的偏移量。所以它必须是sizeof(ver)
颜色属性的类型是GL\u UNSIGNED\u BYTE,而不是GL\u BYTE

glvertexinter(3,GL_INT,4*sizeof(GLubyte),0)
glColorPointer(4,GL_字节,3*sizeof(GLuint),缓冲区偏移量(3*sizeof(GLuint))


  
   glVertexPointer(3, GL_INT, sizeof(ver), 0);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ver), BUFFER_OFFSET(3 * sizeof(GLuint)));

  

 类似资料:
  • 问题内容: 在我的Maven项目中,我创建了一个“ index.xhtml”文件。当我构建并运行该项目时,Web浏览器未显示任何内容。当我查看源代码时,仍然可以看到源代码,而不是普通的html标签。 我尝试通过以下方式创建XHTML文件: 选择项目,右键单击New ..并选择Other ..并选择“ Web”类别,然后选择JSF Page。 选择项目,右键单击New ..,然后选择Other ..

  • 图片

  • 在 Hexo 中,有两个方法可用于渲染文件或字符串,分别是非同步的 hexo.render.render 和同步的 hexo.render.renderSync,这两个方法的使用方式十分类似,因此以下仅以非同步的 hexo.render.render 为例。 渲染字符串 在渲染字符串时,您必须指定 engine,如此一来 Hexo 才知道该使用哪个渲染引擎来渲染。 hexo.render.rend

  • 6.1 渲染模板 一旦你拥有一个模版文件,你可以通过给一个map来给它传递数据。 map是一个变量及赋予的值的集合,模板使用它来得到变量的值,或者对于块标签求值。 它的渲染函数有一个可选的变量键值对map 通过 ctx.Render() 方法来渲染模板,例如: func (r *Render) Serve(ctx *faygo.Context) error { return ctx.Ren

  • 问题内容: 我尝试运行RichFaces4应用,但组件未渲染。例如,当我尝试这个演示:演示时,我得到如下信息: 我的代码与演示中的代码几乎相同。我刚刚添加了表单标签,因为它对此有所抱怨。 问题答案: 这就是Crome开发人员工具告诉我的内容 http://img571.imageshack.us/i/rfnotdefined.jpg (未捕获的ReferenceError:未定义RichFaces

  • 纹理根本不渲染,几何体都是黑色的。 截图:http://i.imgur.com/ypMdQY4.png 代码:http://pastebin.com/SvB8rxxt 我也会链接到我试图渲染的纹理和transformations.py模块,但是我没有被允许放置两个以上链接的声誉。谷歌搜索“现代opengl 02”会给你前者的教程,“转换py”会给你后者。 搜索“纹理材料开始”以查找纹理材料的设置位