簡體   English   中英

使用CUDA,SFML和OpenGL:紋理拒絕出現在Quad上

[英]Using CUDA, SFML, and OpenGL: Texture Refuses to Appear on Quad

在線使用各種教程/示例/文檔/論壇,我輸入了代碼以允許CUDA操作OpenGL紋理,以便可以將其輸出到屏幕。 我的顯示方法是使用PBO和uchar4數組的分配紋理圖像。 盡管我嘗試修復問題,但紋理不會出現在2D表面上。 我似乎無法確定問題所在。

這些是我迄今為止檢查/完成的所有事情:我創建了一個PBO並使用CUDA注冊它,稱為cudaGraphicsResourceGetMappedPointer,並在GPU函數調用之前和之后取消映射等效,確保為2D_TEXTURE調用glEnable,調用glDisable任何不必要的值,不需要時未綁定的紋理/緩沖區。 我還重置了SFML OpenGL狀態,以防SFML成為原因。 還采用了方形紋理。 我的OpenGL verision和CUDA版本適用於我使用的所有函數調用。

當我檢查cudaErrors和OpenGL錯誤時,程序中似乎沒有任何錯誤。

我不確定這是否與它有關但當我打電話時:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

我的四邊形似乎沒有顯示。

我主要從這個網站上找到靈感。 非常感謝你!

這是我的代碼:

Main.cpp的

#include <GL/glew.h>
#include <windows.h>
#include <GL/GL.h>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/System.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include "GeneralTypedef.h"
#include "OpenGLTest.cuh"


int main()
{
    // create the window
    sf::RenderWindow window(sf::VideoMode(1024, 1024), "OpenGL");
    //window.setVerticalSyncEnabled(true);
    sf::Vector2u windowSize;

    windowSize = sf::Vector2u(window.getSize());

    bool running = true;
    glewInit();
    window.resetGLStates();
    std::printf("OpenGL: %s:", glGetString(GL_VERSION));
    // We will not be using SFML's gl states.

    OpenGLTest* test = new OpenGLTest(window.getSize());

    sf::Time time;

    while (running)
    {
        // handle events
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                // end the program
                running = false;
            }
            else if (event.type == sf::Event::Resized)
            {
                // adjust the viewport when the window is resized
                glViewport(0, 0, event.size.width, event.size.height);
                windowSize = window.getSize();
            }

        }

        // clear the buffers
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        test->createFrame(time.asMicroseconds());
        test->drawFrame();
        window.display();
    }

    // release resources...
    delete test;

    return 0;
}

OpenGLTest.cuh

#ifndef OPENGLTEST_CUH
#define OPENGLTEST_CUH

#include <GL/glew.h>
#include <windows.h>
#include <GL/GL.h>

#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>

#include "GeneralTypedef.h"

class OpenGLTest
{
    public:
        uchar4* image;
        GLuint gltexture;
        GLuint pbo;
        cudaGraphicsResource_t cudaPBO;
        uchar4* d_textureBufferData;

        sf::Vector2u windowSize;

        OpenGLTest(sf::Vector2u windowSize)
        {
            this->windowSize = sf::Vector2u(windowSize);
            this->setupOpenGL();
        };

        ~OpenGLTest()
        {
            delete image;
            image == nullptr;
            cudaFree(d_textureBufferData);
            d_textureBufferData == nullptr;
            glDeleteTextures(1, &gltexture);
        }

        void drawFrame();
        void createFrame(float time);
    private:
        void setupOpenGL();
};
#endif //OPENGLTEST_CUH

OpenGLTest.cu

#include "OpenGLTest.cuh"

__global__ void createGPUTexture(uchar4* d_texture)
{
    uint pixelID = blockIdx.x*blockDim.x + threadIdx.x;
    d_texture[pixelID].x = 0;
    d_texture[pixelID].y = 1;
    d_texture[pixelID].z =  1;
    d_texture[pixelID].w = 0;
}
__global__ void wow(uchar4* pos, unsigned int width, unsigned int height,
    float time)
{
    int index = blockIdx.x * blockDim.x + threadIdx.x;
    unsigned int x = index%width;
    unsigned int y = index / width;

    if (index < width*height) {
        unsigned char r = (x + (int)time) & 0xff;
        unsigned char g = (y + (int)time) & 0xff;
        unsigned char b = ((x + y) + (int)time) & 0xff;

        // Each thread writes one pixel location in the texture (textel)
        pos[index].w = 0;
        pos[index].x = r;
        pos[index].y = g;
        pos[index].z = b;
    }
}
void OpenGLTest::drawFrame()
{
    glColor3f(1.0f,1.0f,1.0f);

    glBindTexture(GL_TEXTURE_2D, gltexture);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, windowSize.x, windowSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0);

    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(0.0f, float(windowSize.y));
    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(float(windowSize.x), float(windowSize.y));
    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(float(windowSize.x), 0.0f);
    glTexCoord2f(0.0f,1.0f);
    glVertex2f(0.0f, 0.0f);
    glEnd();

    glFlush();

    // Release
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    glBindTexture(GL_TEXTURE_2D, 0);

    // Test Triangle
    /*
    glBegin(GL_TRIANGLES);
    glColor3f(0.1, 0.2, 0.3);
    glVertex2f(0, 0);
    glVertex2f(10, 0);
    glVertex2f(0, 100);
    glEnd();
    */
}

void OpenGLTest::createFrame(float time)
{
    cudaGraphicsMapResources(1, &cudaPBO, 0);
    size_t numBytes;
    cudaGraphicsResourceGetMappedPointer((void**)&d_textureBufferData, &numBytes, cudaPBO);

    int totalThreads = windowSize.x * windowSize.y;
    int nBlocks = totalThreads/ 256;

    // Run code here.
    createGPUTexture << <nBlocks,  256>> >(d_textureBufferData);
    //wow << <nBlocks, 256 >> >(d_textureBufferData, windowSize.x, windowSize.y, time);
    // Unmap mapping to PBO so that OpenGL can access.
    cudaGraphicsUnmapResources(1, &cudaPBO, 0);
}

void OpenGLTest::setupOpenGL()
{
    image  = new uchar4[1024*1024];

    glViewport(0, 0, windowSize.x, windowSize.y);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, windowSize.x, windowSize.y, 0.0, -1.0, 1.0);

    glEnable(GL_TEXTURE_2D);
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);

    // Unbind any textures from previous.
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

    // Create new textures.
    glGenTextures(1, &gltexture);
    glBindTexture(GL_TEXTURE_2D, gltexture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    // Create image with same resolution as window.
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, windowSize.x , windowSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);


    // Create pixel buffer boject.
    glGenBuffers(1, &pbo);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
    glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, windowSize.x * windowSize.y * sizeof(uchar4), image, GL_STREAM_COPY);

    cudaGraphicsGLRegisterBuffer(&cudaPBO, pbo, cudaGraphicsMapFlagsNone);

    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
}

一般型

#ifndef GENERALTYPEDEF_CUH
#define GENERALTYPEDEF_CUH
typedef unsigned int uint;

#endif // GENERALTYPEDEF_CUH

在重寫整個代碼並進一步理解之后,我已經找到了原因。 內核函數中uchar4的顏色組件映射為0-255。 w組件是透明的。 因此,它應映射到255以顯示圖像。 我希望這對那些可能遇到同樣問題的人有所幫助。 有些網站的價值也很低。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM