add a textured sphere8.obj test with obj loader

fix shaders, so that shadowed and non-shadowed are matching
fix registerGraphicsUnitSphereShape API (level of detail), support textured sphere too
add support for textured cube
add start for a Tutorial.cpp
This commit is contained in:
erwin coumans
2015-08-05 19:03:27 -07:00
parent 250068d5eb
commit a5669d2ffd
29 changed files with 2138 additions and 105 deletions

View File

@@ -2,16 +2,16 @@
rem @echo off
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/instancingVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/instancingVS.h" --stringname="instancingVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/instancingPS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/instancingPS.h" --stringname="instancingFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/pointSpriteVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/pointSpriteVS.h" --stringname="pointSpriteVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/pointSpritePS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/pointSpritePS.h" --stringname="pointSpriteFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingPS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingPS.h" --stringname="createShadowMapInstancingFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/createShadowMapInstancingVS.h" --stringname="createShadowMapInstancingVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingPS.h" --stringname="useShadowMapInstancingFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/useShadowMapInstancingVS.h" --stringname="useShadowMapInstancingVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/linesVS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/linesVS.h" --stringname="linesVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../btgui/OpenGLWindow/Shaders/linesPS.glsl" --headerfile="../btgui/OpenGLWindow/Shaders/linesPS.h" --stringname="linesFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/instancingVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/instancingVS.h" --stringname="instancingVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/instancingPS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/instancingPS.h" --stringname="instancingFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/pointSpriteVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/pointSpriteVS.h" --stringname="pointSpriteVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/pointSpritePS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/pointSpritePS.h" --stringname="pointSpriteFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingPS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingPS.h" --stringname="createShadowMapInstancingFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/createShadowMapInstancingVS.h" --stringname="createShadowMapInstancingVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingPS.h" --stringname="useShadowMapInstancingFragmentShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/useShadowMapInstancingVS.h" --stringname="useShadowMapInstancingVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/linesVS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/linesVS.h" --stringname="linesVertexShader" stringify
premake4 --file=stringifyKernel.lua --kernelfile="../examples/OpenGLWindow/Shaders/linesPS.glsl" --headerfile="../examples/OpenGLWindow/Shaders/linesPS.h" --stringname="linesFragmentShader" stringify

Binary file not shown.

Binary file not shown.

7
data/sphere8.mtl Normal file
View File

@@ -0,0 +1,7 @@
newmtl acmat_0
Kd 1 1 1
Ka 0.2 0.2 0.2
Ks 0.2 0.2 0.2
Ns 16
Tr 0
map_Kd uvmap.png

1695
data/sphere8.obj Normal file

File diff suppressed because it is too large Load Diff

BIN
data/uvmap.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -27,6 +27,14 @@ struct DrawGridData
}
};
enum EnumSphereLevelOfDetail
{
SPHERE_LOD_POINT_SPRITE=0,
SPHERE_LOD_LOW,
SPHERE_LOD_MEDIUM,
SPHERE_LOD_HIGH,
};
struct CommonGraphicsApp
{
class CommonWindowInterface* m_window;
@@ -111,8 +119,9 @@ struct CommonGraphicsApp
virtual void swapBuffer() = 0;
virtual void drawText( const char* txt, int posX, int posY) = 0;
virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size)=0;
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ)=0;
virtual int registerGraphicsSphereShape(float radius, bool usePointSprites=true, int largeSphereThreshold=100, int mediumSphereThreshold=10)=0;
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1)=0;
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1) = 0;
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4])=0;
void defaultMouseButtonCallback( int button, int state, float x, float y)

View File

@@ -43,7 +43,7 @@ struct CommonRenderInterface
virtual void drawPoint(const double* position, const double color[4], double pointDrawSize)=0;
virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType=B3_GL_TRIANGLES, int textureIndex=-1)=0;
virtual void updateShape(int shapeIndex, const float* vertices)=0;
virtual int registerTexture(const unsigned char* texels, int width, int height)=0;
virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex)=0;
virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)=0;
virtual void writeSingleInstanceColorToCPU(float* color, int srcIndex)=0;

View File

@@ -209,9 +209,9 @@ struct CommonRigidBodyBase : public CommonExampleInterface
btVector3 hor;
hor = rayForward.cross(vertical);
hor.normalize();
hor.safeNormalize();
vertical = hor.cross(rayForward);
vertical.normalize();
vertical.safeNormalize();
float tanfov = tanf(0.5f*fov);

View File

@@ -38,7 +38,7 @@
#include "../SharedMemory/PhysicsClientExample.h"
#include "../Constraints/TestHingeTorque.h"
#include "../RenderingExamples/TimeSeriesExample.h"
#include "../Tutorial/Tutorial.h"
#ifdef ENABLE_LUA
#include "../LuaDemo/LuaPhysicsSetup.h"
@@ -76,6 +76,10 @@ struct ExampleEntry
static ExampleEntry gDefaultExamples[]=
{
ExampleEntry(0,"Tutorial"),
ExampleEntry(1,"Free Rigid Body","Free moving rigid body, without external or constraint forces", TutorialCreateFunc,0),
ExampleEntry(0,"API"),
ExampleEntry(1,"Basic Example","Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc),

View File

@@ -51,7 +51,7 @@ static OpenGLGuiHelper* s_guiHelper=0;
static MyProfileWindow* s_profWindow =0;
#define DEMO_SELECTION_COMBOBOX 13
const char* startFileName = "bulletDemo.txt";
const char* startFileName = "0_Bullet3Demo.txt";
static GwenUserInterface* gui = 0;
static int sCurrentDemoIndex = -1;

View File

@@ -62,6 +62,7 @@
"../SharedMemory/PosixSharedMemory.cpp",
"../SharedMemory/Win32SharedMemory.cpp",
"../BasicDemo/BasicExample.*",
"../Tutorial/*",
"../Benchmarks/*",
"../CommonInterfaces/*",
"../ForkLift/ForkLiftDemo.*",

View File

@@ -8,7 +8,7 @@
#include "Wavefront2GLInstanceGraphicsShape.h"
#include "../../Utils/b3ResourcePath.h"
#include "Bullet3Common/b3FileUtils.h"
#include "stb_image/stb_image.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
@@ -58,7 +58,7 @@ void ImportObjSetup::initPhysics()
m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
const char* fileName = "samurai_monastry.obj";
const char* fileName = "sphere8.obj";
char relativeFileName[1024];
if (b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024))
{
@@ -86,10 +86,49 @@ void ImportObjSetup::initPhysics()
btVector3 position = trans.getOrigin();
btQuaternion orn = trans.getRotation();
btVector3 color(0,0,1);
btVector3 color(1,1,1);
int textureIndex = -1;
//try to load some texture
for (int i=0;i<shapes.size();i++)
{
const tinyobj::shape_t& shape = shapes[i];
if (shape.material.diffuse_texname.length()>0)
{
int shapeId = m_guiHelper->getRenderInterface()->registerShape(&gfxShape->m_vertices->at(0).xyzw[0], gfxShape->m_numvertices, &gfxShape->m_indices->at(0), gfxShape->m_numIndices);
int width,height,n;
const char* filename = shape.material.diffuse_texname.c_str();
const unsigned char* image=0;
const char* prefix[]={"./","./data/","../data/","../../data/","../../../data/","../../../../data/"};
int numprefix = sizeof(prefix)/sizeof(const char*);
for (int i=0;!image && i<numprefix;i++)
{
char relativeFileName[1024];
sprintf(relativeFileName,"%s%s",prefix[i],filename);
image = stbi_load(relativeFileName, &width, &height, &n, 0);
}
if (image)
{
textureIndex = m_guiHelper->getRenderInterface()->registerTexture(image,width,height);
if (textureIndex>=0)
{
break;
}
}
}
}
if (1)
{
}
int shapeId = m_guiHelper->getRenderInterface()->registerShape(&gfxShape->m_vertices->at(0).xyzw[0], gfxShape->m_numvertices, &gfxShape->m_indices->at(0), gfxShape->m_numIndices,B3_GL_TRIANGLES,textureIndex);
//int id =
m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling);

View File

@@ -40,24 +40,46 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
vtx0.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f]*3+2];
vtx0.xyzw[3] = 0.f;
vtx0.uv[0] = 0.5f;//shape.mesh.positions[shape.mesh.indices[f]*3+2];?
vtx0.uv[1] = 0.5f;
if (shape.mesh.texcoords.size())
{
vtx0.uv[0] = shape.mesh.texcoords[shape.mesh.indices[f]*2+0];
vtx0.uv[1] = shape.mesh.texcoords[shape.mesh.indices[f]*2+1];
} else
{
vtx0.uv[0] = 0.5;
vtx0.uv[1] = 0.5;
}
GLInstanceVertex vtx1;
vtx1.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f+1]*3+0];
vtx1.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f+1]*3+1];
vtx1.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f+1]*3+2];
vtx1.xyzw[3]= 0.f;
vtx1.uv[0] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[0];
vtx1.uv[1] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[1];
if (shape.mesh.texcoords.size())
{
vtx1.uv[0] = shape.mesh.texcoords[shape.mesh.indices[f+1]*2+0];
vtx1.uv[1] = shape.mesh.texcoords[shape.mesh.indices[f+1]*2+1];
} else
{
vtx1.uv[0] = 0.5f;
vtx1.uv[1] = 0.5f;
}
GLInstanceVertex vtx2;
vtx2.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f+2]*3+0];
vtx2.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f+2]*3+1];
vtx2.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f+2]*3+2];
vtx2.xyzw[3] = 0.f;
vtx2.uv[0] = 0.5f;
vtx2.uv[1] = 0.5f;
if (shape.mesh.texcoords.size())
{
vtx2.uv[0] = shape.mesh.texcoords[shape.mesh.indices[f+2]*2+0];
vtx2.uv[1] = shape.mesh.texcoords[shape.mesh.indices[f+2]*2+1];
} else
{
vtx2.uv[0] = 0.5;
vtx2.uv[1] = 0.5;
}
btVector3 v0(vtx0.xyzw[0],vtx0.xyzw[1],vtx0.xyzw[2]);

View File

@@ -214,6 +214,8 @@ static GLint createShadow_depthMVP=0;
static GLint ModelViewMatrix=0;
static GLint ProjectionMatrix=0;
static GLint regularLightDirIn=0;
static GLint uniform_texture_diffuse = 0;
@@ -688,6 +690,8 @@ void GLInstancingRenderer::InitShaders()
ModelViewMatrix = glGetUniformLocation(instancingShader, "ModelViewMatrix");
ProjectionMatrix = glGetUniformLocation(instancingShader, "ProjectionMatrix");
uniform_texture_diffuse = glGetUniformLocation(instancingShader, "Diffuse");
regularLightDirIn = glGetUniformLocation(instancingShader,"lightDirIn");
glUseProgram(0);
instancingShaderPointSprite = gltLoadShaderPair(pointSpriteVertexShader,pointSpriteFragmentShader);
@@ -1559,6 +1563,11 @@ b3Assert(glGetError() ==GL_NO_ERROR);
glUseProgram(instancingShader);
glUniformMatrix4fv(ProjectionMatrix, 1, false, &m_data->m_projectionMatrix[0]);
glUniformMatrix4fv(ModelViewMatrix, 1, false, &m_data->m_viewMatrix[0]);
b3Vector3 gLightDir = gLightPos;
gLightDir.normalize();
glUniform3f(regularLightDirIn,gLightDir[0],gLightDir[1],gLightDir[2]);
glUniform1i(uniform_texture_diffuse, 0);
glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
break;

View File

@@ -26,7 +26,7 @@ void main(void)
vec3 ct,cf;
float intensity,at,af;
intensity = max(dot(lightDir,normalize(normal)),0);
cf = intensity*vec3(1.0,1.0,1.0)+ambient;
cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;
af = 1.0;
ct = texel.rgb;

View File

@@ -23,7 +23,7 @@ static const char* instancingFragmentShader= \
" vec3 ct,cf;\n"
" float intensity,at,af;\n"
" intensity = max(dot(lightDir,normalize(normal)),0);\n"
" cf = intensity*vec3(1.0,1.0,1.0)+ambient;\n"
" cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;\n"
" af = 1.0;\n"
" \n"
" ct = texel.rgb;\n"

View File

@@ -13,6 +13,7 @@ layout (location = 6) in vec3 instance_scale;
uniform mat4 ModelViewMatrix;
uniform mat4 ProjectionMatrix;
uniform vec3 lightDirIn;
out Fragment
{
@@ -60,17 +61,13 @@ out vec3 lightDir,normal,ambient;
void main(void)
{
vec4 q = instance_quaternion;
ambient = vec3(0.3,.3,0.3);
ambient = vec3(0.6,.6,0.6);
vec4 worldNormal = (quatRotate3( vertexnormal,q));
normal = normalize(worldNormal).xyz;
vec4 local_normal = (quatRotate3( vertexnormal,q));
vec3 light_pos = vec3(-0.3,0.1,0.1);
normal = local_normal.xyz;//normalize(ModelViewMatrix * local_normal).xyz;
lightDir = lightDirIn;
lightDir = normalize(light_pos);//gl_LightSource[0].position.xyz));
// lightDir = normalize(vec3(gl_LightSource[0].position));
vec4 axis = vec4(1,1,1,0);
vec4 localcoord = quatRotate3( position.xyz*instance_scale,q);
vec4 vertexPos = ProjectionMatrix * ModelViewMatrix *(instance_position+localcoord);

View File

@@ -11,6 +11,7 @@ static const char* instancingVertexShader= \
"layout (location = 6) in vec3 instance_scale;\n"
"uniform mat4 ModelViewMatrix;\n"
"uniform mat4 ProjectionMatrix;\n"
"uniform vec3 lightDirIn;\n"
"out Fragment\n"
"{\n"
" vec4 color;\n"
@@ -51,16 +52,13 @@ static const char* instancingVertexShader= \
"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.3,0.1,0.1);\n"
" normal = local_normal.xyz;//normalize(ModelViewMatrix * local_normal).xyz;\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"
" ambient = vec3(0.6,.6,0.6);\n"
" \n"
" vec4 worldNormal = (quatRotate3( vertexnormal,q));\n"
" normal = normalize(worldNormal).xyz;\n"
" \n"
" lightDir = lightDirIn;\n"
" \n"
" vec4 localcoord = quatRotate3( position.xyz*instance_scale,q);\n"
" vec4 vertexPos = ProjectionMatrix * ModelViewMatrix *(instance_position+localcoord);\n"
" gl_Position = vertexPos;\n"

View File

@@ -23,13 +23,13 @@ out vec4 color;
void main(void)
{
vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);//fragment.color;
vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);
vec3 ct,cf;
float intensity,at,af;
intensity = clamp( dot( normalize(normal),lightDir ), 0,1 );
cf = ambient;
af = 1.0;
ct = texel.rgb;
@@ -43,14 +43,9 @@ void main(void)
float visibility = texture(shadowMap, vec3(ShadowCoord.xy,(ShadowCoord.z-bias)/ShadowCoord.w));
intensity*=2;
if (intensity>1)
intensity=1.f;
intensity = 0.7*intensity + 0.3*intensity*visibility;
visibility *= intensity;
cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;
if (visibility<0.6)
visibility=0.6f;
color = vec4(ct * visibility, fragment.color.w);
color = vec4(ct * cf, fragment.color.w);
}

View File

@@ -17,13 +17,13 @@ static const char* useShadowMapInstancingFragmentShader= \
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);//fragment.color;\n"
" vec4 texel = fragment.color*texture(Diffuse,vert.texcoord);\n"
" vec3 ct,cf;\n"
" float intensity,at,af;\n"
" \n"
" intensity = clamp( dot( normalize(normal),lightDir ), 0,1 );\n"
" \n"
" cf = ambient;\n"
" \n"
" af = 1.0;\n"
" \n"
" ct = texel.rgb;\n"
@@ -35,15 +35,10 @@ static const char* useShadowMapInstancingFragmentShader= \
" bias = clamp(bias, 0,0.01);\n"
" float visibility = texture(shadowMap, vec3(ShadowCoord.xy,(ShadowCoord.z-bias)/ShadowCoord.w));\n"
" \n"
" intensity*=2;\n"
" if (intensity>1)\n"
" intensity=1.f;\n"
" intensity = 0.7*intensity + 0.3*intensity*visibility;\n"
" \n"
" visibility *= intensity;\n"
" \n"
" if (visibility<0.6)\n"
" visibility=0.6f;\n"
" cf = intensity*(vec3(1.0,1.0,1.0)-ambient)+ambient;\n"
" \n"
" color = vec4(ct * visibility, fragment.color.w);\n"
" color = vec4(ct * cf, fragment.color.w);\n"
"}\n"
;

View File

@@ -65,7 +65,7 @@ out vec3 lightDir,normal,ambient;
void main(void)
{
vec4 q = instance_quaternion;
ambient = vec3(0.3,.3,0.3);
ambient = vec3(0.6,.6,0.6);
vec4 worldNormal = (quatRotate3( vertexnormal,q));
@@ -73,7 +73,7 @@ void main(void)
lightDir = lightDirIn;
vec4 axis = vec4(1,1,1,0);
vec4 localcoord = quatRotate3( position.xyz*instance_scale,q);
vec4 vertexPos = MVP* vec4((instance_position+localcoord).xyz,1);

View File

@@ -55,14 +55,14 @@ static const char* useShadowMapInstancingVertexShader= \
"void main(void)\n"
"{\n"
" vec4 q = instance_quaternion;\n"
" ambient = vec3(0.3,.3,0.3);\n"
" ambient = vec3(0.6,.6,0.6);\n"
" \n"
" vec4 worldNormal = (quatRotate3( vertexnormal,q));\n"
" \n"
" normal = normalize(worldNormal).xyz;\n"
" lightDir = lightDirIn;\n"
" \n"
" vec4 axis = vec4(1,1,1,0);\n"
" \n"
" vec4 localcoord = quatRotate3( position.xyz*instance_scale,q);\n"
" vec4 vertexPos = MVP* vec4((instance_position+localcoord).xyz,1);\n"
" gl_Position = vertexPos;\n"

View File

@@ -19,11 +19,11 @@ public:
virtual void swapBuffer();
virtual void drawText( const char* txt, int posX, int posY);
virtual void setBackgroundColor(float red, float green, float blue);
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ)
virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1)
{
return 0;
}
virtual int registerGraphicsSphereShape(float radius, bool usePointSprites, int largeSphereThreshold, int mediumSphereThreshold)
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1)
{
return 0;
}

View File

@@ -46,6 +46,10 @@ struct SimpleOpenGL2Renderer : public CommonRenderInterface
{
return m_height;
}
virtual int registerTexture(const unsigned char* texels, int width, int height)
{
return -1;
}
virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling);
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);

View File

@@ -419,7 +419,7 @@ struct GfxVertex
float u,v;
};
int SimpleOpenGL3App::registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ)
int SimpleOpenGL3App::registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex)
{
@@ -442,7 +442,7 @@ int SimpleOpenGL3App::registerCubeShape(float halfExtentsX,float halfExtentsY, f
verts[i].v = cube_vertices[i*9+8];
}
int shapeId = m_instancingRenderer->registerShape(&verts[0].x,numVertices,cube_indices,numIndices);
int shapeId = m_instancingRenderer->registerShape(&verts[0].x,numVertices,cube_indices,numIndices,B3_GL_TRIANGLES,textureIndex);
return shapeId;
}
@@ -480,42 +480,46 @@ void SimpleOpenGL3App::registerGrid(int cells_x, int cells_z, float color0[4], f
}
int SimpleOpenGL3App::registerGraphicsSphereShape(float radius, bool usePointSprites, int largeSphereThreshold, int mediumSphereThreshold)
int SimpleOpenGL3App::registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId)
{
int strideInBytes = 9*sizeof(float);
int graphicsShapeIndex = -1;
if (radius>=largeSphereThreshold)
switch (lod)
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_instancingRenderer->registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices);
} else
{
if (usePointSprites)
case SPHERE_LOD_POINT_SPRITE:
{
int numVertices = sizeof(point_sphere_vertices)/strideInBytes;
int numIndices = sizeof(point_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_instancingRenderer->registerShape(&point_sphere_vertices[0],numVertices,point_sphere_indices,numIndices,B3_GL_POINTS);
} else
{
if (radius>=mediumSphereThreshold)
{
int numVertices = sizeof(medium_sphere_vertices)/strideInBytes;
int numIndices = sizeof(medium_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_instancingRenderer->registerShape(&medium_sphere_vertices[0],numVertices,medium_sphere_indices,numIndices);
} else
{
int numVertices = sizeof(low_sphere_vertices)/strideInBytes;
int numIndices = sizeof(low_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_instancingRenderer->registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices);
}
graphicsShapeIndex = m_instancingRenderer->registerShape(&point_sphere_vertices[0],numVertices,point_sphere_indices,numIndices,B3_GL_POINTS,textureId);
break;
}
}
case SPHERE_LOD_LOW:
{
int numVertices = sizeof(low_sphere_vertices)/strideInBytes;
int numIndices = sizeof(low_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_instancingRenderer->registerShape(&low_sphere_vertices[0],numVertices,low_sphere_indices,numIndices,B3_GL_TRIANGLES,textureId);
break;
}
case SPHERE_LOD_MEDIUM:
{
int numVertices = sizeof(medium_sphere_vertices)/strideInBytes;
int numIndices = sizeof(medium_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_instancingRenderer->registerShape(&medium_sphere_vertices[0],numVertices,medium_sphere_indices,numIndices,B3_GL_TRIANGLES,textureId);
break;
}
case SPHERE_LOD_HIGH:
default:
{
int numVertices = sizeof(detailed_sphere_vertices)/strideInBytes;
int numIndices = sizeof(detailed_sphere_indices)/sizeof(int);
graphicsShapeIndex = m_instancingRenderer->registerShape(&detailed_sphere_vertices[0],numVertices,detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,textureId);
break;
}
};
return graphicsShapeIndex;
}

View File

@@ -19,8 +19,8 @@ struct SimpleOpenGL3App : public CommonGraphicsApp
SimpleOpenGL3App(const char* title, int width,int height);
virtual ~SimpleOpenGL3App();
virtual int registerCubeShape(float halfExtentsX=1.f,float halfExtentsY=1.f, float halfExtentsZ = 1.f);
virtual int registerGraphicsSphereShape(float radius, bool usePointSprites=true, int largeSphereThreshold=100, int mediumSphereThreshold=10);
virtual int registerCubeShape(float halfExtentsX=1.f,float halfExtentsY=1.f, float halfExtentsZ = 1.f, int textureIndex = -1);
virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1);
virtual void registerGrid(int xres, int yres, float color0[4], float color1[4]);
void dumpNextFrameToPng(const char* pngFilename);
void dumpFramesToVideo(const char* mp4Filename);

View File

@@ -0,0 +1,248 @@
#include "Tutorial.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "../CommonInterfaces/CommonRenderInterface.h"
#include "../CommonInterfaces/CommonExampleInterface.h"
#include "LinearMath/btTransform.h"
#include "stb_image/stb_image.h"
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
struct LWPose
{
btVector3 m_worldPosition;
btQuaternion m_worldOrientation;
LWPose()
:m_worldPosition(0,0,0),
m_worldOrientation(0,0,0,1)
{
}
};
enum LWRIGIDBODY_FLAGS
{
LWFLAG_USE_QUATERNION_DERIVATIVE = 1,
};
struct LWRightBody
{
LWPose m_worldPose;
btVector3 m_linearVelocity;
btVector3 m_angularVelocity;
int m_graphicsIndex;
int m_flags;
LWRightBody()
:m_linearVelocity(0,0,0),
m_angularVelocity(0,0,0),
m_flags(LWFLAG_USE_QUATERNION_DERIVATIVE)
{
}
void integrateTransform(double deltaTime)
{
LWPose newPose;
newPose.m_worldPosition = m_worldPose.m_worldPosition + m_linearVelocity*deltaTime;
if (m_flags & LWFLAG_USE_QUATERNION_DERIVATIVE)
{
newPose.m_worldOrientation = m_worldPose.m_worldOrientation;
newPose.m_worldOrientation += (m_angularVelocity * newPose.m_worldOrientation) * (deltaTime * btScalar(0.5));
newPose.m_worldOrientation.normalize();
m_worldPose = newPose;
} else
{
//Exponential map
//google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
btVector3 axis;
btScalar fAngle = m_angularVelocity.length();
//limit the angular motion
const btScalar angularMotionThreshold = btScalar(0.5)*SIMD_HALF_PI;
if (fAngle*deltaTime > angularMotionThreshold)
{
fAngle = angularMotionThreshold / deltaTime;
}
if ( fAngle < btScalar(0.001) )
{
// use Taylor's expansions of sync function
axis = m_angularVelocity*( btScalar(0.5)*deltaTime-(deltaTime*deltaTime*deltaTime)*(btScalar(0.020833333333))*fAngle*fAngle );
}
else
{
// sync(fAngle) = sin(c*fAngle)/t
axis = m_angularVelocity*( btSin(btScalar(0.5)*fAngle*deltaTime)/fAngle );
}
btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*deltaTime*btScalar(0.5) ));
btQuaternion orn0 = m_worldPose.m_worldOrientation;
btQuaternion predictedOrn = dorn * orn0;
predictedOrn.normalize();
m_worldPose.m_worldOrientation = predictedOrn;
}
}
void stepSimulation(double deltaTime)
{
integrateTransform(deltaTime);
}
};
///quick demo showing the right-handed coordinate system and positive rotations around each axis
class Tutorial : public CommonExampleInterface
{
CommonGraphicsApp* m_app;
float m_x;
float m_y;
float m_z;
int m_tutorialIndex;
LWRightBody* m_body;
public:
Tutorial(CommonGraphicsApp* app, int tutorialIndex)
:m_app(app),
m_x(0),
m_y(0),
m_z(0),
m_tutorialIndex(tutorialIndex)
{
m_app->setUpAxis(2);
{
int boxId = m_app->registerCubeShape(100,100,1);
btVector3 pos(0,0,-1);
btQuaternion orn(0,0,0,1);
btVector4 color(1,1,1,1);
btVector3 scaling(1,1,1);
m_app->m_renderer->registerGraphicsInstance(boxId,pos,orn,color,scaling);
}
m_body = new LWRightBody();
m_body->m_worldPose.m_worldPosition.setValue(0,0,3);
{
int textureIndex = -1;
if (1)
{
int width,height,n;
const char* filename = "data/cube.png";
const unsigned char* image=0;
const char* prefix[]={"./","../","../../","../../../","../../../../"};
int numprefix = sizeof(prefix)/sizeof(const char*);
for (int i=0;!image && i<numprefix;i++)
{
char relativeFileName[1024];
sprintf(relativeFileName,"%s%s",prefix[i],filename);
image = stbi_load(relativeFileName, &width, &height, &n, 0);
}
b3Assert(image);
if (image)
{
textureIndex = m_app->m_renderer->registerTexture(image,width,height);
}
}
int boxId = m_app->registerCubeShape(1,1,1,textureIndex);//>registerGraphicsUnitSphereShape(SPHERE_LOD_HIGH, textureIndex);
btVector4 color(1,1,1,1);
btVector3 scaling(1,1,1);
m_body->m_graphicsIndex = m_app->m_renderer->registerGraphicsInstance(boxId,m_body->m_worldPose.m_worldPosition, m_body->m_worldPose.m_worldOrientation,color,scaling);
m_app->m_renderer->writeSingleInstanceTransformToCPU(m_body->m_worldPose.m_worldPosition, m_body->m_worldPose.m_worldOrientation, m_body->m_graphicsIndex);
}
m_app->m_renderer->writeTransforms();
}
virtual ~Tutorial()
{
m_app->m_renderer->enableBlend(false);
}
virtual void initPhysics()
{
}
virtual void exitPhysics()
{
}
virtual void stepSimulation(float deltaTime)
{
m_x+=0.01f;
m_y+=0.01f;
m_z+=0.01f;
//m_body->m_worldPose.m_worldPosition+= btVector3(0,0.01,0);
//m_body->m_linearVelocity=btVector3(0,0.1,0);
m_body->m_angularVelocity =btVector3(0,0.1,0);
m_body->integrateTransform(deltaTime);
m_app->m_renderer->writeSingleInstanceTransformToCPU(m_body->m_worldPose.m_worldPosition, m_body->m_worldPose.m_worldOrientation, m_body->m_graphicsIndex);
m_app->m_renderer->writeTransforms();
}
virtual void renderScene()
{
m_app->m_renderer->renderScene();
m_app->drawText3D("X",1,0,0,1);
m_app->drawText3D("Y",0,1,0,1);
m_app->drawText3D("Z",0,0,1,1);
}
virtual void physicsDebugDraw(int debugDrawFlags)
{
}
virtual bool mouseMoveCallback(float x,float y)
{
return false;
}
virtual bool mouseButtonCallback(int button, int state, float x, float y)
{
return false;
}
virtual bool keyboardCallback(int key, int state)
{
return false;
}
virtual void resetCamera()
{
float dist = 3.5;
float pitch = 136;
float yaw = 32;
float targetPos[3]={0,0,0};
if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
{
m_app->m_renderer->getActiveCamera()->setCameraDistance(dist);
m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch);
m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw);
m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]);
}
}
};
class CommonExampleInterface* TutorialCreateFunc(struct CommonExampleOptions& options)
{
return new Tutorial(options.m_guiHelper->getAppInterface(), options.m_option);
}

View File

@@ -0,0 +1,6 @@
#ifndef TUTORIAL_H
#define TUTORIAL_H
class CommonExampleInterface* TutorialCreateFunc(struct CommonExampleOptions& options);
#endif //TUTORIAL_H