updated embree, fixed cmakefiles, still some bugs in the tutorial example
This commit is contained in:
+498
@@ -0,0 +1,498 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2014 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#include "../common/tutorial/tutorial_device.h"
|
||||
#include "../common/tutorial/scene_device.h"
|
||||
|
||||
|
||||
|
||||
//#define FORCE_FIXED_EDGE_TESSELLATION
|
||||
#define FIXED_EDGE_TESSELLATION_VALUE 4
|
||||
|
||||
#define MAX_EDGE_LEVEL 64.0f
|
||||
#define MIN_EDGE_LEVEL 2.0f
|
||||
#define ENABLE_DISPLACEMENTS 0
|
||||
#if ENABLE_DISPLACEMENTS
|
||||
# define LEVEL_FACTOR 256.0f
|
||||
#else
|
||||
# define LEVEL_FACTOR 64.0f
|
||||
#endif
|
||||
|
||||
/* scene data */
|
||||
extern "C" ISPCScene* g_ispc_scene;
|
||||
RTCScene g_scene = NULL;
|
||||
RTCScene g_embree_scene = NULL;
|
||||
RTCScene g_osd_scene = NULL;
|
||||
|
||||
/* render function to use */
|
||||
renderPixelFunc renderPixel;
|
||||
|
||||
/* error reporting function */
|
||||
void error_handler(const RTCError code, const int8* str)
|
||||
{
|
||||
printf("Embree: ");
|
||||
switch (code) {
|
||||
case RTC_UNKNOWN_ERROR : printf("RTC_UNKNOWN_ERROR"); break;
|
||||
case RTC_INVALID_ARGUMENT : printf("RTC_INVALID_ARGUMENT"); break;
|
||||
case RTC_INVALID_OPERATION: printf("RTC_INVALID_OPERATION"); break;
|
||||
case RTC_OUT_OF_MEMORY : printf("RTC_OUT_OF_MEMORY"); break;
|
||||
case RTC_UNSUPPORTED_CPU : printf("RTC_UNSUPPORTED_CPU"); break;
|
||||
default : printf("invalid error code"); break;
|
||||
}
|
||||
if (str) {
|
||||
printf(" (");
|
||||
while (*str) putchar(*str++);
|
||||
printf(")\n");
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
Vec3fa renderPixelEyeLight(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p);
|
||||
|
||||
|
||||
/* called by the C++ code for initialization */
|
||||
extern "C" void device_init (int8* cfg)
|
||||
{
|
||||
/* initialize ray tracing core */
|
||||
rtcInit(cfg);
|
||||
|
||||
/* set error handler */
|
||||
rtcSetErrorFunction(error_handler);
|
||||
|
||||
/* set start render mode */
|
||||
renderPixel = renderPixelStandard;
|
||||
// renderPixel = renderPixelUV;
|
||||
}
|
||||
|
||||
void updateEdgeLevelBuffer( ISPCMesh* mesh, const Vec3fa& cam_pos, size_t startID, size_t endID )
|
||||
{
|
||||
for (size_t f=startID; f<endID; f++)
|
||||
{
|
||||
const int N = 4;
|
||||
for (size_t i=0; i<N; i++) {
|
||||
const int * index = (int *)&mesh->quads[f];
|
||||
const Vec3fa v0 = mesh->positions[index[i]];
|
||||
const Vec3fa v1 = mesh->positions[index[(i+1)%N]];
|
||||
const Vec3fa edge = v1-v0;
|
||||
const Vec3fa P = 0.5f*(v1+v0);
|
||||
const Vec3fa dist = cam_pos - P;
|
||||
mesh->edge_level[f*4+i] = max(min(LEVEL_FACTOR*(0.5f*length(edge)/length(dist)),MAX_EDGE_LEVEL),MIN_EDGE_LEVEL); // FIXME: map mesh subdivlevel buffer
|
||||
assert( mesh->edge_level[f*4+i] >= 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ISPC)
|
||||
task void updateEdgeLevelBufferTask( ISPCMesh* mesh, const Vec3fa& cam_pos )
|
||||
{
|
||||
const size_t size = mesh->numQuads;
|
||||
const size_t startID = ((taskIndex+0)*size)/taskCount;
|
||||
const size_t endID = ((taskIndex+1)*size)/taskCount;
|
||||
updateEdgeLevelBuffer(mesh,cam_pos,startID,endID);
|
||||
}
|
||||
#endif
|
||||
|
||||
void updateEdgeLevels(ISPCScene* scene_in, const Vec3fa& cam_pos)
|
||||
{
|
||||
for (int i=0; i<g_ispc_scene->numMeshes; i++)
|
||||
{
|
||||
ISPCMesh* mesh = g_ispc_scene->meshes[i];
|
||||
if (mesh->numQuads == 0) continue;
|
||||
|
||||
if (mesh->edge_level)
|
||||
{
|
||||
unsigned int geomID = mesh->geomID;
|
||||
#if defined(ISPC)
|
||||
launch[ getNumHWThreads() ] updateEdgeLevelBufferTask(mesh,cam_pos);
|
||||
#else
|
||||
updateEdgeLevelBuffer(mesh,cam_pos,0,mesh->numQuads);
|
||||
#endif
|
||||
rtcUpdateBuffer(g_scene,geomID,RTC_LEVEL_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t g=0; g<scene_in->numSubdivMeshes; g++)
|
||||
{
|
||||
ISPCSubdivMesh* mesh = g_ispc_scene->subdiv[g];
|
||||
unsigned int geomID = mesh->geomID;
|
||||
for (size_t f=0, e=0; f<mesh->numFaces; e+=mesh->verticesPerFace[f++]) {
|
||||
int N = mesh->verticesPerFace[f];
|
||||
for (size_t i=0; i<N; i++) {
|
||||
const Vec3fa v0 = mesh->positions[mesh->position_indices[e+(i+0)]];
|
||||
const Vec3fa v1 = mesh->positions[mesh->position_indices[e+(i+1)%N]];
|
||||
const Vec3fa edge = v1-v0;
|
||||
const Vec3fa P = 0.5f*(v1+v0);
|
||||
const Vec3fa dist = cam_pos - P;
|
||||
mesh->subdivlevel[e+i] = max(min(LEVEL_FACTOR*(0.5f*length(edge)/length(dist)),MAX_EDGE_LEVEL),MIN_EDGE_LEVEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void displacementFunction(void* ptr, unsigned int geomID, int unsigned primID,
|
||||
const float* u, /*!< u coordinates (source) */
|
||||
const float* v, /*!< v coordinates (source) */
|
||||
const float* nx, /*!< x coordinates of normal at point to displace (source) */
|
||||
const float* ny, /*!< y coordinates of normal at point to displace (source) */
|
||||
const float* nz, /*!< z coordinates of normal at point to displace (source) */
|
||||
float* px, /*!< x coordinates of points to displace (source and target) */
|
||||
float* py, /*!< y coordinates of points to displace (source and target) */
|
||||
float* pz, /*!< z coordinates of points to displace (source and target) */
|
||||
size_t N)
|
||||
{
|
||||
#if 0
|
||||
for (size_t i = 0; i<N; i++) {
|
||||
const Vec3fa dP = 0.02f*Vec3fa(sin(100.0f*px[i]+0.5f),sin(100.0f*pz[i]+1.5f),cos(100.0f*py[i]));
|
||||
px[i] += dP.x; py[i] += dP.y; pz[i] += dP.z;
|
||||
}
|
||||
#else
|
||||
for (size_t i = 0; i<N; i++) {
|
||||
const Vec3fa P = Vec3fa(px[i],py[i],pz[i]);
|
||||
const Vec3fa nor = Vec3fa(nx[i],ny[i],nz[i]);
|
||||
float dN = 0.0f;
|
||||
for (float freq = 1.0f; freq<40.0f; freq*= 2) {
|
||||
float n = abs(noise(freq*P));
|
||||
dN += 1.4f*n*n/freq;
|
||||
}
|
||||
const Vec3fa dP = dN*nor;
|
||||
px[i] += dP.x; py[i] += dP.y; pz[i] += dP.z;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void convertScene(ISPCScene* scene_in, const Vec3fa& p)
|
||||
{
|
||||
/* add all meshes to the scene */
|
||||
for (int i=0; i<scene_in->numMeshes; i++)
|
||||
{
|
||||
/* get ith mesh */
|
||||
ISPCMesh* mesh = scene_in->meshes[i];
|
||||
|
||||
if (mesh->numQuads)
|
||||
{
|
||||
mesh->edge_level = new float[mesh->numQuads*4];
|
||||
for (size_t i=0; i<4*mesh->numQuads; i++)
|
||||
mesh->edge_level[i] = FIXED_EDGE_TESSELLATION_VALUE;
|
||||
|
||||
/* create a triangle mesh */
|
||||
unsigned int geomID = rtcNewSubdivisionMesh (g_scene, RTC_GEOMETRY_STATIC, mesh->numQuads, mesh->numQuads*4, mesh->numVertices, 0, 0, 0);
|
||||
mesh->geomID = geomID;
|
||||
|
||||
unsigned int* faces = (unsigned int*) rtcMapBuffer(g_scene, geomID, RTC_FACE_BUFFER);
|
||||
for (size_t i=0; i<mesh->numQuads; i++) faces[i] = 4;
|
||||
rtcUnmapBuffer(g_scene,geomID,RTC_FACE_BUFFER);
|
||||
|
||||
rtcSetBuffer(g_scene, geomID, RTC_VERTEX_BUFFER, mesh->positions , 0, sizeof(Vec3fa ));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_INDEX_BUFFER, mesh->quads , 0, sizeof(unsigned int));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_LEVEL_BUFFER, mesh->edge_level, 0, sizeof(float));
|
||||
|
||||
#if ENABLE_DISPLACEMENTS == 1
|
||||
rtcSetDisplacementFunction(g_scene,geomID,(RTCDisplacementFunc)&displacementFunction,NULL);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
mesh->edge_level = NULL;
|
||||
}
|
||||
|
||||
/* add all subdiv meshes to the scene */
|
||||
for (size_t i=0; i<scene_in->numSubdivMeshes; i++)
|
||||
{
|
||||
ISPCSubdivMesh* mesh = scene_in->subdiv[i];
|
||||
unsigned int geomID = rtcNewSubdivisionMesh(g_scene, RTC_GEOMETRY_STATIC, mesh->numFaces, mesh->numEdges, mesh->numVertices,
|
||||
mesh->numEdgeCreases, mesh->numVertexCreases, mesh->numHoles);
|
||||
mesh->geomID = geomID;
|
||||
|
||||
rtcSetBuffer(g_scene, geomID, RTC_VERTEX_BUFFER, mesh->positions, 0, sizeof(Vec3fa ));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_LEVEL_BUFFER, mesh->subdivlevel, 0, sizeof(float));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_INDEX_BUFFER, mesh->position_indices , 0, sizeof(unsigned int));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_FACE_BUFFER, mesh->verticesPerFace, 0, sizeof(unsigned int));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_HOLE_BUFFER, mesh->holes, 0, sizeof(unsigned int));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_EDGE_CREASE_INDEX_BUFFER, mesh->edge_creases, 0, 2*sizeof(unsigned int));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_EDGE_CREASE_WEIGHT_BUFFER, mesh->edge_crease_weights, 0, sizeof(float));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_VERTEX_CREASE_INDEX_BUFFER, mesh->vertex_creases, 0, sizeof(unsigned int));
|
||||
rtcSetBuffer(g_scene, geomID, RTC_VERTEX_CREASE_WEIGHT_BUFFER, mesh->vertex_crease_weights, 0, sizeof(float));
|
||||
|
||||
#if ENABLE_DISPLACEMENTS == 1
|
||||
//BBox3fa bounds(Vec3fa(-0.1f,-0.1f,-0.1f),Vec3fa(0.1f,0.1f,0.1f));
|
||||
rtcSetDisplacementFunction(g_scene, geomID, (RTCDisplacementFunc)&displacementFunction,NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__USE_OPENSUBDIV__)
|
||||
|
||||
#include <opensubdiv/far/topologyRefinerFactory.h>
|
||||
using namespace OpenSubdiv;
|
||||
|
||||
struct OSDVertex {
|
||||
|
||||
// Minimal required interface ----------------------
|
||||
OSDVertex() { }
|
||||
|
||||
OSDVertex(OSDVertex const & src) {
|
||||
_position[0] = src._position[0];
|
||||
_position[1] = src._position[1];
|
||||
_position[1] = src._position[1];
|
||||
}
|
||||
|
||||
void Clear( void * =0 ) {
|
||||
_position[0]=_position[1]=_position[2]=0.0f;
|
||||
}
|
||||
|
||||
void AddWithWeight(OSDVertex const & src, float weight) {
|
||||
_position[0]+=weight*src._position[0];
|
||||
_position[1]+=weight*src._position[1];
|
||||
_position[2]+=weight*src._position[2];
|
||||
}
|
||||
|
||||
void AddVaryingWithWeight(OSDVertex const &, float) { }
|
||||
|
||||
// Public interface ------------------------------------
|
||||
void SetPosition(float x, float y, float z) {
|
||||
_position[0]=x;
|
||||
_position[1]=y;
|
||||
_position[2]=z;
|
||||
}
|
||||
|
||||
const float * GetPosition() const {
|
||||
return _position;
|
||||
}
|
||||
|
||||
private:
|
||||
float _position[3];
|
||||
};
|
||||
|
||||
RTCScene constructSceneOpenSubdiv()
|
||||
{
|
||||
if (!g_ispc_scene) return NULL;
|
||||
|
||||
typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor;
|
||||
|
||||
Sdc::Options options;
|
||||
options.SetVVarBoundaryInterpolation(Sdc::Options::VVAR_BOUNDARY_EDGE_ONLY);
|
||||
options.SetCreasingMethod(Sdc::Options::CREASE_CHAIKIN);
|
||||
|
||||
RTCScene scene = rtcNewScene(RTC_SCENE_STATIC, RTC_INTERSECT1);
|
||||
|
||||
for (size_t i=0; i<g_ispc_scene->numSubdivMeshes; i++)
|
||||
{
|
||||
ISPCSubdivMesh* mesh = g_ispc_scene->subdiv[i];
|
||||
|
||||
Descriptor desc;
|
||||
desc.numVertices = mesh->numVertices;
|
||||
desc.numFaces = mesh->numFaces;
|
||||
desc.vertsPerFace = mesh->verticesPerFace;
|
||||
desc.vertIndices = mesh->position_indices;
|
||||
desc.numCreases = mesh->numEdgeCreases;
|
||||
desc.creaseVertexIndexPairs = (int*) mesh->edge_creases;
|
||||
desc.creaseWeights = mesh->edge_crease_weights;
|
||||
desc.numCorners = mesh->numVertexCreases;
|
||||
desc.cornerVertexIndices = mesh->vertex_creases;
|
||||
desc.cornerWeights = mesh->vertex_crease_weights;
|
||||
|
||||
size_t maxlevel = 5;
|
||||
Far::TopologyRefiner* refiner = Far::TopologyRefinerFactory<Descriptor>::Create(OpenSubdiv::Sdc::TYPE_CATMARK, options, desc);
|
||||
refiner->RefineUniform(maxlevel);
|
||||
|
||||
std::vector<OSDVertex> vbuffer(refiner->GetNumVerticesTotal());
|
||||
OSDVertex* verts = &vbuffer[0];
|
||||
|
||||
for (int i=0; i<mesh->numVertices; ++i)
|
||||
verts[i].SetPosition(mesh->positions[i].x,mesh->positions[i].y,mesh->positions[i].z);
|
||||
|
||||
refiner->Interpolate(verts, verts + mesh->numVertices);
|
||||
|
||||
for (int level=0; level<maxlevel; ++level)
|
||||
verts += refiner->GetNumVertices(level);
|
||||
|
||||
const size_t numVertices = refiner->GetNumVertices(maxlevel);
|
||||
const size_t numFaces = refiner->GetNumFaces(maxlevel);
|
||||
|
||||
unsigned int meshID = rtcNewTriangleMesh(scene, RTC_GEOMETRY_STATIC, 2*numFaces, numVertices);
|
||||
rtcSetBuffer(scene, meshID, RTC_VERTEX_BUFFER, verts, 0, sizeof(Vec3fa));
|
||||
|
||||
Vec3i* tris = (Vec3i*) rtcMapBuffer(scene, meshID, RTC_INDEX_BUFFER);
|
||||
for (size_t i=0; i<numFaces; i++) {
|
||||
Far::IndexArray fverts = refiner->GetFaceVertices(maxlevel, i);
|
||||
assert(fverts.size() == 4);
|
||||
tris[2*i+0] = Vec3i(fverts[0],fverts[1],fverts[2]);
|
||||
tris[2*i+1] = Vec3i(fverts[2],fverts[3],fverts[0]);
|
||||
}
|
||||
rtcUnmapBuffer(scene,meshID,RTC_INDEX_BUFFER);
|
||||
}
|
||||
rtcCommit(scene);
|
||||
return scene;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Vec3fa rndColor(const int ID)
|
||||
{
|
||||
int r = ((ID+13)*17*23) & 255;
|
||||
int g = ((ID+15)*11*13) & 255;
|
||||
int b = ((ID+17)* 7*19) & 255;
|
||||
const float oneOver255f = 1.f/255.f;
|
||||
return Vec3fa(r*oneOver255f,g*oneOver255f,b*oneOver255f);
|
||||
}
|
||||
|
||||
|
||||
/* task that renders a single screen tile */
|
||||
Vec3fa renderPixelStandard(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p)
|
||||
{
|
||||
/* initialize ray */
|
||||
RTCRay ray;
|
||||
ray.org = p;
|
||||
ray.dir = normalize(x*vx + y*vy + vz);
|
||||
ray.tnear = 0.0f;
|
||||
ray.tfar = inf;
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
ray.primID = RTC_INVALID_GEOMETRY_ID;
|
||||
ray.mask = -1;
|
||||
ray.time = 0;
|
||||
|
||||
/* intersect ray with scene */
|
||||
rtcIntersect(g_scene,ray);
|
||||
|
||||
/* shade background black */
|
||||
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(0.0f,0.0f,1.0f);
|
||||
|
||||
/* shade all rays that hit something */
|
||||
Vec3fa color = Vec3fa(1.0f);
|
||||
#if 0
|
||||
color = rndColor(ray.geomID);
|
||||
#else
|
||||
/* apply ambient light */
|
||||
Vec3fa Ng = normalize(ray.Ng);
|
||||
color = color*abs(dot(ray.dir,Ng));
|
||||
#endif
|
||||
return color;
|
||||
}
|
||||
|
||||
/* task that renders a single screen tile */
|
||||
void renderTile(int taskIndex, int* pixels,
|
||||
const int width,
|
||||
const int height,
|
||||
const float time,
|
||||
const Vec3fa& vx,
|
||||
const Vec3fa& vy,
|
||||
const Vec3fa& vz,
|
||||
const Vec3fa& p,
|
||||
const int numTilesX,
|
||||
const int numTilesY)
|
||||
{
|
||||
const int tileY = taskIndex / numTilesX;
|
||||
const int tileX = taskIndex - tileY * numTilesX;
|
||||
const int x0 = tileX * TILE_SIZE_X;
|
||||
const int x1 = min(x0+TILE_SIZE_X,width);
|
||||
const int y0 = tileY * TILE_SIZE_Y;
|
||||
const int y1 = min(y0+TILE_SIZE_Y,height);
|
||||
|
||||
for (int y = y0; y<y1; y++) for (int x = x0; x<x1; x++)
|
||||
{
|
||||
/* calculate pixel color */
|
||||
Vec3fa color = renderPixel(x,y,vx,vy,vz,p);
|
||||
|
||||
/* write color to framebuffer */
|
||||
unsigned int r = (unsigned int) (255.0f * clamp(color.x,0.0f,1.0f));
|
||||
unsigned int g = (unsigned int) (255.0f * clamp(color.y,0.0f,1.0f));
|
||||
unsigned int b = (unsigned int) (255.0f * clamp(color.z,0.0f,1.0f));
|
||||
pixels[y*width+x] = (b << 16) + (g << 8) + r;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PARALLEL_COMMIT)
|
||||
task void parallelCommit(RTCScene scene) {
|
||||
rtcCommitThread (scene,threadIndex,threadCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" void toggleOpenSubdiv(int key, int x, int y)
|
||||
{
|
||||
#if defined(__USE_OPENSUBDIV__)
|
||||
if (g_osd_scene == NULL) {
|
||||
g_osd_scene = constructSceneOpenSubdiv();
|
||||
g_embree_scene = g_scene;
|
||||
}
|
||||
if (g_scene == g_embree_scene) g_scene = g_osd_scene;
|
||||
else g_scene = g_embree_scene;
|
||||
#endif
|
||||
}
|
||||
|
||||
Vec3fa old_p;
|
||||
|
||||
/* called by the C++ code to render */
|
||||
extern "C" void device_render (int* pixels,
|
||||
const int width,
|
||||
const int height,
|
||||
const float time,
|
||||
const Vec3fa& vx,
|
||||
const Vec3fa& vy,
|
||||
const Vec3fa& vz,
|
||||
const Vec3fa& p)
|
||||
{
|
||||
Vec3fa cam_org = Vec3fa(p.x,p.y,p.z);
|
||||
|
||||
/* create scene */
|
||||
if (g_scene == NULL)
|
||||
{
|
||||
g_scene = rtcNewScene(RTC_SCENE_DYNAMIC,RTC_INTERSECT1);
|
||||
convertScene(g_ispc_scene,cam_org);
|
||||
|
||||
#if !defined(FORCE_FIXED_EDGE_TESSELLATION)
|
||||
updateEdgeLevels(g_ispc_scene, cam_org);
|
||||
#endif
|
||||
|
||||
old_p = p;
|
||||
|
||||
#if !defined(PARALLEL_COMMIT)
|
||||
rtcCommit (g_scene);
|
||||
#else
|
||||
launch[ getNumHWThreads() ] parallelCommit(g_scene);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(FORCE_FIXED_EDGE_TESSELLATION)
|
||||
{
|
||||
if ((p.x != old_p.x | p.y != old_p.y | p.z != old_p.z))
|
||||
{
|
||||
old_p = p;
|
||||
|
||||
updateEdgeLevels(g_ispc_scene, cam_org);
|
||||
|
||||
#if !defined(PARALLEL_COMMIT)
|
||||
rtcCommit (g_scene);
|
||||
#else
|
||||
launch[ getNumHWThreads() ] parallelCommit(g_scene);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* render image */
|
||||
const int numTilesX = (width +TILE_SIZE_X-1)/TILE_SIZE_X;
|
||||
const int numTilesY = (height+TILE_SIZE_Y-1)/TILE_SIZE_Y;
|
||||
launch_renderTile(numTilesX*numTilesY,pixels,width,height,time,vx,vy,vz,p,numTilesX,numTilesY);
|
||||
|
||||
rtcDebug();
|
||||
}
|
||||
|
||||
/* called by the C++ code for cleanup */
|
||||
extern "C" void device_cleanup ()
|
||||
{
|
||||
rtcDeleteScene (g_scene);
|
||||
rtcExit();
|
||||
}
|
||||
Reference in New Issue
Block a user