mirror of
https://github.com/ENSL/NS.git
synced 2024-11-14 17:01:29 +00:00
149 lines
3.6 KiB
C++
149 lines
3.6 KiB
C++
// opengl.cpp
|
|
//
|
|
// Copyright 1998 by David K. McAllister
|
|
//
|
|
// This file implements the API calls that draw particle groups in OpenGL.
|
|
|
|
#include "general.h"
|
|
|
|
#ifdef WIN32
|
|
// This is for something in gl.h.
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
#include <GL/gl.h>
|
|
// XXX #include <iostream.h>
|
|
|
|
// Emit OpenGL calls to draw the particles. These are drawn with
|
|
// whatever primitive type the user specified(GL_POINTS, for
|
|
// example). The color and radius are set per primitive, by default.
|
|
// For GL_LINES, the other vertex of the line is the velocity vector.
|
|
// XXX const_size is ignored.
|
|
PARTICLEDLL_API void pDrawGroupp(int primitive, bool const_size, bool const_color)
|
|
{
|
|
_ParticleState &_ps = _GetPState();
|
|
|
|
// Get a pointer to the particles in gp memory
|
|
ParticleGroup *pg = _ps.pgrp;
|
|
|
|
if(pg == NULL)
|
|
return; // ERROR
|
|
|
|
if(pg->p_count < 1)
|
|
return;
|
|
|
|
if(primitive == GL_POINTS)
|
|
{
|
|
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
if(!const_color)
|
|
{
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
glColorPointer(4, GL_FLOAT, sizeof(Particle), &pg->list[0].color);
|
|
}
|
|
|
|
glVertexPointer(3, GL_FLOAT, sizeof(Particle), &pg->list[0].pos);
|
|
glDrawArrays((GLenum)primitive, 0, pg->p_count);
|
|
glPopClientAttrib();
|
|
// XXX For E&S
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
}
|
|
else
|
|
{
|
|
// Assume GL_LINES
|
|
glBegin((GLenum)primitive);
|
|
|
|
if(!const_color)
|
|
{
|
|
for(int i = 0; i < pg->p_count; i++)
|
|
{
|
|
Particle &m = pg->list[i];
|
|
|
|
// Warning: this depends on alpha following color in the Particle struct.
|
|
glColor4fv((GLfloat *)&m.color);
|
|
glVertex3fv((GLfloat *)&m.pos);
|
|
|
|
// For lines, make a tail with the velocity vector's direction and
|
|
// a length of radius.
|
|
pVector tail = m.pos - m.vel;
|
|
glVertex3fv((GLfloat *)&tail);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int i = 0; i < pg->p_count; i++)
|
|
{
|
|
Particle &m = pg->list[i];
|
|
glVertex3fv((GLfloat *)&m.pos);
|
|
|
|
// For lines, make a tail with the velocity vector's direction and
|
|
// a length of radius.
|
|
pVector tail = m.pos - m.vel;
|
|
glVertex3fv((GLfloat *)&tail);
|
|
}
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
PARTICLEDLL_API void pDrawGroupl(int dlist, bool const_size, bool const_color, bool const_rotation)
|
|
{
|
|
_ParticleState &_ps = _GetPState();
|
|
|
|
// Get a pointer to the particles in gp memory
|
|
ParticleGroup *pg = _ps.pgrp;
|
|
if(pg == NULL)
|
|
return; // ERROR
|
|
|
|
if(pg->p_count < 1)
|
|
return;
|
|
|
|
//if(const_color)
|
|
// glColor4fv((GLfloat *)&pg->list[0].color);
|
|
|
|
for(int i = 0; i < pg->p_count; i++)
|
|
{
|
|
Particle &m = pg->list[i];
|
|
|
|
glPushMatrix();
|
|
glTranslatef(m.pos.x, m.pos.y, m.pos.z);
|
|
|
|
if(!const_size)
|
|
glScalef(m.size.x, m.size.y, m.size.z);
|
|
else
|
|
glScalef(pg->list[i].size.x, pg->list[i].size.y, pg->list[i].size.z);
|
|
|
|
// Expensive! A sqrt, cross prod and acos. Yow.
|
|
if(!const_rotation)
|
|
{
|
|
pVector vN(m.vel);
|
|
vN.normalize();
|
|
pVector voN(m.velB);
|
|
voN.normalize();
|
|
|
|
pVector biN;
|
|
if(voN.x == vN.x && voN.y == vN.y && voN.z == vN.z)
|
|
biN = pVector(0, 1, 0);
|
|
else
|
|
biN = vN ^ voN;
|
|
biN.normalize();
|
|
|
|
pVector N(vN ^ biN);
|
|
|
|
double M[16];
|
|
M[0] = vN.x; M[4] = biN.x; M[8] = N.x; M[12] = 0;
|
|
M[1] = vN.y; M[5] = biN.y; M[9] = N.y; M[13] = 0;
|
|
M[2] = vN.z; M[6] = biN.z; M[10] = N.z; M[14] = 0;
|
|
M[3] = 0; M[7] = 0; M[11] = 0; M[15] = 1;
|
|
glMultMatrixd(M);
|
|
}
|
|
|
|
// Warning: this depends on alpha following color in the Particle struct.
|
|
if(!const_color)
|
|
glColor4fv((GLfloat *)&m.color);
|
|
|
|
glCallList(dlist);
|
|
|
|
glPopMatrix();
|
|
}
|
|
}
|