Refactor render.cpp and extract some classes to own files
parent
7f052a65e4
commit
8778c07ccb
|
@ -47,6 +47,7 @@ set(CELENGINE_SOURCES
|
||||||
globular.h
|
globular.h
|
||||||
glshader.cpp
|
glshader.cpp
|
||||||
glshader.h
|
glshader.h
|
||||||
|
#hdrfuncrender.cpp
|
||||||
image.cpp
|
image.cpp
|
||||||
image.h
|
image.h
|
||||||
lightenv.h
|
lightenv.h
|
||||||
|
@ -66,11 +67,13 @@ set(CELENGINE_SOURCES
|
||||||
name.h
|
name.h
|
||||||
nebula.cpp
|
nebula.cpp
|
||||||
nebula.h
|
nebula.h
|
||||||
|
objectrenderer.h
|
||||||
observer.cpp
|
observer.cpp
|
||||||
observer.h
|
observer.h
|
||||||
octree.h
|
octree.h
|
||||||
opencluster.cpp
|
opencluster.cpp
|
||||||
opencluster.h
|
opencluster.h
|
||||||
|
orbitsampler.h
|
||||||
overlay.cpp
|
overlay.cpp
|
||||||
overlay.h
|
overlay.h
|
||||||
overlayimage.cpp
|
overlayimage.cpp
|
||||||
|
@ -85,15 +88,20 @@ set(CELENGINE_SOURCES
|
||||||
# particlesystem.h
|
# particlesystem.h
|
||||||
planetgrid.cpp
|
planetgrid.cpp
|
||||||
planetgrid.h
|
planetgrid.h
|
||||||
|
pointstarrenderer.cpp
|
||||||
|
pointstarrenderer.h
|
||||||
|
pointstarvertexbuffer.cpp
|
||||||
|
pointstarvertexbuffer.h
|
||||||
rectangle.h
|
rectangle.h
|
||||||
referencemark.h
|
referencemark.h
|
||||||
rendcontext.cpp
|
rendcontext.cpp
|
||||||
rendcontext.h
|
rendcontext.h
|
||||||
render.cpp
|
render.cpp
|
||||||
|
render.h
|
||||||
renderglsl.cpp
|
renderglsl.cpp
|
||||||
renderglsl.h
|
renderglsl.h
|
||||||
render.h
|
|
||||||
renderinfo.h
|
renderinfo.h
|
||||||
|
renderlistentry.h
|
||||||
rotationmanager.cpp
|
rotationmanager.cpp
|
||||||
rotationmanager.h
|
rotationmanager.h
|
||||||
selection.cpp
|
selection.cpp
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
// License and a copy of the GNU General Public License along with
|
// License and a copy of the GNU General Public License along with
|
||||||
// orbitpath. If not, see <http://www.gnu.org/licenses/>.
|
// orbitpath. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <Eigen/Geometry>
|
#include <Eigen/Geometry>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,443 @@
|
||||||
|
// render.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2009, the Celestia Development Team
|
||||||
|
// Original version by Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#ifdef USE_HDR
|
||||||
|
void Renderer::genBlurTextures()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < BLUR_PASS_COUNT; ++i)
|
||||||
|
{
|
||||||
|
if (blurTextures[i] != nullptr)
|
||||||
|
{
|
||||||
|
delete blurTextures[i];
|
||||||
|
blurTextures[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blurTempTexture != nullptr)
|
||||||
|
{
|
||||||
|
delete blurTempTexture;
|
||||||
|
blurTempTexture = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
blurBaseWidth = sceneTexWidth, blurBaseHeight = sceneTexHeight;
|
||||||
|
|
||||||
|
if (blurBaseWidth > blurBaseHeight)
|
||||||
|
{
|
||||||
|
while (blurBaseWidth > BLUR_SIZE)
|
||||||
|
{
|
||||||
|
blurBaseWidth >>= 1;
|
||||||
|
blurBaseHeight >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (blurBaseHeight > BLUR_SIZE)
|
||||||
|
{
|
||||||
|
blurBaseWidth >>= 1;
|
||||||
|
blurBaseHeight >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genBlurTexture(0);
|
||||||
|
genBlurTexture(1);
|
||||||
|
|
||||||
|
Image *tempImg;
|
||||||
|
ImageTexture *tempTexture;
|
||||||
|
tempImg = new Image(GL_LUMINANCE, blurBaseWidth, blurBaseHeight);
|
||||||
|
tempTexture = new ImageTexture(*tempImg, Texture::EdgeClamp, Texture::DefaultMipMaps);
|
||||||
|
delete tempImg;
|
||||||
|
if (tempTexture && tempTexture->getName() != 0)
|
||||||
|
blurTempTexture = tempTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::genBlurTexture(int blurLevel)
|
||||||
|
{
|
||||||
|
Image *img;
|
||||||
|
ImageTexture *texture;
|
||||||
|
|
||||||
|
#ifdef DEBUG_HDR
|
||||||
|
HDR_LOG <<
|
||||||
|
"Window width = " << windowWidth << ", " <<
|
||||||
|
"Window height = " << windowHeight << ", " <<
|
||||||
|
"Blur tex width = " << (blurBaseWidth>>blurLevel) << ", " <<
|
||||||
|
"Blur tex height = " << (blurBaseHeight>>blurLevel) << endl;
|
||||||
|
#endif
|
||||||
|
img = new Image(blurFormat,
|
||||||
|
blurBaseWidth>>blurLevel,
|
||||||
|
blurBaseHeight>>blurLevel);
|
||||||
|
texture = new ImageTexture(*img,
|
||||||
|
Texture::EdgeClamp,
|
||||||
|
Texture::NoMipMaps);
|
||||||
|
delete img;
|
||||||
|
|
||||||
|
if (texture && texture->getName() != 0)
|
||||||
|
blurTextures[blurLevel] = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::genSceneTexture()
|
||||||
|
{
|
||||||
|
unsigned int *data;
|
||||||
|
if (sceneTexture != 0)
|
||||||
|
glDeleteTextures(1, &sceneTexture);
|
||||||
|
|
||||||
|
sceneTexWidth = 1;
|
||||||
|
sceneTexHeight = 1;
|
||||||
|
while (sceneTexWidth < windowWidth)
|
||||||
|
sceneTexWidth <<= 1;
|
||||||
|
while (sceneTexHeight < windowHeight)
|
||||||
|
sceneTexHeight <<= 1;
|
||||||
|
sceneTexWScale = (windowWidth > 0) ? (GLfloat)sceneTexWidth / (GLfloat)windowWidth :
|
||||||
|
1.0f;
|
||||||
|
sceneTexHScale = (windowHeight > 0) ? (GLfloat)sceneTexHeight / (GLfloat)windowHeight :
|
||||||
|
1.0f;
|
||||||
|
data = (unsigned int* )malloc(sceneTexWidth*sceneTexHeight*4*sizeof(unsigned int));
|
||||||
|
memset(data, 0, sceneTexWidth*sceneTexHeight*4*sizeof(unsigned int));
|
||||||
|
|
||||||
|
glGenTextures(1, &sceneTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, sceneTexWidth, sceneTexHeight, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
#ifdef DEBUG_HDR
|
||||||
|
static int genSceneTexCounter = 1;
|
||||||
|
HDR_LOG <<
|
||||||
|
"[" << genSceneTexCounter++ << "] " <<
|
||||||
|
"Window width = " << windowWidth << ", " <<
|
||||||
|
"Window height = " << windowHeight << ", " <<
|
||||||
|
"Tex width = " << sceneTexWidth << ", " <<
|
||||||
|
"Tex height = " << sceneTexHeight << endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::renderToBlurTexture(int blurLevel)
|
||||||
|
{
|
||||||
|
if (blurTextures[blurLevel] == nullptr)
|
||||||
|
return;
|
||||||
|
GLsizei blurTexWidth = blurBaseWidth>>blurLevel;
|
||||||
|
GLsizei blurTexHeight = blurBaseHeight>>blurLevel;
|
||||||
|
GLsizei blurDrawWidth = (GLfloat)windowWidth/(GLfloat)sceneTexWidth * blurTexWidth;
|
||||||
|
GLsizei blurDrawHeight = (GLfloat)windowHeight/(GLfloat)sceneTexHeight * blurTexHeight;
|
||||||
|
GLfloat blurWScale = 1.f;
|
||||||
|
GLfloat blurHScale = 1.f;
|
||||||
|
GLfloat savedWScale = 1.f;
|
||||||
|
GLfloat savedHScale = 1.f;
|
||||||
|
|
||||||
|
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT);
|
||||||
|
glClearColor(0, 0, 0, 1.f);
|
||||||
|
glViewport(0, 0, blurDrawWidth, blurDrawHeight);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, 1.0f);
|
||||||
|
glEnd();
|
||||||
|
// Do not need to scale alpha so mask it off
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
savedWScale = sceneTexWScale;
|
||||||
|
savedHScale = sceneTexHScale;
|
||||||
|
|
||||||
|
// Remove ldr part of image
|
||||||
|
{
|
||||||
|
const GLfloat bias = -0.5f;
|
||||||
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
|
||||||
|
glColor4f(-bias, -bias, -bias, 0.0f);
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2f(0.0f, 0.0f);
|
||||||
|
glVertex2f(1.f, 0.0f);
|
||||||
|
glVertex2f(1.f, 1.f);
|
||||||
|
glVertex2f(0.0f, 1.f);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
blurTextures[blurLevel]->bind();
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
blurTexWidth, blurTexHeight, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale back up hdr part
|
||||||
|
{
|
||||||
|
glBlendEquationEXT(GL_FUNC_ADD_EXT);
|
||||||
|
glBlendFunc(GL_DST_COLOR, GL_ONE);
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.f, 0.f, 1.f); //x2
|
||||||
|
drawBlendedVertices(0.f, 0.f, 1.f); //x2
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
if (!useLuminanceAlpha)
|
||||||
|
{
|
||||||
|
blurTempTexture->bind();
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, blurLevel, GL_LUMINANCE, 0, 0,
|
||||||
|
blurTexWidth, blurTexHeight, 0);
|
||||||
|
// Erase color, replace with luminance image
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glColor4f(0.f, 0.f, 0.f, 1.f);
|
||||||
|
glVertex2f(0.0f, 0.0f);
|
||||||
|
glVertex2f(1.0f, 0.0f);
|
||||||
|
glVertex2f(1.0f, 1.0f);
|
||||||
|
glVertex2f(0.0f, 1.0f);
|
||||||
|
glEnd();
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.f, 0.f, 1.f);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
blurTextures[blurLevel]->bind();
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
blurTexWidth, blurTexHeight, 0);
|
||||||
|
// blending end
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
GLfloat xdelta = 1.0f / (GLfloat)blurTexWidth;
|
||||||
|
GLfloat ydelta = 1.0f / (GLfloat)blurTexHeight;
|
||||||
|
blurWScale = ((GLfloat)blurTexWidth / (GLfloat)blurDrawWidth);
|
||||||
|
blurHScale = ((GLfloat)blurTexHeight / (GLfloat)blurDrawHeight);
|
||||||
|
sceneTexWScale = blurWScale;
|
||||||
|
sceneTexHScale = blurHScale;
|
||||||
|
|
||||||
|
// Butterworth low pass filter to reduce flickering dots
|
||||||
|
{
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, .5f*1.f);
|
||||||
|
drawBlendedVertices(-xdelta, 0.0f, .5f*0.333f);
|
||||||
|
drawBlendedVertices( xdelta, 0.0f, .5f*0.25f);
|
||||||
|
glEnd();
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
blurTexWidth, blurTexHeight, 0);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, -ydelta, .5f*0.667f);
|
||||||
|
drawBlendedVertices(0.0f, ydelta, .5f*0.333f);
|
||||||
|
glEnd();
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
blurTexWidth, blurTexHeight, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gaussian blur
|
||||||
|
switch (blurLevel)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
case 0:
|
||||||
|
drawGaussian3x3(xdelta, ydelta, blurTexWidth, blurTexHeight, 1.f);
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
#ifdef __APPLE__
|
||||||
|
case 0:
|
||||||
|
drawGaussian5x5(xdelta, ydelta, blurTexWidth, blurTexHeight, 1.f);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
drawGaussian9x9(xdelta, ydelta, blurTexWidth, blurTexHeight, .3f);
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
// Gamma correct: windows=(mac^1.8)^(1/2.2)
|
||||||
|
case 0:
|
||||||
|
drawGaussian5x5(xdelta, ydelta, blurTexWidth, blurTexHeight, 1.f);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
drawGaussian9x9(xdelta, ydelta, blurTexWidth, blurTexHeight, .373f);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
blurTextures[blurLevel]->bind();
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
blurTexWidth, blurTexHeight, 0);
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glPopAttrib();
|
||||||
|
sceneTexWScale = savedWScale;
|
||||||
|
sceneTexHScale = savedHScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::renderToTexture(const Observer& observer,
|
||||||
|
const Universe& universe,
|
||||||
|
float faintestMagNight,
|
||||||
|
const Selection& sel)
|
||||||
|
{
|
||||||
|
if (sceneTexture == 0)
|
||||||
|
return;
|
||||||
|
glPushAttrib(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
draw(observer, universe, faintestMagNight, sel);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0,
|
||||||
|
sceneTexWidth, sceneTexHeight, 0);
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::drawSceneTexture()
|
||||||
|
{
|
||||||
|
if (sceneTexture == 0)
|
||||||
|
return;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sceneTexture);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, 1.0f);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::drawBlendedVertices(float xdelta, float ydelta, float blend)
|
||||||
|
{
|
||||||
|
glColor4f(1.0f, 1.0f, 1.0f, blend);
|
||||||
|
glTexCoord2i(0, 0); glVertex2f(xdelta, ydelta);
|
||||||
|
glTexCoord2i(1, 0); glVertex2f(sceneTexWScale+xdelta, ydelta);
|
||||||
|
glTexCoord2i(1, 1); glVertex2f(sceneTexWScale+xdelta, sceneTexHScale+ydelta);
|
||||||
|
glTexCoord2i(0, 1); glVertex2f(xdelta, sceneTexHScale+ydelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::drawGaussian3x3(float xdelta, float ydelta, GLsizei width, GLsizei height, float blend)
|
||||||
|
{
|
||||||
|
#ifdef USE_BLOOM_LISTS
|
||||||
|
if (gaussianLists[0] == 0)
|
||||||
|
{
|
||||||
|
gaussianLists[0] = glGenLists(1);
|
||||||
|
glNewList(gaussianLists[0], GL_COMPILE);
|
||||||
|
#endif
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, blend);
|
||||||
|
drawBlendedVertices(-xdelta, 0.0f, 0.25f*blend);
|
||||||
|
drawBlendedVertices( xdelta, 0.0f, 0.20f*blend);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
// Take result of horiz pass and apply vertical pass
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
width, height, 0);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, -ydelta, 0.429f);
|
||||||
|
drawBlendedVertices(0.0f, ydelta, 0.300f);
|
||||||
|
glEnd();
|
||||||
|
#ifdef USE_BLOOM_LISTS
|
||||||
|
glEndList();
|
||||||
|
}
|
||||||
|
glCallList(gaussianLists[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::drawGaussian5x5(float xdelta, float ydelta, GLsizei width, GLsizei height, float blend)
|
||||||
|
{
|
||||||
|
#ifdef USE_BLOOM_LISTS
|
||||||
|
if (gaussianLists[1] == 0)
|
||||||
|
{
|
||||||
|
gaussianLists[1] = glGenLists(1);
|
||||||
|
glNewList(gaussianLists[1], GL_COMPILE);
|
||||||
|
#endif
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, blend);
|
||||||
|
drawBlendedVertices(-xdelta, 0.0f, 0.475f*blend);
|
||||||
|
drawBlendedVertices( xdelta, 0.0f, 0.475f*blend);
|
||||||
|
drawBlendedVertices(-2.0f*xdelta, 0.0f, 0.075f*blend);
|
||||||
|
drawBlendedVertices( 2.0f*xdelta, 0.0f, 0.075f*blend);
|
||||||
|
glEnd();
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
width, height, 0);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, -ydelta, 0.475f);
|
||||||
|
drawBlendedVertices(0.0f, ydelta, 0.475f);
|
||||||
|
drawBlendedVertices(0.0f, -2.0f*ydelta, 0.075f);
|
||||||
|
drawBlendedVertices(0.0f, 2.0f*ydelta, 0.075f);
|
||||||
|
glEnd();
|
||||||
|
#ifdef USE_BLOOM_LISTS
|
||||||
|
glEndList();
|
||||||
|
}
|
||||||
|
glCallList(gaussianLists[1]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::drawGaussian9x9(float xdelta, float ydelta, GLsizei width, GLsizei height, float blend)
|
||||||
|
{
|
||||||
|
#ifdef USE_BLOOM_LISTS
|
||||||
|
if (gaussianLists[2] == 0)
|
||||||
|
{
|
||||||
|
gaussianLists[2] = glGenLists(1);
|
||||||
|
glNewList(gaussianLists[2], GL_COMPILE);
|
||||||
|
#endif
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, blend);
|
||||||
|
drawBlendedVertices(-xdelta, 0.0f, 0.632f*blend);
|
||||||
|
drawBlendedVertices( xdelta, 0.0f, 0.632f*blend);
|
||||||
|
drawBlendedVertices(-2.0f*xdelta, 0.0f, 0.159f*blend);
|
||||||
|
drawBlendedVertices( 2.0f*xdelta, 0.0f, 0.159f*blend);
|
||||||
|
drawBlendedVertices(-3.0f*xdelta, 0.0f, 0.016f*blend);
|
||||||
|
drawBlendedVertices( 3.0f*xdelta, 0.0f, 0.016f*blend);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glCopyTexImage2D(GL_TEXTURE_2D, 0, blurFormat, 0, 0,
|
||||||
|
width, height, 0);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, -ydelta, 0.632f);
|
||||||
|
drawBlendedVertices(0.0f, ydelta, 0.632f);
|
||||||
|
drawBlendedVertices(0.0f, -2.0f*ydelta, 0.159f);
|
||||||
|
drawBlendedVertices(0.0f, 2.0f*ydelta, 0.159f);
|
||||||
|
drawBlendedVertices(0.0f, -3.0f*ydelta, 0.016f);
|
||||||
|
drawBlendedVertices(0.0f, 3.0f*ydelta, 0.016f);
|
||||||
|
glEnd();
|
||||||
|
#ifdef USE_BLOOM_LISTS
|
||||||
|
glEndList();
|
||||||
|
}
|
||||||
|
glCallList(gaussianLists[2]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::drawBlur()
|
||||||
|
{
|
||||||
|
blurTextures[0]->bind();
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, 1.0f);
|
||||||
|
glEnd();
|
||||||
|
blurTextures[1]->bind();
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
drawBlendedVertices(0.0f, 0.0f, 1.0f);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Renderer::getBloomEnabled()
|
||||||
|
{
|
||||||
|
return bloomEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::setBloomEnabled(bool aBloomEnabled)
|
||||||
|
{
|
||||||
|
bloomEnabled = aBloomEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::increaseBrightness()
|
||||||
|
{
|
||||||
|
brightPlus += 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::decreaseBrightness()
|
||||||
|
{
|
||||||
|
brightPlus -= 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::getBrightness()
|
||||||
|
{
|
||||||
|
return brightPlus;
|
||||||
|
}
|
||||||
|
#endif // USE_HDR
|
|
@ -0,0 +1,63 @@
|
||||||
|
// objectrenderer.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||||
|
// Original version by Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Eigen/Core>
|
||||||
|
#include "octree.h"
|
||||||
|
|
||||||
|
#ifdef USE_GLCONTEXT
|
||||||
|
class GLContext;
|
||||||
|
#endif
|
||||||
|
class Observer;
|
||||||
|
class Renderer;
|
||||||
|
|
||||||
|
template <class OBJ, class PREC> class ObjectRenderer : public OctreeProcessor<OBJ, PREC>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ObjectRenderer(PREC _distanceLimit) : distanceLimit((float) _distanceLimit) {};
|
||||||
|
void process(const OBJ& /*unused*/, PREC /*unused*/, float /*unused*/) {};
|
||||||
|
|
||||||
|
const Observer* observer { nullptr };
|
||||||
|
#ifdef USE_GLCONTEXT
|
||||||
|
GLContext* context { nullptr };
|
||||||
|
#endif
|
||||||
|
Renderer* renderer { nullptr };
|
||||||
|
|
||||||
|
Eigen::Vector3f viewNormal;
|
||||||
|
|
||||||
|
float fov { 0.0f };
|
||||||
|
float size { 0.0f };
|
||||||
|
float pixelSize { 0.0f };
|
||||||
|
float faintestMag { 0.0f };
|
||||||
|
float faintestMagNight { 0.0f };
|
||||||
|
float saturationMag { 0.0f };
|
||||||
|
#ifdef USE_HDR
|
||||||
|
float exposure { 0.0f };
|
||||||
|
#endif
|
||||||
|
float brightnessScale { 0.0f };
|
||||||
|
float brightnessBias { 0.0f };
|
||||||
|
float distanceLimit { 0.0f };
|
||||||
|
|
||||||
|
// Objects brighter than labelThresholdMag will be labeled
|
||||||
|
float labelThresholdMag { 0.0f };
|
||||||
|
|
||||||
|
// These are not fully used by this template's descendants
|
||||||
|
// but we place them here just in case a more sophisticated
|
||||||
|
// rendering scheme is implemented:
|
||||||
|
int nRendered { 0 };
|
||||||
|
int nClose { 0 };
|
||||||
|
int nBright { 0 };
|
||||||
|
int nProcessed { 0 };
|
||||||
|
int nLabelled { 0 };
|
||||||
|
|
||||||
|
uint64_t renderFlags { 0 };
|
||||||
|
int labelMode { 0 };
|
||||||
|
};
|
|
@ -0,0 +1,48 @@
|
||||||
|
// orbitsampler.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||||
|
// Original version by Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Eigen/Core>
|
||||||
|
#include <celephem/orbit.h>
|
||||||
|
#include "curveplot.h"
|
||||||
|
|
||||||
|
class OrbitSampler : public OrbitSampleProc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<CurvePlotSample> samples;
|
||||||
|
|
||||||
|
OrbitSampler() = default;
|
||||||
|
|
||||||
|
void sample(double t, const Eigen::Vector3d& position, const Eigen::Vector3d& velocity)
|
||||||
|
{
|
||||||
|
CurvePlotSample samp;
|
||||||
|
samp.t = t;
|
||||||
|
samp.position = position;
|
||||||
|
samp.velocity = velocity;
|
||||||
|
samples.push_back(samp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertForward(CurvePlot* plot)
|
||||||
|
{
|
||||||
|
for (const auto& sample : samples)
|
||||||
|
{
|
||||||
|
plot->addSample(sample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertBackward(CurvePlot* plot)
|
||||||
|
{
|
||||||
|
for (auto iter = samples.rbegin(); iter != samples.rend(); ++iter)
|
||||||
|
{
|
||||||
|
plot->addSample(*iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,203 @@
|
||||||
|
// pointstarrenderer.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||||
|
// Original version by Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#include <celengine/starcolors.h>
|
||||||
|
#include <celengine/star.h>
|
||||||
|
#include <celengine/univcoord.h>
|
||||||
|
#include "pointstarvertexbuffer.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "pointstarrenderer.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Eigen;
|
||||||
|
|
||||||
|
// Convert a position in the universal coordinate system to astrocentric
|
||||||
|
// coordinates, taking into account possible orbital motion of the star.
|
||||||
|
static Vector3d astrocentricPosition(const UniversalCoord& pos,
|
||||||
|
const Star& star,
|
||||||
|
double t)
|
||||||
|
{
|
||||||
|
return pos.offsetFromKm(star.getPosition(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
PointStarRenderer::PointStarRenderer() :
|
||||||
|
ObjectRenderer<Star, float>(StarDistanceLimit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointStarRenderer::process(const Star& star, float distance, float appMag)
|
||||||
|
{
|
||||||
|
nProcessed++;
|
||||||
|
|
||||||
|
Vector3f starPos = star.getPosition();
|
||||||
|
|
||||||
|
// Calculate the difference at double precision *before* converting to float.
|
||||||
|
// This is very important for stars that are far from the origin.
|
||||||
|
Vector3f relPos = (starPos.cast<double>() - obsPos).cast<float>();
|
||||||
|
float orbitalRadius = star.getOrbitalRadius();
|
||||||
|
bool hasOrbit = orbitalRadius > 0.0f;
|
||||||
|
|
||||||
|
if (distance > distanceLimit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// A very rough check to see if the star may be visible: is the star in
|
||||||
|
// front of the viewer? If the star might be close (relPos.x^2 < 0.1) or
|
||||||
|
// is moving in an orbit, we'll always regard it as potentially visible.
|
||||||
|
// TODO: consider normalizing relPos and comparing relPos*viewNormal against
|
||||||
|
// cosFOV--this will cull many more stars than relPos*viewNormal, at the
|
||||||
|
// cost of a normalize per star.
|
||||||
|
if (relPos.dot(viewNormal) > 0.0f || relPos.x() * relPos.x() < 0.1f || hasOrbit)
|
||||||
|
{
|
||||||
|
#ifdef HDR_COMPRESS
|
||||||
|
Color starColorFull = colorTemp->lookupColor(star.getTemperature());
|
||||||
|
Color starColor(starColorFull.red() * 0.5f,
|
||||||
|
starColorFull.green() * 0.5f,
|
||||||
|
starColorFull.blue() * 0.5f);
|
||||||
|
#else
|
||||||
|
Color starColor = colorTemp->lookupColor(star.getTemperature());
|
||||||
|
#endif
|
||||||
|
float discSizeInPixels = 0.0f;
|
||||||
|
float orbitSizeInPixels = 0.0f;
|
||||||
|
|
||||||
|
if (hasOrbit)
|
||||||
|
orbitSizeInPixels = orbitalRadius / (distance * pixelSize);
|
||||||
|
|
||||||
|
// Special handling for stars less than one light year away . . .
|
||||||
|
// We can't just go ahead and render a nearby star in the usual way
|
||||||
|
// for two reasons:
|
||||||
|
// * It may be clipped by the near plane
|
||||||
|
// * It may be large enough that we should render it as a mesh
|
||||||
|
// instead of a particle
|
||||||
|
// It's possible that the second condition might apply for stars
|
||||||
|
// further than one light year away if the star is huge, the fov is
|
||||||
|
// very small and the resolution is high. We'll ignore this for now
|
||||||
|
// and use the most inexpensive test possible . . .
|
||||||
|
if (distance < 1.0f || orbitSizeInPixels > 1.0f)
|
||||||
|
{
|
||||||
|
// Compute the position of the observer relative to the star.
|
||||||
|
// This is a much more accurate (and expensive) distance
|
||||||
|
// calculation than the previous one which used the observer's
|
||||||
|
// position rounded off to floats.
|
||||||
|
Vector3d hPos = astrocentricPosition(observer->getPosition(),
|
||||||
|
star,
|
||||||
|
observer->getTime());
|
||||||
|
relPos = hPos.cast<float>() * -astro::kilometersToLightYears(1.0f);
|
||||||
|
distance = relPos.norm();
|
||||||
|
|
||||||
|
// Recompute apparent magnitude using new distance computation
|
||||||
|
appMag = astro::absToAppMag(star.getAbsoluteMagnitude(), distance);
|
||||||
|
|
||||||
|
discSizeInPixels = star.getRadius() / astro::lightYearsToKilometers(distance) / pixelSize;
|
||||||
|
++nClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place labels for stars brighter than the specified label threshold brightness
|
||||||
|
if (((labelMode & Renderer::StarLabels) != 0) && appMag < labelThresholdMag)
|
||||||
|
{
|
||||||
|
Vector3f starDir = relPos;
|
||||||
|
starDir.normalize();
|
||||||
|
if (starDir.dot(viewNormal) > cosFOV)
|
||||||
|
{
|
||||||
|
float distr = 3.5f * (labelThresholdMag - appMag)/labelThresholdMag;
|
||||||
|
if (distr > 1.0f)
|
||||||
|
distr = 1.0f;
|
||||||
|
renderer->addBackgroundAnnotation(nullptr, starDB->getStarName(star, true),
|
||||||
|
Color(Renderer::StarLabelColor, distr * Renderer::StarLabelColor.alpha()),
|
||||||
|
relPos);
|
||||||
|
nLabelled++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Stars closer than the maximum solar system size are actually
|
||||||
|
// added to the render list and depth sorted, since they may occlude
|
||||||
|
// planets.
|
||||||
|
if (distance > SolarSystemMaxDistance)
|
||||||
|
{
|
||||||
|
#ifdef USE_HDR
|
||||||
|
float satPoint = saturationMag;
|
||||||
|
float alpha = exposure*(faintestMag - appMag)/(faintestMag - saturationMag + 0.001f);
|
||||||
|
#else
|
||||||
|
float satPoint = faintestMag - (1.0f - brightnessBias) / brightnessScale; // TODO: precompute this value
|
||||||
|
float alpha = (faintestMag - appMag) * brightnessScale + brightnessBias;
|
||||||
|
#endif
|
||||||
|
#ifdef DEBUG_HDR_ADAPT
|
||||||
|
minMag = max(minMag, appMag);
|
||||||
|
maxMag = min(maxMag, appMag);
|
||||||
|
minAlpha = min(minAlpha, alpha);
|
||||||
|
maxAlpha = max(maxAlpha, alpha);
|
||||||
|
++total;
|
||||||
|
if (alpha > above)
|
||||||
|
{
|
||||||
|
++countAboveN;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (useScaledDiscs)
|
||||||
|
{
|
||||||
|
float discSize = size;
|
||||||
|
if (alpha < 0.0f)
|
||||||
|
{
|
||||||
|
alpha = 0.0f;
|
||||||
|
}
|
||||||
|
else if (alpha > 1.0f)
|
||||||
|
{
|
||||||
|
float discScale = min(MaxScaledDiscStarSize, (float) pow(2.0f, 0.3f * (satPoint - appMag)));
|
||||||
|
discSize *= discScale;
|
||||||
|
|
||||||
|
float glareAlpha = min(0.5f, discScale / 4.0f);
|
||||||
|
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), discSize * 3.0f);
|
||||||
|
|
||||||
|
alpha = 1.0f;
|
||||||
|
}
|
||||||
|
starVertexBuffer->addStar(relPos, Color(starColor, alpha), discSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (alpha < 0.0f)
|
||||||
|
{
|
||||||
|
alpha = 0.0f;
|
||||||
|
}
|
||||||
|
else if (alpha > 1.0f)
|
||||||
|
{
|
||||||
|
float discScale = min(100.0f, satPoint - appMag + 2.0f);
|
||||||
|
float glareAlpha = min(GlareOpacity, (discScale - 2.0f) / 4.0f);
|
||||||
|
glareVertexBuffer->addStar(relPos, Color(starColor, glareAlpha), 2.0f * discScale * size);
|
||||||
|
#ifdef DEBUG_HDR_ADAPT
|
||||||
|
maxSize = max(maxSize, 2.0f * discScale * size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
starVertexBuffer->addStar(relPos, Color(starColor, alpha), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
++nRendered;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Matrix3f viewMat = observer->getOrientationf().toRotationMatrix();
|
||||||
|
Vector3f viewMatZ = viewMat.row(2);
|
||||||
|
|
||||||
|
RenderListEntry rle;
|
||||||
|
rle.renderableType = RenderListEntry::RenderableStar;
|
||||||
|
rle.star = ☆
|
||||||
|
|
||||||
|
// Objects in the render list are always rendered relative to
|
||||||
|
// a viewer at the origin--this is different than for distant
|
||||||
|
// stars.
|
||||||
|
float scale = astro::lightYearsToKilometers(1.0f);
|
||||||
|
rle.position = relPos * scale;
|
||||||
|
rle.centerZ = rle.position.dot(viewMatZ);
|
||||||
|
rle.distance = rle.position.norm();
|
||||||
|
rle.radius = star.getRadius();
|
||||||
|
rle.discSizeInPixels = discSizeInPixels;
|
||||||
|
rle.appMag = appMag;
|
||||||
|
rle.isOpaque = true;
|
||||||
|
renderList->push_back(rle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
// pointstarrenderer.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||||
|
// Original version by Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Eigen/Core>
|
||||||
|
#include <vector>
|
||||||
|
#include "objectrenderer.h"
|
||||||
|
#include "renderlistentry.h"
|
||||||
|
|
||||||
|
class ColorTemperatureTable;
|
||||||
|
class PointStarVertexBuffer;
|
||||||
|
class Star;
|
||||||
|
class StarDatabase;
|
||||||
|
|
||||||
|
// TODO: move these variables to PointStarRenderer class
|
||||||
|
// without adding a variable. Requires C++17
|
||||||
|
constexpr const float StarDistanceLimit = 1.0e6f;
|
||||||
|
// Star disc size in pixels
|
||||||
|
constexpr const float BaseStarDiscSize = 5.0f;
|
||||||
|
constexpr const float MaxScaledDiscStarSize = 8.0f;
|
||||||
|
constexpr const float GlareOpacity = 0.65f;
|
||||||
|
|
||||||
|
class PointStarRenderer : public ObjectRenderer<Star, float>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
#if 0
|
||||||
|
static constexpr const float StarDistanceLimit = 1.0e6f;
|
||||||
|
// Star disc size in pixels
|
||||||
|
static constexpr const float BaseStarDiscSize = 5.0f;
|
||||||
|
static constexpr const float MaxScaledDiscStarSize = 8.0f;
|
||||||
|
static constexpr const float GlareOpacity = 0.65f;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PointStarRenderer();
|
||||||
|
void process(const Star &star, float distance, float appMag);
|
||||||
|
|
||||||
|
Eigen::Vector3d obsPos;
|
||||||
|
std::vector<RenderListEntry>* renderList { nullptr };
|
||||||
|
PointStarVertexBuffer* starVertexBuffer { nullptr };
|
||||||
|
PointStarVertexBuffer* glareVertexBuffer { nullptr };
|
||||||
|
const StarDatabase* starDB { nullptr };
|
||||||
|
const ColorTemperatureTable* colorTemp { nullptr };
|
||||||
|
float SolarSystemMaxDistance { 1.0f };
|
||||||
|
float maxDiscSize { 1.0f };
|
||||||
|
float cosFOV { 1.0f };
|
||||||
|
#ifdef DEBUG_HDR_ADAPT
|
||||||
|
float minMag { 0.0f };
|
||||||
|
float maxMag { 0.0f };
|
||||||
|
float minAlpha { 0.0f };
|
||||||
|
float maxAlpha { 0.0f };
|
||||||
|
float maxSize { 0.0f };
|
||||||
|
float above { 0.0f };
|
||||||
|
unsigned long countAboveN { 0 };
|
||||||
|
unsigned long total { 0 };
|
||||||
|
#endif
|
||||||
|
bool useScaledDiscs { false };
|
||||||
|
};
|
|
@ -0,0 +1,133 @@
|
||||||
|
// starfield.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||||
|
// Original version by Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <celutil/color.h>
|
||||||
|
#include "objectrenderer.h"
|
||||||
|
#include "shadermanager.h"
|
||||||
|
#include "render.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "pointstarvertexbuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
PointStarVertexBuffer::PointStarVertexBuffer(const Renderer& _renderer,
|
||||||
|
unsigned int _capacity) :
|
||||||
|
renderer(_renderer),
|
||||||
|
capacity(_capacity)
|
||||||
|
{
|
||||||
|
vertices = new StarVertex[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
PointStarVertexBuffer::~PointStarVertexBuffer()
|
||||||
|
{
|
||||||
|
delete[] vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointStarVertexBuffer::startSprites()
|
||||||
|
{
|
||||||
|
auto *prog = renderer.getShaderManager().getShader("star");
|
||||||
|
if (prog == nullptr)
|
||||||
|
return;
|
||||||
|
prog->use();
|
||||||
|
prog->samplerParam("starTex") = 0;
|
||||||
|
|
||||||
|
unsigned int stride = sizeof(StarVertex);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, stride, &vertices[0].position);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &vertices[0].color);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
|
||||||
|
glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex,
|
||||||
|
1, GL_FLOAT, GL_FALSE,
|
||||||
|
stride, &vertices[0].size);
|
||||||
|
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
|
glEnable(GL_POINT_SPRITE);
|
||||||
|
|
||||||
|
useSprites = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointStarVertexBuffer::startPoints()
|
||||||
|
{
|
||||||
|
auto *prog = renderer.getShaderManager().getShader(ShaderProperties::PerVertexColor);
|
||||||
|
if (prog == nullptr)
|
||||||
|
return;
|
||||||
|
prog->use();
|
||||||
|
|
||||||
|
unsigned int stride = sizeof(StarVertex);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(3, GL_FLOAT, stride, &vertices[0].position);
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &vertices[0].color);
|
||||||
|
|
||||||
|
// An option to control the size of the stars would be helpful.
|
||||||
|
// Which size looks best depends a lot on the resolution and the
|
||||||
|
// type of display device.
|
||||||
|
// glPointSize(2.0f);
|
||||||
|
// glEnable(GL_POINT_SMOOTH);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
|
useSprites = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointStarVertexBuffer::render()
|
||||||
|
{
|
||||||
|
if (nStars != 0)
|
||||||
|
{
|
||||||
|
unsigned int stride = sizeof(StarVertex);
|
||||||
|
if (useSprites)
|
||||||
|
{
|
||||||
|
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||||
|
glPointSize(1.0f);
|
||||||
|
}
|
||||||
|
glVertexPointer(3, GL_FLOAT, stride, &vertices[0].position);
|
||||||
|
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &vertices[0].color);
|
||||||
|
|
||||||
|
if (useSprites)
|
||||||
|
{
|
||||||
|
glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex,
|
||||||
|
1, GL_FLOAT, GL_FALSE,
|
||||||
|
stride, &vertices[0].size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture != nullptr)
|
||||||
|
texture->bind();
|
||||||
|
glDrawArrays(GL_POINTS, 0, nStars);
|
||||||
|
nStars = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointStarVertexBuffer::finish()
|
||||||
|
{
|
||||||
|
render();
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
|
if (useSprites)
|
||||||
|
{
|
||||||
|
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
|
||||||
|
glDisable(GL_POINT_SPRITE);
|
||||||
|
}
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointStarVertexBuffer::setTexture(Texture* _texture)
|
||||||
|
{
|
||||||
|
texture = _texture;
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
// pointstarvertexbuffer.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2019, the Celestia Development Team
|
||||||
|
// Original version by Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Eigen/Core>
|
||||||
|
|
||||||
|
class Color;
|
||||||
|
class Renderer;
|
||||||
|
class Texture;
|
||||||
|
|
||||||
|
// PointStarVertexBuffer is used when hardware supports point sprites.
|
||||||
|
class PointStarVertexBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using capacity_t = unsigned int;
|
||||||
|
|
||||||
|
PointStarVertexBuffer(const Renderer& _renderer, unsigned int _capacity);
|
||||||
|
~PointStarVertexBuffer();
|
||||||
|
PointStarVertexBuffer() = delete;
|
||||||
|
PointStarVertexBuffer(const PointStarVertexBuffer&) = delete;
|
||||||
|
PointStarVertexBuffer(PointStarVertexBuffer&&) = delete;
|
||||||
|
PointStarVertexBuffer& operator=(const PointStarVertexBuffer&) = delete;
|
||||||
|
PointStarVertexBuffer& operator=(PointStarVertexBuffer&&) = delete;
|
||||||
|
|
||||||
|
void startPoints();
|
||||||
|
void startSprites();
|
||||||
|
void render();
|
||||||
|
void finish();
|
||||||
|
inline void addStar(const Eigen::Vector3f& pos, const Color&, float);
|
||||||
|
void setTexture(Texture* /*_texture*/);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct StarVertex
|
||||||
|
{
|
||||||
|
Eigen::Vector3f position;
|
||||||
|
float size;
|
||||||
|
unsigned char color[4];
|
||||||
|
float pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Renderer& renderer;
|
||||||
|
capacity_t capacity;
|
||||||
|
|
||||||
|
capacity_t nStars { 0 };
|
||||||
|
StarVertex* vertices { nullptr };
|
||||||
|
Texture* texture { nullptr };
|
||||||
|
bool useSprites { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void PointStarVertexBuffer::addStar(const Eigen::Vector3f& pos,
|
||||||
|
const Color& color,
|
||||||
|
float size)
|
||||||
|
{
|
||||||
|
if (nStars < capacity)
|
||||||
|
{
|
||||||
|
vertices[nStars].position = pos;
|
||||||
|
vertices[nStars].size = size;
|
||||||
|
color.get(vertices[nStars].color);
|
||||||
|
nStars++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nStars == capacity)
|
||||||
|
{
|
||||||
|
render();
|
||||||
|
nStars = 0;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,9 @@
|
||||||
#ifndef _CELENGINE_RENDER_H_
|
#ifndef _CELENGINE_RENDER_H_
|
||||||
#define _CELENGINE_RENDER_H_
|
#define _CELENGINE_RENDER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
#include <Eigen/Core>
|
#include <Eigen/Core>
|
||||||
#include <celmath/frustum.h>
|
#include <celmath/frustum.h>
|
||||||
#include <celengine/universe.h>
|
#include <celengine/universe.h>
|
||||||
|
@ -21,15 +24,13 @@
|
||||||
#endif
|
#endif
|
||||||
#include <celengine/starcolors.h>
|
#include <celengine/starcolors.h>
|
||||||
#include <celengine/rendcontext.h>
|
#include <celengine/rendcontext.h>
|
||||||
#include "celengine/vertexobject.h"
|
#include <celengine/renderlistentry.h>
|
||||||
|
#include <celengine/vertexobject.h>
|
||||||
#if NO_TTF
|
#if NO_TTF
|
||||||
#include <celtxf/texturefont.h>
|
#include <celtxf/texturefont.h>
|
||||||
#else
|
#else
|
||||||
#include <celttf/truetypefont.h>
|
#include <celttf/truetypefont.h>
|
||||||
#endif
|
#endif
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
class RendererWatcher;
|
class RendererWatcher;
|
||||||
|
@ -38,6 +39,7 @@ class ReferenceMark;
|
||||||
class CurvePlot;
|
class CurvePlot;
|
||||||
class AsterismList;
|
class AsterismList;
|
||||||
class Rect;
|
class Rect;
|
||||||
|
class PointStarVertexBuffer;
|
||||||
|
|
||||||
struct LightSource
|
struct LightSource
|
||||||
{
|
{
|
||||||
|
@ -48,39 +50,6 @@ struct LightSource
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct RenderListEntry
|
|
||||||
{
|
|
||||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
|
||||||
|
|
||||||
enum RenderableType
|
|
||||||
{
|
|
||||||
RenderableStar,
|
|
||||||
RenderableBody,
|
|
||||||
RenderableCometTail,
|
|
||||||
RenderableReferenceMark,
|
|
||||||
};
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
const Star* star;
|
|
||||||
Body* body;
|
|
||||||
const ReferenceMark* refMark;
|
|
||||||
};
|
|
||||||
|
|
||||||
Eigen::Vector3f position;
|
|
||||||
Eigen::Vector3f sun;
|
|
||||||
float distance;
|
|
||||||
float radius;
|
|
||||||
float centerZ;
|
|
||||||
float nearZ;
|
|
||||||
float farZ;
|
|
||||||
float discSizeInPixels;
|
|
||||||
float appMag;
|
|
||||||
RenderableType renderableType;
|
|
||||||
bool isOpaque;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct SecondaryIlluminator
|
struct SecondaryIlluminator
|
||||||
{
|
{
|
||||||
const Body* body;
|
const Body* body;
|
||||||
|
@ -90,8 +59,6 @@ struct SecondaryIlluminator
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class PointStarVertexBuffer;
|
|
||||||
|
|
||||||
class Renderer
|
class Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
// renderlistentry.h
|
||||||
|
//
|
||||||
|
// Copyright (C) 2001-2019, Celestia Development Team
|
||||||
|
// Contact: Chris Laurel <claurel@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Eigen/Core>
|
||||||
|
|
||||||
|
class Star;
|
||||||
|
class Body;
|
||||||
|
class ReferenceMark;
|
||||||
|
|
||||||
|
struct RenderListEntry
|
||||||
|
{
|
||||||
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||||
|
|
||||||
|
enum RenderableType
|
||||||
|
{
|
||||||
|
RenderableStar,
|
||||||
|
RenderableBody,
|
||||||
|
RenderableCometTail,
|
||||||
|
RenderableReferenceMark,
|
||||||
|
};
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
const Star* star;
|
||||||
|
Body* body;
|
||||||
|
const ReferenceMark* refMark;
|
||||||
|
};
|
||||||
|
|
||||||
|
Eigen::Vector3f position;
|
||||||
|
Eigen::Vector3f sun;
|
||||||
|
float distance;
|
||||||
|
float radius;
|
||||||
|
float centerZ;
|
||||||
|
float nearZ;
|
||||||
|
float farZ;
|
||||||
|
float discSizeInPixels;
|
||||||
|
float appMag;
|
||||||
|
RenderableType renderableType;
|
||||||
|
bool isOpaque;
|
||||||
|
};
|
Loading…
Reference in New Issue