Add the GPU rigid body pipeline from https://github.com/erwincoumans/experiments as a Bullet 3.x preview for Bullet 2.80

This commit is contained in:
erwin.coumans
2012-03-05 00:54:32 +00:00
parent 73c4646b40
commit 571af41cf6
257 changed files with 55106 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
hasCL = findOpenCL_AMD()
if (hasCL) then
project "OpenCL_gpu_rigidbody_pipeline2_AMD"
initOpenCL_AMD()
language "C++"
kind "ConsoleApp"
targetdir "../../../bin"
initOpenGL()
initGlew()
includedirs {
"../../primitives",
"../../../../../src"
}
files {
"../main.cpp",
"../CLPhysicsDemo.cpp",
"../CLPhysicsDemo.h",
"../GLInstancingRenderer.cpp",
"../GLInstancingRenderer.h",
"../GlutRenderer.cpp",
"../GlutRenderer.h",
"../Win32OpenGLRenderManager.cpp",
"../Win32OpenGLRenderManager.h",
"../../gpu_rigidbody_pipeline/btConvexUtility.cpp",
"../../gpu_rigidbody_pipeline/btConvexUtility.h",
"../../gpu_rigidbody_pipeline/btGpuNarrowPhaseAndSolver.cpp",
"../../gpu_rigidbody_pipeline/btGpuNarrowPhaseAndSolver.h",
"../../../dynamics/basic_demo/ConvexHeightFieldShape.cpp",
"../../../dynamics/basic_demo/ConvexHeightFieldShape.h",
"../../../../../src/LinearMath/btConvexHullComputer.cpp",
"../../../../../src/LinearMath/btConvexHullComputer.h",
"../../broadphase_benchmark/findPairsOpenCL.cpp",
"../../broadphase_benchmark/findPairsOpenCL.h",
"../../broadphase_benchmark/btGridBroadphaseCL.cpp",
"../../broadphase_benchmark/btGridBroadphaseCL.h",
"../../3dGridBroadphase/Shared/bt3dGridBroadphaseOCL.cpp",
"../../3dGridBroadphase/Shared/bt3dGridBroadphaseOCL.h",
"../../3dGridBroadphase/Shared/btGpu3DGridBroadphase.cpp",
"../../3dGridBroadphase/Shared/btGpu3DGridBroadphase.h",
"../../../../../src/LinearMath/btAlignedAllocator.cpp",
"../../../../../src/LinearMath/btQuickprof.cpp",
"../../../../../src/LinearMath/btQuickprof.h",
"../../../../../src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp",
"../../../../../src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp",
"../../../../../src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp",
"../../basic_initialize/btOpenCLUtils.cpp",
"../../basic_initialize/btOpenCLUtils.h",
"../../opengl_interop/btOpenCLGLInteropBuffer.cpp",
"../../opengl_interop/btOpenCLGLInteropBuffer.h",
"../../opengl_interop/btStopwatch.cpp",
"../../opengl_interop/btStopwatch.h"
}
end

View File

@@ -0,0 +1,529 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#include "OpenGLInclude.h"
#include "CLPhysicsDemo.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "DemoSettings.h"
#include "../basic_initialize/btOpenCLUtils.h"
#include "../opengl_interop/btOpenCLGLInteropBuffer.h"
#include "../broadphase_benchmark/findPairsOpenCL.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btQuaternion.h"
#include "LinearMath/btMatrix3x3.h"
#include "../../opencl/gpu_rigidbody_pipeline/btGpuNarrowPhaseAndSolver.h"
#include "../../opencl/gpu_rigidbody_pipeline/btConvexUtility.h"
#include "../../dynamics/basic_demo/ConvexHeightFieldShape.h"
#include "../broadphase_benchmark/btGridBroadphaseCl.h"
#include "LinearMath/btQuickprof.h"
#define MSTRINGIFY(A) #A
static char* interopKernelString =
#include "../broadphase_benchmark/integrateKernel.cl"
#define INTEROPKERNEL_SRC_PATH "../../opencl/broadphase_benchmark/integrateKernel.cl"
cl_kernel g_integrateTransformsKernel;
bool runOpenCLKernels = true;
btGpuNarrowphaseAndSolver* narrowphaseAndSolver = 0;
ConvexHeightField* s_convexHeightField = 0 ;
btOpenCLGLInteropBuffer* g_interopBuffer = 0;
extern GLuint cube_vbo;
extern int VBOsize;
cl_mem clBuffer=0;
char* hostPtr=0;
cl_bool blocking= CL_TRUE;
btFindPairsIO gFpIO;
cl_context g_cxMainContext;
cl_command_queue g_cqCommandQue;
cl_device_id g_device;
cl_mem gLinVelMem=0;
cl_mem gAngVelMem=0;
cl_mem gBodyTimes=0;
#include <Adl/Adl.h>
adl::DeviceCL* g_deviceCL=0;
struct btAABBHost //keep this in sync with btAABBCL!
{
float fx;
float fy;
float fz;
unsigned int uw;
};
struct InternalData
{
adl::Buffer<btVector3>* m_linVelBuf;
adl::Buffer<btVector3>* m_angVelBuf;
adl::Buffer<float>* m_bodyTimes;
bool m_useInterop;
btGridBroadphaseCl* m_Broadphase;
adl::Buffer<btAABBHost>* m_localShapeAABB;
btVector3* m_linVelHost;
btVector3* m_angVelHost;
float* m_bodyTimesHost;
InternalData():m_linVelBuf(0),m_angVelBuf(0),m_bodyTimes(0),m_useInterop(0),m_Broadphase(0)
{
m_linVelHost= new btVector3[MAX_CONVEX_BODIES_CL];
m_angVelHost = new btVector3[MAX_CONVEX_BODIES_CL];
m_bodyTimesHost = new float[MAX_CONVEX_BODIES_CL];
}
~InternalData()
{
delete[] m_linVelHost;
delete[] m_angVelHost;
delete[] m_bodyTimesHost;
}
};
void InitCL(int preferredDeviceIndex, int preferredPlatformIndex, bool useInterop)
{
void* glCtx=0;
void* glDC = 0;
#ifdef _WIN32
glCtx = wglGetCurrentContext();
#else //!_WIN32
GLXContext glCtx = glXGetCurrentContext();
#endif //!_WIN32
glDC = wglGetCurrentDC();
int ciErrNum = 0;
#ifdef CL_PLATFORM_INTEL
cl_device_type deviceType = CL_DEVICE_TYPE_ALL;
#else
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
#endif
if (useInterop)
{
g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC);
} else
{
g_cxMainContext = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0,0,preferredDeviceIndex, preferredPlatformIndex);
}
oclCHECKERROR(ciErrNum, CL_SUCCESS);
int numDev = btOpenCLUtils::getNumDevices(g_cxMainContext);
if (numDev>0)
{
g_device= btOpenCLUtils::getDevice(g_cxMainContext,0);
btOpenCLDeviceInfo clInfo;
btOpenCLUtils::getDeviceInfo(g_device,clInfo);
btOpenCLUtils::printDeviceInfo(g_device);
g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_device, 0, &ciErrNum);
oclCHECKERROR(ciErrNum, CL_SUCCESS);
}
}
CLPhysicsDemo::CLPhysicsDemo(Win32OpenGLWindow* renderer)
{
m_numCollisionShapes=0;
m_numPhysicsInstances=0;
m_data = new InternalData;
}
CLPhysicsDemo::~CLPhysicsDemo()
{
}
void CLPhysicsDemo::writeBodiesToGpu()
{
if (narrowphaseAndSolver)
narrowphaseAndSolver->writeAllBodiesToGpu();
}
int CLPhysicsDemo::registerCollisionShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling)
{
btAlignedObjectArray<btVector3> verts;
unsigned char* vts = (unsigned char*) vertices;
for (int i=0;i<numVertices;i++)
{
float* vertex = (float*) &vts[i*strideInBytes];
verts.push_back(btVector3(vertex[0]*scaling[0],vertex[1]*scaling[1],vertex[2]*scaling[2]));
}
btConvexUtility util;
bool merge = true;
util.initializePolyhedralFeatures(verts,merge);
int numFaces= util.m_faces.size();
float4* eqn = new float4[numFaces];
for (int i=0;i<numFaces;i++)
{
eqn[i].x = util.m_faces[i].m_plane[0];
eqn[i].y = util.m_faces[i].m_plane[1];
eqn[i].z = util.m_faces[i].m_plane[2];
eqn[i].w = util.m_faces[i].m_plane[3];
}
printf("numFaces = %d\n", numFaces);
s_convexHeightField = new ConvexHeightField(eqn,numFaces);
int shapeIndex=-1;
if (narrowphaseAndSolver)
shapeIndex = narrowphaseAndSolver->registerShape(s_convexHeightField);
if (shapeIndex>=0)
{
btAABBHost aabbMin, aabbMax;
aabbMin.fx = s_convexHeightField->m_aabb.m_min.x;
aabbMin.fy = s_convexHeightField->m_aabb.m_min.y;
aabbMin.fz= s_convexHeightField->m_aabb.m_min.z;
aabbMin.uw = shapeIndex;
aabbMax.fx = s_convexHeightField->m_aabb.m_max.x;
aabbMax.fy = s_convexHeightField->m_aabb.m_max.y;
aabbMax.fz= s_convexHeightField->m_aabb.m_max.z;
aabbMax.uw = shapeIndex;
m_data->m_localShapeAABB->write(&aabbMin,1,shapeIndex*2);
m_data->m_localShapeAABB->write(&aabbMax,1,shapeIndex*2+1);
adl::DeviceUtils::waitForCompletion( g_deviceCL );
}
m_numCollisionShapes++;
delete[] eqn;
return shapeIndex;
}
int CLPhysicsDemo::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, void* userPointer)
{
btVector3 aabbMin(position[0],position[0],position[0]);
btVector3 aabbMax = aabbMin;
aabbMin -= btVector3(1.f,1.f,1.f);
aabbMax += btVector3(1.f,1.f,1.f);
if (collisionShapeIndex>=0)
{
btBroadphaseProxy* proxy = m_data->m_Broadphase->createProxy(aabbMin,aabbMax,collisionShapeIndex,userPointer,1,1,0,0);//m_dispatcher);
}
bool writeToGpu = false;
int bodyIndex = -1;
if (narrowphaseAndSolver)
bodyIndex = narrowphaseAndSolver->registerRigidBody(collisionShapeIndex,mass,position,orientation,writeToGpu);
m_numPhysicsInstances++;
return bodyIndex;
}
void CLPhysicsDemo::init(int preferredDevice, int preferredPlatform, bool useInterop)
{
InitCL(-1,-1,useInterop);
#define CUSTOM_CL_INITIALIZATION
#ifdef CUSTOM_CL_INITIALIZATION
g_deviceCL = new adl::DeviceCL();
g_deviceCL->m_deviceIdx = g_device;
g_deviceCL->m_context = g_cxMainContext;
g_deviceCL->m_commandQueue = g_cqCommandQue;
g_deviceCL->m_kernelManager = new adl::KernelManager;
#else
DeviceUtils::Config cfg;
cfg.m_type = DeviceUtils::Config::DEVICE_CPU;
g_deviceCL = DeviceUtils::allocate( TYPE_CL, cfg );
#endif
//adl::Solver<adl::TYPE_CL>::allocate(g_deviceCL->allocate(
m_data->m_linVelBuf = new adl::Buffer<btVector3>(g_deviceCL,MAX_CONVEX_BODIES_CL);
m_data->m_angVelBuf = new adl::Buffer<btVector3>(g_deviceCL,MAX_CONVEX_BODIES_CL);
m_data->m_bodyTimes = new adl::Buffer<float>(g_deviceCL,MAX_CONVEX_BODIES_CL);
m_data->m_localShapeAABB = new adl::Buffer<btAABBHost>(g_deviceCL,MAX_CONVEX_SHAPES_CL);
gLinVelMem = (cl_mem)m_data->m_linVelBuf->m_ptr;
gAngVelMem = (cl_mem)m_data->m_angVelBuf->m_ptr;
gBodyTimes = (cl_mem)m_data->m_bodyTimes->m_ptr;
narrowphaseAndSolver = new btGpuNarrowphaseAndSolver(g_deviceCL);
int maxObjects = btMax(256,MAX_CONVEX_BODIES_CL);
int maxPairsSmallProxy = 32;
btOverlappingPairCache* overlappingPairCache=0;
m_data->m_Broadphase = new btGridBroadphaseCl(overlappingPairCache,btVector3(4.f, 4.f, 4.f), 128, 128, 128,maxObjects, maxObjects, maxPairsSmallProxy, 100.f, 128,
g_cxMainContext ,g_device,g_cqCommandQue, g_deviceCL);
cl_program prog = btOpenCLUtils::compileCLProgramFromString(g_cxMainContext,g_device,interopKernelString,0,"",INTEROPKERNEL_SRC_PATH);
g_integrateTransformsKernel = btOpenCLUtils::compileCLKernelFromString(g_cxMainContext, g_device,interopKernelString, "integrateTransformsKernel" ,0,prog);
initFindPairs(gFpIO, g_cxMainContext, g_device, g_cqCommandQue, MAX_CONVEX_BODIES_CL);
}
void CLPhysicsDemo::writeVelocitiesToGpu()
{
m_data->m_linVelBuf->write(m_data->m_linVelHost,MAX_CONVEX_BODIES_CL);
m_data->m_angVelBuf->write(m_data->m_angVelHost,MAX_CONVEX_BODIES_CL);
m_data->m_bodyTimes->write(m_data->m_bodyTimesHost,MAX_CONVEX_BODIES_CL);
adl::DeviceUtils::waitForCompletion( g_deviceCL );
}
void CLPhysicsDemo::setupInterop()
{
m_data->m_useInterop = true;
g_interopBuffer = new btOpenCLGLInteropBuffer(g_cxMainContext,g_cqCommandQue,cube_vbo);
clFinish(g_cqCommandQue);
}
void CLPhysicsDemo::cleanup()
{
delete narrowphaseAndSolver;
delete m_data->m_linVelBuf;
delete m_data->m_angVelBuf;
delete m_data->m_bodyTimes;
delete m_data->m_localShapeAABB;
delete m_data->m_Broadphase;
delete m_data;
delete g_deviceCL->m_kernelManager;
delete g_deviceCL;
m_data=0;
g_deviceCL=0;
delete g_interopBuffer;
delete s_convexHeightField;
}
void CLPhysicsDemo::stepSimulation()
{
BT_PROFILE("simulationLoop");
{
BT_PROFILE("glFinish");
glFinish();
}
cl_int ciErrNum = CL_SUCCESS;
if(m_data->m_useInterop)
{
clBuffer = g_interopBuffer->getCLBUffer();
BT_PROFILE("clEnqueueAcquireGLObjects");
ciErrNum = clEnqueueAcquireGLObjects(g_cqCommandQue, 1, &clBuffer, 0, 0, NULL);
adl::DeviceUtils::waitForCompletion( g_deviceCL );
} else
{
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
glFlush();
BT_PROFILE("glMapBuffer and clEnqueueWriteBuffer");
blocking= CL_TRUE;
hostPtr= (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);//GL_WRITE_ONLY
if (!clBuffer)
{
clBuffer = clCreateBuffer(g_cxMainContext, CL_MEM_READ_WRITE, VBOsize, 0, &ciErrNum);
}
adl::DeviceUtils::waitForCompletion( g_deviceCL );
oclCHECKERROR(ciErrNum, CL_SUCCESS);
ciErrNum = clEnqueueWriteBuffer ( g_cqCommandQue,
clBuffer,
blocking,
0,
VBOsize,
hostPtr,0,0,0
);
adl::DeviceUtils::waitForCompletion( g_deviceCL );
}
oclCHECKERROR(ciErrNum, CL_SUCCESS);
if (runOpenCLKernels && m_numPhysicsInstances)
{
gFpIO.m_numObjects = m_numPhysicsInstances;
gFpIO.m_positionOffset = SHAPE_VERTEX_BUFFER_SIZE/4;
gFpIO.m_clObjectsBuffer = clBuffer;
gFpIO.m_dAABB = m_data->m_Broadphase->m_dAABB;
gFpIO.m_dlocalShapeAABB = (cl_mem)m_data->m_localShapeAABB->m_ptr;
gFpIO.m_numOverlap = 0;
{
BT_PROFILE("setupGpuAabbs");
setupGpuAabbsFull(gFpIO,narrowphaseAndSolver->getBodiesGpu() );
}
if (1)
{
BT_PROFILE("calculateOverlappingPairs");
m_data->m_Broadphase->calculateOverlappingPairs(0, m_numPhysicsInstances);
gFpIO.m_dAllOverlappingPairs = m_data->m_Broadphase->m_dAllOverlappingPairs;
gFpIO.m_numOverlap = m_data->m_Broadphase->m_numPrefixSum;
}
//printf("gFpIO.m_numOverlap = %d\n",gFpIO.m_numOverlap );
if (gFpIO.m_numOverlap>=0 && gFpIO.m_numOverlap<MAX_BROADPHASE_COLLISION_CL)
{
colorPairsOpenCL(gFpIO);
if (1)
{
{
//BT_PROFILE("setupBodies");
if (narrowphaseAndSolver)
setupBodies(gFpIO, gLinVelMem, gAngVelMem, narrowphaseAndSolver->getBodiesGpu(), narrowphaseAndSolver->getBodyInertiasGpu());
}
if (gFpIO.m_numOverlap)
{
BT_PROFILE("computeContactsAndSolver");
if (narrowphaseAndSolver)
narrowphaseAndSolver->computeContactsAndSolver(gFpIO.m_dAllOverlappingPairs,gFpIO.m_numOverlap);
}
{
BT_PROFILE("copyBodyVelocities");
if (narrowphaseAndSolver)
copyBodyVelocities(gFpIO, gLinVelMem, gAngVelMem, narrowphaseAndSolver->getBodiesGpu(), narrowphaseAndSolver->getBodyInertiasGpu());
}
}
} else
{
printf("error, gFpIO.m_numOverlap = %d\n",gFpIO.m_numOverlap);
btAssert(0);
}
{
BT_PROFILE("integrateTransforms");
if (runOpenCLKernels)
{
int numObjects = m_numPhysicsInstances;
int offset = SHAPE_VERTEX_BUFFER_SIZE/4;
ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 0, sizeof(int), &offset);
ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 1, sizeof(int), &numObjects);
ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 2, sizeof(cl_mem), (void*)&clBuffer );
ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 3, sizeof(cl_mem), (void*)&gLinVelMem);
ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 4, sizeof(cl_mem), (void*)&gAngVelMem);
ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 5, sizeof(cl_mem), (void*)&gBodyTimes);
size_t workGroupSize = 64;
size_t numWorkItems = workGroupSize*((m_numPhysicsInstances + (workGroupSize)) / workGroupSize);
if (workGroupSize>numWorkItems)
workGroupSize=numWorkItems;
ciErrNum = clEnqueueNDRangeKernel(g_cqCommandQue, g_integrateTransformsKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0);
oclCHECKERROR(ciErrNum, CL_SUCCESS);
}
}
}
if(m_data->m_useInterop)
{
BT_PROFILE("clEnqueueReleaseGLObjects");
ciErrNum = clEnqueueReleaseGLObjects(g_cqCommandQue, 1, &clBuffer, 0, 0, 0);
adl::DeviceUtils::waitForCompletion( g_deviceCL );
}
else
{
BT_PROFILE("clEnqueueReadBuffer clReleaseMemObject and glUnmapBuffer");
ciErrNum = clEnqueueReadBuffer ( g_cqCommandQue,
clBuffer,
blocking,
0,
VBOsize,
hostPtr,0,0,0);
//clReleaseMemObject(clBuffer);
adl::DeviceUtils::waitForCompletion( g_deviceCL );
glUnmapBuffer( GL_ARRAY_BUFFER);
glFlush();
}
oclCHECKERROR(ciErrNum, CL_SUCCESS);
if (runOpenCLKernels)
{
BT_PROFILE("clFinish");
clFinish(g_cqCommandQue);
}
}

View File

@@ -0,0 +1,53 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#ifndef CL_PHYSICS_DEMO_H
#define CL_PHYSICS_DEMO_H
class Win32OpenGLWindow;
struct CLPhysicsDemo
{
Win32OpenGLWindow* m_renderer;
int m_numCollisionShapes;
int m_numPhysicsInstances;
struct InternalData* m_data;
CLPhysicsDemo(Win32OpenGLWindow* renderer);
virtual ~CLPhysicsDemo();
//btOpenCLGLInteropBuffer* m_interopBuffer;
void init(int preferredDevice, int preferredPlatform, bool useInterop);
void setupInterop();
int registerCollisionShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling);
int registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, void* userPointer);
void writeVelocitiesToGpu();
void writeBodiesToGpu();
void cleanup();
void stepSimulation();
};
#endif//CL_PHYSICS_DEMO_H

View File

@@ -0,0 +1,24 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#ifndef DEMO_SETTINGS_H
#define DEMO_SETTINGS_H
#define SHAPE_VERTEX_BUFFER_SIZE 1024*1024
#define SHAPE_BUFFER_SIZE (SHAPE_VERTEX_BUFFER_SIZE)
#endif //DEMO_SETTINGS_H

View File

@@ -0,0 +1,861 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#include "OpenGLInclude.h"
#include "GLInstancingRenderer.h"
#include <string.h>
#include "DemoSettings.h"
#include <stdio.h>
#include <assert.h>
#include "LinearMath/btVector3.h"
#include "LinearMath/btQuaternion.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btMatrix3x3.h"
#include "../../opencl/gpu_rigidbody_pipeline/btGpuNarrowphaseAndSolver.h"//for MAX_CONVEX_BODIES_CL
struct btGraphicsInstance
{
GLuint m_cube_vao;
GLuint m_index_vbo;
int m_numIndices;
int m_numVertices;
int m_numGraphicsInstances;
int m_instanceOffset;
int m_vertexArrayOffset;
btGraphicsInstance() :m_cube_vao(-1),m_index_vbo(-1),m_numIndices(-1),m_numVertices(-1),m_numGraphicsInstances(0),m_instanceOffset(0),m_vertexArrayOffset(0)
{
}
};
bool m_ortho = false;
int m_glutScreenWidth = 1024;
int m_glutScreenHeight = 768;
extern int gShapeIndex;
btVector3 m_cameraPosition(0,0,0);//will be overridden by a position computed from azi/ele
btVector3 m_cameraTargetPosition(30,-5,-20);
btScalar m_cameraDistance = 95;
btVector3 m_cameraUp(0,1,0);
float m_azi=95.f;
float m_ele=15.f;
int VBOsize =0;
struct InternalDataRenderer
{
GLfloat* m_instance_positions_ptr;
GLfloat* m_instance_quaternion_ptr;
GLfloat* m_instance_colors_ptr;
GLfloat* m_instance_scale_ptr;
InternalDataRenderer() :m_instance_positions_ptr (0),m_instance_quaternion_ptr(0),m_instance_colors_ptr(0),m_instance_scale_ptr(0)
{
}
};
static GLuint instancingShader; // The instancing renderer
GLuint cube_vbo;
static GLuint m_texturehandle;
static bool done = false;
static GLint angle_loc = 0;
static GLint ModelViewMatrix;
static GLint ProjectionMatrix;
GLInstancingRenderer::GLInstancingRenderer()
{
m_data = new InternalDataRenderer;
m_data->m_instance_positions_ptr = (GLfloat*)new float[MAX_CONVEX_BODIES_CL*4];
m_data->m_instance_quaternion_ptr = (GLfloat*)new float[MAX_CONVEX_BODIES_CL*4];
m_data->m_instance_colors_ptr = (GLfloat*)new float[MAX_CONVEX_BODIES_CL*4];
m_data->m_instance_scale_ptr = (GLfloat*)new float[MAX_CONVEX_BODIES_CL*3];
}
GLInstancingRenderer::~GLInstancingRenderer()
{
delete m_data;
}
static GLint uniform_texture_diffuse = 0;
//used for dynamic loading from disk (default switched off)
#define MAX_SHADER_LENGTH 8192
static GLubyte shaderText[MAX_SHADER_LENGTH];
static const char* vertexShader= \
"#version 330\n"
"precision highp float;\n"
"\n"
"\n"
"\n"
"layout (location = 0) in vec4 position;\n"
"layout (location = 1) in vec4 instance_position;\n"
"layout (location = 2) in vec4 instance_quaternion;\n"
"layout (location = 3) in vec2 uvcoords;\n"
"layout (location = 4) in vec3 vertexnormal;\n"
"layout (location = 5) in vec4 instance_color;\n"
"layout (location = 6) in vec3 instance_scale;\n"
"\n"
"\n"
"uniform float angle = 0.0;\n"
"uniform mat4 ModelViewMatrix;\n"
"uniform mat4 ProjectionMatrix;\n"
"\n"
"out Fragment\n"
"{\n"
" vec4 color;\n"
"} fragment;\n"
"\n"
"out Vert\n"
"{\n"
" vec2 texcoord;\n"
"} vert;\n"
"\n"
"\n"
"vec4 quatMul ( in vec4 q1, in vec4 q2 )\n"
"{\n"
" vec3 im = q1.w * q2.xyz + q1.xyz * q2.w + cross ( q1.xyz, q2.xyz );\n"
" vec4 dt = q1 * q2;\n"
" float re = dot ( dt, vec4 ( -1.0, -1.0, -1.0, 1.0 ) );\n"
" return vec4 ( im, re );\n"
"}\n"
"\n"
"vec4 quatFromAxisAngle(vec4 axis, in float angle)\n"
"{\n"
" float cah = cos(angle*0.5);\n"
" float sah = sin(angle*0.5);\n"
" float d = inversesqrt(dot(axis,axis));\n"
" vec4 q = vec4(axis.x*sah*d,axis.y*sah*d,axis.z*sah*d,cah);\n"
" return q;\n"
"}\n"
"//\n"
"// vector rotation via quaternion\n"
"//\n"
"vec4 quatRotate3 ( in vec3 p, in vec4 q )\n"
"{\n"
" vec4 temp = quatMul ( q, vec4 ( p, 0.0 ) );\n"
" return quatMul ( temp, vec4 ( -q.x, -q.y, -q.z, q.w ) );\n"
"}\n"
"vec4 quatRotate ( in vec4 p, in vec4 q )\n"
"{\n"
" vec4 temp = quatMul ( q, p );\n"
" return quatMul ( temp, vec4 ( -q.x, -q.y, -q.z, q.w ) );\n"
"}\n"
"\n"
"out vec3 lightDir,normal,ambient;\n"
"\n"
"void main(void)\n"
"{\n"
" vec4 q = instance_quaternion;\n"
" ambient = vec3(0.3,.3,0.3);\n"
" \n"
" \n"
" vec4 local_normal = (quatRotate3( vertexnormal,q));\n"
" vec3 light_pos = vec3(-0.8,1,-0.6);\n"
" normal = local_normal.xyz;\n"//normalize(ModelViewMatrix * local_normal).xyz;\n"
"\n"
" lightDir = normalize(light_pos);//gl_LightSource[0].position.xyz));\n"
"// lightDir = normalize(vec3(gl_LightSource[0].position));\n"
" \n"
" vec4 axis = vec4(1,1,1,0);\n"
" vec4 localcoord = quatRotate3( position.xyz*instance_scale,q);\n"
" vec4 vertexPos = ProjectionMatrix * ModelViewMatrix *(instance_position+localcoord);\n"
"\n"
" gl_Position = vertexPos;\n"
" \n"
" fragment.color = instance_color;\n"
" vert.texcoord = uvcoords;\n"
"}\n"
;
static const char* fragmentShader= \
"#version 330\n"
"precision highp float;\n"
"\n"
"in Fragment\n"
"{\n"
" vec4 color;\n"
"} fragment;\n"
"\n"
"in Vert\n"
"{\n"
" vec2 texcoord;\n"
"} vert;\n"
"\n"
"uniform sampler2D Diffuse;\n"
"\n"
"in vec3 lightDir,normal,ambient;\n"
"\n"
"out vec4 color;\n"
"\n"
"void main_textured(void)\n"
"{\n"
" color = texture2D(Diffuse,vert.texcoord);//fragment.color;\n"
"}\n"
"\n"
"void main(void)\n"
"{\n"
" vec4 texel = fragment.color*texture2D(Diffuse,vert.texcoord);//fragment.color;\n"
" vec3 ct,cf;\n"
" float intensity,at,af;\n"
" intensity = max(dot(lightDir,normalize(normal)),.2);\n"
" cf = intensity*vec3(1.0,1.0,1.0)+ambient;"
" af = 1.0;\n"
" \n"
" ct = texel.rgb;\n"
" at = texel.a;\n"
" \n"
" color = vec4(ct * cf, at * af); \n"
"}\n"
;
// Load the shader from the source text
void gltLoadShaderSrc(const char *szShaderSrc, GLuint shader)
{
GLchar *fsStringPtr[1];
fsStringPtr[0] = (GLchar *)szShaderSrc;
glShaderSource(shader, 1, (const GLchar **)fsStringPtr, NULL);
}
GLuint gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg)
{
// Temporary Shader objects
GLuint hVertexShader;
GLuint hFragmentShader;
GLuint hReturn = 0;
GLint testVal;
// Create shader objects
hVertexShader = glCreateShader(GL_VERTEX_SHADER);
hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
gltLoadShaderSrc(vertexShader, hVertexShader);
gltLoadShaderSrc(fragmentShader, hFragmentShader);
// Compile them
glCompileShader(hVertexShader);
glCompileShader(hFragmentShader);
// Check for errors
glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal);
if(testVal == GL_FALSE)
{
char temp[256] = "";
glGetShaderInfoLog( hVertexShader, 256, NULL, temp);
fprintf( stderr, "Compile failed:\n%s\n", temp);
assert(0);
exit(0);
glDeleteShader(hVertexShader);
glDeleteShader(hFragmentShader);
return (GLuint)NULL;
}
glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal);
if(testVal == GL_FALSE)
{
char temp[256] = "";
glGetShaderInfoLog( hFragmentShader, 256, NULL, temp);
fprintf( stderr, "Compile failed:\n%s\n", temp);
assert(0);
exit(0);
glDeleteShader(hVertexShader);
glDeleteShader(hFragmentShader);
return (GLuint)NULL;
}
// Link them - assuming it works...
hReturn = glCreateProgram();
glAttachShader(hReturn, hVertexShader);
glAttachShader(hReturn, hFragmentShader);
glLinkProgram(hReturn);
// These are no longer needed
glDeleteShader(hVertexShader);
glDeleteShader(hFragmentShader);
// Make sure link worked too
glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal);
if(testVal == GL_FALSE)
{
glDeleteProgram(hReturn);
return (GLuint)NULL;
}
return hReturn;
}
void GLInstancingRenderer::writeTransforms()
{
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
glFlush();
char* orgBase = (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);
int totalNumInstances= 0;
for (int k=0;k<m_graphicsInstances.size();k++)
{
btGraphicsInstance* gfxObj = m_graphicsInstances[k];
totalNumInstances+=gfxObj->m_numGraphicsInstances;
}
for (int k=0;k<m_graphicsInstances.size();k++)
{
//int k=0;
btGraphicsInstance* gfxObj = m_graphicsInstances[k];
int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int ORIENTATION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int COLOR_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3);
char* base = orgBase;
float* positions = (float*)(base+SHAPE_BUFFER_SIZE);
float* orientations = (float*)(base+SHAPE_BUFFER_SIZE + POSITION_BUFFER_SIZE);
float* colors= (float*)(base+SHAPE_BUFFER_SIZE + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE);
float* scaling= (float*)(base+SHAPE_BUFFER_SIZE + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE);
static int offset=0;
//offset++;
for (int i=0;i<gfxObj->m_numGraphicsInstances;i++)
{
int srcIndex=i+gfxObj->m_instanceOffset;
positions[srcIndex*4] = m_data->m_instance_positions_ptr[srcIndex*4];
positions[srcIndex*4+1] = m_data->m_instance_positions_ptr[srcIndex*4+1];
positions[srcIndex*4+2] = m_data->m_instance_positions_ptr[srcIndex*4+2];
positions[srcIndex*4+3] = m_data->m_instance_positions_ptr[srcIndex*4+3];
orientations[srcIndex*4]=m_data->m_instance_quaternion_ptr[srcIndex*4];
orientations[srcIndex*4+1]=m_data->m_instance_quaternion_ptr[srcIndex*4+1];
orientations[srcIndex*4+2]=m_data->m_instance_quaternion_ptr[srcIndex*4+2];
orientations[srcIndex*4+3]=m_data->m_instance_quaternion_ptr[srcIndex*4+3];
colors[srcIndex*4]=m_data->m_instance_colors_ptr[srcIndex*4];
colors[srcIndex*4+1]=m_data->m_instance_colors_ptr[srcIndex*4+1];
colors[srcIndex*4+2]=m_data->m_instance_colors_ptr[srcIndex*4+2];
colors[srcIndex*4+3]=m_data->m_instance_colors_ptr[srcIndex*4+3];
scaling[srcIndex*3]=m_data->m_instance_scale_ptr[srcIndex*3];
scaling[srcIndex*3+1]=m_data->m_instance_scale_ptr[srcIndex*3+1];
scaling[srcIndex*3+2]=m_data->m_instance_scale_ptr[srcIndex*3+2];
}
}
glUnmapBuffer( GL_ARRAY_BUFFER);
//if this glFinish is removed, the animation is not always working/blocks
//@todo: figure out why
glFlush();
}
int GLInstancingRenderer::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)
{
btGraphicsInstance* gfxObj = m_graphicsInstances[shapeIndex];
int index = gfxObj->m_numGraphicsInstances + gfxObj->m_instanceOffset;
m_data->m_instance_positions_ptr[index*4]=position[0];
m_data->m_instance_positions_ptr[index*4+1]=position[1];
m_data->m_instance_positions_ptr[index*4+2]=position[2];
m_data->m_instance_positions_ptr[index*4+3]=1;
m_data->m_instance_quaternion_ptr[index*4]=quaternion[0];
m_data->m_instance_quaternion_ptr[index*4+1]=quaternion[1];
m_data->m_instance_quaternion_ptr[index*4+2]=quaternion[2];
m_data->m_instance_quaternion_ptr[index*4+3]=quaternion[3];
m_data->m_instance_colors_ptr[index*4]=color[0];
m_data->m_instance_colors_ptr[index*4+1]=color[1];
m_data->m_instance_colors_ptr[index*4+2]=color[2];
m_data->m_instance_colors_ptr[index*4+3]=color[3];
m_data->m_instance_scale_ptr[index*3] = scaling[0];
m_data->m_instance_scale_ptr[index*3+1] = scaling[1];
m_data->m_instance_scale_ptr[index*3+2] = scaling[2];
gfxObj->m_numGraphicsInstances++;
return gfxObj->m_numGraphicsInstances;
}
int GLInstancingRenderer::registerShape(const float* vertices, int numvertices, const int* indices, int numIndices)
{
btGraphicsInstance* gfxObj = new btGraphicsInstance;
if (m_graphicsInstances.size())
{
btGraphicsInstance* prevObj = m_graphicsInstances[m_graphicsInstances.size()-1];
gfxObj->m_instanceOffset = prevObj->m_instanceOffset + prevObj->m_numGraphicsInstances;
gfxObj->m_vertexArrayOffset = prevObj->m_vertexArrayOffset + prevObj->m_numVertices;
} else
{
gfxObj->m_instanceOffset = 0;
}
m_graphicsInstances.push_back(gfxObj);
gfxObj->m_numIndices = numIndices;
gfxObj->m_numVertices = numvertices;
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
char* dest= (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_WRITE_ONLY);//GL_WRITE_ONLY
int vertexStrideInBytes = 9*sizeof(float);
int sz = numvertices*vertexStrideInBytes;
memcpy(dest+vertexStrideInBytes*gfxObj->m_vertexArrayOffset,vertices,sz);
glUnmapBuffer( GL_ARRAY_BUFFER);
glGenBuffers(1, &gfxObj->m_index_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gfxObj->m_index_vbo);
int indexBufferSizeInBytes = gfxObj->m_numIndices*sizeof(int);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSizeInBytes, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,indexBufferSizeInBytes,indices);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glGenVertexArrays(1, &gfxObj->m_cube_vao);
glBindVertexArray(gfxObj->m_cube_vao);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
return m_graphicsInstances.size()-1;
}
void GLInstancingRenderer::InitShaders()
{
int POSITION_BUFFER_SIZE = (MAX_CONVEX_BODIES_CL*sizeof(float)*4);
int ORIENTATION_BUFFER_SIZE = (MAX_CONVEX_BODIES_CL*sizeof(float)*4);
int COLOR_BUFFER_SIZE = (MAX_CONVEX_BODIES_CL*sizeof(float)*4);
int SCALE_BUFFER_SIZE = (MAX_CONVEX_BODIES_CL*sizeof(float)*3);
instancingShader = gltLoadShaderPair(vertexShader,fragmentShader);
glLinkProgram(instancingShader);
glUseProgram(instancingShader);
angle_loc = glGetUniformLocation(instancingShader, "angle");
ModelViewMatrix = glGetUniformLocation(instancingShader, "ModelViewMatrix");
ProjectionMatrix = glGetUniformLocation(instancingShader, "ProjectionMatrix");
uniform_texture_diffuse = glGetUniformLocation(instancingShader, "Diffuse");
GLuint offset = 0;
glGenBuffers(1, &cube_vbo);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
int size = SHAPE_BUFFER_SIZE + POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE+SCALE_BUFFER_SIZE;
VBOsize = size;
glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);//GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void myinit()
{
GLint err = glGetError();
// GLfloat light_ambient[] = { btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0) };
GLfloat light_ambient[] = { btScalar(1.0), btScalar(1.2), btScalar(0.2), btScalar(1.0) };
GLfloat light_diffuse[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0) };
GLfloat light_specular[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0 )};
/* light_position is NOT default value */
GLfloat light_position0[] = { btScalar(10000.0), btScalar(10000.0), btScalar(10000.0), btScalar(0.0 )};
GLfloat light_position1[] = { btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0) };
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
// glShadeModel(GL_FLAT);//GL_SMOOTH);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearColor(float(0.7),float(0.7),float(0.7),float(0));
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
static bool m_textureenabled = true;
static bool m_textureinitialized = false;
if(m_textureenabled)
{
if(!m_textureinitialized)
{
glActiveTexture(GL_TEXTURE0);
GLubyte* image=new GLubyte[256*256*3];
for(int y=0;y<256;++y)
{
const int t=y>>5;
GLubyte* pi=image+y*256*3;
for(int x=0;x<256;++x)
{
if (x<2||y<2||x>253||y>253)
{
pi[0]=0;
pi[1]=0;
pi[2]=0;
} else
{
pi[0]=255;
pi[1]=255;
pi[2]=255;
}
/*
const int s=x>>5;
const GLubyte b=180;
GLubyte c=b+((s+t&1)&1)*(255-b);
pi[0]=c;
pi[1]=c;
pi[2]=c;
*/
pi+=3;
}
}
glGenTextures(1,(GLuint*)&m_texturehandle);
glBindTexture(GL_TEXTURE_2D,m_texturehandle);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,256,256,GL_RGB,GL_UNSIGNED_BYTE,image);
delete[] image;
m_textureinitialized=true;
}
// glMatrixMode(GL_TEXTURE);
// glLoadIdentity();
// glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,m_texturehandle);
} else
{
glDisable(GL_TEXTURE_2D);
}
glEnable(GL_COLOR_MATERIAL);
err = glGetError();
assert(err==GL_NO_ERROR);
// glEnable(GL_CULL_FACE);
// glCullFace(GL_BACK);
}
void updateCamera()
{
btVector3 m_cameraUp(0,1,0);
int m_forwardAxis=2;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//m_azi+=0.0f;
btScalar rele = m_ele * btScalar(0.01745329251994329547);// rads per deg
btScalar razi = m_azi * btScalar(0.01745329251994329547);// rads per deg
btQuaternion rot(m_cameraUp,razi);
btVector3 eyePos(0,0,0);
eyePos[m_forwardAxis] = -m_cameraDistance;
btVector3 forward(eyePos[0],eyePos[1],eyePos[2]);
if (forward.length2() < SIMD_EPSILON)
{
forward.setValue(1.f,0.f,0.f);
}
btVector3 right = m_cameraUp.cross(forward);
btQuaternion roll(right,-rele);
eyePos = btMatrix3x3(rot) * btMatrix3x3(roll) * eyePos;
m_cameraPosition[0] = eyePos.getX();
m_cameraPosition[1] = eyePos.getY();
m_cameraPosition[2] = eyePos.getZ();
m_cameraPosition += m_cameraTargetPosition;
float m_frustumZNear=1;
float m_frustumZFar=1000;
if (m_glutScreenWidth == 0 && m_glutScreenHeight == 0)
return;
float aspect;
btVector3 extents;
if (m_glutScreenWidth > m_glutScreenHeight)
{
aspect = m_glutScreenWidth / (float)m_glutScreenHeight;
extents.setValue(aspect * 1.0f, 1.0f,0);
} else
{
aspect = m_glutScreenHeight / (float)m_glutScreenWidth;
extents.setValue(1.0f, aspect*1.f,0);
}
if (m_ortho)
{
// reset matrix
glLoadIdentity();
extents *= m_cameraDistance;
btVector3 lower = m_cameraTargetPosition - extents;
btVector3 upper = m_cameraTargetPosition + extents;
glOrtho(lower.getX(), upper.getX(), lower.getY(), upper.getY(),-1000,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} else
{
if (m_glutScreenWidth > m_glutScreenHeight)
{
glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar);
} else
{
glFrustum (-aspect * m_frustumZNear, aspect * m_frustumZNear, -m_frustumZNear, m_frustumZNear, m_frustumZNear, m_frustumZFar);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(m_cameraPosition[0], m_cameraPosition[1], m_cameraPosition[2],
m_cameraTargetPosition[0], m_cameraTargetPosition[1], m_cameraTargetPosition[2],
m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());
}
}
void GLInstancingRenderer::RenderScene(void)
{
BT_PROFILE("GlutDisplayFunc");
myinit();
updateCamera();
//render coordinate system
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
//do a finish, to make sure timings are clean
// glFinish();
// glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
glFlush();
//updatePos();
// simulationLoop();
//useCPU = true;
int totalNumInstances = 0;
for (int i=0;i<m_graphicsInstances.size();i++)
{
totalNumInstances+=m_graphicsInstances[i]->m_numGraphicsInstances;
}
int curOffset = 0;
for (int i=0;i<m_graphicsInstances.size();i++)
{
btGraphicsInstance* gfxObj = m_graphicsInstances[i];
int myOffset = gfxObj->m_instanceOffset*4*sizeof(float);
int POSITION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int ORIENTATION_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int COLOR_BUFFER_SIZE = (totalNumInstances*sizeof(float)*4);
int SCALE_BUFFER_SIZE = (totalNumInstances*sizeof(float)*3);
glBindVertexArray(gfxObj->m_cube_vao);
int vertexStride = 9*sizeof(float);
int vertexBase = gfxObj->m_vertexArrayOffset*vertexStride;
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid*)vertexBase);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+SHAPE_BUFFER_SIZE));
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+SHAPE_BUFFER_SIZE+POSITION_BUFFER_SIZE));
int uvoffset = 7*sizeof(float)+vertexBase;
int normaloffset = 4*sizeof(float)+vertexBase;
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid *)uvoffset);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 9*sizeof(float), (GLvoid *)normaloffset);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*4*sizeof(float)+SHAPE_BUFFER_SIZE+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE));
glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(curOffset*3*sizeof(float)+SHAPE_BUFFER_SIZE+POSITION_BUFFER_SIZE+ORIENTATION_BUFFER_SIZE+COLOR_BUFFER_SIZE));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(6);
glVertexAttribDivisor(0, 0);
glVertexAttribDivisor(1, 1);
glVertexAttribDivisor(2, 1);
glVertexAttribDivisor(3, 0);
glVertexAttribDivisor(4, 0);
glVertexAttribDivisor(5, 1);
glVertexAttribDivisor(6, 1);
glUseProgram(instancingShader);
glUniform1f(angle_loc, 0);
GLfloat pm[16];
glGetFloatv(GL_PROJECTION_MATRIX, pm);
glUniformMatrix4fv(ProjectionMatrix, 1, false, &pm[0]);
GLfloat mvm[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mvm);
glUniformMatrix4fv(ModelViewMatrix, 1, false, &mvm[0]);
glUniform1i(uniform_texture_diffuse, 0);
glFlush();
if (gfxObj->m_numGraphicsInstances)
{
int indexCount = gfxObj->m_numIndices;
int indexOffset = 0;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gfxObj->m_index_vbo);
{
BT_PROFILE("glDrawElementsInstanced");
glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances);
}
}
curOffset+= gfxObj->m_numGraphicsInstances;
}
glUseProgram(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
GLint err = glGetError();
assert(err==GL_NO_ERROR);
}
void GLInstancingRenderer::CleanupShaders()
{
delete []m_data->m_instance_positions_ptr;
delete []m_data->m_instance_quaternion_ptr;
delete []m_data->m_instance_colors_ptr;
delete []m_data->m_instance_scale_ptr;
}

View File

@@ -0,0 +1,45 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#ifndef GL_INSTANCING_RENDERER_H
#define GL_INSTANCING_RENDERER_H
#include "LinearMath/btAlignedObjectArray.h"
class GLInstancingRenderer
{
btAlignedObjectArray<struct btGraphicsInstance*> m_graphicsInstances;
struct InternalDataRenderer* m_data;
public:
GLInstancingRenderer();
virtual ~GLInstancingRenderer();
void InitShaders();
void RenderScene(void);
void CleanupShaders();
///vertices must be in the format x,y,z, nx,ny,nz, u,v
int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices);
///position x,y,z, quaternion x,y,z,w, color r,g,b,a, scaling x,y,z
int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
void writeTransforms();
};
#endif //GL_INSTANCING_RENDERER_H

View File

@@ -0,0 +1,107 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#include <GL/glew.h>
#include "GlutRenderer.h"
#include <stdio.h>
GlutRenderer* GlutRenderer::gDemoApplication;
void GlutRenderer::runMainLoop()
{
glutMainLoop();
}
static void glutKeyboardCallback(unsigned char key, int x, int y) { GlutRenderer::gDemoApplication->keyboardCallback(key,x,y); }
static void glutKeyboardUpCallback(unsigned char key, int x, int y){ GlutRenderer::gDemoApplication->keyboardUpCallback(key,x,y);}
static void glutSpecialKeyboardCallback(int key, int x, int y){ GlutRenderer::gDemoApplication->specialKeyboard(key,x,y);}
static void glutSpecialKeyboardUpCallback(int key, int x, int y){ GlutRenderer::gDemoApplication->specialKeyboardUp(key,x,y);}
static void glutReshapeCallback(int w, int h){ GlutRenderer::gDemoApplication->resize(w,h);}
static void glutIdleCallback(){ glutPostRedisplay (); }
static void glutMouseFuncCallback(int button, int state, int x, int y){ GlutRenderer::gDemoApplication->mouseFunc(button,state,x,y);}
static void glutMotionFuncCallback(int x,int y){ GlutRenderer::gDemoApplication->mouseMotionFunc(x,y);}
static void glutDisplayCallback(void){ GlutRenderer::gDemoApplication->displayCallback();}
void GlutRenderer::resize(int width, int height)
{
m_glutScreenWidth = width;
m_glutScreenHeight = height;
}
void GlutRenderer::mouseFunc(int button, int state, int x, int y)
{
}
void GlutRenderer::mouseMotionFunc(int x,int y)
{
}
void GlutRenderer::renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSwapBuffers();
glutPostRedisplay();
GLint err = glGetError();
assert(err==GL_NO_ERROR);
}
void GlutRenderer::displayCallback()
{
updateScene();
renderScene();
}
GlutRenderer::GlutRenderer(int argc, char* argv[])
{
glutInit(&argc, argv);
gDemoApplication = this;
}
void GlutRenderer::initGraphics(int width, int height)
{
m_glutScreenWidth = width;
m_glutScreenHeight = height;
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(m_glutScreenWidth, m_glutScreenHeight);
glutCreateWindow("GPU rigid body pipeline2");
glutKeyboardFunc(glutKeyboardCallback);
glutKeyboardUpFunc(glutKeyboardUpCallback);
glutSpecialFunc(glutSpecialKeyboardCallback);
glutSpecialUpFunc(glutSpecialKeyboardUpCallback);
glutReshapeFunc(glutReshapeCallback);
glutIdleFunc(glutIdleCallback);
glutMouseFunc(glutMouseFuncCallback);
glutPassiveMotionFunc(glutMotionFuncCallback);
glutMotionFunc(glutMotionFuncCallback);
glutDisplayFunc( glutDisplayCallback );
GLenum err = glewInit();
if (GLEW_OK != err)
{
printf("Error: %s\n", glewGetErrorString(err));
}
glClearColor(0.6f,0.6f,1.f,1.f);
}

View File

@@ -0,0 +1,59 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#ifndef GLUT_RENDERER_H
#define GLUT_RENDERER_H
#include "btGlutInclude.h"
#include "LinearMath/btVector3.h"
struct GlutRenderer
{
static GlutRenderer* gDemoApplication;
int m_glutScreenWidth;
int m_glutScreenHeight;
btVector3 m_cameraPosition;
btVector3 m_cameraTargetPosition;
btScalar m_cameraDistance;
btVector3 m_cameraUp;
float m_azimuth;
float m_elevation;
GlutRenderer(int argc, char* argv[]);
virtual void initGraphics(int width, int height);
virtual void cleanup() {}
void runMainLoop();
virtual void updateScene(){};
virtual void renderScene();
virtual void keyboardCallback(unsigned char key, int x, int y) {};
virtual void keyboardUpCallback(unsigned char key, int x, int y) {}
virtual void specialKeyboard(int key, int x, int y){}
virtual void specialKeyboardUp(int key, int x, int y){}
virtual void resize(int w, int h);
virtual void mouseFunc(int button, int state, int x, int y);
virtual void mouseMotionFunc(int x,int y);
virtual void displayCallback();
};
#endif //GLUT_RENDERER_H

View File

@@ -0,0 +1,64 @@
hasCL = findOpenCL_NVIDIA()
if (hasCL) then
project "OpenCL_gpu_rigidbody_pipeline2_NVIDIA"
initOpenCL_NVIDIA()
language "C++"
kind "ConsoleApp"
targetdir "../../../bin"
initOpenGL()
initGlew()
includedirs {
"../../primitives",
"../../../bullet2"
}
files {
"../main.cpp",
"../CLPhysicsDemo.cpp",
"../CLPhysicsDemo.h",
"../GLInstancingRenderer.cpp",
"../GLInstancingRenderer.h",
"../GlutRenderer.cpp",
"../GlutRenderer.h",
"../Win32OpenGLRenderManager.cpp",
"../Win32OpenGLRenderManager.h",
"../../gpu_rigidbody_pipeline/btConvexUtility.cpp",
"../../gpu_rigidbody_pipeline/btConvexUtility.h",
"../../gpu_rigidbody_pipeline/btGpuNarrowPhaseAndSolver.cpp",
"../../gpu_rigidbody_pipeline/btGpuNarrowPhaseAndSolver.h",
"../../../dynamics/basic_demo/ConvexHeightFieldShape.cpp",
"../../../dynamics/basic_demo/ConvexHeightFieldShape.h",
"../../../bullet2/LinearMath/btConvexHullComputer.cpp",
"../../../bullet2/LinearMath/btConvexHullComputer.h",
"../../broadphase_benchmark/findPairsOpenCL.cpp",
"../../broadphase_benchmark/findPairsOpenCL.h",
"../../broadphase_benchmark/btGridBroadphaseCL.cpp",
"../../broadphase_benchmark/btGridBroadphaseCL.h",
"../../3dGridBroadphase/Shared/bt3dGridBroadphaseOCL.cpp",
"../../3dGridBroadphase/Shared/bt3dGridBroadphaseOCL.h",
"../../3dGridBroadphase/Shared/btGpu3DGridBroadphase.cpp",
"../../3dGridBroadphase/Shared/btGpu3DGridBroadphase.h",
"../../../bullet2/LinearMath/btAlignedAllocator.cpp",
"../../../bullet2/LinearMath/btQuickprof.cpp",
"../../../bullet2/LinearMath/btQuickprof.h",
"../../../bullet2/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp",
"../../../bullet2/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp",
"../../../bullet2/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp",
"../../basic_initialize/btOpenCLUtils.cpp",
"../../basic_initialize/btOpenCLUtils.h",
"../../opengl_interop/btOpenCLGLInteropBuffer.cpp",
"../../opengl_interop/btOpenCLGLInteropBuffer.h",
"../../opengl_interop/btStopwatch.cpp",
"../../opengl_interop/btStopwatch.h"
}
end

View File

@@ -0,0 +1,41 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#ifndef __OPENGL_INCLUDE_H
#define __OPENGL_INCLUDE_H
#include <GL/glew.h>
//think different
#if defined(__APPLE__) && !defined (VMDMESA)
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#ifdef _WINDOWS
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#else
#include <GL/gl.h>
#endif //_WINDOWS
#endif //APPLE
#endif //__OPENGL_INCLUDE_H

View File

@@ -0,0 +1,210 @@
#ifndef SHAPE_DATA_H
#define SHAPE_DATA_H
static float barrel_vertices[] = {
0.0f,-0.5f,0.0f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
0.282362f,-0.5f,-0.205148f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
0.349018f,-0.5f,0.0f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
0.107853f,-0.5f,-0.331936f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
-0.107853f,-0.5f,-0.331936f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
0.107853f,-0.5f,-0.331936f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
-0.282362f,-0.5f,-0.205148f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
-0.349018f,-0.5f,0.0f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
-0.282362f,-0.5f,0.205148f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
-0.107853f,-0.5f,0.331936f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
0.107853f,-0.5f,0.331936f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
0.282362f,-0.5f,0.205148f, 1.0f, 0.0f,-1.0f,0.0f, 0.5f, 0.5f,
0.0f,0.5f,0.0f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
0.349018f,0.5f,0.0f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
0.282362f,0.5f,-0.205148f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
0.107853f,0.5f,-0.331936f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
0.107853f,0.5f,-0.331936f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
-0.107853f,0.5f,-0.331936f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
-0.282362f,0.5f,-0.205148f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
-0.349018f,0.5f,0.0f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
-0.282362f,0.5f,0.205148f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
-0.107853f,0.5f,0.331936f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
0.107853f,0.5f,0.331936f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
0.282362f,0.5f,0.205148f, 1.0f, 0.0f,1.0f,0.0f, 0.5f, 0.5f,
0.349018f,-0.5f,0.0f, 1.0f, 0.957307f,-0.289072f,0.0f, 0.5f, 0.5f,
0.404509f,0.0f,-0.293893f, 1.0f, 0.809017f,0.0f,-0.587785f, 0.5f, 0.5f,
0.5f,0.0f,0.0f, 1.0f, 1.0f,0.0f,0.0f, 0.5f, 0.5f,
0.282362f,-0.5f,-0.205148f, 1.0f, 0.774478f,-0.289072f,-0.562691f, 0.5f, 0.5f,
0.154508f,0.0f,-0.475528f, 1.0f, 0.309017f,0.0f,-0.951057f, 0.5f, 0.5f,
0.107853f,-0.5f,-0.331936f, 1.0f, 0.295824f,-0.289072f,-0.910453f, 0.5f, 0.5f,
0.107853f,-0.5f,-0.331936f, 1.0f, 0.295824f,-0.289072f,-0.910453f, 0.5f, 0.5f,
-0.154509f,0.0f,-0.475528f, 1.0f, -0.309017f,0.0f,-0.951057f, 0.5f, 0.5f,
0.154508f,0.0f,-0.475528f, 1.0f, 0.309017f,0.0f,-0.951057f, 0.5f, 0.5f,
-0.107853f,-0.5f,-0.331936f, 1.0f, -0.295824f,-0.289072f,-0.910453f, 0.5f, 0.5f,
-0.404509f,0.0f,-0.293893f, 1.0f, -0.809017f,0.0f,-0.587785f, 0.5f, 0.5f,
-0.282362f,-0.5f,-0.205148f, 1.0f, -0.774478f,-0.289072f,-0.562691f, 0.5f, 0.5f,
-0.5f,0.0f,0.0f, 1.0f, -1.0f,0.0f,0.0f, 0.5f, 0.5f,
-0.349018f,-0.5f,0.0f, 1.0f, -0.957307f,-0.289072f,0.0f, 0.5f, 0.5f,
-0.404508f,0.0f,0.293893f, 1.0f, -0.809017f,0.0f,0.587785f, 0.5f, 0.5f,
-0.282362f,-0.5f,0.205148f, 1.0f, -0.774478f,-0.289072f,0.562691f, 0.5f, 0.5f,
-0.154509f,0.0f,0.475528f, 1.0f, -0.309017f,0.0f,0.951056f, 0.5f, 0.5f,
-0.107853f,-0.5f,0.331936f, 1.0f, -0.295824f,-0.289072f,0.910453f, 0.5f, 0.5f,
0.154509f,0.0f,0.475528f, 1.0f, 0.309017f,0.0f,0.951056f, 0.5f, 0.5f,
0.107853f,-0.5f,0.331936f, 1.0f, 0.295824f,-0.289072f,0.910453f, 0.5f, 0.5f,
0.404509f,0.0f,0.293892f, 1.0f, 0.809017f,0.0f,0.587785f, 0.5f, 0.5f,
0.282362f,-0.5f,0.205148f, 1.0f, 0.774478f,-0.289072f,0.562691f, 0.5f, 0.5f,
0.282362f,0.5f,-0.205148f, 1.0f, 0.774478f,0.289072f,-0.562691f, 0.5f, 0.5f,
0.349018f,0.5f,0.0f, 1.0f, 0.957307f,0.289072f,0.0f, 0.5f, 0.5f,
0.107853f,0.5f,-0.331936f, 1.0f, 0.295824f,0.289072f,-0.910453f, 0.5f, 0.5f,
-0.107853f,0.5f,-0.331936f, 1.0f, -0.295824f,0.289072f,-0.910453f, 0.5f, 0.5f,
0.107853f,0.5f,-0.331936f, 1.0f, 0.295824f,0.289072f,-0.910453f, 0.5f, 0.5f,
-0.282362f,0.5f,-0.205148f, 1.0f, -0.774478f,0.289072f,-0.562691f, 0.5f, 0.5f,
-0.349018f,0.5f,0.0f, 1.0f, -0.957307f,0.289072f,0.0f, 0.5f, 0.5f,
-0.282362f,0.5f,0.205148f, 1.0f, -0.774478f,0.289072f,0.562691f, 0.5f, 0.5f,
-0.107853f,0.5f,0.331936f, 1.0f, -0.295824f,0.289072f,0.910453f, 0.5f, 0.5f,
0.107853f,0.5f,0.331936f, 1.0f, 0.295824f,0.289072f,0.910453f, 0.5f, 0.5f,
0.282362f,0.5f,0.205148f, 1.0f, 0.774478f,0.289072f,0.562691f, 0.5f, 0.5f
};
static int barrel_indices[] = {
0,1,2,
0,3,1,
0,4,5,
0,6,4,
0,7,6,
0,8,7,
0,9,8,
0,10,9,
0,11,10,
0,2,11,
12,13,14,
12,14,15,
12,16,17,
12,17,18,
12,18,19,
12,19,20,
12,20,21,
12,21,22,
12,22,23,
12,23,13,
24,25,26,
24,27,25,
27,28,25,
27,29,28,
30,31,32,
30,33,31,
33,34,31,
33,35,34,
35,36,34,
35,37,36,
37,38,36,
37,39,38,
39,40,38,
39,41,40,
41,42,40,
41,43,42,
43,44,42,
43,45,44,
45,26,44,
45,24,26,
26,46,47,
26,25,46,
25,48,46,
25,28,48,
32,49,50,
32,31,49,
31,51,49,
31,34,51,
34,52,51,
34,36,52,
36,53,52,
36,38,53,
38,54,53,
38,40,54,
40,55,54,
40,42,55,
42,56,55,
42,44,56,
44,47,56,
44,26,47,
};
///position xyz, unused w, normal, uv
static const float cube_vertices[] =
{
-0.5f, -0.5f, 0.5f, 0.0f, 0,0,1, 0,0,//0
0.5f, -0.5f, 0.5f, 0.0f, 0,0,1, 1,0,//1
0.5f, 0.5f, 0.5f, 0.0f, 0,0,1, 1,1,//2
-0.5f, 0.5f, 0.5f, 0.0f, 0,0,1, 0,1 ,//3
-0.5f, -0.5f, -0.5f, 0.5f, 0,0,-1, 0,0,//4
0.5f, -0.5f, -0.5f, 0.5f, 0,0,-1, 1,0,//5
0.5f, 0.5f, -0.5f, 0.5f, 0,0,-1, 1,1,//6
-0.5f, 0.5f, -0.5f, 0.5f, 0,0,-1, 0,1,//7
-0.5f, -0.5f, -0.5f, 0.5f, -1,0,0, 0,0,
-0.5f, 0.5f, -0.5f, 0.5f, -1,0,0, 1,0,
-0.5f, 0.5f, 0.5f, 0.5f, -1,0,0, 1,1,
-0.5f, -0.5f, 0.5f, 0.5f, -1,0,0, 0,1,
0.5f, -0.5f, -0.5f, 0.5f, 1,0,0, 0,0,
0.5f, 0.5f, -0.5f, 0.5f, 1,0,0, 1,0,
0.5f, 0.5f, 0.5f, 0.5f, 1,0,0, 1,1,
0.5f, -0.5f, 0.5f, 0.5f, 1,0,0, 0,1,
-0.5f, -0.5f, -0.5f, 0.5f, 0,-1,0, 0,0,
-0.5f, -0.5f, 0.5f, 0.5f, 0,-1,0, 1,0,
0.5f, -0.5f, 0.5f, 0.5f, 0,-1,0, 1,1,
0.5f,-0.5f, -0.5f, 0.5f, 0,-1,0, 0,1,
-0.5f, 0.5f, -0.5f, 0.5f, 0,1,0, 0,0,
-0.5f, 0.5f, 0.5f, 0.5f, 0,1,0, 1,0,
0.5f, 0.5f, 0.5f, 0.5f, 0,1,0, 1,1,
0.5f,0.5f, -0.5f, 0.5f, 0,1,0, 0,1,
};
///position xyz, unused w, normal, uv
static const float cube_vertices2[] =
{
-1.5f, -0.5f, 0.5f, 0.0f, 0,0,1, 0,0,//0
1.5f, -0.5f, 0.5f, 0.0f, 0,0,1, 1,0,//1
1.5f, 0.5f, 0.5f, 0.0f, 0,0,1, 1,1,//2
-1.5f, 0.5f, 0.5f, 0.0f, 0,0,1, 0,1 ,//3
-1.5f, -0.5f, -0.5f, 0.5f, 0,0,-1, 0,0,//4
1.5f, -0.5f, -0.5f, 0.5f, 0,0,-1, 1,0,//5
1.5f, 0.5f, -0.5f, 0.5f, 0,0,-1, 1,1,//6
-1.5f, 0.5f, -0.5f, 0.5f, 0,0,-1, 0,1,//7
-1.5f, -0.5f, -0.5f, 0.5f, -1,0,0, 0,0,
-1.5f, 0.5f, -0.5f, 0.5f, -1,0,0, 1,0,
-1.5f, 0.5f, 0.5f, 0.5f, -1,0,0, 1,1,
-1.5f, -0.5f, 0.5f, 0.5f, -1,0,0, 0,1,
1.5f, -0.5f, -0.5f, 0.5f, 1,0,0, 0,0,
1.5f, 0.5f, -0.5f, 0.5f, 1,0,0, 1,0,
1.5f, 0.5f, 0.5f, 0.5f, 1,0,0, 1,1,
1.5f, -0.5f, 0.5f, 0.5f, 1,0,0, 0,1,
-1.5f, -0.5f, -0.5f, 0.5f, 0,-1,0, 0,0,
-1.5f, -0.5f, 0.5f, 0.5f, 0,-1,0, 1,0,
1.5f, -0.5f, 0.5f, 0.5f, 0,-1,0, 1,1,
1.5f, -0.5f, -0.5f, 0.5f, 0,-1,0, 0,1,
-1.5f, 0.5f, -0.5f, 0.5f, 0,1,0, 0,0,
-1.5f, 0.5f, 0.5f, 0.5f, 0,1,0, 1,0,
1.5f, 0.5f, 0.5f, 0.5f, 0,1,0, 1,1,
1.5f, 0.5f, -0.5f, 0.5f, 0,1,0, 0,1,
};
static const int cube_indices[]=
{
0,1,2,0,2,3,//ground face
4,5,6,4,6,7,//top face
8,9,10,8,10,11,
12,13,14,12,14,15,
16,17,18,16,18,19,
20,21,22,20,22,23
};
#endif //SHAPE_DATA_H

View File

@@ -0,0 +1,465 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#include "Win32OpenGLRenderManager.h"
#include <windows.h>
#include <GL/gl.h>
static InternalData2* sData = 0;
struct InternalData2
{
HWND m_hWnd;;
int m_width;
int m_height;
HDC m_hDC;
HGLRC m_hRC;
bool m_OpenGLInitialized;
int m_oldScreenWidth;
int m_oldHeight;
int m_oldBitsPerPel;
bool m_quit;
InternalData2()
{
m_hWnd = 0;
m_width = 0;
m_height = 0;
m_hDC = 0;
m_hRC = 0;
m_OpenGLInitialized = false;
m_oldScreenWidth = 0;
m_oldHeight = 0;
m_oldBitsPerPel = 0;
m_quit = false;
}
};
void Win32OpenGLWindow::enableOpenGL()
{
PIXELFORMATDESCRIPTOR pfd;
int format;
// get the device context (DC)
m_data->m_hDC = GetDC( m_data->m_hWnd );
// set the pixel format for the DC
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.cStencilBits = 1;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat( m_data->m_hDC, &pfd );
SetPixelFormat( m_data->m_hDC, format, &pfd );
// create and enable the render context (RC)
m_data->m_hRC = wglCreateContext( m_data->m_hDC );
wglMakeCurrent( m_data->m_hDC, m_data->m_hRC );
m_data->m_OpenGLInitialized = true;
}
void Win32OpenGLWindow::disableOpenGL()
{
m_data->m_OpenGLInitialized = false;
wglMakeCurrent( NULL, NULL );
wglDeleteContext( m_data->m_hRC );
ReleaseDC( m_data->m_hWnd, m_data->m_hDC );
}
void Win32OpenGLWindow::pumpMessage()
{
MSG msg;
// check for messages
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
// handle or dispatch messages
if ( msg.message == WM_QUIT )
{
m_data->m_quit = TRUE;
}
else
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
// gDemoApplication->displayCallback();
};
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
return 0;
case WM_ERASEBKGND:
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
{
switch ( wParam )
{
case 'Q':
case VK_ESCAPE:
{
PostQuitMessage(0);
}
return 0;
}
break;
}
case WM_SIZE: // Size Action Has Taken Place
switch (wParam) // Evaluate Size Action
{
case SIZE_MINIMIZED: // Was Window Minimized?
return 0; // Return
case SIZE_MAXIMIZED: // Was Window Maximized?
sData->m_width = LOWORD (lParam);
sData->m_height = HIWORD (lParam);
//if (sOpenGLInitialized)
//{
// //gDemoApplication->reshape(sWidth,sHeight);
//}
glViewport(0, 0, sData->m_width, sData->m_height);
return 0; // Return
case SIZE_RESTORED: // Was Window Restored?
sData->m_width = LOWORD (lParam);
sData->m_height = HIWORD (lParam);
//if (sOpenGLInitialized)
//{
// gDemoApplication->reshape(sWidth,sHeight);
//}
glViewport(0, 0, sData->m_width, sData->m_height);
return 0; // Return
}
break;
default:{
}
};
return DefWindowProc(hWnd, message, wParam, lParam);
}
void Win32OpenGLWindow::init(int width,int height, bool fullscreen,int colorBitsPerPixel, void* windowHandle)
{
// get handle to exe file
HINSTANCE hInstance = GetModuleHandle(0);
// create the window if we need to and we do not use the null device
if (!windowHandle)
{
const char* ClassName = "DeviceWin32";
// Register Class
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( NULL, IDI_APPLICATION ); //(HICON)LoadImage(hInstance, "bullet_ico.ico", IMAGE_ICON, 0,0, LR_LOADTRANSPARENT);//LR_LOADFROMFILE);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = ClassName;
wcex.hIconSm = 0;
// if there is an icon, load it
wcex.hIcon = (HICON)LoadImage(hInstance, "irrlicht.ico", IMAGE_ICON, 0,0, LR_LOADFROMFILE);
RegisterClassEx(&wcex);
// calculate client size
RECT clientSize;
clientSize.top = 0;
clientSize.left = 0;
clientSize.right = width;
clientSize.bottom = height;
DWORD style = WS_POPUP;
if (!fullscreen)
style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX;
AdjustWindowRect(&clientSize, style, FALSE);
m_data->m_width = clientSize.right - clientSize.left;
m_data->m_height = clientSize.bottom - clientSize.top;
int windowLeft = (GetSystemMetrics(SM_CXSCREEN) - m_data->m_width) / 2;
int windowTop = (GetSystemMetrics(SM_CYSCREEN) - m_data->m_height) / 2;
if (fullscreen)
{
windowLeft = 0;
windowTop = 0;
}
// create window
m_data->m_hWnd = CreateWindow( ClassName, "", style, windowLeft, windowTop,
m_data->m_width, m_data->m_height, NULL, NULL, hInstance, NULL);
ShowWindow(m_data->m_hWnd, SW_SHOW);
UpdateWindow(m_data->m_hWnd);
MoveWindow(m_data->m_hWnd, windowLeft, windowTop, m_data->m_width, m_data->m_height, TRUE);
}
else if (windowHandle)
{
// attach external window
m_data->m_hWnd = static_cast<HWND>(windowHandle);
RECT r;
GetWindowRect(m_data->m_hWnd, &r);
m_data->m_width = r.right - r.left;
m_data->m_height = r.bottom - r.top;
//sFullScreen = false;
//sExternalWindow = true;
}
if (fullscreen)
{
DEVMODE dm;
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
// use default values from current setting
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
m_data->m_oldScreenWidth = dm.dmPelsWidth;
m_data->m_oldHeight = dm.dmPelsHeight;
m_data->m_oldBitsPerPel = dm.dmBitsPerPel;
dm.dmPelsWidth = width;
dm.dmPelsHeight = height;
if (colorBitsPerPixel)
{
dm.dmBitsPerPel = colorBitsPerPixel;
}
dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
LONG res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
if (res != DISP_CHANGE_SUCCESSFUL)
{ // try again without forcing display frequency
dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
}
}
//VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this);
enableOpenGL();
const wchar_t* text= L"OpenCL rigid body demo";
DWORD dwResult;
#ifdef _WIN64
SetWindowTextW(m_data->m_hWnd, text);
#else
SendMessageTimeoutW(m_data->m_hWnd, WM_SETTEXT, 0,
reinterpret_cast<LPARAM>(text),
SMTO_ABORTIFHUNG, 2000, &dwResult);
#endif
}
void Win32OpenGLWindow::switchFullScreen(bool fullscreen,int width,int height,int colorBitsPerPixel)
{
LONG res;
DEVMODE dm;
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
// use default values from current setting
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
if (fullscreen && !m_data->m_oldScreenWidth)
{
m_data->m_oldScreenWidth = dm.dmPelsWidth;
m_data->m_oldHeight = dm.dmPelsHeight;
m_data->m_oldBitsPerPel = dm.dmBitsPerPel;
if (width && height)
{
dm.dmPelsWidth = width;
dm.dmPelsHeight = height;
} else
{
dm.dmPelsWidth = m_data->m_width;
dm.dmPelsHeight = m_data->m_height;
}
if (colorBitsPerPixel)
{
dm.dmBitsPerPel = colorBitsPerPixel;
}
} else
{
if (m_data->m_oldScreenWidth)
{
dm.dmPelsWidth = m_data->m_oldScreenWidth;
dm.dmPelsHeight= m_data->m_oldHeight;
dm.dmBitsPerPel = m_data->m_oldBitsPerPel;
}
}
if (fullscreen)
{
res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
} else
{
res = ChangeDisplaySettings(&dm, 0);
}
}
Win32OpenGLWindow::Win32OpenGLWindow()
{
m_data = new InternalData2();
sData = m_data;
}
Win32OpenGLWindow::~Win32OpenGLWindow()
{
delete m_data;
sData = 0;
}
void Win32OpenGLWindow::init()
{
init(640,480,false);
}
void Win32OpenGLWindow::exit()
{
disableOpenGL();
DestroyWindow(this->m_data->m_hWnd);
}
void Win32OpenGLWindow::startRendering()
{
pumpMessage();
//glClearColor(1.f,0.f,0.f,1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
//glCullFace(GL_BACK);
//glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST);
float aspect;
//btVector3 extents;
if (m_data->m_width > m_data->m_height)
{
aspect = (float)m_data->m_width / (float)m_data->m_height;
//extents.setValue(aspect * 1.0f, 1.0f,0);
} else
{
aspect = (float)m_data->m_height / (float)m_data->m_width;
//extents.setValue(1.0f, aspect*1.f,0);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (m_data->m_width > m_data->m_height)
{
glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0);
} else
{
glFrustum (-1.0, 1.0, -aspect, aspect, 1.0, 10000.0);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Win32OpenGLWindow::renderAllObjects()
{
}
void Win32OpenGLWindow::endRendering()
{
SwapBuffers( m_data->m_hDC );
}
float Win32OpenGLWindow::getTimeInSeconds()
{
return 0.f;
}
void Win32OpenGLWindow::setDebugMessage(int x,int y,const char* message)
{
}
bool Win32OpenGLWindow::requestedExit()
{
return m_data->m_quit;
}

View File

@@ -0,0 +1,70 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
#ifndef _WIN32_OPENGL_RENDER_MANAGER_H
#define _WIN32_OPENGL_RENDER_MANAGER_H
#define RM_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
RM_DECLARE_HANDLE(RenderObjectHandle);
struct InternalData2;
class Win32OpenGLWindow
{
protected:
struct InternalData2* m_data;
void enableOpenGL();
void disableOpenGL();
void pumpMessage();
public:
Win32OpenGLWindow();
virtual ~Win32OpenGLWindow();
virtual void init(); //default implementation uses default settings for width/height/fullscreen
void init(int width,int height, bool fullscreen=false, int colorBitsPerPixel=0, void* windowHandle=0);
void switchFullScreen(bool fullscreen,int width=0,int height=0,int colorBitsPerPixel=0);
virtual void exit();
virtual void startRendering();
virtual void renderAllObjects();
virtual void endRendering();
virtual float getTimeInSeconds();
virtual void setDebugMessage(int x,int y,const char* message);
virtual bool requestedExit();
};
#endif //_WIN32_OPENGL_RENDER_MANAGER_H

View File

@@ -0,0 +1,224 @@
/*
Copyright (c) 2012 Advanced Micro Devices, Inc.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//Originally written by Erwin Coumans
//
//#include "vld.h"
#include <GL/glew.h>
#include "GLInstancingRenderer.h"
#include "GLInstancingRenderer.h"
#include "../opengl_interop/btOpenCLGLInteropBuffer.h"
#include "Win32OpenGLRenderManager.h"
#include "CLPhysicsDemo.h"
#include "../broadphase_benchmark/btGridBroadphaseCl.h"
#include "../../opencl/gpu_rigidbody_pipeline/btGpuNarrowPhaseAndSolver.h"
#include "ShapeData.h"
#include "LinearMath/btQuickprof.h"
int NUM_OBJECTS_X = 32;
int NUM_OBJECTS_Y = 24;
int NUM_OBJECTS_Z = 32;
float X_GAP = 2.f;
float Y_GAP = 2.f;
float Z_GAP = 2.f;
extern int numPairsOut;
void createScene(GLInstancingRenderer& renderer,CLPhysicsDemo& physicsSim)
{
int strideInBytes = sizeof(float)*9;
int barrelShapeIndex = -1;
int cubeShapeIndex = -1;
float position[4]={0,0,0,0};
float orn[4] = {0,0,0,1};
float color[4] = {1,1,1,1};
int index=0;
#if 1
{
int numVertices = sizeof(barrel_vertices)/strideInBytes;
int numIndices = sizeof(barrel_indices)/sizeof(int);
barrelShapeIndex = renderer.registerShape(&barrel_vertices[0],numVertices,barrel_indices,numIndices);
}
float barrelScaling[4] = {2,2,2,1};
int barrelCollisionShapeIndex = physicsSim.registerCollisionShape(&barrel_vertices[0],strideInBytes, sizeof(barrel_vertices)/strideInBytes,&barrelScaling[0]);
for (int i=0;i<NUM_OBJECTS_X;i++)
{
for (int j=0;j<(NUM_OBJECTS_Y/2);j++)
{
for (int k=0;k<NUM_OBJECTS_Z;k++)
{
float mass = j? 1.f : 0.f;
position[0]=(i*X_GAP-NUM_OBJECTS_X/2)+5;
position[1]=(j*Y_GAP*2-NUM_OBJECTS_Y/2);
position[2]=(k*Z_GAP-NUM_OBJECTS_Z/2)-NUM_OBJECTS_Z*3;
position[3] = 1.f;
renderer.registerGraphicsInstance(barrelShapeIndex,position,orn,color,barrelScaling);
void* ptr = (void*) index;
physicsSim.registerPhysicsInstance(mass, position, orn, barrelCollisionShapeIndex,ptr);
index++;
}
}
}
#endif
float cubeScaling[4] = {2,2,2,1};
int cubeCollisionShapeIndex = physicsSim.registerCollisionShape(&cube_vertices[0],strideInBytes, sizeof(cube_vertices)/strideInBytes,&cubeScaling[0]);
{
int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int);
cubeShapeIndex = renderer.registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices);
}
for (int i=0;i<NUM_OBJECTS_X;i++)
{
for (int j=0;j<NUM_OBJECTS_Y/2;j++)
{
for (int k=0;k<NUM_OBJECTS_Z;k++)
{
float mass = 1.f;//j? 1.f : 0.f;
position[0]=(i*X_GAP-NUM_OBJECTS_X/2)+(j&1);
position[1]=(j*Y_GAP-NUM_OBJECTS_Y/2);
position[2]=(k*Z_GAP-NUM_OBJECTS_Z/2)+(j&1);
position[3] = 1.f;
renderer.registerGraphicsInstance(cubeShapeIndex,position,orn,color,cubeScaling);
void* ptr = (void*) index;
physicsSim.registerPhysicsInstance(mass, position, orn, cubeCollisionShapeIndex,ptr);
index++;
}
}
}
if (1)
{
//add some 'special' plane shape
void* ptr = (void*) index;
position[0] = 0.f;
position[1] = -NUM_OBJECTS_Y/2-1;
position[2] = 0.f;
position[3] = 1.f;
physicsSim.registerPhysicsInstance(0.f,position, orn, -1,ptr);
color[0] = 1.f;
color[1] = 0.f;
color[2] = 0.f;
cubeScaling[0] = 5000.f;
cubeScaling[1] = 0.01f;
cubeScaling[2] = 5000.f;
renderer.registerGraphicsInstance(cubeShapeIndex,position,orn,color,cubeScaling);
}
physicsSim.writeBodiesToGpu();
}
int main(int argc, char* argv[])
{
Win32OpenGLWindow* window = new Win32OpenGLWindow();
window->init(1024,768);
GLenum err = glewInit();
window->startRendering();
window->endRendering();
GLInstancingRenderer render;
CLPhysicsDemo demo(window);
bool useInterop = true;
demo.init(-1,-1,useInterop);
render.InitShaders();
if (useInterop)
demo.setupInterop();
createScene(render, demo);
printf("num objects = %d\n", NUM_OBJECTS_X*NUM_OBJECTS_Y*NUM_OBJECTS_Z);
render.writeTransforms();
while (!window->requestedExit())
{
CProfileManager::Reset();
demo.stepSimulation();
window->startRendering();
render.RenderScene();
window->endRendering();
CProfileManager::Increment_Frame_Counter();
static bool printStats = true;
if (printStats)
{
static int count = 10;
count--;
if (count<0)
{
CProfileManager::dumpAll();
//printf("total broadphase pairs= %d\n", gFpIO.m_numOverlap);
printf("numPairsOut (culled) = %d\n", numPairsOut);
printStats = false;
}
}
}
demo.cleanup();
render.CleanupShaders();
window->exit();
delete window;
return 0;
}

View File

@@ -0,0 +1,5 @@
include "AMD"
-- include "Intel"
-- include "NVIDIA"