Skip to content
Snippets Groups Projects
Commit 2bde7292 authored by Oliver Bock's avatar Oliver Bock
Browse files

Use wireframe triangle fans for cones and visualize beam intensity by texture

parent f59e10fc
No related branches found
No related tags found
No related merge requests found
......@@ -57,13 +57,16 @@ PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) :
m_quadricCompanion = NULL;
m_quadricPulsarOrbitPlane = NULL;
m_quadricPulsar = NULL;
m_quadricPulsarCone1 = NULL;
m_quadricPulsarCone2 = NULL;
m_quadricPulsarCone1Shell = NULL;
m_quadricPulsarCone2Shell = NULL;
m_quadricPulsarSpinAxis = NULL;
m_quadricPulsarSpinAxisTop1 = NULL;
m_quadricPulsarSpinAxisTop2 = NULL;
m_quadricPulsarMagneticAxis = NULL;
// initialize texture pointers
m_backgroundTexture = 0;
m_beamTexture = 0;
// initial render timing settings
m_framesPerSecond = 25;
......@@ -82,6 +85,11 @@ PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) :
m_companionSemiMajorAxis = (m_pulsarMass/m_companionMass) * m_pulsarSemiMajorAxis;
// initial spin frequency of 0.5 Hz
m_pulsarRotationDelta = (360.0 * 0.5) / m_framesPerSecond;
// beam properties (keep this order!)
m_pulsarBeamLength = 3.0f;
setPulsarBeamAngle(30);
// update orbital period (based on settings above)
updateOrbitPeriod();
......@@ -109,12 +117,15 @@ PulsarAnimationWidget::~PulsarAnimationWidget()
if(m_quadricCompanion) gluDeleteQuadric(m_quadricCompanion);
if(m_quadricPulsarOrbitPlane) gluDeleteQuadric(m_quadricPulsarOrbitPlane);
if(m_quadricPulsar) gluDeleteQuadric(m_quadricPulsar);
if(m_quadricPulsarCone1) gluDeleteQuadric(m_quadricPulsarCone1);
if(m_quadricPulsarCone2) gluDeleteQuadric(m_quadricPulsarCone2);
if(m_quadricPulsarCone1Shell) gluDeleteQuadric(m_quadricPulsarCone1Shell);
if(m_quadricPulsarCone2Shell) gluDeleteQuadric(m_quadricPulsarCone2Shell);
if(m_quadricPulsarSpinAxis) gluDeleteQuadric(m_quadricPulsarSpinAxis);
if(m_quadricPulsarSpinAxisTop1) gluDeleteQuadric(m_quadricPulsarSpinAxisTop1);
if(m_quadricPulsarSpinAxisTop2) gluDeleteQuadric(m_quadricPulsarSpinAxisTop2);
if(m_quadricPulsarMagneticAxis) gluDeleteQuadric(m_quadricPulsarMagneticAxis);
if(m_backgroundTexture) deleteTexture(m_backgroundTexture);
if(m_beamTexture) deleteTexture(m_beamTexture);
}
void PulsarAnimationWidget::initializeGL()
......@@ -143,7 +154,6 @@ void PulsarAnimationWidget::initializeGL()
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
......@@ -152,18 +162,22 @@ void PulsarAnimationWidget::initializeGL()
m_quadricCompanion = gluNewQuadric();
m_quadricPulsarOrbitPlane = gluNewQuadric();
m_quadricPulsar = gluNewQuadric();
m_quadricPulsarCone1 = gluNewQuadric();
m_quadricPulsarCone2 = gluNewQuadric();
m_quadricPulsarCone1Shell = gluNewQuadric();
m_quadricPulsarCone2Shell = gluNewQuadric();
m_quadricPulsarSpinAxis = gluNewQuadric();
m_quadricPulsarSpinAxisTop1 = gluNewQuadric();
m_quadricPulsarSpinAxisTop2 = gluNewQuadric();
m_quadricPulsarMagneticAxis = gluNewQuadric();
gluQuadricNormals(m_quadricCompanionOrbitPlane, GLU_SMOOTH);
gluQuadricNormals(m_quadricCompanion, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarOrbitPlane, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsar, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarCone1, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarCone2, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarCone1Shell, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarCone2Shell, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarSpinAxis, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarSpinAxisTop1, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarSpinAxisTop2, GLU_SMOOTH);
gluQuadricNormals(m_quadricPulsarMagneticAxis, GLU_SMOOTH);
// query max texture size (estimate)
......@@ -193,16 +207,31 @@ void PulsarAnimationWidget::initializeGL()
backgroundTexture = backgroundTexture.scaled(maxTextureSize, maxTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
}
// prepare and check beam texture
QImage beamTexture(":/textures/resources/texture_beam.png");
if(beamTexture.width() != beamTexture.height()) {
qWarning() << msgShape.arg(tr("Beam"));
}
else {
double integer = 0.0;
double fraction = 0.0;
fraction = modf(log(beamTexture.width()) / log(2.0), &integer);
if(fraction > 0.0) {
qWarning() << msgPower.arg(tr("Beam"));
}
}
if(beamTexture.width() > maxTextureSize) {
qWarning() << msgSize.arg(tr("beam").arg(maxTextureSize).arg(maxTextureSize));
beamTexture = beamTexture.scaled(maxTextureSize, maxTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
}
// bind textures
m_backgroundTexture = bindTexture(backgroundTexture, GL_TEXTURE_2D, GL_RGBA);
m_beamTexture = bindTexture(beamTexture, GL_TEXTURE_2D, GL_RGBA);
// use mipmapped textures
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
// enable 2D mapping (s/t coordinates, sphere map won't rotate texture!)
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
}
void PulsarAnimationWidget::resizeGL(int w, int h)
......@@ -220,6 +249,8 @@ void PulsarAnimationWidget::resizeGL(int w, int h)
void PulsarAnimationWidget::paintGL()
{
GLfloat x,y,angle;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
......@@ -272,10 +303,17 @@ void PulsarAnimationWidget::paintGL()
glTranslatef(sin((m_orbitRotationAngle + 180.0) * deg2rad) * m_companionSemiMajorAxis,
0.0,
cos((m_orbitRotationAngle + 180.0) * deg2rad) * m_companionSemiMajorAxis);
// draw, with proper lighting
glEnable(GL_LIGHTING);
gluSphere(m_quadricCompanion, 1.0, 32, 32);
glDisable(GL_LIGHTING);
}
glPopMatrix();
// enable wireframe mode
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
// draw pulsar
glPushMatrix();
{
......@@ -302,20 +340,15 @@ void PulsarAnimationWidget::paintGL()
glPopMatrix();
}
// enable wireframe mode
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
// draw pulsar
// draw sphere, with proper lighting
glEnable(GL_LIGHTING);
glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
gluSphere(m_quadricPulsar, 1.0, 32, 32);
// disable wireframe mode
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glDisable(GL_LIGHTING);
}
glPopMatrix();
// TODO: should be located elsewhere
static GLfloat coneAmbient[] = {1.0, 1.0, 0.0, 1.0};
static GLfloat coneDiffuse[] = {1.0, 1.0, 0.0, 1.0};
static GLfloat coneSpecular[] = {1.0, 1.0, 0.5, 1.0};
// first cone
glPushMatrix();
{
......@@ -327,24 +360,72 @@ void PulsarAnimationWidget::paintGL()
// draw magnetic axis (for both cones)
if(m_showRotationAxes) {
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
{
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
glTranslatef(0.0, 0.0, -5.0);
gluCylinder(m_quadricPulsarMagneticAxis, 0.05, 0.05, 10.0, 32, 1);
glTranslatef(0.0, 0.0, -4.0);
gluCylinder(m_quadricPulsarMagneticAxis, 0.020, 0.020, 8.0, 32, 1);
}
glPopMatrix();
glPushMatrix();
{
glTranslatef(0.0, 0.0, -4.0);
gluDisk(m_quadricPulsarSpinAxisTop1, 0, 0.020, 32, 8);
}
glPopMatrix();
glPushMatrix();
{
glTranslatef(0.0, 0.0, 4.0);
gluDisk(m_quadricPulsarSpinAxisTop2, 0, 0.020, 32, 8);
}
glPopMatrix();
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
glTranslatef(0.0, 0.0, -m_pulsarBeamLength);
// draw first cone's outer layer
glBegin(GL_TRIANGLE_FAN);
{
// Pinnacle of cone is shared vertex for fan, moved up z-axis
// to produce a cone instead of a circle
glColor4f(1.0f, 1.0f, 0.0f, 0.33f);
glVertex3f(0.0f, 0.0f, m_pulsarBeamLength);
// Loop around in a circle and specify even points along the circle
// as the vertices of the triangle fan (32 sections)
for(angle = 0.0f; angle < (2.0f*PI); angle += (PI/32.0f))
{
// Calculate x and y position of the next vertex
x = m_pulsarBeamOuterRadius * sin(angle);
y = m_pulsarBeamOuterRadius * cos(angle);
// Specify the next vertex for the triangle fan
glVertex2f(x, y);
}
}
glEnd();
// draw first cone's "base" (textured bottom to visualize beam intensity)
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// create texture coordinates and enable texturing
gluQuadricTexture(m_quadricPulsarCone1Shell, GL_TRUE);
glBindTexture(GL_TEXTURE_2D, m_beamTexture);
glEnable(GL_TEXTURE_2D);
glTranslatef(0.0, 0.0, -3.0);
gluDisk(m_quadricPulsarCone1Shell, 0, m_pulsarBeamOuterRadius, 32, 1);
glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse);
gluCylinder(m_quadricPulsarCone1, 0.475, 0.0, 3.0, 32, 32);
// disable texturing
glDisable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
glPopMatrix();
// second cone
// second cone (pointing towards from camera)
glPushMatrix();
{
glRotatef(-90.0, 1.0, 0.0, 0.0);
......@@ -353,43 +434,55 @@ void PulsarAnimationWidget::paintGL()
glRotatef(m_pulsarRotationAngle - 90.0, 0.0, 0.0, 1.0);
glRotatef(m_pulsarMagneticAxisInclination, 1.0, 0.0, 0.0);
glTranslatef(0.0, 0.0, -3.0);
glTranslatef(0.0, 0.0, -m_pulsarBeamLength);
// draw second cone's outer layer
glBegin(GL_TRIANGLE_FAN);
{
// Pinnacle of cone is shared vertex for fan, moved up z-axis
// to produce a cone instead of a circle
glColor4f(1.0f, 1.0f, 0.0f, 0.33f);
glVertex3f(0.0f, 0.0f, m_pulsarBeamLength);
// Loop around in a circle and specify even points along the circle
// as the vertices of the triangle fan (32 sections)
for(angle = 0.0f; angle < (2.0f*PI); angle += (PI/32.0f))
{
// Calculate x and y position of the next vertex
x = m_pulsarBeamOuterRadius * sin(angle);
y = m_pulsarBeamOuterRadius * cos(angle);
glMaterialfv(GL_FRONT, GL_AMBIENT, coneAmbient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, coneDiffuse);
gluCylinder(m_quadricPulsarCone2, 0.475, 0.0, 3.0, 32, 32);
// Specify the next vertex for the triangle fan
glVertex2f(x, y);
}
glPopMatrix();
}
glPopMatrix();
glEnd();
// save current state (the following is using parallel projection)
glMatrixMode(GL_PROJECTION);
glPushMatrix();
{
glLoadIdentity();
glOrtho(0, width(), 0, height(), 0.1, 501.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
{
glLoadIdentity();
// draw second cone's "base" (textured bottom to visualize beam intensity)
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// draw backdrop (independent parallel projection)
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_specular);
glTranslatef(0.0, 0.0, -501.0);
drawTexture(QPointF(0.0, 0.0), m_backgroundTexture);
// create texture coordinates and enable texturing
gluQuadricTexture(m_quadricPulsarCone2Shell, GL_TRUE);
glBindTexture(GL_TEXTURE_2D, m_beamTexture);
glEnable(GL_TEXTURE_2D);
// restore original state
glMatrixMode(GL_PROJECTION);
gluDisk(m_quadricPulsarCone2Shell, 0, m_pulsarBeamOuterRadius, 32, 1);
// disable texturing
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
glPopMatrix();
// back to solid rendering
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
// draw orbital planes
if(m_cameraInteraction || m_showOrbits) {
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, translucent);
glEnable(GL_LIGHTING);
static double sizeOffset = 0.25;
......@@ -424,6 +517,8 @@ void PulsarAnimationWidget::paintGL()
64, 1);
}
glPopMatrix();
glDisable(GL_LIGHTING);
}
// save current state (the following is using parallel projection)
......@@ -629,6 +724,23 @@ void PulsarAnimationWidget::setPulsarMagneticAxisInclination(const int degrees)
updateGL();
}
void PulsarAnimationWidget::setPulsarBeamAngle(const int degrees)
{
double beamTexturePeakCorrectionFactor = 0.83;
double correctedOuterRadius;
// compute visual radius
m_pulsarBeamOuterRadius = tan(deg2rad * degrees * 0.5f) * m_pulsarBeamLength;
// compute corrected angle for pulse profile
correctedOuterRadius = m_pulsarBeamOuterRadius * beamTexturePeakCorrectionFactor;
m_pulsarBeamAngle = 2 * atan(correctedOuterRadius / m_pulsarBeamLength) * 180.0/PI;
updatePulseProfile();
updateGL();
}
void PulsarAnimationWidget::updateOrbitPeriod()
{
m_orbitalPeriod = 3.1553e7 * sqrt(
......
......@@ -46,6 +46,7 @@ public:
void setPulsarSpinAxisInclination(const int degrees);
void setPulsarMagneticAxisInclination(const int degrees);
void setPulsarSemiMajorAxis(const double length);
void setPulsarBeamAngle(const int degrees);
public slots:
void runAnimation();
......@@ -84,12 +85,15 @@ private:
GLUquadricObj *m_quadricCompanion;
GLUquadricObj *m_quadricPulsarOrbitPlane;
GLUquadricObj *m_quadricPulsar;
GLUquadricObj *m_quadricPulsarCone1;
GLUquadricObj *m_quadricPulsarCone2;
GLUquadricObj *m_quadricPulsarCone1Shell;
GLUquadricObj *m_quadricPulsarCone2Shell;
GLUquadricObj *m_quadricPulsarSpinAxis;
GLUquadricObj *m_quadricPulsarSpinAxisTop1;
GLUquadricObj *m_quadricPulsarSpinAxisTop2;
GLUquadricObj *m_quadricPulsarMagneticAxis;
GLuint m_backgroundTexture;
GLuint m_beamTexture;
int m_framesPerSecond;
......@@ -107,6 +111,9 @@ private:
double m_pulsarSpinAxisInclination;
double m_pulsarMagneticAxisInclination;
double m_pulsarBeamLength;
double m_pulsarBeamAngle;
double m_pulsarBeamOuterRadius;
bool m_showOrbits;
bool m_showRotationAxes;
......
......@@ -14,5 +14,6 @@
</qresource>
<qresource prefix="/textures">
<file>resources/texture_background_carina.png</file>
<file>resources/texture_beam.png</file>
</qresource>
</RCC>
src/resources/texture_beam.png

50.2 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="texture_beam.svg">
<defs
id="defs4">
<linearGradient
id="linearGradient3685">
<stop
style="stop-color:#ffff00;stop-opacity:1;"
offset="0"
id="stop3687" />
<stop
style="stop-color:#ffff00;stop-opacity:0;"
offset="1"
id="stop3689" />
</linearGradient>
<linearGradient
id="linearGradient3679">
<stop
id="stop3681"
offset="0"
style="stop-color:#ffff00;stop-opacity:0.17647059;" />
<stop
style="stop-color:#ffff00;stop-opacity:1;"
offset="0.84778017"
id="stop3691" />
<stop
id="stop3683"
offset="1"
style="stop-color:#ffff00;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient3671">
<stop
style="stop-color:#ffff00;stop-opacity:1;"
offset="0"
id="stop3673" />
<stop
style="stop-color:#ffff00;stop-opacity:0;"
offset="1"
id="stop3675" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3679"
id="radialGradient3677"
cx="438.57144"
cy="610.93359"
fx="438.57144"
fy="610.93359"
r="187.14285"
gradientUnits="userSpaceOnUse"
spreadMethod="repeat" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.71743361"
inkscape:cx="123.94066"
inkscape:cy="470.4268"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1680"
inkscape:window-height="1002"
inkscape:window-x="1440"
inkscape:window-y="22"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
sodipodi:type="arc"
style="fill:url(#radialGradient3677);fill-opacity:1.0"
id="path2816"
sodipodi:cx="438.57144"
sodipodi:cy="610.93359"
sodipodi:rx="187.14285"
sodipodi:ry="187.14285"
d="m 625.71429,610.93359 a 187.14285,187.14285 0 1 1 -374.2857,0 187.14285,187.14285 0 1 1 374.2857,0 z"
transform="matrix(1.367939,0,0,1.367939,-217.81337,-338.24157)"
inkscape:export-filename="/Users/oliver/Development/pulsatingscience/src/resources/texture_beam.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
</g>
</svg>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment