2018-04-22 15:55:55 +00:00
|
|
|
// This file implements the API calls that draw particle groups in Half-life
|
|
|
|
|
|
|
|
#include "general.h"
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
// This is for something in gl.h.
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//#include <GL/gl.h>
|
|
|
|
#include "common/triangleapi.h"
|
|
|
|
#include "cl_dll/wrect.h"
|
|
|
|
#include "cl_dll/cl_dll.h"
|
|
|
|
#include "common/renderingconst.h"
|
|
|
|
#include "particles/papi.h"
|
|
|
|
|
|
|
|
// XXX #include <iostream.h>
|
|
|
|
|
|
|
|
// Draw as a splat texture on a quad.
|
|
|
|
void DrawGroupTriSplat(const pVector &view, const pVector &up,
|
|
|
|
float size_scale, bool draw_tex,
|
|
|
|
bool const_size, bool const_color)
|
|
|
|
{
|
|
|
|
int cnt = pGetGroupCount();
|
|
|
|
|
|
|
|
if(cnt < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pVector *ppos = new pVector[cnt];
|
|
|
|
float *color = const_color ? NULL : new float[cnt * 4];
|
|
|
|
pVector *size = const_size ? NULL : new pVector[cnt];
|
|
|
|
|
|
|
|
pGetParticles(0, cnt, (float *)ppos, color, NULL, (float *)size);
|
|
|
|
|
|
|
|
// Compute the vectors from the particle to the corners of its tri.
|
|
|
|
// 2
|
|
|
|
// |\ The particle is at the center of the x.
|
|
|
|
// |-\ V0, V1, and V2 go from there to the vertices.
|
|
|
|
// |x|\ The texcoords are (0,0), (2,0), and (0,2) respectively.
|
|
|
|
// 0-+-1 We clamp the texture so the rest is transparent.
|
|
|
|
|
|
|
|
pVector right = view ^ up;
|
|
|
|
right.normalize();
|
|
|
|
pVector nup = right ^ view;
|
|
|
|
right *= size_scale;
|
|
|
|
nup *= size_scale;
|
|
|
|
|
|
|
|
pVector V0 = -(right + nup);
|
|
|
|
pVector V1 = V0 + right * 4;
|
|
|
|
pVector V2 = V0 + nup*4 + right*2;
|
|
|
|
|
|
|
|
//cerr << "x " << view.x << " " << view.y << " " << view.z << endl;
|
|
|
|
//cerr << "x " << nup.x << " " << nup.y << " " << nup.z << endl;
|
|
|
|
//cerr << "x " << right.x << " " << right.y << " " << right.z << endl;
|
|
|
|
//cerr << "x " << V0.x << " " << V0.y << " " << V0.z << endl;
|
|
|
|
|
|
|
|
//glBegin(GL_TRIANGLES);
|
|
|
|
gEngfuncs.pTriAPI->Begin( TRI_TRIANGLES );
|
|
|
|
//gEngfuncs.pTriAPI->RenderMode( kRenderTransAlpha );
|
|
|
|
|
|
|
|
for(int i = 0; i < cnt; i++)
|
|
|
|
{
|
|
|
|
pVector &p = ppos[i];
|
|
|
|
|
|
|
|
float* theCurrentColor = &color[i*4];
|
|
|
|
if(!const_color)
|
|
|
|
{
|
|
|
|
//glColor4fv((GLfloat *)&color[i*4]);
|
|
|
|
gEngfuncs.pTriAPI->Color4f(theCurrentColor[0], theCurrentColor[1], theCurrentColor[2], theCurrentColor[3]);
|
|
|
|
}
|
|
|
|
//else
|
|
|
|
//{
|
|
|
|
// gEngfuncs.pTriAPI->Color4f(1.0f, 1.0f, 1.0f, .5f);
|
|
|
|
//}
|
|
|
|
|
|
|
|
pVector sV0 = V0;
|
|
|
|
pVector sV1 = V1;
|
|
|
|
pVector sV2 = V2;
|
|
|
|
|
|
|
|
if(!const_size)
|
|
|
|
{
|
|
|
|
sV0 *= size[i].x;
|
|
|
|
sV1 *= size[i].x;
|
|
|
|
sV2 *= size[i].x;
|
|
|
|
}
|
|
|
|
|
|
|
|
//if(draw_tex) glTexCoord2f(0,0);
|
|
|
|
if(draw_tex) gEngfuncs.pTriAPI->TexCoord2f(0,0);
|
|
|
|
pVector ver = p + sV0;
|
|
|
|
//glVertex3fv((GLfloat *)&ver);
|
|
|
|
gEngfuncs.pTriAPI->Vertex3fv((float*)&ver);
|
|
|
|
|
|
|
|
//if(draw_tex) glTexCoord2f(2,0);
|
|
|
|
if(draw_tex) gEngfuncs.pTriAPI->TexCoord2f(1,0);
|
|
|
|
ver = p + sV1;
|
|
|
|
//glVertex3fv((GLfloat *)&ver);
|
|
|
|
gEngfuncs.pTriAPI->Vertex3fv((float*)&ver);
|
|
|
|
|
|
|
|
//if(draw_tex) glTexCoord2f(0,2);
|
|
|
|
if(draw_tex) gEngfuncs.pTriAPI->TexCoord2f(.5,1);
|
|
|
|
ver = p + sV2;
|
|
|
|
//glVertex3fv((GLfloat *)&ver);
|
|
|
|
gEngfuncs.pTriAPI->Vertex3fv((float*)&ver);
|
|
|
|
}
|
|
|
|
|
|
|
|
//glEnd();
|
|
|
|
gEngfuncs.pTriAPI->End();
|
|
|
|
|
|
|
|
delete [] ppos;
|
|
|
|
if(color) delete [] color;
|
|
|
|
if(size) delete [] size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
// }
|
|
|
|
//}
|