mirror of
https://github.com/bulletphysics/bullet3
synced 2025-01-11 09:50:06 +00:00
261 lines
7.7 KiB
C++
261 lines
7.7 KiB
C++
/*
|
|
* Copyright 1993-2006 NVIDIA Corporation. All rights reserved.
|
|
*
|
|
* NOTICE TO USER:
|
|
*
|
|
* This source code is subject to NVIDIA ownership rights under U.S. and
|
|
* international Copyright laws.
|
|
*
|
|
* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
|
|
* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
|
|
* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
|
|
* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
|
|
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
|
* OR PERFORMANCE OF THIS SOURCE CODE.
|
|
*
|
|
* U.S. Government End Users. This source code is a "commercial item" as
|
|
* that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
|
|
* "commercial computer software" and "commercial computer software
|
|
* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
|
|
* and is provided to the U.S. Government only as a commercial end item.
|
|
* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
|
|
* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
|
|
* source code with only those rights set forth herein.
|
|
*/
|
|
|
|
#include <GL/glew.h>
|
|
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
|
|
#include "BMF_Api.h"
|
|
|
|
#include "render_particles.h"
|
|
#include "shaders.h"
|
|
#include "LinearMath/btQuickprof.h"
|
|
#include "paramgl.h"
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.1415926535897932384626433832795
|
|
#endif
|
|
|
|
ParticleRenderer::ParticleRenderer()
|
|
: m_pos(0),
|
|
m_numParticles(0),
|
|
m_pointSize(1.0f),
|
|
m_particleRadius(0.125f * 0.5f),
|
|
m_program(0),
|
|
m_vbo(0),
|
|
m_colorVBO(0)
|
|
{
|
|
_initGL();
|
|
#ifndef BT_NO_PROFILE
|
|
m_profileIterator = CProfileManager::Get_Iterator();
|
|
#endif //BT_NO_PROFILE
|
|
}
|
|
|
|
ParticleRenderer::~ParticleRenderer()
|
|
{
|
|
m_pos = 0;
|
|
}
|
|
|
|
void ParticleRenderer::setPositions(float *pos, int numParticles)
|
|
{
|
|
m_pos = pos;
|
|
m_numParticles = numParticles;
|
|
}
|
|
|
|
void ParticleRenderer::setVertexBuffer(unsigned int vbo, int numParticles)
|
|
{
|
|
m_vbo = vbo;
|
|
m_numParticles = numParticles;
|
|
}
|
|
|
|
void ParticleRenderer::_drawPoints()
|
|
{
|
|
if (!m_vbo)
|
|
{
|
|
glBegin(GL_POINTS);
|
|
{
|
|
int k = 0;
|
|
for (int i = 0; i < m_numParticles; ++i)
|
|
{
|
|
glVertex3fv(&m_pos[k]);
|
|
k += 4;
|
|
}
|
|
}
|
|
glEnd();
|
|
}
|
|
else
|
|
{
|
|
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vbo);
|
|
glVertexPointer(4, GL_FLOAT, 0, 0);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
if (m_colorVBO) {
|
|
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_colorVBO);
|
|
glColorPointer(4, GL_FLOAT, 0, 0);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
}
|
|
|
|
glDrawArrays(GL_POINTS, 0, m_numParticles);
|
|
|
|
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
}
|
|
}
|
|
|
|
void ParticleRenderer::display(DisplayMode mode /* = PARTICLE_POINTS */)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case PARTICLE_POINTS:
|
|
glColor3f(1, 1, 1);
|
|
glPointSize(m_pointSize);
|
|
_drawPoints();
|
|
break;
|
|
|
|
default:
|
|
case PARTICLE_SPHERES:
|
|
glEnable(GL_POINT_SPRITE_ARB);
|
|
glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
|
|
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);
|
|
glDepthMask(GL_TRUE);
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glUseProgram(m_program);
|
|
glUniform1f( glGetUniformLocation(m_program, "pointScale"), m_window_h / tanf(m_fov*0.5f*(float)M_PI/180.0f) );
|
|
glUniform1f( glGetUniformLocation(m_program, "pointRadius"), m_particleRadius );
|
|
|
|
glColor3f(1, 1, 1);
|
|
_drawPoints();
|
|
|
|
glUseProgram(0);
|
|
glDisable(GL_POINT_SPRITE_ARB);
|
|
break;
|
|
}
|
|
}
|
|
|
|
GLuint
|
|
ParticleRenderer::_compileProgram(const char *vsource, const char *fsource)
|
|
{
|
|
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
glShaderSource(vertexShader, 1, &vsource, 0);
|
|
glShaderSource(fragmentShader, 1, &fsource, 0);
|
|
|
|
glCompileShader(vertexShader);
|
|
glCompileShader(fragmentShader);
|
|
|
|
GLuint program = glCreateProgram();
|
|
|
|
glAttachShader(program, vertexShader);
|
|
glAttachShader(program, fragmentShader);
|
|
|
|
glLinkProgram(program);
|
|
|
|
// check if program linked
|
|
GLint success = 0;
|
|
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
|
|
|
if (!success) {
|
|
char temp[256];
|
|
glGetProgramInfoLog(program, 256, 0, temp);
|
|
printf("Failed to link program:\n%s\n", temp);
|
|
glDeleteProgram(program);
|
|
program = 0;
|
|
}
|
|
|
|
return program;
|
|
}
|
|
|
|
void ParticleRenderer::_initGL()
|
|
{
|
|
m_program = _compileProgram(vertexShader, spherePixelShader);
|
|
|
|
#if !defined(__APPLE__) && !defined(MACOSX)
|
|
glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE);
|
|
glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE);
|
|
#endif
|
|
}
|
|
|
|
#if 1
|
|
void ParticleRenderer::showProfileInfo(float& xOffset,float& yStart, float yIncr)
|
|
{
|
|
#ifndef BT_NO_PROFILE
|
|
|
|
static double time_since_reset = 0.f;
|
|
// if (!m_idle)
|
|
{
|
|
time_since_reset = CProfileManager::Get_Time_Since_Reset();
|
|
}
|
|
beginWinCoords();
|
|
|
|
{
|
|
//recompute profiling data, and store profile strings
|
|
|
|
char blockTime[128];
|
|
|
|
double totalTime = 0;
|
|
|
|
int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
|
|
|
|
m_profileIterator->First();
|
|
|
|
double parent_time = m_profileIterator->Is_Root() ? time_since_reset : m_profileIterator->Get_Current_Parent_Total_Time();
|
|
|
|
{
|
|
sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", m_profileIterator->Get_Current_Parent_Name(), parent_time );
|
|
displayProfileString(xOffset,yStart,blockTime);
|
|
yStart += yIncr;
|
|
sprintf(blockTime,"press number (1,2...) to display child timings, or 0 to go up to parent" );
|
|
displayProfileString(xOffset,yStart,blockTime);
|
|
yStart += yIncr;
|
|
|
|
}
|
|
double accumulated_time = 0.f;
|
|
|
|
for (int i = 0; !m_profileIterator->Is_Done(); m_profileIterator->Next())
|
|
{
|
|
double current_total_time = m_profileIterator->Get_Current_Total_Time();
|
|
accumulated_time += current_total_time;
|
|
double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
|
|
|
|
sprintf(blockTime,"%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)",
|
|
++i, m_profileIterator->Get_Current_Name(), fraction,
|
|
(current_total_time / (double)frames_since_reset),m_profileIterator->Get_Current_Total_Calls());
|
|
displayProfileString(xOffset,yStart,blockTime);
|
|
yStart += yIncr;
|
|
totalTime += current_total_time;
|
|
}
|
|
|
|
sprintf(blockTime,"%s (%.3f %%) :: %.3f ms", "Unaccounted",
|
|
// (min(0, time_since_reset - totalTime) / time_since_reset) * 100);
|
|
parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
|
|
|
|
displayProfileString(xOffset,yStart,blockTime);
|
|
yStart += yIncr;
|
|
sprintf(blockTime,"-------------------------------------------------");
|
|
displayProfileString(xOffset,yStart,blockTime);
|
|
yStart += yIncr;
|
|
|
|
}
|
|
endWinCoords();
|
|
#endif//BT_NO_PROFILE
|
|
}
|
|
|
|
|
|
void ParticleRenderer::displayProfileString(int xOffset,int yStart,char* message)
|
|
{
|
|
glRasterPos3f(xOffset,yStart,0);
|
|
BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),message);
|
|
}
|
|
|
|
#endif |