2015-06-03 78 views
1

在線使用各種教程/示例/文檔/論壇,我輸入了代碼以允許CUDA操作OpenGL紋理,以便將其輸出到屏幕。我的顯示方法是使用PBO和uchar4數組的分配紋理圖像。儘管我嘗試解決這個問題,但紋理不會出現在2D表面上。我似乎無法找出問題所在。使用CUDA,SFML和OpenGL:紋理拒絕出現在四邊形上

這些都是我檢查了東西/迄今所做:我創建了一個PBO與CUDA註冊它,叫cudaGraphicsResourceGetMappedPointer之前和GPU函數調用後未作圖等同,確信glEnable被調用2D_TEXTURE ,glDisable在不需要時調用任何不必要的值,未綁定的紋理/緩衝區。如果SFML是原因,我還重置了SFML OpenGL狀態。方形紋理也被使用。我的OpenGL版本和CUDA版本適用於我使用的所有函數調用。

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

我不知道,如果這事做吧,但是當我打電話:

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

我四似乎並沒有顯示。

我主要從這個website找到靈感。 非常感謝!

這裏是我的代碼:

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 

回答

3

重寫整個代碼,並瞭解它更多的之後,我想通了的原因。內核函數中uchar4的顏色分量從0-255映射。 w組件是透明的。因此,應將其映射到255以顯示圖像。我希望這對那些可能有同樣問題的人有幫助。有些網站也將此值設置得非常低。

相關問題