add preliminary ray tracing test (ray-sphere placeholder on CPU)

This commit is contained in:
Erwin Coumans
2013-05-25 01:45:43 -07:00
parent a92223890f
commit a3559b3c92
6 changed files with 261 additions and 15 deletions

View File

@@ -18,9 +18,11 @@
#include "GpuRigidBodyDemoInternalData.h"
#include "../gwenUserInterface.h"
#include "Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h"
#include "OpenGLWindow/GLPrimitiveRenderer.h"
void GpuConvexScene::setupScene(const ConstructionInfo& ci)
{
m_primRenderer = ci.m_primRenderer;
int index=0;
createStaticEnvironment(ci);
@@ -30,11 +32,15 @@ void GpuConvexScene::setupScene(const ConstructionInfo& ci)
m_data->m_rigidBodyPipeline->writeAllInstancesToGpu();
float camPos[4]={ci.arraySizeX,ci.arraySizeY/2,ci.arraySizeZ,0};
float camPos[4]={0,0,0,0};//ci.arraySizeX,ci.arraySizeY/2,ci.arraySizeZ,0};
//float camPos[4]={1,12.5,1.5,0};
m_instancingRenderer->setCameraTargetPosition(camPos);
m_instancingRenderer->setCameraDistance(100);
m_instancingRenderer->setCameraDistance(30);
m_instancingRenderer->setCameraYaw(0);
m_instancingRenderer->setCameraPitch(0);
m_instancingRenderer->updateCamera();
char msg[1024];
int numInstances = index;
@@ -174,3 +180,203 @@ void GpuConvexPlaneScene::createStaticEnvironment(const ConstructionInfo& ci)
int pid = m_data->m_rigidBodyPipeline->registerPhysicsInstance(0.f,position,orn,colIndex,index,false);
}
struct GpuRaytraceInternalData
{
GLuint* m_texId;
unsigned char* m_texels;
int textureWidth;
int textureHeight;
};
#include <string.h>
GpuRaytraceScene::GpuRaytraceScene()
{
m_raytraceData = new GpuRaytraceInternalData;
m_raytraceData->m_texId = new GLuint;
m_raytraceData->textureWidth = 1024;
m_raytraceData->textureHeight = 768;
//create new texture
glGenTextures(1, m_raytraceData->m_texId);
GLenum err = glGetError();
assert(err==GL_NO_ERROR);
glBindTexture(GL_TEXTURE_2D, *m_raytraceData->m_texId);
m_raytraceData->m_texels = (unsigned char*)malloc(m_raytraceData->textureWidth*m_raytraceData->textureHeight*3);
memset(m_raytraceData->m_texels,0,m_raytraceData->textureWidth*m_raytraceData->textureHeight*3);
for (int i=0;i<m_raytraceData->textureWidth;i++)
{
for (int y=0;y<m_raytraceData->textureHeight;y++)
{
int color = 0;
if (y<m_raytraceData->textureHeight-1 && (y>0) && (i>0 && i<m_raytraceData->textureWidth-1))
color = 255;
m_raytraceData->m_texels[(i+m_raytraceData->textureWidth*y)*3+0] = color;
m_raytraceData->m_texels[(i+m_raytraceData->textureWidth*y)*3+1] = color;
m_raytraceData->m_texels[(i+m_raytraceData->textureWidth*y)*3+2] = color;
}
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_raytraceData->textureWidth, m_raytraceData->textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, m_raytraceData->m_texels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
err = glGetError();
assert(err==GL_NO_ERROR);
}
GpuRaytraceScene::~GpuRaytraceScene()
{
glDeleteTextures(1,m_raytraceData->m_texId);
delete[] m_raytraceData->m_texels;
delete m_raytraceData;
}
bool sphere_intersect(const b3Vector3& spherePos, b3Scalar radius, const b3Vector3& rayFrom, const b3Vector3& rayTo)
{
// rs = ray.org - sphere.center
const b3Vector3& rs = rayFrom - spherePos;
b3Vector3 rayDir = rayTo-rayFrom;//rayFrom-rayTo;
rayDir.normalize();
float B = b3Dot(rs, rayDir);
float C = b3Dot(rs, rs) - (radius * radius);
float D = B * B - C;
if (D > 0.0)
{
float t = -B - sqrt(D);
if ( (t > 0.0))// && (t < isect.t) )
{
return true;//isect.t = t;
}
}
return false;
}
void GpuRaytraceScene::renderScene()
{
B3_PROFILE("raytrace");
//raytrace into the texels
m_instancingRenderer->updateCamera();
//generate primary rays
float top = 1.f;
float bottom = -1.f;
float nearPlane = 1.f;
float tanFov = (top-bottom)*0.5f / nearPlane;
float fov = 2.0 * atanf (tanFov);
b3Vector3 rayFrom, camTarget;
m_instancingRenderer->getCameraPosition(rayFrom);
m_instancingRenderer->getCameraTargetPosition(camTarget);
b3Vector3 rayForward = camTarget-rayFrom;
rayForward.normalize();
float farPlane = 500.f;
rayForward*= farPlane;
b3Vector3 rightOffset;
b3Vector3 vertical(0.f,1.f,0.f);
b3Vector3 hor;
hor = rayForward.cross(vertical);
hor.normalize();
vertical = hor.cross(rayForward);
vertical.normalize();
float tanfov = tanf(0.5f*fov);
hor *= 2.f * farPlane * tanfov;
vertical *= 2.f * farPlane * tanfov;
b3Vector3 rayToCenter = rayFrom + rayForward;
//should be screenwidth/height
b3Vector3 dHor = hor * 1.f/float(m_raytraceData->textureWidth);
b3Vector3 dVert = vertical * 1.f/float(m_raytraceData->textureHeight);
b3Transform rayFromTrans;
rayFromTrans.setIdentity();
rayFromTrans.setOrigin(rayFrom);
b3Transform rayFromLocal;
b3Transform rayToLocal;
//cast primary rays
m_data->m_np->readbackAllBodiesToCpu();
for (int x=0;x<m_raytraceData->textureWidth;x++)
{
for (int y=0;y<m_raytraceData->textureHeight;y++)
{
b3Vector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
rayTo += x * dHor;
rayTo -= y * dVert;
//if there is a hit, color the pixels
int numBodies = m_data->m_rigidBodyPipeline->getNumBodies();
bool hits = false;
for (int i=0;i<numBodies && !hits;i++)
{
b3Vector3 pos;
b3Quaternion orn;
m_data->m_np->getObjectTransformFromCpu(pos,orn,i);
b3Scalar radius = 1;
hits = sphere_intersect(pos, radius, rayFrom, rayTo);
}
if (hits)
{
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+0] = 255;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+1] = 0;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+2] = 0;
} else
{
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+0] = 0;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+1] = 0;
m_raytraceData->m_texels[(x+m_raytraceData->textureWidth*y)*3+2] = 0;
}
}
}
GLint err;
err = glGetError();
assert(err==GL_NO_ERROR);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, *m_raytraceData->m_texId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_raytraceData->textureWidth, m_raytraceData->textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, m_raytraceData->m_texels);
err = glGetError();
assert(err==GL_NO_ERROR);
b3Assert(m_primRenderer);
float color[4] = {1,1,1,1};
float rect[4] = {0,0,m_raytraceData->textureWidth,m_raytraceData->textureHeight};
float u[2] = {0,1};
float v[2] = {0,1};
int useRGBA = 1;
m_primRenderer->drawTexturedRect(rect[0],rect[1],rect[2],rect[3],color,u[0],v[0],u[1],v[1], useRGBA);
err = glGetError();
assert(err==GL_NO_ERROR);
}

View File

@@ -5,9 +5,12 @@
class GpuConvexScene : public GpuRigidBodyDemo
{
protected:
class GLPrimitiveRenderer* m_primRenderer;
public:
GpuConvexScene(){}
GpuConvexScene() :m_primRenderer(0) {}
virtual ~GpuConvexScene(){}
virtual const char* getName()
{
@@ -72,7 +75,30 @@ public:
virtual int createDynamicsObjects(const ConstructionInfo& ci);
};
class GpuRaytraceScene : public GpuBoxPlaneScene
{
protected:
struct GpuRaytraceInternalData* m_raytraceData;
public:
GpuRaytraceScene();
virtual ~GpuRaytraceScene();
virtual const char* getName()
{
return "GPURaytrace";
}
static GpuDemo* MyCreateFunc()
{
GpuDemo* demo = new GpuRaytraceScene;
return demo;
}
void renderScene();
};
#endif //GPU_CONVEX_SCENE_H