Hello I'm using Nvidia OptiX to create a RayTracer. I used the example Programs "sample0" and "tutorial" to set up a simple tracer.
In my C++ Code i set up Everything with:
this->buffer_height = 512u;
this->buffer_width = 512u;
char path_to_ptx[512];
_context = _context->create();
_context->setRayTypeCount( 1 );
_context->setEntryPointCount( 1 );
_context->setStackSize( 4640 );
_context["radiance_ray_type"]->setUint( 0 );
_context["scene_epsilon"]->setFloat( 1.e-3f );
_context["result_buffer"]->set( _context->createBuffer( RT_BUFFER_OUTPUT, RT_FORMAT_FLOAT4, this->buffer_width, this->buffer_height) );
sprintf( path_to_ptx, "%s/%s", projectPath, "RayTracer_generated_draw_color.cu.ptx" );
_context->setRayGenerationProgram( 0, _context->createProgramFromPTXFile( path_to_ptx, "draw_solid_color" ) );
_context["draw_color"]->setFloat( 0.462f, 0.725f, 0.0f, 1.0f );
_context["eye"]->setFloat( 0.0f, 0.0f, 5.0f );
_context->setMissProgram( 0, _context->createProgramFromPTXFile( path_to_ptx, "miss" ) );
_context["bg_color"]->setFloat( 1.0f, 0.0f, 0.0f, 1.0f );
sprintf( path_to_ptx, "%s/%s", projectPath, "RayTracer_generated_box.cu.ptx" );
Program box_bounds = _context->createProgramFromPTXFile( path_to_ptx, "box_bounds" );
Program box_intersect = _context->createProgramFromPTXFile( path_to_ptx, "box_intersect" );
sprintf( path_to_ptx, "%s/%s", projectPath, "RayTracer_generated_draw_color.cu.ptx" );
// This block must be full there. It is not possible just to create a geometry and not attach a program to it this would lead the program to crash when _context->compile();
Geometry gbox = _context->createGeometry();
gbox->setPrimitiveCount( 1u );
gbox->setBoundingBoxProgram( box_bounds );
gbox->setIntersectionProgram( box_intersect );
gbox["boxmin"]->setFloat( -2.0f, 0.0f, -2.0f );
gbox["boxmax"]->setFloat( 2.0f, 7.0f, 2.0f );
Material box_matl = _context->createMaterial();
Program box_ch = _context->createProgramFromPTXFile( path_to_ptx, "closest_hit_radiance0" );
box_matl->setClosestHitProgram( 0, box_ch );
GeometryInstance geomIns = _context->createGeometryInstance( /* gbox, &box_matl, &box_matl+1 */ );
geomIns->setGeometry( gbox );
geomIns->setMaterialCount( 1u );
geomIns->setMaterial( 0, box_matl );
GeometryGroup geomGrp = _context->createGeometryGroup();
geomGrp->setChildCount( 1u );
geomGrp->setChild( 0, geomIns );
geomGrp->setAcceleration( _context->createAcceleration("NoAccel","NoAccel") );
//_context["target"]->set( geomGrp );
_context->validate();
_context->compile();
_context->launch( 0, buffer_width, buffer_height );
this->imageData = _context["result_buffer"]->getBuffer()->map();
this->vboId = 0;
rtBufferGetGLBOId( _context["result_buffer"]->getBuffer()->get() , &this->vboId );
RTsize buffer_width_tmp, buffer_height_tmp;
rtBufferGetSize2D( _context["result_buffer"]->getBuffer()->get() , &buffer_width_tmp , &buffer_height_tmp );
this->width = static_cast<GLsizei>(buffer_width_tmp);
this->height = static_cast<GLsizei>(buffer_height_tmp);
My .cu program looks like this:
#include <optix.h>
#include <optixu/optixu_math_namespace.h>
#include "commonStructs.h"
using namespace optix;
// Variables of Context
rtDeclareVariable( unsigned int, radiance_ray_type, , );
rtDeclareVariable( float, scene_epsilon, , );
rtDeclareVariable( rtObject, target, , );
rtBuffer<float4, 2> result_buffer;
// Variables of RayGenerationProgram
rtDeclareVariable( float3, eye, , );
rtDeclareVariable( float4, draw_color, , );
// Globals
rtDeclareVariable( PerRayData_radiance, prd_radiance, rtPayload, );
rtDeclareVariable( uint2, launch_index, rtLaunchIndex, );
rtDeclareVariable( uint2, launch_dim, rtLaunchDim, );
rtDeclareVariable( float3, shading_normal, attribute shading_normal, );
RT_PROGRAM void draw_solid_color()
{
float2 d = make_float2(launch_index) / make_float2(launch_dim) * 2.f - 1.f;
float3 U,V,W;
U.x = 1.0; U.y = 0.0; U.z = 0.0;
V.x = 0.0; V.y = 1.0; V.z = 0.0;
W.x = 0.0; W.y = 0.0; W.z = -1.0;
// Calc the ray Direction
float3 ray_origin = eye;
float3 ray_direction = normalize( d.x*U + d.y*V + W );
// shoot the ray
optix::Ray ray(ray_origin, ray_direction, radiance_ray_type, scene_epsilon );
// Add ray Data
PerRayData_radiance prd;
prd.importance = 1.f;
prd.depth = 0;
//rtTrace(target, ray, prd);
//result_buffer[launch_index] = make_float4(prd.result.x, prd.result.y, prd.result.z, prd.result.w);
result_buffer[launch_index] = make_float4( abs(d.x), abs(d.y), 0.0f, 1.0f );
}
//
// Returns solid color for miss rays
//
rtDeclareVariable(float4, bg_color, , );
RT_PROGRAM void miss()
{
prd_radiance.result = bg_color;
}
//
// Returns shading normal as the surface shading result
//
RT_PROGRAM void closest_hit_radiance0()
{
float3 res = normalize(rtTransformNormal(RT_OBJECT_TO_WORLD, shading_normal))*0.5f + 0.5f;
float4 result;
result.x = res.x;
result.y = res.y;
result.z = res.z;
result.w = 1.0f;
prd_radiance.result = result;
}
Like I posted it it works fine and a colored picture is visible, but you may have noticed that //_context["target"]->set( geomGrp ); in the c++ code. If I uncomment that the Program gets an exception in _context->compile();
The Box Program is the same as in all the examples.
Does anyone have an idea about what goes wrong when i want to set the target to the _context.
_context is of type Context like in #include .
Best Regards
Edit: found out more about the exception:
_context->compile();
is a shortcut for
checkError( rtContextCompile( m_context ) );
in optixx_namespace.h the returned result that is checked in checkError is a RT_ERROR_INVALID_VALUE .
Fortunately I could fix the issue by myself. My Problem was I had an old install of CUDA 3.2 and CUDA 5.0 running side by side.