OpenGL ES 2.0 initial support

pull/771/head
Hleb Valoshka 2020-05-12 18:51:25 +03:00
parent 20b066cbcd
commit c588f80824
80 changed files with 1183 additions and 528 deletions

View File

@ -39,6 +39,11 @@ option(FAST_MATH "Build with unsafe fast-math compiller option (Default: of
option(ENABLE_TTF "Use TrueType fonts instead of TXF (Default: off)" OFF)
option(ENABLE_TESTS "Enable unit tests? (Default: off)" OFF)
option(ENABLE_DATA "Install data from content submodule? (Default: on)" ON)
option(ENABLE_GLES "Build for OpenGL ES 2.0 instead of OpenGL 2.1 (Default: off)" OFF)
if(ENABLE_GLES)
add_definitions(-DGL_ES)
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type." FORCE)
@ -177,9 +182,11 @@ if(WIN32)
link_libraries("vfw32" "comctl32" "winmm")
endif()
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIRS})
link_libraries(${OPENGL_LIBRARIES})
if(NOT ENABLE_GLES)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIRS})
link_libraries(${OPENGL_LIBRARIES})
endif()
find_package(Libepoxy REQUIRED)
link_libraries(libepoxy::libepoxy)

View File

@ -17,14 +17,17 @@ echo "deb https://download.opensuse.org/repositories/home:/munix9:/unstable/Debi
sudo apt update && sudo apt install celestia
```
### On Ubuntu 18.04 and derived systems:
### On Ubuntu 18.04/20.04 and derived systems:
```
curl https://download.opensuse.org/repositories/home:/munix9:/unstable/Ubuntu_18.04/Release.key | sudo apt-key add -
echo "deb https://download.opensuse.org/repositories/home:/munix9:/unstable/Ubuntu_18.04/ ./" | sudo tee /etc/apt/sources.list.d/celestia-obs.list
curl https://download.opensuse.org/repositories/home:/munix9:/unstable/Ubuntu_${VERSION}/Release.key | sudo apt-key add -
echo "deb https://download.opensuse.org/repositories/home:/munix9:/unstable/Ubuntu_${VERSION}/ ./" | sudo tee /etc/apt/sources.list.d/celestia-obs.list
sudo apt update && sudo apt install celestia
```
Where VERSION is 18.04 or 20.04.
### On openSUSE Leap 15.1:
```
@ -254,7 +257,7 @@ default linker in gcc.
pacman -S mingw-w64-x86_64-lld mingw-w64-x86_64-lldb
```
Follow by:
Follow by:
```
cmake .. -G "MSYS Makefiles" -DENABLE_WIN=OFF -DCMAKE_CXX_FLAGS='-fuse-ld=lld' -DCMAKE_BUILD_TYPE=Debug
@ -335,15 +338,16 @@ List of supported parameters (passed as `-DPARAMETER=VALUE`):
| ENABLE_TOOLS | bool | OFF | Build tools for Celestia data files
| ENABLE_TTF | bool | \*\*\*\*OFF | Build with FreeType support
| ENABLE_DATA | bool | OFF | Use CelestiaContent submodule for data
| ENABLE_GLES | bool | OFF | Use OpenGL ES 2.0 in rendering code
| NATIVE_OSX_APP | bool | OFF | Support native OSX data paths
Notes:
Notes:
\* /usr/local on Unix-like systems, c:\Program Files or c:\Program Files (x86)
on Windows depending on OS type (32 or 64 bit) and build configuration.
This option effect is overriden by NATIVE_OSX_APP.
\*\* Ignored on Windows systems.
\*\*\* Ignored on Unix-like systems.
\*\*\*\* This option support is not finished yet.
This option effect is overriden by NATIVE_OSX_APP.
\*\* Ignored on Windows systems.
\*\*\* Ignored on Unix-like systems.
\*\*\*\* This option support is not finished yet.
Parameters of type "bool" accept ON or OFF value. Parameters of type "path"
accept any directory.

View File

@ -1,5 +1,3 @@
#version 120
uniform vec3 color;
varying float shade;

View File

@ -1,5 +1,3 @@
#version 120
attribute vec4 in_Position;
attribute vec3 in_Normal;
attribute float brightness;
@ -13,5 +11,5 @@ varying float shade;
void main(void)
{
shade = abs(dot(viewDir.xyz, in_Normal.xyz) * brightness * fadeFactor);
gl_Position = gl_ModelViewProjectionMatrix * in_Position;
gl_Position = MVPMatrix * in_Position;
}

View File

@ -1,5 +1,3 @@
#version 120
uniform vec4 color;
void main(void)

View File

@ -1,5 +1,3 @@
#version 120
attribute vec4 in_Position;
uniform float radius;
@ -11,10 +9,10 @@ void main(void)
{
float c = cos(angle);
float s = sin(angle);
mat3 rot = mat3(c, s, 0.0f, -s, c, 0.0f, 0.0f, 0.0f, 1.0f);
mat3 rot = mat3(c, s, 0.0, -s, c, 0.0, 0.0, 0.0, 1.0);
float x = in_Position.x * width + radius;
float y = in_Position.y * h;
vec3 p = rot * vec3(x, y, 0.0f);
gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f);
vec3 p = rot * vec3(x, y, 0.0);
gl_Position = MVPMatrix * vec4(p, 1.0);
}

View File

@ -1,5 +1,3 @@
#version 120
void main(void)
{
}

View File

@ -1,7 +1,4 @@
#version 120
attribute vec4 in_Position;
uniform mat4 MVPMatrix;
void main(void)
{

View File

@ -1,5 +1,3 @@
#version 120
uniform vec4 color;
void main(void)

View File

@ -1,9 +1,7 @@
#version 120
attribute vec2 in_Position;
void main(void)
{
vec4 p = vec4(in_Position.x, 0.0f, in_Position.y, 1.0f);
gl_Position = gl_ModelViewProjectionMatrix * p;
vec4 p = vec4(in_Position.x, 0.0, in_Position.y, 1.0);
gl_Position = MVPMatrix * p;
}

View File

@ -1,5 +1,3 @@
#version 120
varying vec4 color;
varying vec2 texCoord;

View File

@ -1,5 +1,3 @@
#version 120
attribute vec4 in_Position;
attribute vec4 in_TexCoord0;
//attribute float in_ColorIndex;
@ -15,12 +13,12 @@ void main(void)
// we pass color index as short int
// reusing gl_MultiTexCoord0.z
// we use 255 only because we have 256 color indices
float t = in_TexCoord0.z / 255.0f; // [0, 255] -> [0, 1]
float t = in_TexCoord0.z / 255.0; // [0, 255] -> [0, 1]
// we pass alpha values as as short int
// reusing gl_MultiTexCoord0.w
// we use 65535 for better precision
float a = in_TexCoord0.w / 65535.0f; // [0, 65535] -> [0, 1]
color = vec4(texture2D(colorTex, vec2(t, 0.0f)).rgb, a);
float a = in_TexCoord0.w / 65535.0; // [0, 65535] -> [0, 1]
color = vec4(texture2D(colorTex, vec2(t, 0.0)).rgb, a);
texCoord = in_TexCoord0.st;
gl_Position = gl_ModelViewProjectionMatrix * in_Position;
gl_Position = MVPMatrix * in_Position;
}

View File

@ -1,5 +1,3 @@
#version 120
uniform sampler2D starTex;
varying vec4 color;

View File

@ -1,5 +1,3 @@
#version 120
attribute vec3 in_Position;
attribute vec4 in_Color;
attribute float starSize;
@ -11,10 +9,10 @@ uniform float brightness;
uniform float pixelWeight;
uniform float RRatio;
const float RRatio_min = pow(10.0f, 1.7f);
const float clipDistance = 100.0f; // observer distance [ly] from globular, where we
// start "morphing" the star-sprite sizes towards
// their physical values
const float RRatio_min = pow(10.0, 1.7);
const float clipDistance = 100.0; // observer distance [ly] from globular, where we
// start "morphing" the star-sprite sizes towards
// their physical values
varying vec4 color;
@ -31,27 +29,27 @@ float relStarDensity(void)
*/
float rRatio = max(RRatio_min, RRatio);
float Xi = 1.0f / sqrt(1.0f + rRatio * rRatio);
float Xi = 1.0 / sqrt(1.0 + rRatio * rRatio);
float XI2 = Xi * Xi;
float rho2 = 1.0001f + eta * eta * rRatio * rRatio; //add 1e-4 as regulator near rho=0
float rho2 = 1.0001 + eta * eta * rRatio * rRatio; //add 1e-4 as regulator near rho=0
return ((log(rho2) + 4.0f * (1.0f - sqrt(rho2)) * Xi) / (rho2 - 1.0f) + XI2) / (1.0f - 2.0f * Xi + XI2);
return ((log(rho2) + 4.0 * (1.0 - sqrt(rho2)) * Xi) / (rho2 - 1.0) + XI2) / (1.0 - 2.0 * Xi + XI2);
}
void main(void)
{
vec3 p = m * in_Position.xyz;
float br = 2.0f * brightness;
float br = 2.0 * brightness;
vec4 mod = gl_ModelViewMatrix * vec4(in_Position, 1.0f);
vec4 mod = ModelViewMatrix * vec4(in_Position, 1.0);
float s = 2000.0 / -mod.z * br * starSize;
float obsDistanceToStarRatio = length(p + offset) / clipDistance;
// "Morph" the star-sprite sizes at close observer distance such that
// the overdense globular core is dissolved upon closing in.
gl_PointSize = s * min(obsDistanceToStarRatio, 1.0f);
gl_PointSize = s * min(obsDistanceToStarRatio, 1.0);
color = vec4(in_Color.rgb, min(1.0f, br * (1.0f - pixelWeight * relStarDensity())));
gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f);
color = vec4(in_Color.rgb, min(1.0, br * (1.0 - pixelWeight * relStarDensity())));
gl_Position = MVPMatrix * vec4(p, 1.0);
}

View File

@ -1,5 +1,3 @@
#version 120
uniform vec4 color;
void main(void)

View File

@ -1,5 +1,3 @@
#version 120
attribute vec2 in_Position;
uniform float pixelSize;
@ -12,5 +10,5 @@ void main(void)
float x = in_Position.x * pixelSize;
float y = in_Position.y * pixelSize;
vec3 pos = (x * c - y * s + x0) * u + (x * s + y * c + y0) * v;
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0f);
gl_Position = MVPMatrix * vec4(pos, 1.0);
}

View File

@ -1,4 +1,3 @@
#version 120
uniform sampler2D starTex;
varying vec4 color;

View File

@ -1,5 +1,3 @@
#version 120
attribute vec3 in_Position;
attribute vec4 in_Color;
attribute float in_PointSize;
@ -9,5 +7,5 @@ void main(void)
{
gl_PointSize = in_PointSize;
color = in_Color;
gl_Position = gl_ModelViewProjectionMatrix * vec4(in_Position, 1.0);
gl_Position = MVPMatrix * vec4(in_Position, 1.0);
}

View File

@ -1,5 +1,3 @@
#version 120
varying vec2 texCoord;
varying vec4 color;

View File

@ -1,5 +1,3 @@
#version 120
attribute vec2 in_Position;
attribute vec2 in_TexCoord0;
attribute vec4 in_Color;
@ -9,7 +7,7 @@ varying vec4 color;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * vec4(in_Position.xy, 0, 1);
gl_Position = MVPMatrix * vec4(in_Position.xy, 0, 1);
texCoord = in_TexCoord0.st;
color = in_Color;
}

View File

@ -1,5 +1,3 @@
#version 120
uniform vec4 color;
uniform sampler2D tidalTex;
varying vec2 texCoord;

View File

@ -1,5 +1,3 @@
#version 120
attribute vec3 in_Position;
attribute vec2 in_TexCoord0;
@ -11,7 +9,7 @@ varying vec2 texCoord;
void main(void)
{
vec3 p = viewMat * in_Position.xyz * tidalSize;
gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f);
gl_Position = MVPMatrix * vec4(p, 1.0);
texCoord = in_TexCoord0.st;
}

View File

@ -28,7 +28,7 @@ bool AsterismRenderer::sameAsterisms(const AsterismList *asterisms) const
/*! Draw visible asterisms.
*/
void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColor)
void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColor, const Eigen::Matrix4f &mvp)
{
auto *prog = renderer.getShaderManager().getShader(m_shadprop);
if (prog == nullptr)
@ -50,6 +50,7 @@ void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColo
}
prog->use();
prog->MVPMatrix = mvp;
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, defaultColor);
m_vo.draw(GL_LINES, m_vtxTotal);

View File

@ -28,7 +28,7 @@ class AsterismRenderer
AsterismRenderer& operator=(const AsterismRenderer&) = delete;
AsterismRenderer& operator=(AsterismRenderer&&) = delete;
void render(const Renderer &renderer, const Color &color);
void render(const Renderer &renderer, const Color &color, const Eigen::Matrix4f &mvp);
bool sameAsterisms(const AsterismList *asterisms) const;
private:

View File

@ -24,6 +24,7 @@
using namespace Eigen;
using namespace std;
using namespace celestia;
using namespace celmath;
using namespace celgl;
@ -241,9 +242,10 @@ ArrowReferenceMark::setColor(Color _color)
void
ArrowReferenceMark::render(Renderer* renderer,
const Vector3f& /* position */,
const Vector3f& position,
float /* discSize */,
double tdb) const
double tdb,
const Matrices& m) const
{
Vector3d v = getDirection(tdb);
if (v.norm() < 1.0e-12)
@ -275,20 +277,20 @@ ArrowReferenceMark::render(Renderer* renderer,
#endif
}
glPushMatrix();
glRotate(q.cast<float>());
glScalef(size, size, size);
Affine3f transform = Translation3f(position) * q.cast<float>() * Scaling(size);
Matrix4f mv = (*m.modelview) * transform.matrix();
CelestiaGLProgram* prog = renderer->getShaderManager().getShader(shadprop);
if (prog == nullptr)
return;
prog->use();
prog->MVPMatrix = (*m.projection) * mv;
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex,
color.red(), color.green(), color.blue(), opacity);
auto &vo = renderer->getVertexObject(VOType::AxisArrow, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
RenderArrow(vo);
glPopMatrix();
glUseProgram(0);
glDisable(GL_DEPTH_TEST);
@ -333,9 +335,10 @@ AxesReferenceMark::setOpacity(float _opacity)
void
AxesReferenceMark::render(Renderer* renderer,
const Vector3f& /* position */,
const Vector3f& position,
float /* discSize */,
double tdb) const
double tdb,
const Matrices& m) const
{
Quaterniond q = getOrientation(tdb);
@ -358,9 +361,8 @@ AxesReferenceMark::render(Renderer* renderer,
#endif
}
glPushMatrix();
glRotate(q.cast<float>());
glScalef(size, size, size);
Affine3f transform = Translation3f(position) * q.cast<float>() * Scaling(size);
Matrix4f mvp = (*m.projection) * (*m.modelview) * transform.matrix();
#if 0
// Simple line axes
@ -390,37 +392,33 @@ AxesReferenceMark::render(Renderer* renderer,
auto &vo = renderer->getVertexObject(VOType::AxisArrow, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
Affine3f labelTransform = Translation3f(Vector3f(0.1f, 0.0f, 0.75f)) * Scaling(labelScale);
Matrix4f labelTransformMatrix = labelTransform.matrix();
Matrix4f t;
// x-axis
glPushMatrix();
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
t = mvp * vecgl::rotate(AngleAxisf(90.0_deg, Vector3f::UnitY()));
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 1.0f, 0.0f, 0.0f, opacity);
prog->MVPMatrix = t;
RenderArrow(vo);
glTranslatef(0.1f, 0.0f, 0.75f);
glScalef(labelScale, labelScale, labelScale);
prog->MVPMatrix = t * labelTransformMatrix;
RenderX(vo);
glPopMatrix();
// y-axis
glPushMatrix();
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
t = mvp * vecgl::rotate(AngleAxisf(180.0_deg, Vector3f::UnitY()));
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 1.0f, 0.0f, opacity);
prog->MVPMatrix = t;
RenderArrow(vo);
glTranslatef(0.1f, 0.0f, 0.75f);
glScalef(labelScale, labelScale, labelScale);
prog->MVPMatrix = t * labelTransformMatrix;
RenderY(vo);
glPopMatrix();
// z-axis
glPushMatrix();
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
t = mvp *vecgl::rotate(AngleAxisf(-90.0_deg, Vector3f::UnitX()));
glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 0.0f, 1.0f, opacity);
prog->MVPMatrix = t;
RenderArrow(vo);
glTranslatef(0.1f, 0.0f, 0.75f);
glScalef(labelScale, labelScale, labelScale);
prog->MVPMatrix = t * labelTransformMatrix;
RenderZ(vo);
glPopMatrix();
glPopMatrix();
glUseProgram(0);
glDisable(GL_DEPTH_TEST);

View File

@ -29,7 +29,11 @@ class ArrowReferenceMark : public ReferenceMark
void setSize(float _size);
void setColor(Color _color);
void render(Renderer* renderer, const Eigen::Vector3f& position, float discSize, double tdb) const;
void render(Renderer* renderer,
const Eigen::Vector3f& position,
float discSize,
double tdb,
const Matrices& m) const override;
float boundingSphereRadius() const
{
return size;
@ -61,7 +65,11 @@ class AxesReferenceMark : public ReferenceMark
void setSize(float _size);
void setOpacity(float _opacity);
void render(Renderer* renderer, const Eigen::Vector3f& position, float discSize, double tdb) const;
void render(Renderer* renderer,
const Eigen::Vector3f& position,
float discSize,
double tdb,
const Matrices& m) const override;
float boundingSphereRadius() const
{
return size;
@ -138,6 +146,3 @@ private:
};
#endif // _CELENGINE_AXISARROW_H_

View File

@ -30,7 +30,7 @@ bool BoundariesRenderer::sameBoundaries(const ConstellationBoundaries *boundarie
return m_boundaries == boundaries;
}
void BoundariesRenderer::render(const Renderer &renderer, const Color &color)
void BoundariesRenderer::render(const Renderer &renderer, const Color &color, const Eigen::Matrix4f &mvp)
{
auto *prog = renderer.getShaderManager().getShader(m_shadprop);
if (prog == nullptr)
@ -51,6 +51,7 @@ void BoundariesRenderer::render(const Renderer &renderer, const Color &color)
}
prog->use();
prog->MVPMatrix = mvp;
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
m_vo.draw(GL_LINES, m_vtxTotal);

View File

@ -27,7 +27,7 @@ class BoundariesRenderer
BoundariesRenderer& operator=(const BoundariesRenderer&) = delete;
BoundariesRenderer& operator=(BoundariesRenderer&&) = delete;
void render(const Renderer &renderer, const Color &color);
void render(const Renderer &renderer, const Color &color, const Eigen::Matrix4f &mvp);
bool sameBoundaries(const ConstellationBoundaries*) const;
private:

View File

@ -80,12 +80,7 @@ bool Console::setRowCount(int _nRows)
void Console::begin()
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrix(Ortho2D(0.0f, (float)xscale, 0.0f, (float)yscale));
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
mpv = Ortho2D(0.0f, (float)xscale, 0.0f, (float)yscale);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -96,11 +91,8 @@ void Console::begin()
void Console::end()
{
font->unbind();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
if (font != nullptr)
font->unbind();
}
@ -110,6 +102,7 @@ void Console::render(int rowHeight)
return;
font->bind();
font->setMVPMatrix(mpv);
savePos();
for (int i = 0; i < rowHeight; i++)
{

View File

@ -12,8 +12,9 @@
#include <string>
#include <iosfwd>
#include <vector>
#include <celutil/color.h>
#include <vector>
#include <Eigen/Core>
class Console;
class TextureFont;
@ -108,6 +109,7 @@ class Console : public std::ostream
};
CursorPosition global { 0.0f, 0.0f };
std::vector<CursorPosition> posStack;
Eigen::Matrix4f mpv;
};
#endif // _CELENGINE_CONSOLE_H_

View File

@ -159,18 +159,20 @@ Image* LoadDDSImage(const fs::path& filename)
}
else if (ddsd.format.bpp == 24)
{
if (ddsd.format.redMask == 0x00ff0000 &&
if (ddsd.format.redMask == 0x000000ff &&
ddsd.format.greenMask == 0x0000ff00 &&
ddsd.format.blueMask == 0x000000ff)
{
format = GL_BGR_EXT;
}
else if (ddsd.format.redMask == 0x000000ff &&
ddsd.format.greenMask == 0x0000ff00 &&
ddsd.format.blueMask == 0x00ff0000)
ddsd.format.blueMask == 0x00ff0000)
{
format = GL_RGB;
}
#ifndef GL_ES
else if (ddsd.format.redMask == 0x00ff0000 &&
ddsd.format.greenMask == 0x0000ff00 &&
ddsd.format.blueMask == 0x000000ff)
{
format = GL_BGR;
}
#endif
}
}

View File

@ -25,6 +25,7 @@
class Selection;
class Renderer;
struct Matrices;
constexpr const float DSO_DEFAULT_ABS_MAGNITUDE = -1000.0f;
@ -90,6 +91,7 @@ class DeepSkyObject : public AstroObject
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer*) = 0;
virtual uint64_t getRenderMask() const { return 0; }

View File

@ -17,6 +17,7 @@
#include "dsorenderer.h"
using namespace Eigen;
using namespace celestia;
using namespace celmath;
// The parameter 'enhance' adjusts the DSO brightness as viewed from "inside"
@ -85,6 +86,9 @@ void DSORenderer::process(DeepSkyObject* const &dso,
if (brightness < 0)
brightness = 0;
Matrix4f mv = vecgl::translate(renderer->getModelViewMatrix(), relPos);
Matrix4f pr;
if (dsoRadius < 1000.0)
{
// Small objects may be prone to clipping; give them special
@ -99,26 +103,17 @@ void DSORenderer::process(DeepSkyObject* const &dso,
farZ = nearZ * 10000.0f;
}
glMatrixMode(GL_PROJECTION);
glPushMatrix();
float t = (float)wWidth / (float)wHeight;
glLoadMatrix(Perspective(fov, t, nearZ, farZ));
glMatrixMode(GL_MODELVIEW);
pr = Perspective(fov, t, nearZ, farZ);
}
else
{
pr = renderer->getProjectionMatrix();
}
glPushMatrix();
glTranslate(relPos);
dso->render(relPos, observer->getOrientationf(), brightness,
pixelSize, renderer);
glPopMatrix();
pixelSize, { &pr, &mv }, renderer);
if (dsoRadius < 1000.0)
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
} // renderFlags check
// Only render those labels that are in front of the camera:

View File

@ -89,12 +89,22 @@ FramebufferObject::generateColorTexture()
// Set the texture dimensions
// Do we need to set GL_DEPTH_COMPONENT24 here?
#ifdef GL_ES
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
#endif
// Unbind the texture
glBindTexture(GL_TEXTURE_2D, 0);
}
#ifdef GL_ES
#define CEL_DEPTH_FORMAT GL_UNSIGNED_INT
#else
#define CEL_DEPTH_FORMAT GL_UNSIGNED_BYTE
#endif
void
FramebufferObject::generateDepthTexture()
{
@ -102,6 +112,9 @@ FramebufferObject::generateDepthTexture()
glGenTextures(1, &m_depthTexId);
glBindTexture(GL_TEXTURE_2D, m_depthTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
// Only nearest sampling is appropriate for depth textures
// But we can use linear to decrease aliasing
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -113,7 +126,8 @@ FramebufferObject::generateDepthTexture()
// Set the texture dimensions
// Do we need to set GL_DEPTH_COMPONENT24 here?
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_width, m_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_width, m_height, 0, GL_DEPTH_COMPONENT, CEL_DEPTH_FORMAT, nullptr);
// Unbind the texture
glBindTexture(GL_TEXTURE_2D, 0);
@ -126,7 +140,9 @@ FramebufferObject::generateFbo(unsigned int attachments)
glGenFramebuffers(1, &m_fboId);
glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);
#ifndef GL_ES
glReadBuffer(GL_NONE);
#endif
if ((attachments & ColorAttachment) != 0)
{
@ -140,11 +156,13 @@ FramebufferObject::generateFbo(unsigned int attachments)
return;
}
}
#ifndef GL_ES
else
{
// Depth-only rendering; no color buffer.
glDrawBuffer(GL_NONE);
}
#endif
if ((attachments & DepthAttachment) != 0)
{

View File

@ -9,7 +9,6 @@
// of the License, or (at your option) any later version.
#include "render.h"
#include <config.h>
#include "astro.h"
#include "galaxy.h"
#include "vecgl.h"
@ -20,7 +19,6 @@
#include <celutil/gettext.h>
#include <celutil/debug.h>
#include <celcompat/filesystem.h>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <random>
@ -29,6 +27,7 @@
using namespace Eigen;
using namespace std;
using namespace celmath;
using namespace celestia;
static int width = 128, height = 128;
static const unsigned int GALAXY_POINTS = 3500;
@ -272,6 +271,7 @@ void Galaxy::render(const Vector3f& offset,
const Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* renderer)
{
if (form == nullptr)
@ -280,7 +280,7 @@ void Galaxy::render(const Vector3f& offset,
}
else
{
renderGalaxyPointSprites(offset, viewerOrientation, brightness, pixelSize, renderer);
renderGalaxyPointSprites(offset, viewerOrientation, brightness, pixelSize, m, renderer);
}
}
@ -311,6 +311,7 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
const Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& ms,
const Renderer* renderer)
{
if (form == nullptr)
@ -346,7 +347,9 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
if (colorTex == nullptr)
{
colorTex = CreateProceduralTexture(256, 1, GL_RGBA,
ColorTextureEval);
ColorTextureEval,
Texture::EdgeClamp,
Texture::NoMipMaps);
}
assert(colorTex != nullptr);
glActiveTexture(GL_TEXTURE1);
@ -394,8 +397,8 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
brightness_corr = 0.45f;
}
glPushMatrix();
glTranslatef(-offset.x(), -offset.y(), -offset.z());
Matrix4f mv = vecgl::translate(*ms.modelview, Vector3f(-offset));
const float btot = ((type > SBc) && (type < Irr)) ? 2.5f : 5.0f;
const float spriteScaleFactor = 1.0f / 1.55f;
@ -411,6 +414,7 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
GLushort j = 0;
prog->use();
prog->mat4Param("MVPMatrix") = (*ms.projection) * mv;
prog->samplerParam("galaxyTex") = 0;
prog->samplerParam("colorTex") = 1;
@ -468,7 +472,6 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glUseProgram(0);
glPopMatrix();
glActiveTexture(GL_TEXTURE0);
}

View File

@ -47,6 +47,7 @@ class Galaxy : public DeepSkyObject
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* r) override;
GalacticForm* getForm() const;
@ -86,6 +87,7 @@ class Galaxy : public DeepSkyObject
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& mvp,
const Renderer* r);
#if 0
void renderGalaxyEllipsoid(const Eigen::Vector3f& offset,

View File

@ -0,0 +1,199 @@
// glcompat.h
//
// Copyright (C) 2020, the Celestia Development Team
//
// OpenGL 2.1 compatibility layer for OpenGL ES 2.0
//
// 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 <cassert>
#include <cstring> // for memcpy
#include "glcompat.h"
constexpr const int MODELVIEW_STACK_DEPTH = 8;
constexpr const int PROJECTION_STACK_DEPTH = 2;
static float g_modelViewStack[MODELVIEW_STACK_DEPTH][16];
static float g_projectionStack[PROJECTION_STACK_DEPTH][16];
static size_t g_modelViewPosition = 0;
static size_t g_projectionPosition = 0;
static int g_matrixMode = GL_MODELVIEW;
void
initGLCompat() noexcept
{
g_matrixMode = GL_PROJECTION;
for (size_t i = 0; i < PROJECTION_STACK_DEPTH; i++)
{
g_projectionPosition = i;
glesLoadIdentity();
}
g_projectionPosition = 0;
g_matrixMode = GL_MODELVIEW;
for (size_t i = 0; i < MODELVIEW_STACK_DEPTH; i++)
{
g_modelViewPosition = i;
glesLoadIdentity();
}
g_modelViewPosition = 0;
}
void
glesMatrixMode(int _g_matrixMode) noexcept
{
g_matrixMode = _g_matrixMode;
}
void
glesPushMatrix() noexcept
{
switch (g_matrixMode)
{
case GL_MODELVIEW:
if (g_modelViewPosition < MODELVIEW_STACK_DEPTH - 1)
g_modelViewPosition++;
else
assert(0 && "Matrix stack overflow");
break;
case GL_PROJECTION:
if (g_projectionPosition < PROJECTION_STACK_DEPTH - 1)
g_projectionPosition++;
else
assert(0 && "Matrix stack overflow");
break;
default:
assert(0 && "Incorrect matrix g_matrixMode");
}
}
void
glesPopMatrix() noexcept
{
switch (g_matrixMode)
{
case GL_MODELVIEW:
if (g_modelViewPosition > 0)
g_modelViewPosition--;
else
assert(0 && "Matrix stack underflow");
break;
case GL_PROJECTION:
if (g_projectionPosition > 0)
g_projectionPosition--;
else
assert(0 && "Matrix stack underflow");
break;
default:
assert(0 && "Incorrect matrix g_matrixMode");
}
}
void
glesLoadMatrix(const float *data) noexcept
{
glesLoadMatrix(g_matrixMode, data);
}
void
glesLoadMatrix(int mode, const float *data) noexcept
{
switch (mode)
{
case GL_MODELVIEW:
memcpy(g_modelViewStack[g_modelViewPosition], data, sizeof(float)*16);
break;
case GL_PROJECTION:
memcpy(g_projectionStack[g_projectionPosition], data, sizeof(float)*16);
break;
default:
assert("Incorrect matrix g_matrixMode");
}
}
float*
glesGetMatrix(int mode) noexcept
{
switch (mode)
{
case GL_MODELVIEW:
assert(g_modelViewPosition < MODELVIEW_STACK_DEPTH);
if (g_modelViewPosition < MODELVIEW_STACK_DEPTH)
return g_modelViewStack[g_modelViewPosition];
break;
case GL_PROJECTION:
assert(g_projectionPosition < PROJECTION_STACK_DEPTH);
if (g_projectionPosition < PROJECTION_STACK_DEPTH)
return g_projectionStack[g_projectionPosition];
break;
default:
assert(0 && "Incorrect matrix mode");
}
return nullptr;
}
void
glesGetMatrix(float *data) noexcept
{
glesGetMatrix(g_matrixMode, data);
}
void
glesGetMatrix(int mode, float *data) noexcept
{
switch (mode)
{
case GL_MODELVIEW:
assert(g_modelViewPosition < MODELVIEW_STACK_DEPTH);
if (g_modelViewPosition < MODELVIEW_STACK_DEPTH)
memcpy(data, g_modelViewStack[g_modelViewPosition], sizeof(float)*16);
break;
case GL_PROJECTION:
assert(g_projectionPosition < PROJECTION_STACK_DEPTH);
if (g_projectionPosition < PROJECTION_STACK_DEPTH)
memcpy(data, g_projectionStack[g_projectionPosition], sizeof(float)*16);
break;
default:
assert(0 && "Incorrect matrix mode");
}
}
void
glesLoadIdentity() noexcept
{
float *p = nullptr;
switch (g_matrixMode)
{
case GL_MODELVIEW:
assert(g_modelViewPosition < MODELVIEW_STACK_DEPTH);
if (g_modelViewPosition < MODELVIEW_STACK_DEPTH)
p = g_modelViewStack[g_modelViewPosition];
break;
case GL_PROJECTION:
assert(g_projectionPosition < PROJECTION_STACK_DEPTH);
if (g_projectionPosition < PROJECTION_STACK_DEPTH)
p = g_projectionStack[g_projectionPosition];
break;
default:
assert(0 && "Incorrect matrix mode");
}
if (p != nullptr)
{
for (size_t i = 0; i < 4; i++)
for (size_t j = 0; j < 4; j++)
p[i * 4 + j] = i == j ? 1.0f : 0.0f;
}
}

View File

@ -0,0 +1,60 @@
// glcompat.h
//
// Copyright (C) 2020, the Celestia Development Team
//
// OpenGL 2.1 compatibility layer for OpenGL ES 2.0
//
// 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
#if !defined(__gles2_gl2_h_) && !defined(EPOXY_GL_H)
#error "glcompat.h must be included after GLES2/gl2.h"
#endif
#ifndef GL_PROJECTION
#define GL_PROJECTION 0x1701
#endif
#ifndef GL_MODELVIEW
#define GL_MODELVIEW 0x1700
#endif
#ifdef glMatrixMode
#undef glMatrixMode
#endif
#define glMatrixMode(m) glesMatrixMode(m)
#ifdef glPushMatrix
#undef glPushMatrix
#endif
#define glPushMatrix glesPushMatrix
#ifdef glPopMatrix
#undef glPopMatrix
#endif
#define glPopMatrix glesPopMatrix
#ifdef glLoadMatrixf
#undef glLoadMatrixf
#endif
#define glLoadMatrixf(m) glesLoadMatrix(m)
#ifdef glLoadIdentity
#undef glLoadIdentity
#endif
#define glLoadIdentity glesLoadIdentity
void initGLCompat() noexcept;
void glesMatrixMode(int _g_matrixMode) noexcept;
void glesPushMatrix() noexcept;
void glesPopMatrix() noexcept;
void glesLoadMatrix(const float *data) noexcept;
void glesLoadMatrix(int mode, const float *data) noexcept;
void glesGetMatrix(float *data) noexcept;
void glesGetMatrix(int mode, float *data) noexcept;
float* glesGetMatrix(int mode) noexcept;
void glesLoadIdentity() noexcept;
void glesTranslate(float x, float y, float z) noexcept;

View File

@ -22,6 +22,7 @@
using namespace std;
using namespace celgl;
using namespace celmath;
using namespace celestia;
using namespace Eigen;
@ -216,7 +217,10 @@ static void initVO(VertexObject& vo)
vo.setVertices(2, GL_FLOAT, false, 0, 0);
}
void Renderer::renderMarker(MarkerRepresentation::Symbol symbol, float size, const Color& color)
void Renderer::renderMarker(MarkerRepresentation::Symbol symbol,
float size,
const Color &color,
const Matrices &m)
{
assert(shaderManager != nullptr);
ShaderProperties shadprop;
@ -231,10 +235,11 @@ void Renderer::renderMarker(MarkerRepresentation::Symbol symbol, float size, con
if (!markerVO.initialized())
initVO(markerVO);
float s = size / 2.0f;
prog->use();
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
glScalef(s, s, 0);
prog->use();
float s = size / 2.0f;
prog->MVPMatrix = (*m.projection) * (*m.modelview) * vecgl::scale(Vector3f(s, s, 0));
switch (symbol)
{
@ -322,7 +327,7 @@ void Renderer::renderSelectionPointer(const Observer& observer,
if (prog == nullptr)
return;
Matrix3f cameraMatrix = observer.getOrientationf().conjugate().toRotationMatrix();
Matrix3f cameraMatrix = getCameraOrientation().conjugate().toRotationMatrix();
const Vector3f u = cameraMatrix.col(0);
const Vector3f v = cameraMatrix.col(1);
double distance = position.norm();
@ -352,15 +357,14 @@ void Renderer::renderSelectionPointer(const Observer& observer,
x0 *= t;
y0 *= t;
const Vector3f &center = cameraMatrix.col(2);
glPushMatrix();
glTranslatef(-center.x(), -center.y(), -center.z());
auto &markerVO = getVertexObject(VOType::Marker, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
markerVO.bind();
if (!markerVO.initialized())
initVO(markerVO);
prog->use();
const Vector3f &center = cameraMatrix.col(2);
prog->mat4Param("MVPMatrix") = getProjectionMatrix() * getModelViewMatrix() * vecgl::translate(Vector3f(-center));
prog->vec4Param("color") = Color(SelectionCursorColor, 0.6f).toVector4();
prog->floatParam("pixelSize") = pixelSize;
prog->floatParam("s") = s;
@ -374,8 +378,6 @@ void Renderer::renderSelectionPointer(const Observer& observer,
glUseProgram(0);
markerVO.unbind();
glPopMatrix();
#ifdef USE_HDR
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
#endif
@ -400,6 +402,7 @@ void Renderer::renderEclipticLine()
initVO(markerVO);
prog->use();
prog->mat4Param("MVPMatrix") = getProjectionMatrix() * getModelViewMatrix();
prog->vec4Param("color") = EclipticColor.toVector4();
markerVO.draw(GL_LINE_LOOP, EclipticCount, EclipticOffset);
@ -407,7 +410,10 @@ void Renderer::renderEclipticLine()
markerVO.unbind();
}
void Renderer::renderCrosshair(float selectionSizeInPixels, double tsec, const Color &color)
void Renderer::renderCrosshair(float selectionSizeInPixels,
double tsec,
const Color &color,
const Matrices &m)
{
assert(shaderManager != nullptr);
auto* prog = shaderManager->getShader("crosshair");
@ -432,6 +438,7 @@ void Renderer::renderCrosshair(float selectionSizeInPixels, double tsec, const C
float cursorGrow = max(1.0f, min(2.5f, (selectionSizeInPixels - 10.0f) / 100.0f));
prog->use();
prog->mat4Param("MVPMatrix") = (*m.projection) * (*m.modelview);
prog->vec4Param("color") = color.toVector4();
prog->floatParam("radius") = cursorRadius;
prog->floatParam("width") = minCursorWidth * cursorGrow;

View File

@ -11,7 +11,6 @@
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#include <config.h>
#include "astro.h"
#include "render.h"
#include "globular.h"
@ -24,11 +23,13 @@
#include <fstream>
#include <algorithm>
#include <cassert>
#include "vecgl.h"
using namespace Eigen;
using namespace std;
using namespace celmath;
using namespace celgl;
using namespace celestia;
constexpr const int cntrTexWidth = 512;
constexpr const int cntrTexHeight = 512;
@ -300,9 +301,10 @@ void Globular::render(const Vector3f& offset,
const Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* r)
{
renderGlobularPointSprites(offset, viewerOrientation, brightness, pixelSize, r);
renderGlobularPointSprites(offset, viewerOrientation, brightness, pixelSize, m, r);
}
@ -378,6 +380,7 @@ void Globular::renderGlobularPointSprites(
const Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* renderer)
{
if (form == nullptr)
@ -442,8 +445,10 @@ void Globular::renderGlobularPointSprites(
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifndef GL_ES
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
float tidalSize = 2 * tidalRadius;
@ -462,6 +467,9 @@ void Globular::renderGlobularPointSprites(
tidalProg->use();
centerTex[ic]->bind();
Matrix4f mvp = (*m.projection) * (*m.modelview);
tidalProg->mat4Param("MVPMatrix") = mvp;
Matrix3f viewMat = viewerOrientation.conjugate().toRotationMatrix();
tidalProg->vec4Param("color") = Vector4f(Rr, Gg, Bb, min(2 * brightness * pixelWeight, 1.0f));
tidalProg->floatParam("tidalSize") = tidalSize;
@ -484,8 +492,10 @@ void Globular::renderGlobularPointSprites(
globProg->use();
globularTex->bind();
Matrix3f m = Scaling(form->scale) * getOrientation().toRotationMatrix() * Scaling(tidalSize);
globProg->mat3Param("m") = m;
globProg->mat4Param("MVPMatrix") = mvp;
globProg->mat4Param("ModelViewMatrix") = vecgl::translate(*m.modelview, offset);
Matrix3f mx = Scaling(form->scale) * getOrientation().toRotationMatrix() * Scaling(tidalSize);
globProg->mat3Param("m") = mx;
globProg->vec3Param("offset") = offset;
globProg->floatParam("brightness") = brightness;
globProg->floatParam("pixelWeight") = pixelWeight;
@ -496,8 +506,10 @@ void Globular::renderGlobularPointSprites(
glUseProgram(0);
vo.unbind();
#ifndef GL_ES
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
// These should be called but stars are broken then
// TODO: find and fix
//glDisable(GL_BLEND);

View File

@ -62,6 +62,7 @@ class Globular : public DeepSkyObject
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* r) override;
GlobularForm* getForm() const;
@ -75,6 +76,7 @@ class Globular : public DeepSkyObject
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* r);
// Reference values ( = data base averages) of core radius, King concentration

View File

@ -5,9 +5,13 @@ namespace celestia
namespace gl
{
bool ARB_shader_texture_lod = false;
#ifdef GL_ES
bool OES_vertex_array_object = false;
#else
bool ARB_vertex_array_object = false;
bool EXT_framebuffer_object = false;
#endif
bool ARB_shader_texture_lod = false;
bool EXT_texture_compression_s3tc = false;
bool EXT_texture_filter_anisotropic = false;
@ -21,9 +25,13 @@ namespace
bool init() noexcept
{
ARB_shader_texture_lod = has_extension("GL_ARB_shader_texture_lod");
#ifdef GL_ES
OES_vertex_array_object = has_extension("GL_OES_vertex_array_object");
#else
ARB_vertex_array_object = has_extension("GL_ARB_vertex_array_object");
EXT_framebuffer_object = has_extension("GL_EXT_framebuffer_object");
#endif
ARB_shader_texture_lod = has_extension("GL_ARB_shader_texture_lod");
EXT_texture_compression_s3tc = has_extension("GL_EXT_texture_compression_s3tc");
EXT_texture_filter_anisotropic = has_extension("GL_EXT_texture_filter_anisotropic");

View File

@ -1,5 +1,13 @@
#pragma once
#ifdef GL_ES
#include <epoxy/gl.h>
/*
#include <GLES2/gl2.h>
#define GL_GLEXT_PROTOTYPES 1
#include <GLES2/gl2ext.h>
*/
#else
#ifdef _WIN32
#include <windows.h>
#endif
@ -9,6 +17,14 @@
#else
#include <GL/glu.h>
#endif
#endif
#ifdef GL_ES
#ifdef glDepthRange
#undef glDepthRange
#endif
#define glDepthRange glDepthRangef
#endif
namespace celestia
{
@ -18,10 +34,14 @@ namespace gl
constexpr const int GL_2_1 = 21;
extern bool ARB_shader_texture_lod;
extern bool ARB_vertex_array_object;
extern bool EXT_framebuffer_object;
extern bool EXT_texture_compression_s3tc;
extern bool EXT_texture_filter_anisotropic;
#ifdef GL_ES
extern bool OES_vertex_array_object;
#else
extern bool ARB_vertex_array_object;
extern bool EXT_framebuffer_object;
#endif
bool init() noexcept;
bool checkVersion(int) noexcept;

View File

@ -47,10 +47,14 @@ static int formatComponents(int fmt)
case GL_BGRA_EXT:
return 4;
case GL_RGB:
#ifndef GL_ES
case GL_BGR_EXT:
#endif
return 3;
case GL_LUMINANCE_ALPHA:
#ifndef GL_ES
case GL_DSDT_NV:
#endif
return 2;
case GL_ALPHA:
case GL_LUMINANCE:

View File

@ -69,9 +69,9 @@ void Marker::setSizing(MarkerSizing sizing)
}
void Marker::render(Renderer& r, float size) const
void Marker::render(Renderer& r, float size, const Matrices &m) const
{
m_representation.render(r, m_sizing == DistanceBasedSize ? size : m_representation.size());
m_representation.render(r, m_sizing == DistanceBasedSize ? size : m_representation.size(), m);
}
@ -117,7 +117,7 @@ void MarkerRepresentation::setLabel(const std::string& label)
/*! Render the marker symbol at the specified size. The size is
* the diameter of the marker in pixels.
*/
void MarkerRepresentation::render(Renderer& r, float size) const
void MarkerRepresentation::render(Renderer &r, float size, const Matrices &m) const
{
r.renderMarker(m_symbol, size, m_color);
r.renderMarker(m_symbol, size, m_color, m);
}

View File

@ -17,6 +17,7 @@
#include <celutil/debug.h>
class Renderer;
struct Matrices;
class MarkerRepresentation
{
@ -61,7 +62,7 @@ public:
string label() const { return m_label; }
void setLabel(const std::string&);
void render(Renderer& r, float size) const;
void render(Renderer &r, float size, const Matrices &m) const;
private:
Symbol m_symbol;
@ -105,7 +106,7 @@ class Marker
MarkerRepresentation& representation() { return m_representation; }
void setRepresentation(const MarkerRepresentation& rep);
void render(Renderer& r, float size) const;
void render(Renderer &r, float size, const Matrices &m) const;
private:
Selection m_object;

View File

@ -7,7 +7,6 @@
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
#include <config.h>
#include "vecgl.h"
#include "render.h"
#include "astro.h"
@ -22,6 +21,7 @@
using namespace Eigen;
using namespace std;
using namespace celmath;
using namespace celestia;
const char* Nebula::getType() const
@ -82,10 +82,11 @@ bool Nebula::load(AssociativeArray* params, const fs::path& resPath)
}
void Nebula::render(const Vector3f& /*unused*/,
void Nebula::render(const Vector3f& offset,
const Quaternionf& /*unused*/,
float /*unused*/,
float pixelSize,
const Matrices& m,
const Renderer* renderer)
{
Geometry* g = nullptr;
@ -96,11 +97,13 @@ void Nebula::render(const Vector3f& /*unused*/,
glDisable(GL_BLEND);
glScalef(getRadius(), getRadius(), getRadius());
glRotate(getOrientation());
Matrix4f mv = vecgl::rotate(vecgl::scale(*m.modelview, getRadius()),
getOrientation());
GLSLUnlit_RenderContext rc(renderer, getRadius());
rc.setPointScale(2.0f * getRadius() / pixelSize);
rc.setProjectionMatrix(m.projection);
rc.setModelViewMatrix(&mv);
g->render(rc);
glUseProgram(0);

View File

@ -32,6 +32,7 @@ class Nebula : public DeepSkyObject
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* renderer) override;
uint64_t getRenderMask() const override;

View File

@ -67,6 +67,7 @@ void OpenCluster::render(const Vector3f& /*unused*/,
const Quaternionf& /*unused*/,
float /*unused*/,
float /*unused*/,
const Matrices& /*m*/,
const Renderer* /*unused*/)
{
// Nothing to do right now; open clusters are only visible as their

View File

@ -33,6 +33,7 @@ class OpenCluster : public DeepSkyObject
const Eigen::Quaternionf& viewerOrientation,
float brightness,
float pixelSize,
const Matrices& m,
const Renderer* r = nullptr) override;
uint64_t getRenderMask() const override;

View File

@ -40,12 +40,8 @@ Overlay::Overlay(Renderer& r) :
void Overlay::begin()
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrix(Ortho2D(0.0f, (float)windowWidth, 0.0f, (float)windowHeight));
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
mvp = Ortho2D(0.0f, (float)windowWidth, 0.0f, (float)windowHeight);
// ModelView is Identity
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -56,10 +52,6 @@ void Overlay::begin()
void Overlay::end()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
@ -88,6 +80,7 @@ void Overlay::beginText()
if (font != nullptr)
{
font->bind();
font->setMVPMatrix(mvp);
useTexture = true;
fontChanged = false;
}
@ -111,6 +104,7 @@ void Overlay::print(wchar_t c)
if (!useTexture || fontChanged)
{
font->bind();
font->setMVPMatrix(mvp);
useTexture = true;
fontChanged = false;
}
@ -141,6 +135,7 @@ void Overlay::print(char c)
if (!useTexture || fontChanged)
{
font->bind();
font->setMVPMatrix(mvp);
useTexture = true;
fontChanged = false;
}
@ -185,7 +180,7 @@ void Overlay::drawRectangle(const Rect& r)
useTexture = false;
}
renderer.drawRectangle(r);
renderer.drawRectangle(r, mvp);
}
void Overlay::setColor(float r, float g, float b, float a)

View File

@ -13,6 +13,7 @@
#include <iosfwd>
#include <string>
#include <vector>
#include <Eigen/Core>
class Color;
class Overlay;
@ -107,6 +108,7 @@ class Overlay : public std::ostream
};
CursorPosition global { 0.0f, 0.0f };
std::vector<CursorPosition> posStack;
Eigen::Matrix4f mvp;
};
#endif // _OVERLAY_H_

View File

@ -11,7 +11,9 @@ OverlayImage::OverlayImage(fs::path f, Renderer *r) :
filename(std::move(f)),
renderer(r)
{
texture = std::unique_ptr<Texture>(LoadTextureFromFile(fs::path("images") / filename));
texture = std::unique_ptr<Texture>(LoadTextureFromFile(fs::path("images") / filename,
Texture::EdgeClamp,
Texture::NoMipMaps));
}
void OverlayImage::setColor(const Color& c)
@ -61,5 +63,5 @@ void OverlayImage::render(float curr_time, int width, int height)
r.colors[i] = Color(colors[i], colors[i].alpha() * alpha);
}
r.nColors = 4;
renderer->drawRectangle(r);
renderer->drawRectangle(r, renderer->getOrthoProjectionMatrix());
}

View File

@ -22,6 +22,7 @@
using namespace Eigen;
using namespace celmath;
using namespace celestia;
unsigned int PlanetographicGrid::circleSubdivisions = 100;
@ -89,7 +90,8 @@ void
PlanetographicGrid::render(Renderer* renderer,
const Eigen::Vector3f& pos,
float discSizeInPixels,
double tdb) const
double tdb,
const Matrices& m) const
{
ShaderProperties shadprop;
shadprop.texUsage = ShaderProperties::VertexColors;
@ -111,7 +113,7 @@ PlanetographicGrid::render(Renderer* renderer,
Vector3f semiAxes = body.getSemiAxes();
Vector3d posd = pos.cast<double>();
Vector3d viewRayOrigin = q * -pos.cast<double>();
Vector3d viewRayOrigin = q * -posd;
// Calculate the view normal; this is used for placement of the long/lat
// label text.
@ -123,9 +125,8 @@ PlanetographicGrid::render(Renderer* renderer,
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
glPushMatrix();
glRotate(qf.conjugate());
glScale(scale * semiAxes);
Affine3f transform = Translation3f(pos) * qf.conjugate() * Scaling(scale * semiAxes);
Matrix4f mvp = (*m.projection) * (*m.modelview) * transform.matrix();
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
@ -162,11 +163,9 @@ PlanetographicGrid::render(Renderer* renderer,
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex,
Renderer::PlanetographicGridColor);
}
glPushMatrix();
glTranslatef(0.0f, (float) std::sin(phi), 0.0f);
glScalef(r, r, r);
prog->MVPMatrix = mvp * vecgl::translate(0.0f, sin(phi), 0.0f) * vecgl::scale(r);;
glDrawArrays(GL_LINE_LOOP, 0, circleSubdivisions);
glPopMatrix();
glLineWidth(1.0f);
if (showCoordinateLabels)
@ -179,7 +178,7 @@ PlanetographicGrid::render(Renderer* renderer,
else
ns = northDirection == NorthNormal ? 'N' : 'S';
string buf;
buf = fmt::sprintf("%d%c", (int) fabs((double) latitude), ns);
buf = fmt::sprintf("%d%c", (int) fabs(latitude), ns);
longLatLabel(buf, 0.0, latitude, viewRayOrigin, viewNormal, posd, q, semiAxes, offset, renderer);
longLatLabel(buf, 180.0, latitude, viewRayOrigin, viewNormal, posd, q, semiAxes, offset, renderer);
}
@ -193,10 +192,8 @@ PlanetographicGrid::render(Renderer* renderer,
Renderer::PlanetographicGridColor);
for (float longitude = 0.0f; longitude <= 180.0f; longitude += longitudeStep)
{
glPushMatrix();
glRotatef(longitude, 0.0f, 1.0f, 0.0f);
prog->MVPMatrix = mvp * vecgl::rotate(AngleAxisf(degToRad(longitude), Vector3f::UnitY()));
glDrawArrays(GL_LINE_LOOP, 0, circleSubdivisions);
glPopMatrix();
if (showCoordinateLabels)
{
@ -251,8 +248,6 @@ PlanetographicGrid::render(Renderer* renderer,
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glPopMatrix();
glUseProgram(0);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);

View File

@ -52,7 +52,8 @@ public:
void render(Renderer* renderer,
const Eigen::Vector3f& pos,
float discSizeInPixels,
double tdb) const;
double tdb,
const Matrices& m) const override;
float boundingSphereRadius() const;
void setIAULongLatConvention();

View File

@ -36,6 +36,7 @@ void PointStarVertexBuffer::startSprites()
if (prog == nullptr)
return;
prog->use();
prog->mat4Param("MVPMatrix") = renderer.getProjectionMatrix() * renderer.getModelViewMatrix();
prog->samplerParam("starTex") = 0;
unsigned int stride = sizeof(StarVertex);
@ -53,7 +54,9 @@ void PointStarVertexBuffer::startSprites()
1, GL_FLOAT, GL_FALSE,
stride, &vertices[0].size);
#ifndef GL_ES
glEnable(GL_POINT_SPRITE);
#endif
useSprites = true;
}
@ -67,6 +70,7 @@ void PointStarVertexBuffer::startPoints()
if (prog == nullptr)
return;
prog->use();
prog->MVPMatrix = renderer.getProjectionMatrix() * renderer.getModelViewMatrix();
unsigned int stride = sizeof(StarVertex);
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
@ -91,6 +95,7 @@ void PointStarVertexBuffer::render()
if (nStars != 0)
{
unsigned int stride = sizeof(StarVertex);
#ifndef GL_ES
if (useSprites)
{
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
@ -100,6 +105,7 @@ void PointStarVertexBuffer::render()
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glPointSize(1.0f);
}
#endif
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE,
stride, &vertices[0].position);
@ -130,7 +136,9 @@ void PointStarVertexBuffer::finish()
if (useSprites)
{
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
#ifndef GL_ES
glDisable(GL_POINT_SPRITE);
#endif
}
glUseProgram(0);
}

View File

@ -17,6 +17,7 @@
#include <Eigen/Core>
class Renderer;
struct Matrices;
/*! Reference marks give additional visual information about the
* position and orientation of a solar system body. Items such as
@ -40,7 +41,8 @@ class ReferenceMark
virtual void render(Renderer* renderer,
const Eigen::Vector3f& position,
float discSizeInPixels,
double tdb) const = 0;
double tdb,
const Matrices& m) const = 0;
/*! Return the radius of a bounding sphere (in kilometers) large enough
* to contain the reference mark geometry.

View File

@ -22,7 +22,11 @@ using namespace Eigen;
using namespace std;
#ifndef GL_ONLY_SHADOWS
#ifndef GL_ES
#define GL_ONLY_SHADOWS 1
#else
#define GL_ONLY_SHADOWS 0
#endif
#endif
static Material defaultMaterial;
@ -168,21 +172,24 @@ RenderContext::drawGroup(const Mesh::PrimitiveGroup& group)
if (group.prim == Mesh::SpriteList)
{
#ifndef GL_ES
glEnable(GL_POINT_SPRITE);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
glActiveTexture(GL_TEXTURE0);
}
glDrawElements(GLPrimitiveModes[(int) group.prim],
group.nIndices,
GL_UNSIGNED_INT,
group.indices);
#ifndef GL_ES
if (group.prim == Mesh::SpriteList)
{
glDisable(GL_POINT_SPRITE);
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
}
#endif
}
@ -216,6 +223,17 @@ RenderContext::setVertexArrays(const Mesh::VertexDescription& desc,
}
}
void
RenderContext::setProjectionMatrix(const Eigen::Matrix4f *m)
{
projectionMatrix = m;
}
void
RenderContext::setModelViewMatrix(const Eigen::Matrix4f *m)
{
modelViewMatrix = m;
}
void
setStandardVertexArrays(const Mesh::VertexDescription& desc,
@ -500,8 +518,13 @@ GLSL_RenderContext::makeCurrent(const Material& m)
// Tweak the texture--set clamp to border and a border color with
// a zero alpha.
float bc[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
#ifndef GL_ES
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bc);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
#else
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR_OES, bc);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_OES);
#endif
glActiveTexture(GL_TEXTURE0);
shaderProps.texUsage |= ShaderProperties::RingShadowTexture;
@ -543,6 +566,7 @@ GLSL_RenderContext::makeCurrent(const Material& m)
return;
prog->use();
prog->MVPMatrix = (*projectionMatrix) * (*modelViewMatrix);
for (unsigned int i = 0; i < nTextures; i++)
{
@ -747,6 +771,9 @@ GLSLUnlit_RenderContext::makeCurrent(const Material& m)
return;
prog->use();
prog->MVPMatrix = (*projectionMatrix) * (*modelViewMatrix);
if (usePointSize)
prog->ModelViewMatrix = *modelViewMatrix;
for (unsigned int i = 0; i < nTextures; i++)
{

View File

@ -52,6 +52,9 @@ class RenderContext
void setCameraOrientation(const Eigen::Quaternionf& q);
Eigen::Quaternionf getCameraOrientation() const;
void setModelViewMatrix(const Eigen::Matrix4f *m);
void setProjectionMatrix(const Eigen::Matrix4f *m);
private:
const cmod::Material* material{ nullptr };
bool locked{ false };
@ -65,6 +68,8 @@ class RenderContext
bool useNormals{ true };
bool useColors{ false };
bool useTexCoords{ true };
const Eigen::Matrix4f *modelViewMatrix;
const Eigen::Matrix4f *projectionMatrix;
};

View File

@ -249,7 +249,9 @@ Renderer::Renderer() :
screenDpi(96),
corrFac(1.12f),
faintestAutoMag45deg(8.0f), //def. 7.0f
#ifndef GL_ES
renderMode(GL_FILL),
#endif
labelMode(LocationLabels), //def. NoLabels
renderFlags(DefaultRenderFlags),
orbitMask(Body::Planet | Body::Moon | Body::Stellar),
@ -636,8 +638,6 @@ bool Renderer::init(
delete testTex;
#endif
glLoadIdentity();
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
@ -729,10 +729,22 @@ void Renderer::setFont(FontStyle fs, TextureFont* txf)
markSettingsChanged();
}
void Renderer::setRenderMode(int _renderMode)
void Renderer::setRenderMode(RenderMode _renderMode)
{
renderMode = _renderMode;
#ifndef GL_ES
switch(_renderMode)
{
case RenderMode::Fill:
renderMode = GL_FILL;
break;
case RenderMode::Line:
renderMode = GL_LINE;
break;
default:
return;
}
markSettingsChanged();
#endif
}
uint64_t Renderer::getRenderFlags() const
@ -996,7 +1008,9 @@ Renderer::enableSmoothLines() const
#else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
#ifndef GL_ES
glEnable(GL_LINE_SMOOTH);
#endif
glLineWidth(1.5f);
}
@ -1008,7 +1022,9 @@ Renderer::disableSmoothLines() const
// glDisable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
#ifndef GL_ES
glDisable(GL_LINE_SMOOTH);
#endif
glLineWidth(1.0f);
}
@ -1075,7 +1091,8 @@ void Renderer::renderOrbit(const OrbitPathListEntry& orbitPath,
const Quaterniond& cameraOrientation,
const Frustum& frustum,
float nearDist,
float farDist)
float farDist,
const Matrices& m)
{
ShaderProperties shadprop;
shadprop.texUsage = ShaderProperties::VertexColors;
@ -1258,9 +1275,6 @@ void Renderer::renderOrbit(const OrbitPathListEntry& orbitPath,
modelview = cameraOrientation * Translation3d(orbitPath.origin) * orientation.conjugate();
}
glPushMatrix();
glLoadIdentity();
bool highlight;
if (body != nullptr)
highlight = highlightObject.body() == body;
@ -1282,6 +1296,7 @@ void Renderer::renderOrbit(const OrbitPathListEntry& orbitPath,
}
prog->use();
prog->MVPMatrix = *m.projection; // Skip MV as it's Identity
if (orbit->isPeriodic())
{
double period = orbit->getPeriod();
@ -1334,7 +1349,6 @@ void Renderer::renderOrbit(const OrbitPathListEntry& orbitPath,
#endif
glUseProgram(0);
glPopMatrix();
}
@ -1438,7 +1452,8 @@ setupSecondaryLightSources(vector<SecondaryIlluminator>& secondaryIlluminators,
void Renderer::renderItem(const RenderListEntry& rle,
const Observer& observer,
float nearPlaneDistance,
float farPlaneDistance)
float farPlaneDistance,
const Matrices& m)
{
switch (rle.renderableType)
{
@ -1448,7 +1463,8 @@ void Renderer::renderItem(const RenderListEntry& rle,
rle.distance,
rle.appMag,
observer.getTime(),
nearPlaneDistance, farPlaneDistance);
nearPlaneDistance, farPlaneDistance,
m);
break;
case RenderListEntry::RenderableBody:
@ -1457,14 +1473,16 @@ void Renderer::renderItem(const RenderListEntry& rle,
rle.distance,
rle.appMag,
observer,
nearPlaneDistance, farPlaneDistance);
nearPlaneDistance, farPlaneDistance,
m);
break;
case RenderListEntry::RenderableCometTail:
renderCometTail(*rle.body,
rle.position,
observer,
rle.discSizeInPixels);
rle.discSizeInPixels,
m);
break;
case RenderListEntry::RenderableReferenceMark:
@ -1472,7 +1490,8 @@ void Renderer::renderItem(const RenderListEntry& rle,
rle.position,
rle.distance,
observer.getTime(),
nearPlaneDistance);
nearPlaneDistance,
m);
break;
default:
@ -1672,12 +1691,6 @@ void Renderer::draw(const Observer& observer,
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_FALSE);
glMatrixMode(GL_PROJECTION);
glLoadMatrix(m_projMatrix);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrix(m_modelMatrix);
// Render sky grids first--these will always be in the background
enableSmoothLines();
renderSkyGrids(observer);
@ -1706,15 +1719,16 @@ void Renderer::draw(const Observer& observer,
#endif
// Translate the camera before rendering the asterisms and boundaries
glPushMatrix();
// Set up the camera for star rendering; the units of this phase
// are light years.
Vector3f observerPosLY = observer.getPosition().offsetFromLy(Vector3f::Zero());
glTranslatef(-observerPosLY.x(), -observerPosLY.y(), -observerPosLY.z());
Vector3f observerPosLY = -observer.getPosition().offsetFromLy(Vector3f::Zero());
Matrix4f asterismMVP = getProjectionMatrix() *
getModelViewMatrix() *
vecgl::translate(observerPosLY);
float dist = observerPosLY.norm() * 1.6e4f;
renderAsterisms(universe, dist);
renderBoundaries(universe, dist);
renderAsterisms(universe, dist, asterismMVP);
renderBoundaries(universe, dist, asterismMVP);
// Render star and deep sky object labels
renderBackgroundAnnotations(FontNormal);
@ -1726,9 +1740,6 @@ void Renderer::draw(const Observer& observer,
renderBackgroundAnnotations(FontLarge);
}
// Pop observer translation
glPopMatrix();
if ((renderFlags & ShowMarkers) != 0)
{
markersToAnnotations(*universe.getMarkers(), observer, now);
@ -1757,29 +1768,25 @@ void Renderer::draw(const Observer& observer,
adjustEclipsedStarExposure(now);
#endif
#ifndef GL_ES
glPolygonMode(GL_FRONT_AND_BACK, (GLenum) renderMode);
#endif
int nIntervals = buildDepthPartitions();
renderSolarSystemObjects(observer, nIntervals, now);
renderForegroundAnnotations(FontNormal);
glMatrixMode(GL_PROJECTION);
glLoadMatrix(m_projMatrix);
glMatrixMode(GL_MODELVIEW);
if (!selectionVisible && (renderFlags & ShowMarkers))
{
renderSelectionPointer(observer, now, xfrustum, sel);
}
// Pop camera orientation matrix
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
#ifndef GL_ES
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}
@ -1788,7 +1795,8 @@ void renderPoint(const Renderer &renderer,
const Vector3f &position,
const Color &color,
float size,
bool useSprite)
bool useSprite,
const Matrices &m)
{
auto *prog = renderer.getShaderManager().getShader("star");
if (prog == nullptr)
@ -1796,18 +1804,23 @@ void renderPoint(const Renderer &renderer,
prog->use();
prog->samplerParam("starTex") = 0;
prog->mat4Param("MVPMatrix") = (*m.projection) * (*m.modelview);
#ifndef GL_ES
glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
#endif
glVertexAttrib3fv(CelestiaGLProgram::VertexCoordAttributeIndex, position.data());
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
glVertexAttrib1f(CelestiaGLProgram::PointSizeAttributeIndex, useSprite ? size : 1.0f);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDrawArrays(GL_POINTS, 0, 1);
#ifndef GL_ES
if (useSprite)
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisable(GL_POINT_SPRITE);
#endif
glUseProgram(0);
}
@ -1822,9 +1835,10 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
float appMag,
float _faintestMag,
float discSizeInPixels,
Color color,
const Color &color,
bool useHalos,
bool emissive)
bool emissive,
const Matrices &m)
{
const float maxSize = MaxScaledDiscStarSize;
float maxDiscSize = (starStyle == ScaledDiscStars) ? maxSize : 1.0f;
@ -1898,7 +1912,7 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
bool useSprites = starStyle != PointStars;
if (useSprites)
gaussianDiscTex->bind();
renderPoint(*this, position, {color, alpha}, pointSize, useSprites);
renderPoint(*this, position, {color, alpha}, pointSize, useSprites, m);
// If the object is brighter than magnitude 1, add a halo around it to
// make it appear more brilliant. This is a hack to compensate for the
@ -1909,7 +1923,7 @@ void Renderer::renderObjectAsPoint(const Vector3f& position,
if (useHalos && glareAlpha > 0.0f)
{
gaussianGlareTex->bind();
renderPoint(*this, position, {color, glareAlpha}, glareSize, true);
renderPoint(*this, position, {color, glareAlpha}, glareSize, true, m);
}
glDisable(GL_DEPTH_TEST);
@ -1939,7 +1953,8 @@ void Renderer::renderEllipsoidAtmosphere(const Atmosphere& atmosphere,
const Vector3f& sunDirection,
const LightingState& ls,
float pixSize,
bool lit)
bool lit,
const Matrices &m)
{
if (atmosphere.height == 0.0f)
return;
@ -2190,6 +2205,7 @@ void Renderer::renderEllipsoidAtmosphere(const Atmosphere& atmosphere,
4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SkyVertex),
static_cast<void*>(&skyVertices[0].color));
prog->use();
prog->MVPMatrix = (*m.projection) * (*m.modelview);
for (int i = 0; i < nRings; i++)
{
glDrawElements(GL_TRIANGLE_STRIP,
@ -2206,6 +2222,7 @@ void Renderer::renderEllipsoidAtmosphere(const Atmosphere& atmosphere,
static void renderSphereUnlit(const RenderInfo& ri,
const Frustum& frustum,
const Matrices &m,
const Renderer *r)
{
Texture* textures[MAX_SPHERE_MESH_TEXTURES];
@ -2236,6 +2253,7 @@ static void renderSphereUnlit(const RenderInfo& ri,
return;
prog->use();
prog->MVPMatrix = (*m.projection) * (*m.modelview);
prog->textureOffset = 0.0f;
prog->ambientColor = ri.color.toVector3();
prog->opacity = 1.0f;
@ -2252,6 +2270,7 @@ static void renderCloudsUnlit(const RenderInfo& ri,
const Frustum& frustum,
Texture *cloudTex,
float cloudTexOffset,
const Matrices &m,
const Renderer *r)
{
ShaderProperties shadprop;
@ -2263,6 +2282,7 @@ static void renderCloudsUnlit(const RenderInfo& ri,
if (prog == nullptr)
return;
prog->use();
prog->MVPMatrix = (*m.projection) * (*m.modelview);
prog->textureOffset = cloudTexOffset;
g_lodSphere->render(frustum, ri.pixWidth, &cloudTex, 1);
@ -2601,7 +2621,8 @@ void Renderer::renderObject(const Vector3f& pos,
float nearPlaneDistance,
float farPlaneDistance,
RenderProperties& obj,
const LightingState& ls)
const LightingState& ls,
const Matrices &m)
{
RenderInfo ri;
@ -2647,11 +2668,6 @@ void Renderer::renderObject(const Vector3f& pos,
if ((obj.surface->appearanceFlags & Surface::ApplyOverlay) != 0)
ri.overlayTex = obj.surface->overlayTexture.find(textureResolution);
// Apply the modelview transform for the object
glPushMatrix();
glTranslate(pos);
glRotate(obj.orientation.conjugate());
// Scaling will be nonuniform for nonspherical planets. As long as the
// deviation from spherical isn't too large, the nonuniform scale factor
// shouldn't mess up the lighting calculations enough to be noticeable
@ -2672,7 +2688,11 @@ void Renderer::renderObject(const Vector3f& pos,
scaleFactors = Vector3f::Constant(geometryScale);
ri.pointScale = 2.0f * geometryScale / pixelSize;
}
glScale(scaleFactors);
// Apply the modelview transform for the object
Affine3f transform = Translation3f(pos) * obj.orientation.conjugate() * Scaling(scaleFactors);
Matrix4f mv = (*m.modelview) * transform.matrix();
Matrices mvp = { m.projection, &mv };
Matrix3f planetRotation = obj.orientation.toRotationMatrix();
@ -2786,11 +2806,13 @@ void Renderer::renderObject(const Vector3f& pos,
scaleFactors,
textureResolution,
renderFlags,
obj.orientation, viewFrustum, this);
obj.orientation,
viewFrustum,
mvp, this);
}
else
{
renderSphereUnlit(ri, viewFrustum, this);
renderSphereUnlit(ri, viewFrustum, mvp, this);
}
}
else
@ -2810,7 +2832,7 @@ void Renderer::renderObject(const Vector3f& pos,
renderFlags,
obj.orientation,
astro::daysToSecs(now - astro::J2000),
this);
mvp, this);
}
else
{
@ -2821,7 +2843,7 @@ void Renderer::renderObject(const Vector3f& pos,
renderFlags,
obj.orientation,
astro::daysToSecs(now - astro::J2000),
this);
mvp, this);
}
for (unsigned int i = 0; i < 8;/*context->getMaxTextures();*/ i++)
@ -2845,7 +2867,7 @@ void Renderer::renderObject(const Vector3f& pos,
textureResolution,
(renderFlags & ShowRingShadows) != 0 && lit,
segmentSizeInPixels,
this);
mvp, this);
}
}
@ -2881,17 +2903,15 @@ void Renderer::renderObject(const Vector3f& pos,
radius * atmScale,
obj.orientation,
viewFrustum,
this);
mvp, this);
}
else
{
glPushMatrix();
glLoadIdentity();
Matrix4f mv = vecgl::rotate(getCameraOrientation());
Matrices mvp = { m.projection, &mv };
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glRotate(getCameraOrientation());
renderEllipsoidAtmosphere(*atmosphere,
pos,
obj.orientation,
@ -2899,18 +2919,16 @@ void Renderer::renderObject(const Vector3f& pos,
ri.sunDir_eye,
ls,
thicknessInPixels,
lit);
glPopMatrix();
lit, mvp);
}
}
// If there's a cloud layer, we'll render it now.
if (cloudTex != nullptr)
{
glPushMatrix();
float cloudScale = 1.0f + atmosphere->cloudHeight / radius;
glScalef(cloudScale, cloudScale, cloudScale);
Matrix4f cmv = vecgl::scale(mv, cloudScale);
Matrices mvp = { m.projection, &cmv };
// If we're beneath the cloud level, render the interior of
// the cloud sphere.
@ -2944,17 +2962,16 @@ void Renderer::renderObject(const Vector3f& pos,
renderFlags,
obj.orientation,
viewFrustum,
this);
mvp, this);
}
else
{
renderCloudsUnlit(ri, viewFrustum, cloudTex, cloudTexOffset, this);
renderCloudsUnlit(ri,viewFrustum, cloudTex, cloudTexOffset, mvp, this);
}
glDisable(GL_POLYGON_OFFSET_FILL);
glDepthMask(GL_TRUE);
glFrontFace(GL_CCW);
glPopMatrix();
}
}
@ -2975,11 +2992,10 @@ void Renderer::renderObject(const Vector3f& pos,
textureResolution,
(renderFlags & ShowRingShadows) != 0 && lit,
segmentSizeInPixels,
this);
mvp, this);
}
}
glPopMatrix();
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
@ -3139,7 +3155,8 @@ void Renderer::renderPlanet(Body& body,
float appMag,
const Observer& observer,
float nearPlaneDistance,
float farPlaneDistance)
float farPlaneDistance,
const Matrices &m)
{
double now = observer.getTime();
float altitude = distance - body.getRadius();
@ -3371,7 +3388,7 @@ void Renderer::renderPlanet(Body& body,
renderObject(pos, distance, now,
nearPlaneDistance, farPlaneDistance,
rp, lights);
rp, lights, m);
if (body.getLocations() != nullptr && (labelMode & LocationLabels) != 0)
{
@ -3409,7 +3426,7 @@ void Renderer::renderPlanet(Body& body,
faintestMag,
discSizeInPixels,
body.getSurface().color,
false, false);
false, false, m);
}
#ifdef USE_HDR
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@ -3423,7 +3440,8 @@ void Renderer::renderStar(const Star& star,
float appMag,
double now,
float nearPlaneDistance,
float farPlaneDistance)
float farPlaneDistance,
const Matrices &m)
{
if (!star.getVisibility())
return;
@ -3483,7 +3501,7 @@ void Renderer::renderStar(const Star& star,
renderObject(pos, distance, now,
nearPlaneDistance, farPlaneDistance,
rp, LightingState());
rp, LightingState(), m);
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
@ -3497,7 +3515,8 @@ void Renderer::renderStar(const Star& star,
faintestMag,
discSizeInPixels,
color,
true, true);
true, true,
m);
#ifdef USE_HDR
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
#endif
@ -3530,7 +3549,8 @@ static float cometDustTailLength(float distanceToSun,
void Renderer::renderCometTail(const Body& body,
const Vector3f& pos,
const Observer& observer,
float discSizeInPixels)
float discSizeInPixels,
const Matrices &m)
{
auto prog = shaderManager->getShader("comet");
if (prog == nullptr)
@ -3659,14 +3679,14 @@ void Renderer::renderCometTail(const Body& body,
}
}
glPushMatrix();
glTranslate(pos);
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
prog->use();
prog->mat4Param("MVPMatrix") = (*m.projection) * (*m.modelview) * vecgl::translate(pos);
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
auto brightness = prog->attribIndex("brightness");
@ -3716,8 +3736,6 @@ void Renderer::renderCometTail(const Body& body,
glDisableClientState(GL_VERTEX_ARRAY);
glEnable(GL_BLEND);
#endif
glPopMatrix();
}
@ -3726,7 +3744,8 @@ void Renderer::renderReferenceMark(const ReferenceMark& refMark,
const Vector3f& pos,
float distance,
double now,
float nearPlaneDistance)
float nearPlaneDistance,
const Matrices &m)
{
float altitude = distance - refMark.boundingSphereRadius();
float discSizeInPixels = refMark.boundingSphereRadius() /
@ -3735,13 +3754,7 @@ void Renderer::renderReferenceMark(const ReferenceMark& refMark,
if (discSizeInPixels <= 1)
return;
// Apply the modelview transform for the object
glPushMatrix();
glTranslate(pos);
refMark.render(this, pos, discSizeInPixels, now);
glPopMatrix();
refMark.render(this, pos, discSizeInPixels, now, m);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
@ -3750,7 +3763,7 @@ void Renderer::renderReferenceMark(const ReferenceMark& refMark,
}
void Renderer::renderAsterisms(const Universe& universe, float dist)
void Renderer::renderAsterisms(const Universe& universe, float dist, const Matrix4f& mvp)
{
auto *asterisms = universe.getAsterisms();
@ -3775,12 +3788,12 @@ void Renderer::renderAsterisms(const Universe& universe, float dist)
}
enableSmoothLines();
m_asterismRenderer->render(*this, Color(ConstellationColor, opacity));
m_asterismRenderer->render(*this, Color(ConstellationColor, opacity), mvp);
disableSmoothLines();
}
void Renderer::renderBoundaries(const Universe& universe, float dist)
void Renderer::renderBoundaries(const Universe& universe, float dist, const Matrix4f& mvp)
{
auto boundaries = universe.getBoundaries();
if ((renderFlags & ShowBoundaries) == 0 || boundaries == nullptr)
@ -3806,7 +3819,7 @@ void Renderer::renderBoundaries(const Universe& universe, float dist)
}
enableSmoothLines();
m_boundariesRenderer->render(*this, Color(BoundaryColor, opacity));
m_boundariesRenderer->render(*this, Color(BoundaryColor, opacity), mvp);
disableSmoothLines();
}
@ -4436,10 +4449,12 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
float faintestMagNight,
const Observer& observer)
{
#ifndef GL_ES
// Disable multisample rendering when drawing point stars
bool toggleAA = (starStyle == Renderer::PointStars && glIsEnabled(GL_MULTISAMPLE));
if (toggleAA)
glDisable(GL_MULTISAMPLE);
#endif
Vector3d obsPos = observer.getPosition().toLy();
@ -4531,8 +4546,10 @@ void Renderer::renderPointStars(const StarDatabase& starDB,
starRenderer.starVertexBuffer->finish();
starRenderer.glareVertexBuffer->finish();
#ifndef GL_ES
if (toggleAA)
glEnable(GL_MULTISAMPLE);
#endif
}
void Renderer::renderDeepSkyObjects(const Universe& universe,
@ -4765,7 +4782,9 @@ void Renderer::renderParticles(const vector<Particle>& particles)
return;
prog->use();
#ifndef GL_ES
glEnable(GL_POINT_SPRITE);
#endif
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE, sizeof(Particle), &particles[0].center);
@ -4778,36 +4797,40 @@ void Renderer::renderParticles(const vector<Particle>& particles)
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
glUseProgram(0);
#ifndef GL_ES
glDisable(GL_POINT_SPRITE);
#endif
}
void
Renderer::renderAnnotationMarker(const Annotation &a,
FontStyle fs,
float depth)
float depth,
const Matrices &m)
{
const MarkerRepresentation& markerRep = *a.markerRep;
float size = a.size > 0.0f ? a.size : markerRep.size();
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, a.color);
glPushMatrix();
glTranslatef((int)a.position.x(), (int)a.position.y(), depth);
Matrix4f mv = vecgl::translate(*m.modelview, (float)(int)a.position.x(), (float)(int)a.position.y(), depth);
Matrices mm = { m.projection, &mv };
if (markerRep.symbol() == MarkerRepresentation::Crosshair)
renderCrosshair(size, realTime, a.color);
renderCrosshair(size, realTime, a.color, mm);
else
markerRep.render(*this, size);
markerRep.render(*this, size, mm);
if (!markerRep.label().empty())
{
int labelOffset = (int)markerRep.size() / 2;
glTranslatef(labelOffset + PixelOffset,
-labelOffset - font[fs]->getHeight() + PixelOffset, 0.0f);
float x = labelOffset + PixelOffset;
float y = -labelOffset - font[fs]->getHeight() + PixelOffset;
font[fs]->bind();
font[fs]->render(markerRep.label(), 0.0f, 0.0f);
font[fs]->setMVPMatrix((*m.projection) * mv);
font[fs]->render(markerRep.label(), x, y);
font[fs]->flush();
}
glPopMatrix();
}
void
@ -4815,21 +4838,25 @@ Renderer::renderAnnotationLabel(const Annotation &a,
FontStyle fs,
int hOffset,
int vOffset,
float depth)
float depth,
const Matrices &m)
{
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, a.color);
glPushMatrix();
glTranslatef((int)a.position.x() + hOffset + PixelOffset,
(int)a.position.y() + vOffset + PixelOffset,
depth);
Matrix4f mv = vecgl::translate(*m.modelview,
(int)a.position.x() + hOffset + PixelOffset,
(int)a.position.y() + vOffset + PixelOffset,
depth);
font[fs]->bind();
font[fs]->setMVPMatrix((*m.projection) * mv);
font[fs]->render(a.labelText, 0.0f, 0.0f);
font[fs]->flush();
glPopMatrix();
}
// stars and constellations. DSOs
void Renderer::renderAnnotations(const vector<Annotation>& annotations, FontStyle fs)
void Renderer::renderAnnotations(const vector<Annotation>& annotations,
FontStyle fs)
{
if (font[fs] == nullptr)
return;
@ -4843,18 +4870,14 @@ void Renderer::renderAnnotations(const vector<Annotation>& annotations, FontStyl
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrix(m_orthoProjMatrix);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
Matrix4f mv = Matrix4f::Identity();
Matrices m = { &m_orthoProjMatrix, &mv };
for (int i = 0; i < (int) annotations.size(); i++)
{
if (annotations[i].markerRep != nullptr)
{
renderAnnotationMarker(annotations[i], fs, 0.0f);
renderAnnotationMarker(annotations[i], fs, 0.0f, m);
}
if (!annotations[i].labelText.empty())
@ -4893,14 +4916,10 @@ void Renderer::renderAnnotations(const vector<Annotation>& annotations, FontStyl
vOffset = 0;
break;
}
renderAnnotationLabel(annotations[i], fs, hOffset, vOffset, 0.0f);
renderAnnotationLabel(annotations[i], fs, hOffset, vOffset, 0.0f, m);
}
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
#ifdef USE_HDR
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
#endif
@ -4957,12 +4976,8 @@ Renderer::renderAnnotations(vector<Annotation>::iterator startIter,
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrix(m_orthoProjMatrix);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
Matrix4f mv = Matrix4f::Identity();
Matrices m = { &m_orthoProjMatrix, &mv };
// Precompute values that will be used to generate the normalized device z value;
// we're effectively just handling the projection instead of OpenGL. We use an orthographic
@ -4983,7 +4998,7 @@ Renderer::renderAnnotations(vector<Annotation>::iterator startIter,
if (iter->markerRep != nullptr)
{
renderAnnotationMarker(*iter, fs, ndc_z);
renderAnnotationMarker(*iter, fs, ndc_z, m);
}
if (!iter->labelText.empty())
@ -4991,14 +5006,10 @@ Renderer::renderAnnotations(vector<Annotation>::iterator startIter,
if (iter->markerRep != nullptr)
labelHOffset += (int) iter->markerRep->size() / 2 + 3;
renderAnnotationLabel(*iter, fs, labelHOffset, labelVOffset, ndc_z);
renderAnnotationLabel(*iter, fs, labelHOffset, labelVOffset, ndc_z, m);
}
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
font[fs]->unbind();
@ -5236,19 +5247,23 @@ void Renderer::removeScissor()
void Renderer::enableMSAA()
{
#ifndef GL_ES
if ((m_GLStateFlag & Multisaple) == 0)
{
glEnable(GL_MULTISAMPLE);
m_GLStateFlag |= Multisaple;
}
#endif
}
void Renderer::disableMSAA()
{
#ifndef GL_ES
if ((m_GLStateFlag & Multisaple) != 0)
{
glDisable(GL_MULTISAMPLE);
m_GLStateFlag &= ~Multisaple;
}
#endif
}
bool Renderer::isMSAAEnabled() const
@ -5263,13 +5278,15 @@ constexpr GLenum toGLFormat(Renderer::PixelFormat format)
bool Renderer::captureFrame(int x, int y, int w, int h, Renderer::PixelFormat format, unsigned char* buffer, bool back) const
{
#ifndef GL_ES
glReadBuffer(back ? GL_BACK : GL_FRONT);
#endif
glReadPixels(x, y, w, h, toGLFormat(format), GL_UNSIGNED_BYTE, (void*) buffer);
return glGetError() == GL_NO_ERROR;
}
void Renderer::drawRectangle(const Rect &r)
void Renderer::drawRectangle(const Rect &r, const Matrix4f &mvp)
{
ShaderProperties shadprop;
shadprop.lightModel = ShaderProperties::UnlitModel;
@ -5308,6 +5325,7 @@ void Renderer::drawRectangle(const Rect &r)
}
prog->use();
prog->MVPMatrix = mvp;
if (r.type != Rect::Type::BorderOnly)
{
@ -5372,6 +5390,7 @@ bool Renderer::getInfo(map<string, string>& info) const
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
info["MaxTextureSize"] = to_string(maxTextureSize);
#ifndef GL_ES
GLint maxTextureUnits = 1;
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextureUnits);
info["MaxTextureUnits"] = to_string(maxTextureUnits);
@ -5385,10 +5404,6 @@ bool Renderer::getInfo(map<string, string>& info) const
glGetFloatv(GL_SMOOTH_POINT_SIZE_GRANULARITY, &pointSizeGran);
info["PointSizeGran"] = fmt::sprintf("%.2f", pointSizeGran);
GLint maxCubeMapSize = 0;
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapSize);
info["MaxCubeMapSize"] = to_string(maxCubeMapSize);
GLint maxVaryings = 0;
glGetIntegerv(GL_MAX_VARYING_FLOATS, &maxVaryings);
info["MaxVaryingFloats"] = to_string(maxVaryings);
@ -5399,6 +5414,13 @@ bool Renderer::getInfo(map<string, string>& info) const
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
info["MaxAnisotropy"] = fmt::sprintf("%.2f", maxAnisotropy);
}
#endif
#if 0 // we don't use cubemaps yet
GLint maxCubeMapSize = 0;
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeMapSize);
info["MaxCubeMapSize"] = to_string(maxCubeMapSize);
#endif
s = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
if (s != nullptr)
@ -5919,9 +5941,8 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
// Set up a perspective projection using the current interval's near and
// far clip planes.
glMatrixMode(GL_PROJECTION);
glLoadMatrix(Perspective(fov, getAspectRatio(), nearPlaneDistance, farPlaneDistance));
glMatrixMode(GL_MODELVIEW);
Matrix4f proj = Perspective(fov, getAspectRatio(), nearPlaneDistance, farPlaneDistance);
Matrices m = { &proj, &m_modelMatrix };
Frustum intervalFrustum(degToRad(fov),
getAspectRatio(),
@ -5940,7 +5961,7 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
// Treat objects that are smaller than one pixel as transparent and
// render them in the second pass.
if (renderList[i].isOpaque && renderList[i].discSizeInPixels > 1.0f)
renderItem(renderList[i], observer, nearPlaneDistance, farPlaneDistance);
renderItem(renderList[i], observer, nearPlaneDistance, farPlaneDistance, m);
i--;
}
@ -5972,7 +5993,8 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
observer.getOrientation(),
intervalFrustum,
nearPlaneDistance,
farPlaneDistance);
farPlaneDistance,
m);
}
}
@ -5985,7 +6007,7 @@ Renderer::renderSolarSystemObjects(const Observer &observer,
while (i >= 0 && renderList[i].farZ < depthPartitions[interval].nearZ)
{
if (!renderList[i].isOpaque || renderList[i].discSizeInPixels <= 1.0f)
renderItem(renderList[i], observer, nearPlaneDistance, farPlaneDistance);
renderItem(renderList[i], observer, nearPlaneDistance, farPlaneDistance, m);
i--;
}

View File

@ -42,6 +42,12 @@ namespace celmath
class Frustum;
};
struct Matrices
{
Eigen::Matrix4f *projection;
Eigen::Matrix4f *modelview;
};
struct LightSource
{
Eigen::Vector3d position;
@ -69,6 +75,11 @@ enum class VOType
Count = 4
};
enum class RenderMode
{
Fill = 0,
Line = 1
};
class Renderer
{
@ -102,7 +113,7 @@ class Renderer
void setFaintestAM45deg(float);
float getFaintestAM45deg() const;
void setRenderMode(int);
void setRenderMode(RenderMode);
void autoMag(float& faintestMag);
void render(const Observer&,
const Universe&,
@ -212,7 +223,9 @@ class Renderer
enum class PixelFormat
{
RGB = GL_RGB,
#ifndef GL_ES
BGR_EXT = GL_BGR_EXT
#endif
};
uint64_t getRenderFlags() const;
@ -242,7 +255,7 @@ class Renderer
void enableMSAA();
void disableMSAA();
bool isMSAAEnabled() const;
void drawRectangle(const Rect& r);
void drawRectangle(const Rect& r, const Eigen::Matrix4f& mvp);
void setRenderRegion(int x, int y, int width, int height, bool withScissor = true);
const ColorTemperatureTable* getStarColorTable() const;
@ -254,7 +267,43 @@ class Renderer
bool captureFrame(int, int, int, int, PixelFormat format, unsigned char*, bool = false) const;
void renderMarker(MarkerRepresentation::Symbol symbol, float size, const Color& color);
void renderMarker(MarkerRepresentation::Symbol symbol,
float size,
const Color &color,
const Matrices &m);
const Eigen::Matrix4f& getModelViewMatrix() const
{
return m_modelMatrix;
}
const Eigen::Matrix4f& getProjectionMatrix() const
{
return m_projMatrix;
}
const Eigen::Matrix4f& getOrthoProjectionMatrix() const
{
return m_orthoProjMatrix;
}
const Eigen::Matrix4f& getCurrentModelViewMatrix() const
{
return *m_modelViewPtr;
}
void setCurrentModelViewMatrix(const Eigen::Matrix4f& m)
{
m_modelViewPtr = &m;
}
const Eigen::Matrix4f& getCurrentProjectionMatrix() const
{
return *m_projectionPtr;
}
void setCurrentProjectionMatrix(const Eigen::Matrix4f& m)
{
m_projectionPtr = &m;
}
#ifdef USE_HDR
bool getBloomEnabled();
@ -466,10 +515,10 @@ class Renderer
const celmath::Frustum& viewFrustum,
const Selection& sel);
void renderAsterisms(const Universe&, float);
void renderBoundaries(const Universe&, float);
void renderAsterisms(const Universe&, float, const Eigen::Matrix4f&);
void renderBoundaries(const Universe&, float, const Eigen::Matrix4f&);
void renderEclipticLine();
void renderCrosshair(float size, double tsec, const Color &color);
void renderCrosshair(float size, double tsec, const Color &color, const Matrices &m);
void buildNearSystemsLists(const Universe &universe,
const Observer &observer,
@ -509,41 +558,47 @@ class Renderer
float nearPlaneDistance,
float farPlaneDistance,
RenderProperties& obj,
const LightingState&);
const LightingState&,
const Matrices&);
void renderPlanet(Body& body,
const Eigen::Vector3f& pos,
float distance,
float appMag,
const Observer& observer,
float, float);
float, float,
const Matrices&);
void renderStar(const Star& star,
const Eigen::Vector3f& pos,
float distance,
float appMag,
double now,
float, float);
float, float,
const Matrices&);
void renderReferenceMark(const ReferenceMark& refMark,
const Eigen::Vector3f& pos,
float distance,
double now,
float nearPlaneDistance);
float nearPlaneDistance,
const Matrices&);
void renderCometTail(const Body& body,
const Eigen::Vector3f& pos,
const Observer& observer,
float discSizeInPixels);
float discSizeInPixels,
const Matrices&);
void renderObjectAsPoint(const Eigen::Vector3f& center,
float radius,
float appMag,
float _faintestMag,
float discSizeInPixels,
Color color,
const Color& color,
bool useHalos,
bool emissive);
bool emissive,
const Matrices&);
void renderEllipsoidAtmosphere(const Atmosphere& atmosphere,
const Eigen::Vector3f& center,
@ -552,7 +607,8 @@ class Renderer
const Eigen::Vector3f& sunDirection,
const LightingState& ls,
float fade,
bool lit);
bool lit,
const Matrices&);
void locationsToAnnotations(const Body& body,
const Eigen::Vector3d& bodyPosition,
@ -562,7 +618,8 @@ class Renderer
void renderItem(const RenderListEntry& rle,
const Observer& observer,
float nearPlaneDistance,
float farPlaneDistance);
float farPlaneDistance,
const Matrices&);
bool testEclipse(const Body& receiver,
const Body& caster,
@ -586,24 +643,27 @@ class Renderer
bool special = false);
void renderAnnotationMarker(const Annotation &a,
FontStyle fs,
float depth);
float depth,
const Matrices&);
void renderAnnotationLabel(const Annotation &a,
FontStyle fs,
int hOffset,
int vOffset,
float depth);
void renderAnnotations(const std::vector<Annotation>&, FontStyle fs);
float depth,
const Matrices&);
void renderAnnotations(const std::vector<Annotation>&,
FontStyle fs);
void renderBackgroundAnnotations(FontStyle fs);
void renderForegroundAnnotations(FontStyle fs);
std::vector<Annotation>::iterator renderSortedAnnotations(std::vector<Annotation>::iterator,
float nearDist,
float farDist,
FontStyle fs);
std::vector<Renderer::Annotation>::iterator renderAnnotations(std::vector<Annotation>::iterator startIter,
std::vector<Annotation>::iterator endIter,
float nearDist,
float farDist,
FontStyle fs);
std::vector<Annotation>::iterator renderAnnotations(std::vector<Annotation>::iterator startIter,
std::vector<Annotation>::iterator endIter,
float nearDist,
float farDist,
FontStyle fs);
void markersToAnnotations(const MarkerList &markers,
const Observer &observer,
@ -623,7 +683,8 @@ class Renderer
const Eigen::Quaterniond& cameraOrientation,
const celmath::Frustum& frustum,
float nearDist,
float farDist);
float farDist,
const Matrices&);
void renderSolarSystemObjects(const Observer &observer,
int nIntervals,
@ -723,6 +784,8 @@ class Renderer
Eigen::Matrix4f m_projMatrix;
Eigen::Matrix4f m_MVPMatrix;
Eigen::Matrix4f m_orthoProjMatrix;
const Eigen::Matrix4f *m_modelViewPtr { &m_modelMatrix };
const Eigen::Matrix4f *m_projectionPtr { &m_projMatrix };
bool useCompressedTextures{ false };
unsigned int textureResolution;

View File

@ -36,9 +36,14 @@ using namespace cmod;
using namespace Eigen;
using namespace std;
using namespace celmath;
using namespace celestia;
#ifndef GL_ONLY_SHADOWS
#ifndef GL_ES
#define GL_ONLY_SHADOWS 1
#else
#define GL_ONLY_SHADOWS 0
#endif
#endif
static
@ -51,12 +56,10 @@ void renderGeometryShadow_GLSL(Geometry* geometry,
const Quaternionf& planetOrientation,
double tsec,
const Renderer* renderer,
Eigen::Matrix4f *lightMatrix);
Matrix4f *lightMatrix);
static
Matrix4f directionalLightMatrix(const Vector3f& lightDirection);
static
Matrix4f shadowProjectionMatrix(float objectRadius);
// Render a planet sphere with GLSL shaders
void renderEllipsoid_GLSL(const RenderInfo& ri,
@ -68,6 +71,7 @@ void renderEllipsoid_GLSL(const RenderInfo& ri,
uint64_t renderFlags,
const Quaternionf& planetOrientation,
const Frustum& frustum,
const Matrices &m,
const Renderer* renderer)
{
float radius = semiAxes.maxCoeff();
@ -214,8 +218,13 @@ void renderEllipsoid_GLSL(const RenderInfo& ri,
// Tweak the texture--set clamp to border and a border color with
// a zero alpha.
float bc[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
#ifndef GL_ES
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bc);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
#else
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR_OES, bc);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER_OES);
#endif
glActiveTexture(GL_TEXTURE0);
shadprop.texUsage |= ShaderProperties::RingShadowTexture;
@ -238,6 +247,7 @@ void renderEllipsoid_GLSL(const RenderInfo& ri,
return;
prog->use();
prog->MVPMatrix = (*m.projection) * (*m.modelview);
#ifdef USE_HDR
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black, ri.nightLightScale);
@ -280,7 +290,7 @@ void renderEllipsoid_GLSL(const RenderInfo& ri,
}
}
if (shadprop.hasEclipseShadows() != 0)
if (shadprop.hasEclipseShadows())
prog->setEclipseShadowParameters(ls, semiAxes, planetOrientation);
unsigned int attributes = LODSphereMesh::Normals;
@ -309,6 +319,7 @@ void renderGeometry_GLSL(Geometry* geometry,
uint64_t renderFlags,
const Quaternionf& planetOrientation,
double tsec,
const Matrices &m,
const Renderer* renderer)
{
auto *shadowBuffer = renderer->getShadowFBO(0);
@ -319,8 +330,6 @@ void renderGeometry_GLSL(Geometry* geometry,
std::array<int, 4> viewport;
renderer->getViewport(viewport);
// Save current GL state to avoid depth rendering bugs
glPushAttrib(GL_TRANSFORM_BIT);
float range[2];
glGetFloatv(GL_DEPTH_RANGE, range);
glDepthRange(0.0f, 1.0f);
@ -344,7 +353,7 @@ void renderGeometry_GLSL(Geometry* geometry,
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrix(Ortho2D(0.0f, (float)viewport[2], 0.0f, (float)viewport[3]));
glLoadMatrixf(Ortho2D(0.0f, (float)viewport[2], 0.0f, (float)viewport[3]).data());
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
@ -378,11 +387,12 @@ void renderGeometry_GLSL(Geometry* geometry,
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
#endif
glPopAttrib();
glDepthRange(range[0], range[1]);
}
GLSL_RenderContext rc(renderer, ls, geometryScale, planetOrientation);
rc.setModelViewMatrix(m.modelview);
rc.setProjectionMatrix(m.projection);
if ((renderFlags & Renderer::ShowAtmospheres) != 0)
{
@ -436,10 +446,13 @@ void renderGeometry_GLSL_Unlit(Geometry* geometry,
uint64_t /* renderFlags */,
const Quaternionf& /* planetOrientation */,
double tsec,
const Matrices &m,
const Renderer* renderer)
{
GLSLUnlit_RenderContext rc(renderer, geometryScale);
rc.setModelViewMatrix(m.modelview);
rc.setProjectionMatrix(m.projection);
rc.setPointScale(ri.pointScale);
// Handle material override; a texture specified in an ssc file will
@ -479,6 +492,7 @@ void renderClouds_GLSL(const RenderInfo& ri,
uint64_t renderFlags,
const Quaternionf& planetOrientation,
const Frustum& frustum,
const Matrices &m,
const Renderer* renderer)
{
float radius = semiAxes.maxCoeff();
@ -559,6 +573,7 @@ void renderClouds_GLSL(const RenderInfo& ri,
return;
prog->use();
prog->MVPMatrix = (*m.projection) * (*m.modelview);
prog->setLightParameters(ls, ri.color, ri.specularColor, Color::Black);
prog->eyePosition = ls.eyePos_obj;
@ -608,6 +623,7 @@ renderAtmosphere_GLSL(const RenderInfo& ri,
float radius,
const Quaternionf& /*planetOrientation*/,
const Frustum& frustum,
const Matrices &m,
const Renderer* renderer)
{
// Currently, we just skip rendering an atmosphere when there are no
@ -644,8 +660,8 @@ renderAtmosphere_GLSL(const RenderInfo& ri,
prog->setEclipseShadowParameters(ls, radius, planetOrientation);
#endif
glPushMatrix();
glScalef(atmScale, atmScale, atmScale);
prog->MVPMatrix = (*m.projection) * (*m.modelview) * vecgl::scale(atmScale);
glFrontFace(GL_CW);
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
@ -659,7 +675,6 @@ renderAtmosphere_GLSL(const RenderInfo& ri,
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glFrontFace(GL_CCW);
glPopMatrix();
glUseProgram(0);
}
@ -760,6 +775,7 @@ void renderRings_GLSL(RingSystem& rings,
unsigned int textureResolution,
bool renderShadow,
float segmentSizeInPixels,
const Matrices &m,
const Renderer* renderer)
{
float inner = rings.innerRadius / planetRadius;
@ -790,6 +806,7 @@ void renderRings_GLSL(RingSystem& rings,
return;
prog->use();
prog->MVPMatrix = (*m.projection) * (*m.modelview);
prog->eyePosition = ls.eyePos_obj;
prog->ambientColor = ri.ambientColor.toVector3();
@ -915,7 +932,10 @@ void renderGeometryShadow_GLSL(Geometry* geometry,
const Renderer* renderer,
Eigen::Matrix4f *lightMatrix)
{
glBindTexture(GL_TEXTURE_2D, 0);
auto *prog = renderer->getShaderManager().getShader("depth");
if (prog == nullptr)
return;
shadowFbo->bind();
glViewport(0, 0, shadowFbo->width(), shadowFbo->height());
@ -924,15 +944,11 @@ void renderGeometryShadow_GLSL(Geometry* geometry,
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
// Render backfaces only in order to reduce self-shadowing artifacts
glCullFace(GL_FRONT);
Shadow_RenderContext rc(renderer);
auto *prog = renderer->getShaderManager().getShader("depth");
if (prog == nullptr)
return;
prog->use();
// Enable poligon offset to decrease "shadow acne"

View File

@ -27,6 +27,7 @@ void renderEllipsoid_GLSL(const RenderInfo& ri,
uint64_t renderFlags,
const Eigen::Quaternionf& planetOrientation,
const celmath::Frustum& frustum,
const Matrices &m,
const Renderer* renderer);
void renderGeometry_GLSL(Geometry* geometry,
@ -38,6 +39,7 @@ void renderGeometry_GLSL(Geometry* geometry,
uint64_t renderFlags,
const Eigen::Quaternionf& planetOrientation,
double tsec,
const Matrices &m,
const Renderer* renderer);
void renderClouds_GLSL(const RenderInfo& ri,
@ -51,6 +53,7 @@ void renderClouds_GLSL(const RenderInfo& ri,
uint64_t renderFlags,
const Eigen::Quaternionf& planetOrientation,
const celmath::Frustum& frustum,
const Matrices &m,
const Renderer* renderer);
void renderAtmosphere_GLSL(const RenderInfo& ri,
@ -59,6 +62,7 @@ void renderAtmosphere_GLSL(const RenderInfo& ri,
float radius,
const Eigen::Quaternionf& planetOrientation,
const celmath::Frustum& frustum,
const Matrices &m,
const Renderer* renderer);
void renderRings_GLSL(RingSystem& rings,
@ -69,6 +73,7 @@ void renderRings_GLSL(RingSystem& rings,
unsigned int textureResolution,
bool renderShadow,
float segmentSizeInPixels,
const Matrices &m,
const Renderer* renderer);
void renderGeometry_GLSL_Unlit(Geometry* geometry,
@ -78,6 +83,7 @@ void renderGeometry_GLSL_Unlit(Geometry* geometry,
uint64_t renderFlags,
const Eigen::Quaternionf& planetOrientation,
double tsec,
const Matrices &m,
const Renderer* renderer);
#endif // _CELENGINE_RENDERGLSL_H_

View File

@ -31,7 +31,11 @@ using namespace std;
#define POINT_FADE 0
#ifndef GL_ONLY_SHADOWS
#ifndef GL_ES
#define GL_ONLY_SHADOWS 1
#else
#define GL_ONLY_SHADOWS 0
#endif
#endif
constexpr const int ShadowSampleKernelWidth = 2;
@ -54,7 +58,7 @@ enum ShaderVariableType
static const char* errorVertexShaderSource =
"attribute vec4 in_Position;\n"
"void main(void) {\n"
" gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n"
" gl_Position = MVPMatrix * in_Position;\n"
"}\n";
static const char* errorFragmentShaderSource =
"void main(void) {\n"
@ -62,7 +66,19 @@ static const char* errorFragmentShaderSource =
"}\n";
#ifndef GL_ES
static const char* CommonHeader = "#version 120\n";
#else
static const char* CommonHeader = "#version 100\nprecision highp float;\n";
#endif
static const char* VertexHeader = R"glsl(
uniform mat4 ModelViewMatrix;
uniform mat4 MVPMatrix;
invariant gl_Position;
)glsl";
static const char* FragmentHeader = "";
static const char* CommonAttribs = R"glsl(
attribute vec4 in_Position;
@ -924,13 +940,13 @@ CloudShadowTexCoord(unsigned int index)
static string
VarScatterInVS()
{
return string("gl_FrontSecondaryColor.rgb");
return "v_ScatterColor";
}
static string
VarScatterInFS()
{
return string("gl_SecondaryColor.rgb");
return "v_ScatterColor";
}
@ -1561,10 +1577,10 @@ TextureSamplerDeclarations(const ShaderProperties& props)
if (props.texUsage & ShaderProperties::ShadowMapTexture)
{
#ifndef GL_ONLY_SHADOWS
source += DeclareUniform("shadowMapTex0", Shader_Sampler2D);
#else
#if GL_ONLY_SHADOWS
source += DeclareUniform("shadowMapTex0", Shader_Sampler2DShadow);
#else
source += DeclareUniform("shadowMapTex0", Shader_Sampler2D);
#endif
}
@ -1621,7 +1637,7 @@ string
PointSizeCalculation()
{
string source;
source += "float ptSize = pointScale * in_PointSize / length(vec3(gl_ModelViewMatrix * in_Position));\n";
source += "float ptSize = pointScale * in_PointSize / length(vec3(ModelViewMatrix * in_Position));\n";
source += "pointFade = min(1.0, ptSize * ptSize);\n";
source += "gl_PointSize = ptSize;\n";
@ -1675,6 +1691,7 @@ GLVertexShader*
ShaderManager::buildVertexShader(const ShaderProperties& props)
{
string source(CommonHeader);
source += VertexHeader;
source += CommonAttribs;
source += DeclareLights(props);
@ -1762,6 +1779,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
{
//source += "varying vec3 scatterIn;\n";
source += "varying vec3 scatterEx;\n";
source += DeclareVarying(VarScatterInVS(), Shader_Vector3);
}
// Shadow parameters
@ -2008,9 +2026,9 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
source += PointSizeCalculation();
if (props.hasShadowMap())
source += "shadowTexCoord0 = ShadowMatrix0 * vec4(in_Position.xyz, 1);\n";
source += "shadowTexCoord0 = ShadowMatrix0 * vec4(in_Position.xyz, 1.0);\n";
source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "gl_Position = MVPMatrix * in_Position;\n";
source += "}\n";
DumpVSSource(source);
@ -2132,6 +2150,7 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
{
//source += "varying vec3 scatterIn;\n";
source += "varying vec3 scatterEx;\n";
source += DeclareVarying(VarScatterInFS(), Shader_Vector3);
}
if ((props.texUsage & ShaderProperties::NightTexture))
@ -2348,6 +2367,8 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
}
else if (props.usesShadows())
{
source += "float shadowMapCoeff = 1.0;\n";
// Sum the contributions from each light source
for (unsigned i = 0; i < props.nLights; i++)
{
@ -2360,6 +2381,13 @@ ShaderManager::buildFragmentShader(const ShaderProperties& props)
" * " +
FragLightProperty(i, "specColor") + ";\n";
}
if (props.hasShadowMap() && i == 0)
{
source += "shadowMapCoeff = calculateShadow();\n";
source += "diff.rgb *= shadowMapCoeff;\n";
if (props.lightModel == ShaderProperties::SpecularModel)
source += "spec.rgb *= shadowMapCoeff;\n";
}
}
}
@ -2465,6 +2493,7 @@ GLVertexShader*
ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
{
string source(CommonHeader);
source += VertexHeader;
source += CommonAttribs;
source += DeclareLights(props);
@ -2505,7 +2534,7 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
}
}
source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "gl_Position = MVPMatrix * in_Position;\n";
source += "}\n";
DumpVSSource(source);
@ -2606,6 +2635,7 @@ GLVertexShader*
ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
{
string source(CommonHeader);
source += VertexHeader;
source += CommonAttribs;
source += DeclareLights(props);
@ -2634,7 +2664,7 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
}
}
source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "gl_Position = MVPMatrix * in_Position;\n";
source += "}\n";
DumpVSSource(source);
@ -2759,6 +2789,7 @@ GLVertexShader*
ShaderManager::buildAtmosphereVertexShader(const ShaderProperties& props)
{
string source(CommonHeader);
source += VertexHeader;
source += CommonAttribs;
source += DeclareLights(props);
@ -2781,7 +2812,7 @@ ShaderManager::buildAtmosphereVertexShader(const ShaderProperties& props)
source += AtmosphericEffects(props);
source += "eyeDir_obj = eyeDir;\n";
source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "gl_Position = MVPMatrix * in_Position;\n";
source += "}\n";
DumpVSSource(source);
@ -2854,6 +2885,7 @@ GLVertexShader*
ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
{
string source(CommonHeader);
source += VertexHeader;
source += CommonAttribs;
source += "uniform float opacity;\n";
@ -2876,6 +2908,9 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
source += "varying float pointFade;\n";
}
source += DeclareVarying("v_Color", Shader_Vector4);
source += DeclareVarying("v_TexCoord0", Shader_Vector2);
// Begin main() function
source += "\nvoid main(void)\n{\n";
@ -2884,7 +2919,7 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
if ((props.texUsage & ShaderProperties::DiffuseTexture) &&
!(props.texUsage & ShaderProperties::PointSprite))
{
source += " gl_TexCoord[0].st = " + TexCoord2D(0) + ";\n";
source += " v_TexCoord0.st = " + TexCoord2D(0) + ";\n";
}
// Set the color.
@ -2894,13 +2929,13 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
else
colorSource = LightProperty(0, "diffuse");
source += " gl_FrontColor = vec4(" + colorSource + ", opacity);\n";
source += " v_Color = vec4(" + colorSource + ", opacity);\n";
// Optional point size
if ((props.texUsage & ShaderProperties::PointSprite) != 0)
source += PointSizeCalculation();
source += " gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += " gl_Position = MVPMatrix * in_Position;\n";
source += "}\n";
// End of main()
@ -2928,14 +2963,17 @@ ShaderManager::buildEmissiveFragmentShader(const ShaderProperties& props)
source += "varying float pointFade;\n";
}
source += DeclareVarying("v_Color", Shader_Vector4);
source += DeclareVarying("v_TexCoord0", Shader_Vector2);
// Begin main()
source += "\nvoid main(void)\n";
source += "{\n";
string colorSource = "gl_Color";
string colorSource = "v_Color";
if (props.texUsage & ShaderProperties::PointSprite)
{
source += " vec4 color = gl_Color;\n";
source += " vec4 color = v_Color;\n";
#if POINT_FADE
source += " color.a *= pointFade;\n";
#endif
@ -2947,7 +2985,7 @@ ShaderManager::buildEmissiveFragmentShader(const ShaderProperties& props)
if (props.texUsage & ShaderProperties::PointSprite)
source += " gl_FragColor = " + colorSource + " * texture2D(diffTex, gl_PointCoord);\n";
else
source += " gl_FragColor = " + colorSource + " * texture2D(diffTex, gl_TexCoord[0].st);\n";
source += " gl_FragColor = " + colorSource + " * texture2D(diffTex, v_TexCoord0.st);\n";
}
else
{
@ -2972,6 +3010,7 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
ostringstream source;
source << CommonHeader;
source << VertexHeader;
source << CommonAttribs;
source << "// PARTICLE SHADER\n";
@ -2990,6 +3029,8 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
source << DeclareVarying("pointFade", Shader_Float);
}
source << DeclareVarying("v_Color", Shader_Vector4);
// Shadow parameters
if (props.shadowCounts != 0)
{
@ -3020,13 +3061,13 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
#endif
// Set the color. Should *always* use vertex colors for color and opacity.
source << " gl_FrontColor = in_Color * brightness;\n";
source << " v_Color = in_Color * brightness;\n";
// Optional point size
if ((props.texUsage & ShaderProperties::PointSprite) != 0)
source << PointSizeCalculation();
source << " gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source << " gl_Position = MVPMatrix * in_Position;\n";
source << "}\n";
// End of main()
@ -3081,17 +3122,19 @@ ShaderManager::buildParticleFragmentShader(const ShaderProperties& props)
}
}
source << DeclareVarying("v_Color", Shader_Vector4);
// Begin main()
source << "\nvoid main(void)\n";
source << "{\n";
if (props.texUsage & ShaderProperties::DiffuseTexture)
{
source << " gl_FragColor = gl_Color * texture2D(diffTex, gl_PointCoord);\n";
source << " gl_FragColor = v_Color * texture2D(diffTex, gl_PointCoord);\n";
}
else
{
source << " gl_FragColor = gl_Color;\n";
source << " gl_FragColor = v_Color;\n";
}
source << "}\n";
@ -3227,10 +3270,13 @@ ShaderManager::buildProgram(const std::string& vs, const std::string& fs)
GLProgram* prog = nullptr;
GLShaderStatus status;
DumpVSSource(vs);
DumpFSSource(fs);
string _vs = fmt::sprintf("%s%s%s\n", CommonHeader, VertexHeader, vs);
string _fs = fmt::sprintf("%s%s%s\n", CommonHeader, FragmentHeader, fs);
status = GLShaderLoader::CreateProgram(vs, fs, &prog);
DumpVSSource(_vs);
DumpFSSource(_fs);
status = GLShaderLoader::CreateProgram(_vs, _fs, &prog);
if (status == ShaderStatus_OK)
{
glBindAttribLocation(prog->getID(),
@ -3376,6 +3422,9 @@ CelestiaGLProgram::attribIndex(const std::string& paramName) const
void
CelestiaGLProgram::initParameters()
{
ModelViewMatrix = mat4Param("ModelViewMatrix");
MVPMatrix = mat4Param("MVPMatrix");
for (unsigned int i = 0; i < props.nLights; i++)
{
lights[i].direction = vec3Param(LightProperty(i, "direction"));

View File

@ -264,6 +264,9 @@ class CelestiaGLProgram
Mat3ShaderParameter mat3Param(const std::string&);
Mat4ShaderParameter mat4Param(const std::string&);
Mat4ShaderParameter ModelViewMatrix;
Mat4ShaderParameter MVPMatrix;
int attribIndex(const std::string&) const;
private:

View File

@ -24,6 +24,7 @@
using namespace Eigen;
using namespace std;
using namespace celmath;
using namespace celestia;
// #define DEBUG_LABEL_PLACEMENT
@ -549,13 +550,12 @@ SkyGrid::render(Renderer& renderer,
prog->use();
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, m_lineColor);
// Render the parallels
glPushMatrix();
glRotate(xrot90 * m_orientation.conjugate() * xrot90.conjugate());
// Radius of sphere is arbitrary, with the constraint that it shouldn't
// intersect the near or far plane of the view frustum.
glScalef(1000.0f, 1000.0f, 1000.0f);
Matrix4f m = renderer.getModelViewMatrix() *
vecgl::rotate((xrot90 * m_orientation.conjugate() * xrot90.conjugate()).cast<float>()) *
vecgl::scale(1000.0f);
prog->MVPMatrix = renderer.getProjectionMatrix() * m;
double arcStep = (maxTheta - minTheta) / (double) ARC_SUBDIVISIONS;
double theta0 = minTheta;
@ -715,7 +715,6 @@ SkyGrid::render(Renderer& renderer,
glDrawArrays(GL_LINES, 0, 8);
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glPopMatrix();
glUseProgram(0);
delete[] buffer;
}

View File

@ -64,6 +64,7 @@ static void DumpTextureMipmapInfo(GLenum target)
static bool testMaxLevel()
{
#ifndef GL_ES
unsigned char texels[64];
GLuint textureID;
glGenTextures(1, &textureID);
@ -83,6 +84,9 @@ static bool testMaxLevel()
glDeleteTextures(1, &textureID);
return maxLev == 2;
#else
return false;
#endif
}
@ -96,6 +100,7 @@ static const TextureCaps& GetTextureCaps()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texCaps.maxTextureSize);
texCaps.preferredAnisotropy = 1;
#ifndef GL_ES
if (gl::EXT_texture_filter_anisotropic)
{
GLint maxAnisotropy = 1;
@ -105,6 +110,7 @@ static const TextureCaps& GetTextureCaps()
// the user to control this.
texCaps.preferredAnisotropy = min(8, maxAnisotropy);
}
#endif
}
return texCaps;
@ -114,22 +120,14 @@ static const TextureCaps& GetTextureCaps()
static int getInternalFormat(int format)
{
#ifdef GL_ES
switch (format)
{
case GL_RGBA:
case GL_BGRA:
return 4;
case GL_RGB:
case GL_BGR:
return 3;
case GL_LUMINANCE_ALPHA:
return 2;
case GL_ALPHA:
case GL_INTENSITY:
case GL_LUMINANCE:
return 1;
case GL_DSDT_NV:
return format;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
@ -137,6 +135,26 @@ static int getInternalFormat(int format)
default:
return 0;
}
#else
switch (format)
{
case GL_RGBA:
case GL_BGRA:
case GL_RGB:
case GL_BGR:
case GL_LUMINANCE_ALPHA:
case GL_ALPHA:
case GL_INTENSITY:
case GL_LUMINANCE:
case GL_DSDT_NV:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
return format;
default:
return 0;
}
#endif
}
@ -189,7 +207,11 @@ static GLenum GetGLTexAddressMode(Texture::AddressMode addressMode)
return GL_CLAMP_TO_EDGE;
case Texture::BorderClamp:
#ifndef GL_ES
return GL_CLAMP_TO_BORDER;
#else
return GL_CLAMP_TO_BORDER_OES;
#endif
}
return 0;
@ -200,7 +222,11 @@ static void SetBorderColor(Color borderColor, GLenum target)
{
float bc[4] = { borderColor.red(), borderColor.green(),
borderColor.blue(), borderColor.alpha() };
#ifndef GL_ES
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bc);
#else
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR_OES, bc);
#endif
}
@ -390,18 +416,22 @@ ImageTexture::ImageTexture(Image& img,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
#ifndef GL_ES
if (gl::EXT_texture_filter_anisotropic && texCaps.preferredAnisotropy > 1)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, texCaps.preferredAnisotropy);
}
#endif
#ifndef GL_ES
if (mipMapMode == AutoMipMaps)
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
#endif
int internalFormat = getInternalFormat(img.getFormat());
bool genMipmaps = mipmap && !precomputedMipMaps;
#ifdef NO_GLU
#if !defined(GL_ES) && defined(NO_GLU)
if (genMipmaps && !FramebufferObject::isSupported())
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
#endif
@ -540,10 +570,12 @@ TiledTexture::TiledTexture(Image& img,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
#ifndef GL_ES
if (gl::EXT_texture_filter_anisotropic && texCaps.preferredAnisotropy > 1)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, texCaps.preferredAnisotropy);
}
#endif
// Copy texels from the subtexture area to the pixel buffer. This
// is straightforward for normal textures, but an immense headache
@ -626,11 +658,13 @@ TiledTexture::TiledTexture(Image& img,
LoadMiplessTexture(*tile, GL_TEXTURE_2D);
glGenerateMipmap(GL_TEXTURE_2D);
}
#ifndef GL_ES
else
{
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
LoadMiplessTexture(*tile, GL_TEXTURE_2D);
}
#endif
#else
gluBuild2DMipmaps(GL_TEXTURE_2D,
internalFormat,
@ -750,7 +784,7 @@ CubeMap::CubeMap(Image* faces[]) :
int internalFormat = getInternalFormat(format);
bool genMipmaps = mipmap && !precomputedMipMaps;
#ifdef NO_GLU
#if !defined(GL_ES) && defined(NO_GLU)
if (genMipmaps && !FramebufferObject::isSupported())
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
#endif

View File

@ -19,68 +19,7 @@
#include <Eigen/Geometry>
/**** Eigen helpers for OpenGL ****/
inline void glMatrix(const Eigen::Matrix4f& m)
{
glMultMatrixf(m.data());
}
inline void glMatrix(const Eigen::Matrix4d& m)
{
glMultMatrixd(m.data());
}
inline void glLoadMatrix(const Eigen::Matrix4f& m)
{
glLoadMatrixf(m.data());
}
inline void glLoadMatrix(const Eigen::Matrix4d& m)
{
glLoadMatrixd(m.data());
}
inline void glScale(const Eigen::Vector3f& scale)
{
glScalef(scale.x(), scale.y(), scale.z());
}
inline void glTranslate(const Eigen::Vector3f& offset)
{
glTranslatef(offset.x(), offset.y(), offset.z());
}
inline void glTranslate(const Eigen::Vector3d& offset)
{
glTranslated(offset.x(), offset.y(), offset.z());
}
inline void glRotate(const Eigen::Quaternionf& q)
{
Eigen::Matrix4f m = Eigen::Matrix4f::Identity();
m.topLeftCorner(3, 3) = q.toRotationMatrix();
glMultMatrixf(m.data());
}
inline void glRotate(const Eigen::Quaterniond& q)
{
Eigen::Matrix4d m = Eigen::Matrix4d::Identity();
m.topLeftCorner(3, 3) = q.toRotationMatrix();
glMultMatrixd(m.data());
}
inline void glVertex(const Eigen::Vector3f& v)
{
glVertex3fv(v.data());
}
#if 0
inline void glVertex(const Eigen::Vector3d& v)
{
glVertex3dv(v.data());
}
#endif
/**** Helpers for OpenGL ****/
inline void glVertexAttrib(GLuint index, const Color &color)
{
@ -96,4 +35,124 @@ inline void glVertexAttrib(GLuint index, const Eigen::Vector4f &v)
glVertexAttrib4fv(index, v.data());
}
namespace celestia
{
namespace vecgl
{
template<typename T>
inline Eigen::Matrix<T,4,4>
scale(const Eigen::Matrix<T,4,4> &m, const Eigen::Matrix<T,4,1> &s)
{
return m * Eigen::Transform<T,3,Eigen::Affine>(Eigen::Scaling(s.x(), s.y(), s.z())).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
scale(const Eigen::Matrix<T,4,1> &s)
{
Eigen::Matrix<T,4,4> sm(Eigen::Matrix<T,4,4>::Zero());
sm.diagonal() = s;
return sm;
}
template<typename T>
inline Eigen::Matrix<T,4,4>
scale(const Eigen::Matrix<T,4,4> &m, const Eigen::Matrix<T,3,1> &s)
{
return m * Eigen::Transform<T,3,Eigen::Affine>(Eigen::Scaling(s.x(), s.y(), s.z())).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
scale(const Eigen::Matrix<T,3,1> &s)
{
return Eigen::Transform<T,3,Eigen::Affine>(Eigen::Scaling(s.x(), s.y(), s.z())).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
scale(const Eigen::Matrix<T,4,4> &m, T s)
{
return m * Eigen::Transform<T,3,Eigen::Affine>(Eigen::Scaling(s)).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
scale(T s)
{
return Eigen::Transform<T,3,Eigen::Affine>(Eigen::Scaling(s)).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
rotate(const Eigen::Matrix<T,4,4> &m, const Eigen::Quaternion<T> &q)
{
return m * Eigen::Transform<T,3,Eigen::Affine>(q).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
rotate(const Eigen::Quaternion<T> &q)
{
return Eigen::Transform<T,3,Eigen::Affine>(q).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
rotate(const Eigen::Matrix<T,4,4> &m, const Eigen::AngleAxis<T> &aa)
{
return m * Eigen::Transform<T,3,Eigen::Affine>(aa).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
rotate(const Eigen::AngleAxis<T> &aa)
{
return Eigen::Transform<T,3,Eigen::Affine>(aa).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
rotate(const Eigen::Matrix<T,4,4> &m, T angle, const Eigen::Matrix<T,3,1> &axis)
{
return rotate(m, Eigen::AngleAxis<T>(angle, axis));
}
template<typename T>
inline Eigen::Matrix<T,4,4>
rotate(T angle, const Eigen::Matrix<T,3,1> &axis)
{
return rotate(Eigen::AngleAxis<T>(angle, axis));
}
template<typename T>
inline Eigen::Matrix<T,4,4>
translate(const Eigen::Matrix<T,4,4> &m, const Eigen::Matrix<T,3,1> &t)
{
return m * Eigen::Transform<T,3,Eigen::Affine>(Eigen::Translation<T,3>(t)).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
translate(const Eigen::Matrix<T,3,1> &t)
{
return Eigen::Transform<T,3,Eigen::Affine>(Eigen::Translation<T,3>(t)).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
translate(const Eigen::Matrix<T,4,4> &m, T x, T y, T z)
{
return m * Eigen::Transform<T,3,Eigen::Affine>(Eigen::Translation<T,3>(Eigen::Matrix<T,3,1>(x,y,z))).matrix();
}
template<typename T>
inline Eigen::Matrix<T,4,4>
translate(T x, T y, T z)
{
return Eigen::Transform<T,3,Eigen::Affine>(Eigen::Translation<T,3>(Eigen::Matrix<T,3,1>(x,y,z))).matrix();
}
} // namespace vecgl
} // namespace celestia
#endif // _CELENGINE_VECGL_H_

View File

@ -32,7 +32,7 @@ VertexObject::~VertexObject()
{
delete m_attribParams;
if (m_vaoId != 0 && gl::ARB_vertex_array_object)
if (m_vaoId != 0 && isVAOSupported())
glDeleteVertexArrays(1, &m_vaoId);
if (m_vboId != 0)
@ -43,7 +43,7 @@ void VertexObject::bind() noexcept
{
if ((m_state & State::Initialize) != 0)
{
if (gl::ARB_vertex_array_object)
if (isVAOSupported())
{
glGenVertexArrays(1, &m_vaoId);
glBindVertexArray(m_vaoId);
@ -53,7 +53,7 @@ void VertexObject::bind() noexcept
}
else
{
if (gl::ARB_vertex_array_object)
if (isVAOSupported())
{
glBindVertexArray(m_vaoId);
if ((m_state & State::Update) != 0)
@ -75,7 +75,7 @@ void VertexObject::bindWritable() noexcept
void VertexObject::unbind() noexcept
{
if (gl::ARB_vertex_array_object)
if (isVAOSupported())
{
if ((m_state & (State::Initialize | State::Update)) != 0)
glBindBuffer(m_bufferType, 0);

View File

@ -54,6 +54,15 @@ class VertexObject
void setStreamType(GLenum streamType) noexcept { m_streamType = streamType; }
private:
inline bool isVAOSupported() const
{
#ifndef GL_ES
return celestia::gl::ARB_vertex_array_object;
#else
return celestia::gl::OES_vertex_array_object;
#endif
}
enum State : uint16_t
{
NormalState = 0x0000,

View File

@ -84,7 +84,10 @@ VisibleRegion::setOpacity(float opacity)
constexpr const unsigned maxSections = 360;
static void
renderTerminator(Renderer* renderer, const vector<Vector3f>& pos, const Color& color)
renderTerminator(Renderer* renderer,
const vector<Vector3f>& pos,
const Color& color,
const Matrix4f& mvp)
{
/*!
* Proper terminator calculation requires double precision floats in GLSL
@ -112,6 +115,7 @@ renderTerminator(Renderer* renderer, const vector<Vector3f>& pos, const Color& c
vo.setBufferData(pos.data(), 0, pos.size() * sizeof(Vector3f));
prog->use();
prog->MVPMatrix = mvp;
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
vo.draw(GL_LINE_LOOP, pos.size());
@ -123,9 +127,10 @@ renderTerminator(Renderer* renderer, const vector<Vector3f>& pos, const Color& c
void
VisibleRegion::render(Renderer* renderer,
const Vector3f& /* pos */,
const Vector3f& position,
float discSizeInPixels,
double tdb) const
double tdb,
const Matrices& m) const
{
// Don't render anything if the current time is not within the
// target object's time window.
@ -170,9 +175,6 @@ VisibleRegion::render(Renderer* renderer,
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
glPushMatrix();
glRotate(qf.conjugate());
double maxSemiAxis = m_body.getRadius();
// In order to avoid precision problems and extremely large values, scale
@ -211,9 +213,9 @@ VisibleRegion::render(Renderer* renderer,
pos.push_back(toCenter.cast<float>());
}
renderTerminator(renderer, pos, Color(m_color, opacity));
glPopMatrix();
Affine3f transform = Translation3f(position) * qf.conjugate();
Matrix4f mvp = (*m.projection) * (*m.modelview) * transform.matrix();
renderTerminator(renderer, pos, Color(m_color, opacity), mvp);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);

View File

@ -33,7 +33,8 @@ public:
void render(Renderer* renderer,
const Eigen::Vector3f& pos,
float discSizeInPixels,
double tdb) const;
double tdb,
const Matrices& m) const override;
float boundingSphereRadius() const;
Color color() const;

View File

@ -1178,7 +1178,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers)
case '\027': // Ctrl+W
wireframe = !wireframe;
renderer->setRenderMode(wireframe ? GL_LINE : GL_FILL);
renderer->setRenderMode(wireframe ? RenderMode::Line : RenderMode::Fill);
break;
case '\030': // Ctrl+X

View File

@ -50,7 +50,11 @@ static bool ParseCommandLine();
int main(int argc, char *argv[])
{
#ifndef GL_ES
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
#else
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#endif
QApplication app(argc, argv);
QTranslator qtTranslator;

View File

@ -262,5 +262,5 @@ void View::drawBorder(int gWidth, int gHeight, const Color &color, float linewid
r.setColor(color);
r.setType(Rect::Type::BorderOnly);
r.setLineWidth(linewidth);
renderer->drawRectangle(r);
renderer->drawRectangle(r, renderer->getOrthoProjectionMatrix());
}

View File

@ -6,8 +6,6 @@ set(CELX_SOURCES
celx.cpp
celx_frame.cpp
celx_frame.h
celx_gl.cpp
celx_gl.h
celx.h
celx_internal.h
celx_misc.cpp
@ -28,4 +26,8 @@ set(CELX_SOURCES
luascript.h
)
if(NOT ENABLE_GLES)
set(CELX_SOURCES ${CELX_SOURCES} celx_gl.cpp celx_gl.h)
endif()
add_library(celluascript OBJECT ${CELX_SOURCES})

View File

@ -1124,7 +1124,9 @@ static void loadLuaLibs(lua_State* state)
ExtendCelestiaMetaTable(state);
ExtendObjectMetaTable(state);
#ifndef GL_ES
LoadLuaGraphicsLibrary(state);
#endif
}

View File

@ -200,6 +200,12 @@ static int font_render(lua_State* l)
const char* s = celx.safeGetString(2, AllErrors, "First argument to font:render must be a string");
auto font = *celx.getThis<TextureFont*>();
#ifndef GL_ES
Eigen::Matrix4f p, m;
glGetFloatv(GL_PROJECTION_MATRIX, p.data());
glGetFloatv(GL_MODELVIEW_MATRIX, m.data());
font->setMVPMatrix(p * m);
#endif
return celx.push(font->render(s));
}

View File

@ -82,9 +82,11 @@ struct TextureFontPrivate
Glyph& getGlyph(wchar_t, wchar_t);
int toPos(wchar_t) const;
void optimize();
CelestiaGLProgram* getProgram();
void flush();
const Renderer *m_renderer;
CelestiaGLProgram *m_prog { nullptr };
FT_Face m_face; // font face
@ -104,6 +106,8 @@ struct TextureFontPrivate
int m_inserted { 0 };
Eigen::Matrix4f m_MVP;
bool m_shaderInUse { false };
vector<FontVertex> m_fontVertices;
};
@ -439,6 +443,14 @@ float TextureFontPrivate::render(wchar_t ch, float xoffset, float yoffset)
return g.ax;
}
CelestiaGLProgram* TextureFontPrivate::getProgram()
{
if (m_prog != nullptr)
return m_prog;
m_prog = m_renderer->getShaderManager().getShader("text");
return m_prog;
}
void TextureFontPrivate::flush()
{
if (m_fontVertices.size() < 4)
@ -580,7 +592,7 @@ int TextureFont::getTextureName() const
void TextureFont::bind()
{
auto *prog = impl->m_renderer->getShaderManager().getShader("text");
auto *prog = impl->getProgram();
if (prog == nullptr)
return;
@ -590,12 +602,26 @@ void TextureFont::bind()
glBindTexture(GL_TEXTURE_2D, impl->m_texName);
prog->use();
prog->samplerParam("atlasTex") = 0;
impl->m_shaderInUse = true;
prog->mat4Param("MVPMatrix") = impl->m_MVP;
}
}
void TextureFont::setMVPMatrix(const Eigen::Matrix4f& mvp)
{
impl->m_MVP = mvp;
auto *prog = impl->getProgram();
if (prog != nullptr && impl->m_shaderInUse)
{
flush();
prog->mat4Param("MVPMatrix") = mvp;
}
}
void TextureFont::unbind()
{
flush();
impl->m_shaderInUse = false;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glUseProgram(0);

View File

@ -11,6 +11,7 @@
#include <string>
#include <celcompat/filesystem.h>
#include <Eigen/Core>
class Renderer;
@ -26,6 +27,8 @@ class TextureFont
TextureFont& operator=(const TextureFont&) = delete;
TextureFont& operator=(TextureFont&&) = delete;
void setMVPMatrix(const Eigen::Matrix4f& m);
float render(wchar_t c, float xoffset = 0.0f, float yoffset = 0.0f) const;
float render(const std::string& str, float xoffset = 0.0f, float yoffset = 0.0f) const;