我參考了 第0個示例 OptixHello 學習Optix的工程配置以及基本框架 的配置程序,該文對于 Optix 的框架介紹的很好,但是按照該文配置遇到了一些問題,我花費了一番功夫自己摸索終于配置好了環境,實作了用Optix計算然后在OpenGL上展示結果的一個簡單的Demo,
我的配置環境為:Win10,GTX1080,驅動版本431.6,Cuda9.0,Optix6.0,VS2015
Cuda我很早就安裝了,很簡單,這里就不做介紹了,
1、下載Optix6.0
地址:https://developer.nvidia.com/designworks/optix/downloads/legacy
GTX1080應該是只能支持到6.0版本,我剛開始下載了6.5版本,然后順利使用Cmake打包、VS編譯,將Optix引擎庫引入VS工程后,運行 optix::Context::create(); 都會報錯 “缺失Optix Library”!!!
查閱檔案后發現可能是驅動的問題:

Optix6.5需要435以上的驅動,我更新了我的驅動后只能到431.6,所以只能下載Optix6.0,Optix6.0需要418以上的驅動,好極了!我的驅動合適 ^_^
至此,optix::Context::create()是可以運行了,
2、設定VS生成ptx
我們可以在.cu檔案中寫 Optix 的 shader 代碼,這個代碼運行在GPU端,需要使用nvcc編譯(cuda),但是編譯完不會保留中間匯編檔案.ptx,而 Optix 需要使用這個 .ptx 檔案生成“光線發生器模塊”,
換句話說,Optix得使用一個.ptx格式的 shader 進行GPU端的計算,那么我們必須在VS中進行相關設定,保留.ptx中間檔案,
兩種方式:
- cuda命令列中設定,加入 --keep ,保留所有的中間結果

- cuda的common屬性配置中設定

然后就可以獲取ptx生成“光線發生器模塊”了
std::string ptxPath(const char* filename) { return std::string("./x64/Release/") + std::string(filename) + ".cu.ptx"; }optix::Program ray_gen_program = context->createProgramFromPTXFile(ptx, "draw_solid_color");
這里除了從ptx檔案生成program,還可以從ptx字串生成program
context->createProgramFromPTXString("……", "draw_solid_color");
3、設定.cu編譯方式
我寫了一個簡單的程式,編譯就報錯,.cu檔案編譯出錯

我想到可能是編譯方式的問題,我最開始設定的混編,因為cuda程式需要混編,

我查了資料,有人說可以混編,可是我覺得可能是混編的問題,所以修改為了只編譯GPU端代碼,但是!!! 我之前寫過cuda混編的代碼,工程中含有cuda混編的代碼,不能直接修改編譯方式,修改了直接報錯,
如果剔除之前cuda的混編代碼還有點麻煩,想了想既然有人說可以混編,那我就不改編譯方式了,結果,,,,,, ,一晚上查了各種資料找不到問題所在,,,,,,
已經晚上11多了,一個師兄還在實驗室,我過去請教了一把,師兄看到我設定的混編,告訴我不能設定為混編,他從一開始就設定的Generate .ptx file(-ptx),但是言語之間仿佛師兄也沒有設定過混編,不知道行不行,我試著改為編譯GPU端-ptx方式,然后剔除了cuda的混編代碼,然后就好了!
驚不驚喜,意不意外!
附上檔案配置路徑:
- 包含目錄

- 庫目錄

- 附加依賴項

代碼:
- draw_color.cu檔案
#include <optix.h>#include <optixu/optixu_math_namespace.h>using namespace optix;rtDeclareVariable(uint2, launch_index, rtLaunchIndex, );rtBuffer<float4, 2> result_buffer;rtDeclareVariable(float3, draw_color, , );RT_PROGRAM void draw_solid_color(){ //result_buffer[launch_index] = make_float4(draw_color, 1.0f); float2 degree = make_float2(launch_index)*3.14 / 180.0f; result_buffer[launch_index] = make_float4(sin(degree.x), cos(degree.y), 0.0, 0.f);}
- OptixFrame.h
#pragma once#include <iostream>#include <sstream>#include <fstream>#include <optix.h>#include <nvrtc.h>#include <optixu/optixpp_namespace.h>#include <sutil.h>#include <GL/glew.h>#include "../Model/Texture.h"class OptixFrame{public: OptixFrame(); ~OptixFrame(); GLuint TransBuffer2Texture(GLfloat*); GLuint getSrcTexId() { return this->srcTexID; }private: int width = 800, height = 800; optix::Context context; optix::Buffer outputBuffer; GLuint srcTexID;private: void setup(); void setColorSpace(); std::string ptxPath(const char* filename) { return std::string("./x64/Release/") + std::string(filename) + ".cu.ptx"; }};
- OptixFrame.cpp
#include "./OptixFrame.h"OptixFrame::OptixFrame(){ try { this->setup(); } catch (const std::exception& e) { std::cerr << "Optix Error: " << e.what() << "\n"; }}OptixFrame::~OptixFrame(){}void OptixFrame::setColorSpace() { GLboolean use_SRGB = GL_FALSE; glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &use_SRGB); if (use_SRGB) { glEnable(GL_FRAMEBUFFER_SRGB_EXT); }}GLuint OptixFrame::TransBuffer2Texture(GLfloat* data) { glGenTextures(1, &this->srcTexID); glBindTexture(GL_TEXTURE_2D, this->srcTexID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->width,this->height, 0, GL_RGBA, GL_FLOAT, data); glGenerateMipmap(GL_TEXTURE_2D); //Parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); return this->srcTexID;}void OptixFrame::setup() { context = optix::Context::create(); context->setRayTypeCount(1); //1種光線(有時可以2種,渲染+陰影) context->setEntryPointCount(1); //申請Buffer this->outputBuffer = context->createBuffer(RT_BUFFER_OUTPUT, RT_FORMAT_FLOAT4, width, height); context["result_buffer"]->set(outputBuffer); //編譯Shader //const char* ptx = sutil::getPtxString("Optix","draw_color.cu"); std::string ptx = this->ptxPath("draw_color"); //從ptx字串中標識 "draw_solid_color"入口函式,并創建并回傳光線發生器模塊 optix::Program ray_gen_program = context->createProgramFromPTXFile(ptx, "draw_solid_color"); context->setRayGenerationProgram(0, ray_gen_program); context["draw_color"]->setFloat(0.8f, 0.7f, 0.0f); context->setPrintEnabled(true); //可以配合tfPrintf()進行shader端列印 context->setPrintBufferSize(4096); //內部檢查有效性 context->validate(); //開啟第0個入口 context->launch(0, width, height); this->setColorSpace(); GLfloat* imageData = https://www.cnblogs.com/chen9510/p/(GLfloat*)outputBuffer->map(0, RT_BUFFER_MAP_READ); this->TransBuffer2Texture(imageData);}
這些代碼生成了OpenGL的texture2D紋理,然后就可以在OpenGL上顯示了,OpenGL上的顯示代碼就不做展示了,
效果圖:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/2091.html
標籤:其他
上一篇:DOS下查看驅動版本號
