Replace fixed function GL code with GL ES compatible one

pull/738/head
Hleb Valoshka 2020-04-28 15:56:56 +03:00
parent e9282b9d6d
commit 1fb1f2de91
37 changed files with 528 additions and 467 deletions

View File

@ -1,5 +1,7 @@
#version 120 #version 120
attribute vec4 in_Position;
attribute vec3 in_Normal;
attribute float brightness; attribute float brightness;
uniform vec3 color; uniform vec3 color;
@ -10,6 +12,6 @@ varying float shade;
void main(void) void main(void)
{ {
shade = abs(dot(viewDir.xyz, gl_Normal.xyz) * brightness * fadeFactor); shade = abs(dot(viewDir.xyz, in_Normal.xyz) * brightness * fadeFactor);
gl_Position = ftransform(); gl_Position = gl_ModelViewProjectionMatrix * in_Position;
} }

View File

@ -1,5 +1,7 @@
#version 120 #version 120
attribute vec4 in_Position;
uniform float radius; uniform float radius;
uniform float width; uniform float width;
uniform float h; uniform float h;
@ -11,8 +13,8 @@ void main(void)
float s = sin(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.0f, -s, c, 0.0f, 0.0f, 0.0f, 1.0f);
float x = gl_Vertex.x * width + radius; float x = in_Position.x * width + radius;
float y = gl_Vertex.y * h; float y = in_Position.y * h;
vec3 p = rot * vec3(x, y, 0.0f); vec3 p = rot * vec3(x, y, 0.0f);
gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f); gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f);
} }

View File

@ -1,8 +1,9 @@
#version 120 #version 120
attribute vec4 in_Position;
uniform mat4 MVPMatrix; uniform mat4 MVPMatrix;
void main(void) void main(void)
{ {
gl_Position = MVPMatrix * gl_Vertex; gl_Position = MVPMatrix * in_Position;
} }

View File

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

View File

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

View File

@ -1,5 +1,7 @@
#version 120 #version 120
attribute vec3 in_Position;
attribute vec4 in_Color;
attribute float starSize; attribute float starSize;
attribute float eta; attribute float eta;
@ -39,10 +41,10 @@ float relStarDensity(void)
void main(void) void main(void)
{ {
vec3 p = m * gl_Vertex.xyz; vec3 p = m * in_Position.xyz;
float br = 2.0f * brightness; float br = 2.0f * brightness;
vec4 mod = vec4(gl_ModelViewMatrix * gl_Vertex); vec4 mod = gl_ModelViewMatrix * vec4(in_Position, 1.0f);
float s = 2000.0 / -mod.z * br * starSize; float s = 2000.0 / -mod.z * br * starSize;
float obsDistanceToStarRatio = length(p + offset) / clipDistance; float obsDistanceToStarRatio = length(p + offset) / clipDistance;
@ -50,6 +52,6 @@ void main(void)
// the overdense globular core is dissolved upon closing in. // the overdense globular core is dissolved upon closing in.
gl_PointSize = s * min(obsDistanceToStarRatio, 1.0f); gl_PointSize = s * min(obsDistanceToStarRatio, 1.0f);
color = vec4(gl_Color.rgb, min(1.0f, br * (1.0f - pixelWeight * relStarDensity()))); color = vec4(in_Color.rgb, min(1.0f, br * (1.0f - pixelWeight * relStarDensity())));
gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f); gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f);
} }

View File

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

View File

@ -1,10 +0,0 @@
#version 110
uniform sampler2D tex;
uniform vec4 color;
varying vec2 texCoord;
void main(void)
{
gl_FragColor = texture2D(tex, texCoord) * color;
}

View File

@ -1,9 +0,0 @@
#version 110
varying vec2 texCoord;
void main(void)
{
gl_Position = ftransform();
texCoord = gl_MultiTexCoord0.st;
}

View File

@ -1,10 +1,13 @@
#version 120 #version 120
attribute float pointSize;
attribute vec3 in_Position;
attribute vec4 in_Color;
attribute float in_PointSize;
varying vec4 color; varying vec4 color;
void main(void) void main(void)
{ {
gl_PointSize = pointSize; gl_PointSize = in_PointSize;
color = gl_Color; color = in_Color;
gl_Position = ftransform(); gl_Position = gl_ModelViewProjectionMatrix * vec4(in_Position, 1.0);
} }

View File

@ -1,11 +1,15 @@
#version 120 #version 120
attribute vec2 in_Position;
attribute vec2 in_TexCoord0;
attribute vec4 in_Color;
varying vec2 texCoord; varying vec2 texCoord;
varying vec4 color; varying vec4 color;
void main(void) void main(void)
{ {
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xy, 0, 1); gl_Position = gl_ModelViewProjectionMatrix * vec4(in_Position.xy, 0, 1);
texCoord = gl_MultiTexCoord0.st; texCoord = in_TexCoord0.st;
color = gl_Color; color = in_Color;
} }

View File

@ -1,5 +1,8 @@
#version 120 #version 120
attribute vec3 in_Position;
attribute vec2 in_TexCoord0;
uniform mat3 viewMat; uniform mat3 viewMat;
uniform float tidalSize; uniform float tidalSize;
varying vec2 texCoord; varying vec2 texCoord;
@ -7,8 +10,8 @@ varying vec2 texCoord;
void main(void) void main(void)
{ {
vec3 p = viewMat * gl_Vertex.xyz * tidalSize; vec3 p = viewMat * in_Position.xyz * tidalSize;
gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f); gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f);
texCoord = gl_MultiTexCoord0.st; texCoord = in_TexCoord0.st;
} }

View File

@ -50,7 +50,7 @@ void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColo
} }
prog->use(); prog->use();
glColor(defaultColor); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, defaultColor);
m_vo.draw(GL_LINES, m_vtxTotal); m_vo.draw(GL_LINES, m_vtxTotal);
assert(m_asterisms->size() == m_vtxCount.size()); assert(m_asterisms->size() == m_vtxCount.size());
@ -66,7 +66,8 @@ void AsterismRenderer::render(const Renderer &renderer, const Color &defaultColo
continue; continue;
} }
glColor(ast->getOverrideColor(), opacity); Color color = {ast->getOverrideColor(), opacity};
glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
m_vo.draw(GL_LINES, m_vtxCount[i], offset); m_vo.draw(GL_LINES, m_vtxCount[i], offset);
offset += m_vtxCount[i]; offset += m_vtxCount[i];
} }

View File

@ -283,7 +283,8 @@ ArrowReferenceMark::render(Renderer* renderer,
if (prog == nullptr) if (prog == nullptr)
return; return;
prog->use(); prog->use();
glColor(color, opacity); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex,
color.red(), color.green(), color.blue(), opacity);
auto &vo = renderer->getVertexObject(VOType::AxisArrow, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW); auto &vo = renderer->getVertexObject(VOType::AxisArrow, GL_ARRAY_BUFFER, 0, GL_STATIC_DRAW);
RenderArrow(vo); RenderArrow(vo);
@ -392,7 +393,7 @@ AxesReferenceMark::render(Renderer* renderer,
// x-axis // x-axis
glPushMatrix(); glPushMatrix();
glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glColor4f(1.0f, 0.0f, 0.0f, opacity); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 1.0f, 0.0f, 0.0f, opacity);
RenderArrow(vo); RenderArrow(vo);
glTranslatef(0.1f, 0.0f, 0.75f); glTranslatef(0.1f, 0.0f, 0.75f);
glScalef(labelScale, labelScale, labelScale); glScalef(labelScale, labelScale, labelScale);
@ -402,7 +403,7 @@ AxesReferenceMark::render(Renderer* renderer,
// y-axis // y-axis
glPushMatrix(); glPushMatrix();
glRotatef(180.0f, 0.0f, 1.0f, 0.0f); glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
glColor4f(0.0f, 1.0f, 0.0f, opacity); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 1.0f, 0.0f, opacity);
RenderArrow(vo); RenderArrow(vo);
glTranslatef(0.1f, 0.0f, 0.75f); glTranslatef(0.1f, 0.0f, 0.75f);
glScalef(labelScale, labelScale, labelScale); glScalef(labelScale, labelScale, labelScale);
@ -412,7 +413,7 @@ AxesReferenceMark::render(Renderer* renderer,
// z-axis // z-axis
glPushMatrix(); glPushMatrix();
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glColor4f(0.0f, 0.0f, 1.0f, opacity); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, 0.0f, 0.0f, 1.0f, opacity);
RenderArrow(vo); RenderArrow(vo);
glTranslatef(0.1f, 0.0f, 0.75f); glTranslatef(0.1f, 0.0f, 0.75f);
glScalef(labelScale, labelScale, labelScale); glScalef(labelScale, labelScale, labelScale);

View File

@ -51,7 +51,7 @@ void BoundariesRenderer::render(const Renderer &renderer, const Color &color)
} }
prog->use(); prog->use();
glColor(color); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
m_vo.draw(GL_LINES, m_vtxTotal); m_vo.draw(GL_LINES, m_vtxTotal);
glUseProgram(0); glUseProgram(0);

View File

@ -17,6 +17,7 @@
#include "glsupport.h" #include "glsupport.h"
#include "vecgl.h" #include "vecgl.h"
#include "console.h" #include "console.h"
#include "shadermanager.h"
#if NO_TTF #if NO_TTF
#include <celtxf/texturefont.h> #include <celtxf/texturefont.h>
#else #else
@ -236,13 +237,15 @@ int Console::getHeight() const
void Console::setColor(float r, float g, float b, float a) const void Console::setColor(float r, float g, float b, float a) const
{ {
glColor4f(r, g, b, a); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, r, g, b, a);
} }
void Console::setColor(const Color& c) const void Console::setColor(const Color& c) const
{ {
glColor4f(c.red(), c.green(), c.blue(), c.alpha()); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex,
c.red(), c.green(), c.blue(), c.alpha());
} }

View File

@ -13,6 +13,7 @@
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
#include <vector> #include <vector>
#include <celutil/color.h>
class Console; class Console;
class TextureFont; class TextureFont;

View File

@ -36,6 +36,7 @@
#include "glsupport.h" #include "glsupport.h"
#include "curveplot.h" #include "curveplot.h"
#include "shadermanager.h"
#include <vector> #include <vector>
#include <iostream> #include <iostream>
@ -180,14 +181,16 @@ public:
glBindBuffer(GL_ARRAY_BUFFER, vbobj); glBindBuffer(GL_ARRAY_BUFFER, vbobj);
} }
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableClientState(GL_COLOR_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
Vector4f* vertexBase = vbobj ? (Vector4f*) offsetof(Vertex, position) : &data[0].position; Vector4f* vertexBase = vbobj ? (Vector4f*) offsetof(Vertex, position) : &data[0].position;
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), vertexBase); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE, sizeof(Vertex), vertexBase);
Vector4f* colorBase = vbobj ? (Vector4f*) offsetof(Vertex, color) : &data[0].color; Vector4f* colorBase = vbobj ? (Vector4f*) offsetof(Vertex, color) : &data[0].color;
glColorPointer(4, GL_FLOAT, sizeof(Vertex), colorBase); glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
4, GL_FLOAT, GL_FALSE, sizeof(Vertex), colorBase);
stripLengths.clear(); stripLengths.clear();
currentStripLength = 0; currentStripLength = 0;
@ -200,8 +203,8 @@ public:
#if USE_VERTEX_BUFFER #if USE_VERTEX_BUFFER
if (vbobj) if (vbobj)
{ {
glDisableClientState(GL_COLOR_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }
#endif #endif

View File

@ -294,8 +294,12 @@ struct GalaxyVertex
static void draw(const GalaxyVertex *v, size_t count, void *indices) static void draw(const GalaxyVertex *v, size_t count, void *indices)
{ {
glVertexPointer(4, GL_FLOAT, sizeof(GalaxyVertex), &v->position); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
glTexCoordPointer(4, GL_SHORT, sizeof(GalaxyVertex), &v->texCoord); 4, GL_FLOAT, GL_FALSE,
sizeof(GalaxyVertex), &v->position);
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
4, GL_SHORT, GL_FALSE,
sizeof(GalaxyVertex), &v->texCoord);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices); glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices);
} }
@ -392,8 +396,8 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
const float btot = ((type > SBc) && (type < Irr)) ? 2.5f : 5.0f; const float btot = ((type > SBc) && (type < Irr)) ? 2.5f : 5.0f;
const float spriteScaleFactor = 1.0f / 1.55f; const float spriteScaleFactor = 1.0f / 1.55f;
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
vector<GalaxyVertex, aligned_allocator<GalaxyVertex>> vertices; vector<GalaxyVertex, aligned_allocator<GalaxyVertex>> vertices;
vertices.reserve(4096 / sizeof(GalaxyVertex)); vertices.reserve(4096 / sizeof(GalaxyVertex));
@ -464,8 +468,8 @@ void Galaxy::renderGalaxyPointSprites(const Vector3f& offset,
if (indices.size() > 0) if (indices.size() > 0)
draw(&vertices[0], indices.size(), indices.data()); draw(&vertices[0], indices.size(), indices.data());
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glUseProgram(0); glUseProgram(0);
glPopMatrix(); glPopMatrix();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);

View File

@ -233,7 +233,7 @@ void Renderer::renderMarker(MarkerRepresentation::Symbol symbol, float size, con
float s = size / 2.0f; float s = size / 2.0f;
prog->use(); prog->use();
glColor(color); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
glScalef(s, s, 0); glScalef(s, s, 0);
switch (symbol) switch (symbol)

View File

@ -311,7 +311,7 @@ void initGlobularData(VertexObject& vo, vector<GBlob>* points, GLint sizeLoc, GL
struct GlobularVtx struct GlobularVtx
{ {
Vector3f position; Vector3f position;
Vector3f color; Color color;
float starSize; float starSize;
float eta; float eta;
}; };
@ -319,10 +319,10 @@ void initGlobularData(VertexObject& vo, vector<GBlob>* points, GLint sizeLoc, GL
globularVtx.reserve(4 + points->size()); globularVtx.reserve(4 + points->size());
// Reuse the buffer for a tidal // Reuse the buffer for a tidal
globularVtx.push_back({{-1, -1, 0}, {0, 0, 0}, 0, 0}); globularVtx.push_back({{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0.0f, 0.0f});
globularVtx.push_back({{ 1, -1, 0}, {0, 0, 0}, 1, 0}); globularVtx.push_back({{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 1.0f, 0.0f});
globularVtx.push_back({{ 1, 1, 0}, {0, 0, 0}, 1, 1}); globularVtx.push_back({{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 1.0f, 1.0f});
globularVtx.push_back({{-1, 1, 0}, {0, 0, 0}, 0, 1}); globularVtx.push_back({{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0.0f, 1.0f});
// regarding used constants: // regarding used constants:
// pow2 = 128; // Associate "Red Giants" with the 128 biggest star-sprites // pow2 = 128; // Associate "Red Giants" with the 128 biggest star-sprites
@ -359,8 +359,7 @@ void initGlobularData(VertexObject& vo, vector<GBlob>* points, GLint sizeLoc, GL
* sizes (while pow2 = 128). * sizes (while pow2 = 128).
*/ */
Color col = (pow2 < 256) ? colorTable[255] : colorTable[b.colorIndex]; vtx.color = (pow2 < 256) ? colorTable[255] : colorTable[b.colorIndex];
vtx.color = col.toVector3();
globularVtx.push_back(vtx); globularVtx.push_back(vtx);
} }
@ -368,11 +367,9 @@ void initGlobularData(VertexObject& vo, vector<GBlob>* points, GLint sizeLoc, GL
vo.allocate(globularVtx.size() * sizeof(GlobularVtx), globularVtx.data()); vo.allocate(globularVtx.size() * sizeof(GlobularVtx), globularVtx.data());
vo.setVertices(3, GL_FLOAT, false, sizeof(GlobularVtx), 0); vo.setVertices(3, GL_FLOAT, false, sizeof(GlobularVtx), 0);
vo.setTextureCoords(2, GL_FLOAT, false, sizeof(GlobularVtx), offsetof(GlobularVtx, starSize)); //HACK!!! used only for tidal vo.setTextureCoords(2, GL_FLOAT, false, sizeof(GlobularVtx), offsetof(GlobularVtx, starSize)); //HACK!!! used only for tidal
vo.setColors(3, GL_FLOAT, false, sizeof(GlobularVtx), offsetof(GlobularVtx, color)); vo.setColors(4, GL_UNSIGNED_BYTE, true, sizeof(GlobularVtx), offsetof(GlobularVtx, color));
if (sizeLoc != -1) vo.setVertexAttribArray(sizeLoc, 1, GL_FLOAT, false, sizeof(GlobularVtx), offsetof(GlobularVtx, starSize));
vo.setVertexAttrib(sizeLoc, 1, GL_FLOAT, false, sizeof(GlobularVtx), offsetof(GlobularVtx, starSize)); vo.setVertexAttribArray(etaLoc, 1, GL_FLOAT, false, sizeof(GlobularVtx), offsetof(GlobularVtx, eta));
if (etaLoc != -1)
vo.setVertexAttrib(etaLoc, 1, GL_FLOAT, false, sizeof(GlobularVtx), offsetof(GlobularVtx, eta));
} }
@ -443,9 +440,10 @@ void Globular::renderGlobularPointSprites(
assert(globularTex != nullptr); assert(globularTex != nullptr);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SPRITE); glEnable(GL_POINT_SPRITE);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float tidalSize = 2 * tidalRadius; float tidalSize = 2 * tidalRadius;

View File

@ -288,19 +288,15 @@ void LODSphereMesh::render(unsigned int attributes,
for (i = 0; i < nTextures; i++) for (i = 0; i < nTextures; i++)
vertexSize += 2; vertexSize += 2;
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
if ((attributes & Normals) != 0) if ((attributes & Normals) != 0)
glEnableClientState(GL_NORMAL_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
for (i = 0; i < nTextures; i++) for (i = 0; i < nTextures; i++)
{ {
if (nTextures > 1) glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex + i);
glClientActiveTexture(GL_TEXTURE0 + i);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
} }
glDisableClientState(GL_COLOR_ARRAY);
if ((attributes & Tangents) != 0) if ((attributes & Tangents) != 0)
glEnableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex); glEnableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex);
@ -350,9 +346,9 @@ void LODSphereMesh::render(unsigned int attributes,
} }
} }
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
if ((attributes & Normals) != 0) if ((attributes & Normals) != 0)
glDisableClientState(GL_NORMAL_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
if ((attributes & Tangents) != 0) if ((attributes & Tangents) != 0)
glDisableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex); glDisableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex);
@ -360,18 +356,11 @@ void LODSphereMesh::render(unsigned int attributes,
for (i = 0; i < nTextures; i++) for (i = 0; i < nTextures; i++)
{ {
tex[i]->endUsage(); tex[i]->endUsage();
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex + i);
if (nTextures > 1)
{
glClientActiveTexture(GL_TEXTURE0 + i);
glActiveTexture(GL_TEXTURE0 + i);
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} }
if (nTextures > 1) if (nTextures > 1)
{ {
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
} }
@ -465,15 +454,21 @@ void LODSphereMesh::renderSection(int phi0, int theta0, int extent,
int texCoordOffset = ((ri.attributes & Tangents) != 0) ? 6 : 3; int texCoordOffset = ((ri.attributes & Tangents) != 0) ? 6 : 3;
float* vertexBase = nullptr; float* vertexBase = nullptr;
glVertexPointer(3, GL_FLOAT, stride, vertexBase + 0); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE,
stride, vertexBase + 0);
if ((ri.attributes & Normals) != 0) if ((ri.attributes & Normals) != 0)
glNormalPointer(GL_FLOAT, stride, vertexBase); {
glVertexAttribPointer(CelestiaGLProgram::NormalAttributeIndex,
3, GL_FLOAT, GL_FALSE,
stride, vertexBase);
}
for (int tc = 0; tc < nTexturesUsed; tc++) for (int tc = 0; tc < nTexturesUsed; tc++)
{ {
if (nTexturesUsed > 1) glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex + tc,
glClientActiveTexture(GL_TEXTURE0 + tc); 2, GL_FLOAT, GL_FALSE,
glTexCoordPointer(2, GL_FLOAT, stride, vertexBase + (tc * 2) + texCoordOffset); stride, vertexBase + (tc * 2) + texCoordOffset);
} }
if ((ri.attributes & Tangents) != 0) if ((ri.attributes & Tangents) != 0)

View File

@ -188,12 +188,13 @@ void Overlay::drawRectangle(const Rect& r)
void Overlay::setColor(float r, float g, float b, float a) void Overlay::setColor(float r, float g, float b, float a)
{ {
glColor4f(r, g, b, a); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex, r, g, b, a);
} }
void Overlay::setColor(const Color& c) void Overlay::setColor(const Color& c)
{ {
glColor4f(c.red(), c.green(), c.blue(), c.alpha()); glVertexAttrib4f(CelestiaGLProgram::ColorAttributeIndex,
c.red(), c.green(), c.blue(), c.alpha());
} }

View File

@ -127,9 +127,9 @@ PlanetographicGrid::render(Renderer* renderer,
glRotate(qf.conjugate()); glRotate(qf.conjugate());
glScale(scale * semiAxes); glScale(scale * semiAxes);
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
glVertexPointer(3, GL_FLOAT, 0, xzCircle); 3, GL_FLOAT, GL_FALSE, 0, xzCircle);
// Only show the coordinate labels if the body is sufficiently large on screen // Only show the coordinate labels if the body is sufficiently large on screen
bool showCoordinateLabels = false; bool showCoordinateLabels = false;
@ -153,12 +153,14 @@ PlanetographicGrid::render(Renderer* renderer,
if (latitude == 0.0f) if (latitude == 0.0f)
{ {
glColor(Renderer::PlanetEquatorColor); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex,
Renderer::PlanetEquatorColor);
glLineWidth(2.0f); glLineWidth(2.0f);
} }
else else
{ {
glColor(Renderer::PlanetographicGridColor); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex,
Renderer::PlanetographicGridColor);
} }
glPushMatrix(); glPushMatrix();
glTranslatef(0.0f, (float) std::sin(phi), 0.0f); glTranslatef(0.0f, (float) std::sin(phi), 0.0f);
@ -184,9 +186,11 @@ PlanetographicGrid::render(Renderer* renderer,
} }
} }
glVertexPointer(3, GL_FLOAT, 0, xyCircle); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE, 0, xyCircle);
prog->vec4Param("color") = Renderer::PlanetographicGridColor.toVector4(); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex,
Renderer::PlanetographicGridColor);
for (float longitude = 0.0f; longitude <= 180.0f; longitude += longitudeStep) for (float longitude = 0.0f; longitude <= 180.0f; longitude += longitudeStep)
{ {
glPushMatrix(); glPushMatrix();
@ -245,7 +249,7 @@ PlanetographicGrid::render(Renderer* renderer,
} }
} }
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glPopMatrix(); glPopMatrix();

View File

@ -39,19 +39,20 @@ void PointStarVertexBuffer::startSprites()
prog->samplerParam("starTex") = 0; prog->samplerParam("starTex") = 0;
unsigned int stride = sizeof(StarVertex); unsigned int stride = sizeof(StarVertex);
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexPointer(3, GL_FLOAT, stride, &vertices[0].position); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
glEnableClientState(GL_COLOR_ARRAY); 3, GL_FLOAT, GL_FALSE,
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &vertices[0].color); stride, &vertices[0].position);
glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
4, GL_UNSIGNED_BYTE, GL_TRUE,
stride, &vertices[0].color);
glEnableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex); glEnableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex, glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex,
1, GL_FLOAT, GL_FALSE, 1, GL_FLOAT, GL_FALSE,
stride, &vertices[0].size); stride, &vertices[0].size);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glEnable(GL_POINT_SPRITE); glEnable(GL_POINT_SPRITE);
useSprites = true; useSprites = true;
@ -68,19 +69,20 @@ void PointStarVertexBuffer::startPoints()
prog->use(); prog->use();
unsigned int stride = sizeof(StarVertex); unsigned int stride = sizeof(StarVertex);
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexPointer(3, GL_FLOAT, stride, &vertices[0].position); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
glEnableClientState(GL_COLOR_ARRAY); 3, GL_FLOAT, GL_FALSE,
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &vertices[0].color); stride, &vertices[0].position);
glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
4, GL_UNSIGNED_BYTE, GL_TRUE,
stride, &vertices[0].color);
// An option to control the size of the stars would be helpful. // An option to control the size of the stars would be helpful.
// Which size looks best depends a lot on the resolution and the // Which size looks best depends a lot on the resolution and the
// type of display device. // type of display device.
// glPointSize(2.0f); // glPointSize(2.0f);
// glEnable(GL_POINT_SMOOTH); // glEnable(GL_POINT_SMOOTH);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
useSprites = false; useSprites = false;
} }
@ -98,8 +100,12 @@ void PointStarVertexBuffer::render()
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glPointSize(1.0f); glPointSize(1.0f);
} }
glVertexPointer(3, GL_FLOAT, stride, &vertices[0].position); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
glColorPointer(4, GL_UNSIGNED_BYTE, stride, &vertices[0].color); 3, GL_FLOAT, GL_FALSE,
stride, &vertices[0].position);
glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
4, GL_UNSIGNED_BYTE, GL_TRUE,
stride, &vertices[0].color);
if (useSprites) if (useSprites)
{ {
@ -118,9 +124,8 @@ void PointStarVertexBuffer::render()
void PointStarVertexBuffer::finish() void PointStarVertexBuffer::finish()
{ {
render(); render();
glDisableClientState(GL_COLOR_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (useSprites) if (useSprites)
{ {

View File

@ -231,38 +231,43 @@ setStandardVertexArrays(const Mesh::VertexDescription& desc,
return; return;
// Set up the vertex arrays // Set up the vertex arrays
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexPointer(3, GL_FLOAT, desc.stride, glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
reinterpret_cast<const char*>(vertexData) + position.offset); 3, GL_FLOAT, GL_FALSE, desc.stride,
reinterpret_cast<const char*>(vertexData) + position.offset);
// Set up the normal array // Set up the normal array
switch (normal.format) switch (normal.format)
{ {
case Mesh::Float3: case Mesh::Float3:
glEnableClientState(GL_NORMAL_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
glNormalPointer(GLComponentTypes[(int) normal.format], glVertexAttribPointer(CelestiaGLProgram::NormalAttributeIndex,
desc.stride, 3, GLComponentTypes[(int) normal.format],
reinterpret_cast<const char*>(vertexData) + normal.offset); GL_FALSE, desc.stride,
reinterpret_cast<const char*>(vertexData) + normal.offset);
break; break;
default: default:
glDisableClientState(GL_NORMAL_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
break; break;
} }
GLint normalized = GL_TRUE;
// Set up the color array // Set up the color array
switch (color0.format) switch (color0.format)
{ {
case Mesh::Float3: case Mesh::Float3:
case Mesh::Float4: case Mesh::Float4:
normalized = GL_FALSE;
case Mesh::UByte4: case Mesh::UByte4:
glEnableClientState(GL_COLOR_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glColorPointer(GLComponentCounts[color0.format], glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
GLComponentTypes[color0.format], GLComponentCounts[color0.format],
desc.stride, GLComponentTypes[color0.format],
reinterpret_cast<const char*>(vertexData) + color0.offset); normalized, desc.stride,
reinterpret_cast<const char*>(vertexData) + color0.offset);
break; break;
default: default:
glDisableClientState(GL_COLOR_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
break; break;
} }
@ -273,14 +278,16 @@ setStandardVertexArrays(const Mesh::VertexDescription& desc,
case Mesh::Float2: case Mesh::Float2:
case Mesh::Float3: case Mesh::Float3:
case Mesh::Float4: case Mesh::Float4:
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glTexCoordPointer(GLComponentCounts[(int) texCoord0.format], glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
GLComponentTypes[(int) texCoord0.format], GLComponentCounts[(int) texCoord0.format],
desc.stride, GLComponentTypes[(int) texCoord0.format],
reinterpret_cast<const char*>(vertexData) + texCoord0.offset); GL_FALSE,
desc.stride,
reinterpret_cast<const char*>(vertexData) + texCoord0.offset);
break; break;
default: default:
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
break; break;
} }
} }
@ -360,10 +367,10 @@ GLSL_RenderContext::GLSL_RenderContext(const Renderer* renderer,
GLSL_RenderContext::~GLSL_RenderContext() GLSL_RenderContext::~GLSL_RenderContext()
{ {
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableClientState(GL_NORMAL_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
glDisableClientState(GL_COLOR_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex); glDisableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex); glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
} }
@ -687,10 +694,10 @@ GLSLUnlit_RenderContext::GLSLUnlit_RenderContext(const Renderer* renderer, float
GLSLUnlit_RenderContext::~GLSLUnlit_RenderContext() GLSLUnlit_RenderContext::~GLSLUnlit_RenderContext()
{ {
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableClientState(GL_NORMAL_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
glDisableClientState(GL_COLOR_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex); glDisableVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex); glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
} }

View File

@ -1783,18 +1783,7 @@ void renderPoint(const Renderer &renderer,
float size, float size,
bool useSprite) bool useSprite)
{ {
CelestiaGLProgram *prog; auto *prog = renderer.getShaderManager().getShader("star");
if (useSprite)
{
prog = renderer.getShaderManager().getShader("star");
}
else
{
ShaderProperties shadprop;
shadprop.texUsage = ShaderProperties::VertexColors;
shadprop.lightModel = ShaderProperties::UnlitModel;
prog = renderer.getShaderManager().getShader(shadprop);
}
if (prog == nullptr) if (prog == nullptr)
return; return;
@ -1802,29 +1791,15 @@ void renderPoint(const Renderer &renderer,
prog->samplerParam("starTex") = 0; prog->samplerParam("starTex") = 0;
glEnable(GL_POINT_SPRITE); glEnable(GL_POINT_SPRITE);
glEnableClientState(GL_VERTEX_ARRAY); glVertexAttrib3fv(CelestiaGLProgram::VertexCoordAttributeIndex, position.data());
glVertexPointer(3, GL_FLOAT, 0, &position); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
glEnableClientState(GL_COLOR_ARRAY); glVertexAttrib1f(CelestiaGLProgram::PointSizeAttributeIndex, useSprite ? size : 1.0f);
Vector4f mainColor = color.toVector4(); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glColorPointer(4, GL_FLOAT, 0, &mainColor);
glEnableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
if (useSprite)
{
glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex,
1, GL_FLOAT, GL_FALSE,
0, &size);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
}
glDrawArrays(GL_POINTS, 0, 1); glDrawArrays(GL_POINTS, 0, 1);
if (useSprite) if (useSprite)
{
glDisable(GL_VERTEX_PROGRAM_POINT_SIZE); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
}
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_POINT_SPRITE); glDisable(GL_POINT_SPRITE);
glUseProgram(0); glUseProgram(0);
} }
@ -2199,12 +2174,14 @@ void Renderer::renderEllipsoidAtmosphere(const Atmosphere& atmosphere,
skyIndices[index++] = baseVertex + nSlices; skyIndices[index++] = baseVertex + nSlices;
} }
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexPointer(3, GL_FLOAT, sizeof(SkyVertex), &skyVertices[0].x); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
glEnableClientState(GL_COLOR_ARRAY); 3, GL_FLOAT, GL_FALSE,
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(SkyVertex), sizeof(SkyVertex), &skyVertices[0].x);
static_cast<void*>(&skyVertices[0].color)); glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SkyVertex),
static_cast<void*>(&skyVertices[0].color));
prog->use(); prog->use();
for (int i = 0; i < nRings; i++) for (int i = 0; i < nRings; i++)
{ {
@ -2214,8 +2191,8 @@ void Renderer::renderEllipsoidAtmosphere(const Atmosphere& atmosphere,
&skyIndices[(nSlices + 1) * 2 * i]); &skyIndices[(nSlices + 1) * 2 * i]);
} }
glDisableClientState(GL_COLOR_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glUseProgram(0); glUseProgram(0);
} }
@ -3683,8 +3660,8 @@ void Renderer::renderCometTail(const Body& body,
glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendFunc(GL_SRC_ALPHA, GL_ONE);
prog->use(); prog->use();
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableClientState(GL_NORMAL_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
auto brightness = prog->attribIndex("brightness"); auto brightness = prog->attribIndex("brightness");
if (brightness != -1) if (brightness != -1)
glEnableVertexAttribArray(brightness); glEnableVertexAttribArray(brightness);
@ -3709,14 +3686,16 @@ void Renderer::renderCometTail(const Body& body,
for (i = 0; i < nTailPoints - 1; i++) for (i = 0; i < nTailPoints - 1; i++)
{ {
const auto p = &cometTailVertices[i * nTailSlices]; const auto p = &cometTailVertices[i * nTailSlices];
glVertexPointer(3, GL_FLOAT, stride, &p->point); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
glNormalPointer(GL_FLOAT, stride, &p->normal); 3, GL_FLOAT, GL_FALSE, stride, &p->point);
glVertexAttribPointer(CelestiaGLProgram::NormalAttributeIndex,
3, GL_FLOAT, GL_FALSE, stride, &p->normal);
if (brightness != -1) if (brightness != -1)
glVertexAttribPointer(brightness, 1, GL_FLOAT, GL_FALSE, stride, &p->brightness); glVertexAttribPointer(brightness, 1, GL_FLOAT, GL_FALSE, stride, &p->brightness);
glDrawElements(GL_TRIANGLE_STRIP, indices.size(), GL_UNSIGNED_SHORT, indices.data()); glDrawElements(GL_TRIANGLE_STRIP, indices.size(), GL_UNSIGNED_SHORT, indices.data());
} }
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableClientState(GL_NORMAL_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex);
if (brightness != -1) if (brightness != -1)
glDisableVertexAttribArray(brightness); glDisableVertexAttribArray(brightness);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
@ -4780,15 +4759,16 @@ void Renderer::renderParticles(const vector<Particle>& particles)
prog->use(); prog->use();
glEnable(GL_POINT_SPRITE); glEnable(GL_POINT_SPRITE);
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexPointer(3, GL_FLOAT, sizeof(Particle), &particles[0].center); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE, sizeof(Particle), &particles[0].center);
glEnableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex); glEnableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex, glVertexAttribPointer(CelestiaGLProgram::PointSizeAttributeIndex,
1, GL_FLOAT, GL_FALSE, 1, GL_FLOAT, GL_FALSE,
sizeof(Particle), &particles[0].size); sizeof(Particle), &particles[0].size);
glDrawArrays(GL_POINTS, 0, particles.size()); glDrawArrays(GL_POINTS, 0, particles.size());
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex); glDisableVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex);
glUseProgram(0); glUseProgram(0);
glDisable(GL_POINT_SPRITE); glDisable(GL_POINT_SPRITE);
@ -4802,7 +4782,7 @@ Renderer::renderAnnotationMarker(const Annotation &a,
const MarkerRepresentation& markerRep = *a.markerRep; const MarkerRepresentation& markerRep = *a.markerRep;
float size = a.size > 0.0f ? a.size : markerRep.size(); float size = a.size > 0.0f ? a.size : markerRep.size();
glColor(a.color); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, a.color);
glPushMatrix(); glPushMatrix();
glTranslatef(a.position.x(), a.position.y(), depth); glTranslatef(a.position.x(), a.position.y(), depth);
@ -4829,7 +4809,7 @@ Renderer::renderAnnotationLabel(const Annotation &a,
int vOffset, int vOffset,
float depth) float depth)
{ {
glColor(a.color); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, a.color);
glPushMatrix(); glPushMatrix();
glTranslatef(a.position.x() + hOffset + PixelOffset, glTranslatef(a.position.x() + hOffset + PixelOffset,
a.position.y() + vOffset + PixelOffset, a.position.y() + vOffset + PixelOffset,
@ -5297,22 +5277,25 @@ void Renderer::drawRectangle(const Rect &r)
constexpr array<short, 8> texels = {0, 1, 1, 1, 1, 0, 0, 0}; constexpr array<short, 8> texels = {0, 1, 1, 1, 1, 0, 0, 0};
array<float, 8> vertices = { r.x, r.y, r.x+r.w, r.y, r.x+r.w, r.y+r.h, r.x, r.y+r.h }; array<float, 8> vertices = { r.x, r.y, r.x+r.w, r.y, r.x+r.w, r.y+r.h, r.x, r.y+r.h };
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexPointer(2, GL_FLOAT, 0, vertices.data()); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
2, GL_FLOAT, GL_FALSE, 0, vertices.data());
if (r.tex != nullptr) if (r.tex != nullptr)
{ {
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glTexCoordPointer(2, GL_SHORT, 0, texels.data()); glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
2, GL_SHORT, GL_FALSE, 0, texels.data());
r.tex->bind(); r.tex->bind();
} }
if (r.nColors == 4) if (r.nColors == 4)
{ {
glEnableClientState(GL_COLOR_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, r.colors.data()); glVertexAttribPointer(CelestiaGLProgram::ColorAttributeIndex,
4, GL_UNSIGNED_BYTE, GL_TRUE, 0, r.colors.data());
} }
else if (r.nColors == 1) else if (r.nColors == 1)
{ {
glColor(r.colors[0]); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, r.colors[0]);
} }
prog->use(); prog->use();
@ -5331,9 +5314,9 @@ void Renderer::drawRectangle(const Rect &r)
} }
glUseProgram(0); glUseProgram(0);
glDisableClientState(GL_COLOR_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
} }
void Renderer::setRenderRegion(int x, int y, int width, int height, bool withScissor) void Renderer::setRenderRegion(int x, int y, int width, int height, bool withScissor)

View File

@ -716,21 +716,16 @@ static void renderRingSystem(GLuint *vboId,
{ {
glBindBuffer(GL_ARRAY_BUFFER, *vboId); glBindBuffer(GL_ARRAY_BUFFER, *vboId);
} }
// I haven't found a way to use glEnableVertexAttribArray instead of glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
// glEnableClientState with OpenGL2 glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 2, GL_SHORT, GL_FALSE,
glTexCoordPointer(2, GL_SHORT, sizeof(struct RingVertex), sizeof(struct RingVertex),
(GLvoid*) offsetof(struct RingVertex, tex)); (GLvoid*) offsetof(struct RingVertex, tex));
#if 0
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex, glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE, 3, GL_FLOAT, GL_FALSE,
sizeof(struct RingVertex), 0); sizeof(struct RingVertex), 0);
#else
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(struct RingVertex), 0);
#endif
// Celestia uses glCullFace(GL_BACK) by default so we just skip it here // Celestia uses glCullFace(GL_BACK) by default so we just skip it here
glDrawArrays(GL_TRIANGLE_STRIP, 0, (nSections+1)*2); glDrawArrays(GL_TRIANGLE_STRIP, 0, (nSections+1)*2);
@ -738,12 +733,8 @@ static void renderRingSystem(GLuint *vboId,
glDrawArrays(GL_TRIANGLE_STRIP, 0, (nSections+1)*2); glDrawArrays(GL_TRIANGLE_STRIP, 0, (nSections+1)*2);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
#if 0
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
#else
glDisableClientState(GL_VERTEX_ARRAY);
#endif
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
} }

View File

@ -52,8 +52,9 @@ enum ShaderVariableType
}; };
static const char* errorVertexShaderSource = static const char* errorVertexShaderSource =
"attribute vec4 in_Position;\n"
"void main(void) {\n" "void main(void) {\n"
" gl_Position = ftransform();\n" " gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n"
"}\n"; "}\n";
static const char* errorFragmentShaderSource = static const char* errorFragmentShaderSource =
"void main(void) {\n" "void main(void) {\n"
@ -63,6 +64,15 @@ static const char* errorFragmentShaderSource =
static const char* CommonHeader = "#version 120\n"; static const char* CommonHeader = "#version 120\n";
static const char* CommonAttribs = R"glsl(
attribute vec4 in_Position;
attribute vec3 in_Normal;
attribute vec4 in_TexCoord0;
attribute vec4 in_TexCoord1;
attribute vec4 in_TexCoord2;
attribute vec4 in_TexCoord3;
attribute vec4 in_Color;
)glsl";
bool bool
ShaderProperties::usesShadows() const ShaderProperties::usesShadows() const
@ -1041,7 +1051,7 @@ ShadowDepth(unsigned int i)
static string static string
TexCoord2D(unsigned int i) TexCoord2D(unsigned int i)
{ {
return fmt::sprintf("gl_MultiTexCoord%d.st", i); return fmt::sprintf("in_TexCoord%d.st", i);
} }
@ -1072,9 +1082,9 @@ TangentSpaceTransform(const string& dst, const string& src)
{ {
string source; string source;
source += dst + ".x = dot(tangent, " + src + ");\n"; source += dst + ".x = dot(in_Tangent, " + src + ");\n";
source += dst + ".y = dot(-bitangent, " + src + ");\n"; source += dst + ".y = dot(-bitangent, " + src + ");\n";
source += dst + ".z = dot(gl_Normal, " + src + ");\n"; source += dst + ".z = dot(in_Normal, " + src + ");\n";
return source; return source;
} }
@ -1137,18 +1147,18 @@ AddDirectionalLightContrib(unsigned int i, const ShaderProperties& props)
} }
else else
{ {
source += "NL = max(0.0, dot(gl_Normal, " + source += "NL = max(0.0, dot(in_Normal, " +
LightProperty(i, "direction") + "));\n"; LightProperty(i, "direction") + "));\n";
} }
if (props.lightModel == ShaderProperties::SpecularModel) if (props.lightModel == ShaderProperties::SpecularModel)
{ {
source += "H = normalize(" + LightProperty(i, "direction") + " + normalize(eyePosition - gl_Vertex.xyz));\n"; source += "H = normalize(" + LightProperty(i, "direction") + " + normalize(eyePosition - in_Position.xyz));\n";
source += "NH = max(0.0, dot(gl_Normal, H));\n"; source += "NH = max(0.0, dot(in_Normal, H));\n";
// The calculation below uses the infinite viewer approximation. It's slightly faster, // The calculation below uses the infinite viewer approximation. It's slightly faster,
// but results in less accurate rendering. // but results in less accurate rendering.
// source += "NH = max(0.0, dot(gl_Normal, " + LightProperty(i, "halfVector") + "));\n"; // source += "NH = max(0.0, dot(in_Normal, " + LightProperty(i, "halfVector") + "));\n";
} }
if (props.usesTangentSpaceLighting()) if (props.usesTangentSpaceLighting())
@ -1170,7 +1180,7 @@ AddDirectionalLightContrib(unsigned int i, const ShaderProperties& props)
source += "float sinAlpha = sqrt(1.0 - cosAlpha * cosAlpha);\n"; source += "float sinAlpha = sqrt(1.0 - cosAlpha * cosAlpha);\n";
source += "float sinBeta = sqrt(1.0 - cosBeta * cosBeta);\n"; source += "float sinBeta = sqrt(1.0 - cosBeta * cosBeta);\n";
source += "float tanBeta = sinBeta / cosBeta;\n"; source += "float tanBeta = sinBeta / cosBeta;\n";
source += "float cosAzimuth = dot(normalize(eye - gl_Normal * NV), normalize(light - gl_Normal * NL));\n"; source += "float cosAzimuth = dot(normalize(eye - in_Normal * NV), normalize(light - in_Normal * NL));\n";
// TODO: precalculate these constants; place them in uniform values // TODO: precalculate these constants; place them in uniform values
source += "float roughness2 = 0.7 * 0.7;\n"; source += "float roughness2 = 0.7 * 0.7;\n";
source += "float A = 1.0f - (0.5f * roughness2) / (roughness2 + 0.33);\n"; source += "float A = 1.0f - (0.5f * roughness2) / (roughness2 + 0.33);\n";
@ -1349,7 +1359,7 @@ AtmosphericEffects(const ShaderProperties& props)
source += " float qq = dot(eyePosition, eyePosition) - atmosphereRadius.y;\n"; source += " float qq = dot(eyePosition, eyePosition) - atmosphereRadius.y;\n";
source += " float d = sqrt(rq * rq - qq);\n"; source += " float d = sqrt(rq * rq - qq);\n";
source += " vec3 atmEnter = eyePosition + min(0.0, (-rq + d)) * eyeDir;\n"; source += " vec3 atmEnter = eyePosition + min(0.0, (-rq + d)) * eyeDir;\n";
source += " vec3 atmLeave = gl_Vertex.xyz;\n"; source += " vec3 atmLeave = in_Position.xyz;\n";
source += " vec3 atmSamplePoint = (atmEnter + atmLeave) * 0.5;\n"; source += " vec3 atmSamplePoint = (atmEnter + atmLeave) * 0.5;\n";
//source += " vec3 atmSamplePoint = atmEnter * 0.2 + atmLeave * 0.8;\n"; //source += " vec3 atmSamplePoint = atmEnter * 0.2 + atmLeave * 0.8;\n";
@ -1441,7 +1451,7 @@ AtmosphericEffects(const ShaderProperties& props, unsigned int nSamples)
source += " float qq = dot(eyePosition, eyePosition) - atmosphereRadius.y;\n"; source += " float qq = dot(eyePosition, eyePosition) - atmosphereRadius.y;\n";
source += " float d = sqrt(rq * rq - qq);\n"; source += " float d = sqrt(rq * rq - qq);\n";
source += " vec3 atmEnter = eyePosition + min(0.0, (-rq + d)) * eyeDir;\n"; source += " vec3 atmEnter = eyePosition + min(0.0, (-rq + d)) * eyeDir;\n";
source += " vec3 atmLeave = gl_Vertex.xyz;\n"; source += " vec3 atmLeave = in_Position.xyz;\n";
source += " vec3 step = (atmLeave - atmEnter) * (1.0 / 10.0);\n"; source += " vec3 step = (atmLeave - atmEnter) * (1.0 / 10.0);\n";
source += " float stepLength = length(step);\n"; source += " float stepLength = length(step);\n";
@ -1611,7 +1621,7 @@ string
PointSizeCalculation() PointSizeCalculation()
{ {
string source; string source;
source += "float ptSize = pointScale * pointSize / length(vec3(gl_ModelViewMatrix * gl_Vertex));\n"; source += "float ptSize = pointScale * in_PointSize / length(vec3(gl_ModelViewMatrix * in_Position));\n";
source += "pointFade = min(1.0, ptSize * ptSize);\n"; source += "pointFade = min(1.0, ptSize * ptSize);\n";
source += "gl_PointSize = ptSize;\n"; source += "gl_PointSize = ptSize;\n";
@ -1665,6 +1675,7 @@ GLVertexShader*
ShaderManager::buildVertexShader(const ShaderProperties& props) ShaderManager::buildVertexShader(const ShaderProperties& props)
{ {
string source(CommonHeader); string source(CommonHeader);
source += CommonAttribs;
source += DeclareLights(props); source += DeclareLights(props);
if (props.lightModel == ShaderProperties::SpecularModel) if (props.lightModel == ShaderProperties::SpecularModel)
@ -1683,13 +1694,13 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
if (props.texUsage & ShaderProperties::PointSprite) if (props.texUsage & ShaderProperties::PointSprite)
{ {
source += DeclareUniform("pointScale", Shader_Float); source += DeclareUniform("pointScale", Shader_Float);
source += DeclareAttribute("pointSize", Shader_Float); source += DeclareAttribute("in_PointSize", Shader_Float);
source += DeclareVarying("pointFade", Shader_Float); source += DeclareVarying("pointFade", Shader_Float);
} }
if (props.usesTangentSpaceLighting()) if (props.usesTangentSpaceLighting())
{ {
source += "attribute vec3 tangent;\n"; source += "attribute vec3 in_Tangent;\n";
for (unsigned int i = 0; i < props.nLights; i++) for (unsigned int i = 0; i < props.nLights; i++)
{ {
source += "varying vec3 " + LightDir_tan(i) + ";\n"; source += "varying vec3 " + LightDir_tan(i) + ";\n";
@ -1788,15 +1799,15 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
source += "\nvoid main(void)\n{\n"; source += "\nvoid main(void)\n{\n";
if (props.isViewDependent() || props.hasScattering()) if (props.isViewDependent() || props.hasScattering())
{ {
source += "vec3 eyeDir = normalize(eyePosition - gl_Vertex.xyz);\n"; source += "vec3 eyeDir = normalize(eyePosition - in_Position.xyz);\n";
if (!props.usesTangentSpaceLighting()) if (!props.usesTangentSpaceLighting())
{ {
source += "float NV = dot(gl_Normal, eyeDir);\n"; source += "float NV = dot(in_Normal, eyeDir);\n";
} }
} }
else if (props.lightModel == ShaderProperties::SpecularModel) else if (props.lightModel == ShaderProperties::SpecularModel)
{ {
source += "vec3 eyeDir = normalize(eyePosition - gl_Vertex.xyz);\n"; source += "vec3 eyeDir = normalize(eyePosition - in_Position.xyz);\n";
} }
source += "float NL;\n"; source += "float NL;\n";
@ -1813,7 +1824,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
if (props.usesTangentSpaceLighting()) if (props.usesTangentSpaceLighting())
{ {
source += "vec3 bitangent = cross(gl_Normal, tangent);\n"; source += "vec3 bitangent = cross(in_Normal, in_Tangent);\n";
if (props.isViewDependent() && if (props.isViewDependent() &&
props.lightModel != ShaderProperties::SpecularModel) props.lightModel != ShaderProperties::SpecularModel)
{ {
@ -1822,7 +1833,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
} }
else if (props.lightModel == ShaderProperties::PerPixelSpecularModel) else if (props.lightModel == ShaderProperties::PerPixelSpecularModel)
{ {
source += "normal = gl_Normal;\n"; source += "normal = in_Normal;\n";
} }
else if (props.usesShadows()) else if (props.usesShadows())
{ {
@ -1832,7 +1843,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
if (props.lightModel == ShaderProperties::UnlitModel) if (props.lightModel == ShaderProperties::UnlitModel)
{ {
if ((props.texUsage & ShaderProperties::VertexColors) != 0) if ((props.texUsage & ShaderProperties::VertexColors) != 0)
source += "diff = gl_Color;\n"; source += "diff = in_Color;\n";
else else
source += "diff = vec4(1.0);\n"; source += "diff = vec4(1.0);\n";
} }
@ -1846,7 +1857,7 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
if (props.hasShadowMap()) if (props.hasShadowMap())
{ {
source += "cosNormalLightDir = dot(gl_Normal, lights[0].direction);\n"; source += "cosNormalLightDir = dot(in_Normal, lights[0].direction);\n";
} }
for (unsigned int i = 0; i < props.nLights; i++) for (unsigned int i = 0; i < props.nLights; i++)
@ -1917,12 +1928,12 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
if (props.hasRingShadows()) if (props.hasRingShadows())
{ {
source += "vec3 ringShadowProj;\n"; source += "vec3 ringShadowProj;\n";
source += "float t = -(dot(gl_Vertex.xyz, ringPlane.xyz) + ringPlane.w);\n"; source += "float t = -(dot(in_Position.xyz, ringPlane.xyz) + ringPlane.w);\n";
for (unsigned int j = 0; j < props.nLights; j++) for (unsigned int j = 0; j < props.nLights; j++)
{ {
if (props.hasRingShadowForLight(j)) if (props.hasRingShadowForLight(j))
{ {
source += "ringShadowProj = gl_Vertex.xyz + " + source += "ringShadowProj = in_Position.xyz + " +
LightProperty(j, "direction") + LightProperty(j, "direction") +
" * max(0.0, t / dot(" + " * max(0.0, t / dot(" +
LightProperty(j, "direction") + ", ringPlane.xyz));\n"; LightProperty(j, "direction") + ", ringPlane.xyz));\n";
@ -1956,11 +1967,11 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
// fp32 texture serving as a lookup table. // fp32 texture serving as a lookup table.
#if 0 #if 0
// Compute the intersection of the sun direction and the cloud layer (currently assumed to be a sphere) // Compute the intersection of the sun direction and the cloud layer (currently assumed to be a sphere)
source += " float rq = dot(" + LightProperty(j, "direction") + ", gl_Vertex.xyz);\n"; source += " float rq = dot(" + LightProperty(j, "direction") + ", in_Position.xyz);\n";
source += " float qq = dot(gl_Vertex.xyz, gl_Vertex.xyz) - cloudHeight * cloudHeight;\n"; source += " float qq = dot(in_Position.xyz, in_Position.xyz) - cloudHeight * cloudHeight;\n";
source += " float d = sqrt(rq * rq - qq);\n"; source += " float d = sqrt(rq * rq - qq);\n";
source += " vec3 cloudSpherePos = (gl_Vertex.xyz + (-rq + d) * " + LightProperty(j, "direction") + ");\n"; source += " vec3 cloudSpherePos = (in_Position.xyz + (-rq + d) * " + LightProperty(j, "direction") + ");\n";
//source += " vec3 cloudSpherePos = gl_Vertex.xyz;\n"; //source += " vec3 cloudSpherePos = in_Position.xyz;\n";
// Find the texture coordinates at this point on the sphere by converting from rectangular to spherical; this is an // Find the texture coordinates at this point on the sphere by converting from rectangular to spherical; this is an
// expensive calculation to perform per vertex. // expensive calculation to perform per vertex.
@ -1990,16 +2001,16 @@ ShaderManager::buildVertexShader(const ShaderProperties& props)
if (props.hasEclipseShadows()) if (props.hasEclipseShadows())
{ {
source += "position_obj = gl_Vertex.xyz;\n"; source += "position_obj = in_Position.xyz;\n";
} }
if ((props.texUsage & ShaderProperties::PointSprite) != 0) if ((props.texUsage & ShaderProperties::PointSprite) != 0)
source += PointSizeCalculation(); source += PointSizeCalculation();
if (props.hasShadowMap()) if (props.hasShadowMap())
source += "shadowTexCoord0 = ShadowMatrix0 * vec4(gl_Vertex.xyz, 1);\n"; source += "shadowTexCoord0 = ShadowMatrix0 * vec4(in_Position.xyz, 1);\n";
source += "gl_Position = ftransform();\n"; source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "}\n"; source += "}\n";
DumpVSSource(source); DumpVSSource(source);
@ -2454,6 +2465,7 @@ GLVertexShader*
ShaderManager::buildRingsVertexShader(const ShaderProperties& props) ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
{ {
string source(CommonHeader); string source(CommonHeader);
source += CommonAttribs;
source += DeclareLights(props); source += DeclareLights(props);
source += "uniform vec3 eyePosition;\n"; source += "uniform vec3 eyePosition;\n";
@ -2472,7 +2484,7 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
source += "\nvoid main(void)\n{\n"; source += "\nvoid main(void)\n{\n";
// Get the normalized direction from the eye to the vertex // Get the normalized direction from the eye to the vertex
source += "vec3 eyeDir = normalize(eyePosition - gl_Vertex.xyz);\n"; source += "vec3 eyeDir = normalize(eyePosition - in_Position.xyz);\n";
for (unsigned int i = 0; i < props.nLights; i++) for (unsigned int i = 0; i < props.nLights; i++)
{ {
@ -2485,15 +2497,15 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
if (props.hasEclipseShadows() != 0) if (props.hasEclipseShadows() != 0)
{ {
source += "position_obj = gl_Vertex.xyz;\n"; source += "position_obj = in_Position.xyz;\n";
for (unsigned int i = 0; i < props.nLights; i++) for (unsigned int i = 0; i < props.nLights; i++)
{ {
source += ShadowDepth(i) + " = dot(gl_Vertex.xyz, " + source += ShadowDepth(i) + " = dot(in_Position.xyz, " +
LightProperty(i, "direction") + ");\n"; LightProperty(i, "direction") + ");\n";
} }
} }
source += "gl_Position = ftransform();\n"; source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "}\n"; source += "}\n";
DumpVSSource(source); DumpVSSource(source);
@ -2594,6 +2606,7 @@ GLVertexShader*
ShaderManager::buildRingsVertexShader(const ShaderProperties& props) ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
{ {
string source(CommonHeader); string source(CommonHeader);
source += CommonAttribs;
source += DeclareLights(props); source += DeclareLights(props);
@ -2611,17 +2624,17 @@ ShaderManager::buildRingsVertexShader(const ShaderProperties& props)
if (props.texUsage & ShaderProperties::DiffuseTexture) if (props.texUsage & ShaderProperties::DiffuseTexture)
source += "diffTexCoord = " + TexCoord2D(0) + ";\n"; source += "diffTexCoord = " + TexCoord2D(0) + ";\n";
source += "position_obj = gl_Vertex.xyz;\n"; source += "position_obj = in_Position.xyz;\n";
if (props.hasEclipseShadows()) if (props.hasEclipseShadows())
{ {
for (unsigned int i = 0; i < props.nLights; i++) for (unsigned int i = 0; i < props.nLights; i++)
{ {
source += ShadowDepth(i) + " = dot(gl_Vertex.xyz, " + source += ShadowDepth(i) + " = dot(in_Position.xyz, " +
LightProperty(i, "direction") + ");\n"; LightProperty(i, "direction") + ");\n";
} }
} }
source += "gl_Position = ftransform();\n"; source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "}\n"; source += "}\n";
DumpVSSource(source); DumpVSSource(source);
@ -2746,6 +2759,7 @@ GLVertexShader*
ShaderManager::buildAtmosphereVertexShader(const ShaderProperties& props) ShaderManager::buildAtmosphereVertexShader(const ShaderProperties& props)
{ {
string source(CommonHeader); string source(CommonHeader);
source += CommonAttribs;
source += DeclareLights(props); source += DeclareLights(props);
source += "uniform vec3 eyePosition;\n"; source += "uniform vec3 eyePosition;\n";
@ -2761,13 +2775,13 @@ ShaderManager::buildAtmosphereVertexShader(const ShaderProperties& props)
// Begin main() function // Begin main() function
source += "\nvoid main(void)\n{\n"; source += "\nvoid main(void)\n{\n";
source += "float NL;\n"; source += "float NL;\n";
source += "vec3 eyeDir = normalize(eyePosition - gl_Vertex.xyz);\n"; source += "vec3 eyeDir = normalize(eyePosition - in_Position.xyz);\n";
source += "float NV = dot(gl_Normal, eyeDir);\n"; source += "float NV = dot(in_Normal, eyeDir);\n";
source += AtmosphericEffects(props); source += AtmosphericEffects(props);
source += "eyeDir_obj = eyeDir;\n"; source += "eyeDir_obj = eyeDir;\n";
source += "gl_Position = ftransform();\n"; source += "gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "}\n"; source += "}\n";
DumpVSSource(source); DumpVSSource(source);
@ -2840,6 +2854,7 @@ GLVertexShader*
ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props) ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
{ {
string source(CommonHeader); string source(CommonHeader);
source += CommonAttribs;
source += "uniform float opacity;\n"; source += "uniform float opacity;\n";
@ -2857,7 +2872,7 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
if (props.texUsage & ShaderProperties::PointSprite) if (props.texUsage & ShaderProperties::PointSprite)
{ {
source += "uniform float pointScale;\n"; source += "uniform float pointScale;\n";
source += "attribute float pointSize;\n"; source += "attribute float in_PointSize;\n";
source += "varying float pointFade;\n"; source += "varying float pointFade;\n";
} }
@ -2875,7 +2890,7 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
// Set the color. // Set the color.
string colorSource; string colorSource;
if (props.texUsage & ShaderProperties::VertexColors) if (props.texUsage & ShaderProperties::VertexColors)
colorSource = "gl_Color.rgb"; colorSource = "in_Color.rgb";
else else
colorSource = LightProperty(0, "diffuse"); colorSource = LightProperty(0, "diffuse");
@ -2885,7 +2900,7 @@ ShaderManager::buildEmissiveVertexShader(const ShaderProperties& props)
if ((props.texUsage & ShaderProperties::PointSprite) != 0) if ((props.texUsage & ShaderProperties::PointSprite) != 0)
source += PointSizeCalculation(); source += PointSizeCalculation();
source += " gl_Position = ftransform();\n"; source += " gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source += "}\n"; source += "}\n";
// End of main() // End of main()
@ -2957,6 +2972,7 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
ostringstream source; ostringstream source;
source << CommonHeader; source << CommonHeader;
source << CommonAttribs;
source << "// PARTICLE SHADER\n"; source << "// PARTICLE SHADER\n";
source << "// shadow count: " << props.shadowCounts << endl; source << "// shadow count: " << props.shadowCounts << endl;
@ -2970,7 +2986,7 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
if (props.texUsage & ShaderProperties::PointSprite) if (props.texUsage & ShaderProperties::PointSprite)
{ {
source << "uniform float pointScale;\n"; source << "uniform float pointScale;\n";
source << "attribute float pointSize;\n"; source << "attribute float in_PointSize;\n";
source << DeclareVarying("pointFade", Shader_Float); source << DeclareVarying("pointFade", Shader_Float);
} }
@ -2989,7 +3005,7 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
float miePhaseAsymmetry = 1.55f * g - 0.55f * g * g * g; float miePhaseAsymmetry = 1.55f * g - 0.55f * g * g * g;
source << " float mieK = " << miePhaseAsymmetry << ";\n"; source << " float mieK = " << miePhaseAsymmetry << ";\n";
source << " vec3 eyeDir = normalize(eyePosition - gl_Vertex.xyz);\n"; source << " vec3 eyeDir = normalize(eyePosition - in_Position.xyz);\n";
source << " float brightness = 0.0;\n"; source << " float brightness = 0.0;\n";
for (unsigned int i = 0; i < min(1u, props.nLights); i++) for (unsigned int i = 0; i < min(1u, props.nLights); i++)
{ {
@ -3004,13 +3020,13 @@ ShaderManager::buildParticleVertexShader(const ShaderProperties& props)
#endif #endif
// Set the color. Should *always* use vertex colors for color and opacity. // Set the color. Should *always* use vertex colors for color and opacity.
source << " gl_FrontColor = gl_Color * brightness;\n"; source << " gl_FrontColor = in_Color * brightness;\n";
// Optional point size // Optional point size
if ((props.texUsage & ShaderProperties::PointSprite) != 0) if ((props.texUsage & ShaderProperties::PointSprite) != 0)
source << PointSizeCalculation(); source << PointSizeCalculation();
source << " gl_Position = ftransform();\n"; source << " gl_Position = gl_ModelViewProjectionMatrix * in_Position;\n";
source << "}\n"; source << "}\n";
// End of main() // End of main()
@ -3128,18 +3144,46 @@ ShaderManager::buildProgram(const ShaderProperties& props)
status = GLShaderLoader::CreateProgram(*vs, *fs, &prog); status = GLShaderLoader::CreateProgram(*vs, *fs, &prog);
if (status == ShaderStatus_OK) if (status == ShaderStatus_OK)
{ {
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::VertexCoordAttributeIndex,
"in_Position");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::NormalAttributeIndex,
"in_Normal");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord0AttributeIndex,
"in_TexCoord0");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord1AttributeIndex,
"in_TexCoord1");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord2AttributeIndex,
"in_TexCoord2");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord3AttributeIndex,
"in_TexCoord3");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::ColorAttributeIndex,
"in_Color");
if (props.texUsage & ShaderProperties::NormalTexture) if (props.texUsage & ShaderProperties::NormalTexture)
{ {
glBindAttribLocation(prog->getID(), glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TangentAttributeIndex, CelestiaGLProgram::TangentAttributeIndex,
"tangent"); "in_Tangent");
} }
if (props.texUsage & ShaderProperties::PointSprite) if (props.texUsage & ShaderProperties::PointSprite)
{ {
glBindAttribLocation(prog->getID(), glBindAttribLocation(prog->getID(),
CelestiaGLProgram::PointSizeAttributeIndex, CelestiaGLProgram::PointSizeAttributeIndex,
"pointSize"); "in_PointSize");
} }
status = prog->link(); status = prog->link();
@ -3189,12 +3233,41 @@ ShaderManager::buildProgram(const std::string& vs, const std::string& fs)
status = GLShaderLoader::CreateProgram(vs, fs, &prog); status = GLShaderLoader::CreateProgram(vs, fs, &prog);
if (status == ShaderStatus_OK) if (status == ShaderStatus_OK)
{ {
// Tangents always in attribute 6 (should be a constant glBindAttribLocation(prog->getID(),
// someplace) CelestiaGLProgram::VertexCoordAttributeIndex,
glBindAttribLocation(prog->getID(), 6, "tangent"); "in_Position");
// Point size is always in attribute 7 glBindAttribLocation(prog->getID(),
glBindAttribLocation(prog->getID(), 7, "pointSize"); CelestiaGLProgram::NormalAttributeIndex,
"in_Normal");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord0AttributeIndex,
"in_TexCoord0");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord1AttributeIndex,
"in_TexCoord1");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord2AttributeIndex,
"in_TexCoord2");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TextureCoord3AttributeIndex,
"in_TexCoord3");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::ColorAttributeIndex,
"in_Color");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::TangentAttributeIndex,
"in_Tangent");
glBindAttribLocation(prog->getID(),
CelestiaGLProgram::PointSizeAttributeIndex,
"in_PointSize");
status = prog->link(); status = prog->link();
} }

View File

@ -173,9 +173,15 @@ class CelestiaGLProgram
enum enum
{ {
VertexCoordAttributeIndex = 0, VertexCoordAttributeIndex = 0,
TangentAttributeIndex = 6, NormalAttributeIndex = 1,
PointSizeAttributeIndex = 7, TextureCoord0AttributeIndex = 2,
TextureCoord1AttributeIndex = 3,
TextureCoord2AttributeIndex = 4,
TextureCoord3AttributeIndex = 5,
TangentAttributeIndex = 6,
PointSizeAttributeIndex = 7,
ColorAttributeIndex = 8,
}; };
public: public:

View File

@ -547,7 +547,7 @@ SkyGrid::render(Renderer& renderer,
Quaternionf orientationf = q.cast<float>(); Quaternionf orientationf = q.cast<float>();
prog->use(); prog->use();
glColor(m_lineColor); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, m_lineColor);
// Render the parallels // Render the parallels
glPushMatrix(); glPushMatrix();
@ -561,8 +561,9 @@ SkyGrid::render(Renderer& renderer,
double theta0 = minTheta; double theta0 = minTheta;
auto buffer = new Vector3f[ARC_SUBDIVISIONS+1]; auto buffer = new Vector3f[ARC_SUBDIVISIONS+1];
glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glVertexPointer(3, GL_FLOAT, 0, buffer); glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
3, GL_FLOAT, GL_FALSE, 0, buffer);
for (int dec = startDec; dec <= endDec; dec += decIncrement) for (int dec = startDec; dec <= endDec; dec += decIncrement)
{ {
@ -713,7 +714,7 @@ SkyGrid::render(Renderer& renderer,
buffer[7] = {0.0f, -1.0f, polarCrossSize}; buffer[7] = {0.0f, -1.0f, polarCrossSize};
glDrawArrays(GL_LINES, 0, 8); glDrawArrays(GL_LINES, 0, 8);
glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glPopMatrix(); glPopMatrix();
glUseProgram(0); glUseProgram(0);
delete[] buffer; delete[] buffer;

View File

@ -149,5 +149,18 @@ inline void glLightColor(GLenum light, GLenum which, const Eigen::Vector4f& colo
glLightfv(light, which, color.data()); glLightfv(light, which, color.data());
} }
#endif // _CELENGINE_VECGL_H_ inline void glVertexAttrib(GLuint index, const Color &color)
{
#ifdef GL_ES
glVertexAttrib4fv(index, color.toVector4().data());
#else
glVertexAttrib4Nubv(index, color.data());
#endif
}
inline void glVertexAttrib(GLuint index, const Eigen::Vector4f &v)
{
glVertexAttrib4fv(index, v.data());
}
#endif // _CELENGINE_VECGL_H_

View File

@ -9,6 +9,7 @@
// as published by the Free Software Foundation; either version 2 // as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version. // of the License, or (at your option) any later version.
#include "shadermanager.h"
#include "vertexobject.h" #include "vertexobject.h"
using namespace celestia; using namespace celestia;
@ -111,7 +112,7 @@ bool VertexObject::allocate(GLenum bufferType, GLsizeiptr bufferSize, const void
bool VertexObject::setBufferData(const void* data, GLintptr offset, GLsizeiptr size) noexcept bool VertexObject::setBufferData(const void* data, GLintptr offset, GLsizeiptr size) noexcept
{ {
glBufferSubData(m_bufferType, offset, size == 0 ? m_bufferSize : size, data); glBufferSubData(m_bufferType, offset, size == 0 ? m_bufferSize : size, data);
return glGetError() != GL_NO_ERROR; return glGetError() == GL_NO_ERROR;
} }
void VertexObject::draw(GLenum primitive, GLsizei count, GLint first) noexcept void VertexObject::draw(GLenum primitive, GLsizei count, GLint first) noexcept
@ -126,62 +127,6 @@ void VertexObject::enableAttribArrays() noexcept
{ {
glBindBuffer(m_bufferType, m_vboId); glBindBuffer(m_bufferType, m_vboId);
if (m_attrIndexes & AttrType::Vertices)
{
const auto& p = m_params[0];
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(p.count, p.type, p.stride, (GLvoid*) p.offset);
}
if (m_attrIndexes & AttrType::Normal)
{
const auto& p = m_params[1];
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(p.type, p.stride, (GLvoid*) p.offset);
}
if (m_attrIndexes & AttrType::Color)
{
const auto& p = m_params[2];
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(p.count, p.type, p.stride, (GLvoid*) p.offset);
}
if (m_attrIndexes & AttrType::Index)
{
const auto& p = m_params[3];
glEnableClientState(GL_INDEX_ARRAY);
glIndexPointer(p.type, p.stride, (GLvoid*) p.offset);
}
if (m_attrIndexes & AttrType::Texture)
{
const auto& p = m_params[4];
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(p.count, p.type, p.stride, (GLvoid*) p.offset);
}
if (m_attrIndexes & AttrType::EdgeFlag)
{
const auto& p = m_params[5];
glEnableClientState(GL_EDGE_FLAG_ARRAY);
glEdgeFlagPointer(p.stride, (GLvoid*) p.offset);
}
if (m_attrIndexes & AttrType::Tangent)
{
const auto& p = m_params[6];
glEnableVertexAttribArray(6);
glVertexAttribPointer(6, p.count, p.type, p.normalized, p.stride, (GLvoid*) p.offset);
}
if (m_attrIndexes & AttrType::PointSize)
{
const auto& p = m_params[7];
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, p.count, p.type, p.normalized, p.stride, (GLvoid*) p.offset);
}
if (m_attribParams != nullptr) if (m_attribParams != nullptr)
{ {
for (const auto& t : *m_attribParams) for (const auto& t : *m_attribParams)
@ -196,30 +141,6 @@ void VertexObject::enableAttribArrays() noexcept
void VertexObject::disableAttribArrays() noexcept void VertexObject::disableAttribArrays() noexcept
{ {
if (m_attrIndexes & AttrType::Vertices)
glDisableClientState(GL_VERTEX_ARRAY);
if (m_attrIndexes & AttrType::Normal)
glDisableClientState(GL_NORMAL_ARRAY);
if (m_attrIndexes & AttrType::Color)
glDisableClientState(GL_COLOR_ARRAY);
if (m_attrIndexes & AttrType::Index)
glDisableClientState(GL_INDEX_ARRAY);
if (m_attrIndexes & AttrType::Texture)
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (m_attrIndexes & AttrType::EdgeFlag)
glDisableClientState(GL_EDGE_FLAG_ARRAY);
if (m_attrIndexes & AttrType::Tangent)
glDisableVertexAttribArray(6);
if (m_attrIndexes & AttrType::PointSize)
glDisableVertexAttribArray(7);
if (m_attribParams != nullptr) if (m_attribParams != nullptr)
{ {
for (const auto& t : *m_attribParams) for (const auto& t : *m_attribParams)
@ -231,54 +152,39 @@ void VertexObject::disableAttribArrays() noexcept
void VertexObject::setVertices(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept void VertexObject::setVertices(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{ {
m_attrIndexes |= AttrType::Vertices; setVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex, count, type, normalized, stride, offset);
m_params[0] = { offset, stride, count, type, normalized };
} }
void VertexObject::setNormals(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept void VertexObject::setNormals(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{ {
m_attrIndexes |= AttrType::Normal; setVertexAttribArray(CelestiaGLProgram::NormalAttributeIndex, count, type, normalized, stride, offset);
m_params[1] = { offset, stride, count, type, normalized };
} }
void VertexObject::setColors(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept void VertexObject::setColors(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{ {
m_attrIndexes |= AttrType::Color; setVertexAttribArray(CelestiaGLProgram::ColorAttributeIndex, count, type, normalized, stride, offset);
m_params[2] = { offset, stride, count, type, normalized };
}
void VertexObject::setIndexes(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{
m_attrIndexes |= AttrType::Index;
m_params[3] = { offset, stride, count, type, normalized };
} }
void VertexObject::setTextureCoords(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept void VertexObject::setTextureCoords(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{ {
m_attrIndexes |= AttrType::Texture; setVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex, count, type, normalized, stride, offset);
m_params[4] = { offset, stride, count, type, normalized };
}
void VertexObject::setEdgeFlags(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{
m_attrIndexes |= AttrType::EdgeFlag;
m_params[5] = { offset, stride, count, type, normalized };
} }
void VertexObject::setTangents(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept void VertexObject::setTangents(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{ {
m_attrIndexes |= AttrType::Tangent; setVertexAttribArray(CelestiaGLProgram::TangentAttributeIndex, count, type, normalized, stride, offset);
m_params[6] = { offset, stride, count, type, normalized };
} }
void VertexObject::setPointSizes(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept void VertexObject::setPointSizes(GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) noexcept
{ {
m_attrIndexes |= AttrType::PointSize; setVertexAttribArray(CelestiaGLProgram::PointSizeAttributeIndex, count, type, normalized, offset, stride);
m_params[7] = { offset, stride, count, type, normalized };
} }
void VertexObject::setVertexAttrib(GLint location, GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset) void VertexObject::setVertexAttribArray(GLint location, GLint count, GLenum type, bool normalized, GLsizei stride, GLsizeiptr offset)
{ {
if (location < 0)
return;
if (m_attribParams == nullptr) if (m_attribParams == nullptr)
m_attribParams = new std::map<GLint, PtrParams>; m_attribParams = new std::map<GLint, PtrParams>;

View File

@ -41,12 +41,10 @@ class VertexObject
void setVertices(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept; void setVertices(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setNormals(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept; void setNormals(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setColors(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept; void setColors(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setIndexes(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setTextureCoords(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept; void setTextureCoords(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setEdgeFlags(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setTangents(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept; void setTangents(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setPointSizes(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept; void setPointSizes(GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0) noexcept;
void setVertexAttrib(GLint location, GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0); void setVertexAttribArray(GLint location, GLint count, GLenum type, bool normalized = false, GLsizei stride = 0, GLsizeiptr offset = 0);
inline bool initialized() const noexcept inline bool initialized() const noexcept
{ {
return (m_state & State::Initialize) == 0; return (m_state & State::Initialize) == 0;
@ -56,19 +54,6 @@ class VertexObject
void setStreamType(GLenum streamType) noexcept { m_streamType = streamType; } void setStreamType(GLenum streamType) noexcept { m_streamType = streamType; }
private: private:
enum AttrType : uint16_t
{
Nothing = 0x00000000,
Vertices = 0x00000001,
Normal = 0x00000002,
Color = 0x00000004,
Index = 0x00000008,
Texture = 0x00000010,
EdgeFlag = 0x00000020,
Tangent = 0x00000040,
PointSize = 0x00000080
};
enum State : uint16_t enum State : uint16_t
{ {
NormalState = 0x0000, NormalState = 0x0000,
@ -90,13 +75,11 @@ class VertexObject
GLuint m_vboId{ 0 }; GLuint m_vboId{ 0 };
GLuint m_vaoId{ 0 }; GLuint m_vaoId{ 0 };
uint16_t m_attrIndexes{ AttrType::Nothing };
uint16_t m_state{ State::Initialize }; uint16_t m_state{ State::Initialize };
GLsizeiptr m_bufferSize{ 0 }; GLsizeiptr m_bufferSize{ 0 };
GLenum m_bufferType{ 0 }; GLenum m_bufferType{ 0 };
GLenum m_streamType{ 0 }; GLenum m_streamType{ 0 };
std::array<PtrParams, 8> m_params {};
std::map<GLint, PtrParams>* m_attribParams{ nullptr }; std::map<GLint, PtrParams>* m_attribParams{ nullptr };
}; };
}; // namespace }; // namespace

View File

@ -84,7 +84,7 @@ VisibleRegion::setOpacity(float opacity)
constexpr const unsigned maxSections = 360; constexpr const unsigned maxSections = 360;
static void static void
renderTerminator(Renderer* renderer, const vector<Vector3f>& pos, const Vector4f& color, const Quaternionf& qf) renderTerminator(Renderer* renderer, const vector<Vector3f>& pos, const Color& color)
{ {
/*! /*!
* Proper terminator calculation requires double precision floats in GLSL * Proper terminator calculation requires double precision floats in GLSL
@ -112,7 +112,7 @@ renderTerminator(Renderer* renderer, const vector<Vector3f>& pos, const Vector4f
vo.setBufferData(pos.data(), 0, pos.size() * sizeof(Vector3f)); vo.setBufferData(pos.data(), 0, pos.size() * sizeof(Vector3f));
prog->use(); prog->use();
glColor(color); glVertexAttrib(CelestiaGLProgram::ColorAttributeIndex, color);
vo.draw(GL_LINE_LOOP, pos.size()); vo.draw(GL_LINE_LOOP, pos.size());
@ -211,7 +211,7 @@ VisibleRegion::render(Renderer* renderer,
pos.push_back(toCenter.cast<float>()); pos.push_back(toCenter.cast<float>());
} }
renderTerminator(renderer, pos, Color(m_color, opacity).toVector4(), qf); renderTerminator(renderer, pos, Color(m_color, opacity));
glPopMatrix(); glPopMatrix();

View File

@ -7,7 +7,6 @@
// as published by the Free Software Foundation; either version 2 // as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version. // of the License, or (at your option) any later version.
#include <config.h>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <iostream> #include <iostream>
@ -34,17 +33,17 @@ struct Glyph
{ {
wchar_t ch; wchar_t ch;
float ax; // advance.x int ax; // advance.x
float ay; // advance.y int ay; // advance.y
float bw; // bitmap.width; int bw; // bitmap.width;
float bh; // bitmap.height; int bh; // bitmap.height;
float bl; // bitmap_left; int bl; // bitmap_left;
float bt; // bitmap_top; int bt; // bitmap_top;
float tx; // x offset of glyph in texture coordinates float tx; // x offset of glyph in texture coordinates
float ty; // y offset of glyph in texture coordinates float ty; // y offset of glyph in texture coordinates
}; };
struct UnicodeBlock struct UnicodeBlock
@ -248,8 +247,8 @@ bool TextureFontPrivate::buildAtlas()
} }
glTexSubImage2D(GL_TEXTURE_2D, 0, ox, oy, g->bitmap.width, g->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer); glTexSubImage2D(GL_TEXTURE_2D, 0, ox, oy, g->bitmap.width, g->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
c.tx = ox / (float)m_texWidth; c.tx = (float)ox / (float)m_texWidth;
c.ty = oy / (float)m_texHeight; c.ty = (float)oy / (float)m_texHeight;
rowh = max(rowh, (int)g->bitmap.rows); rowh = max(rowh, (int)g->bitmap.rows);
ox += g->bitmap.width + 1; ox += g->bitmap.width + 1;
@ -337,6 +336,15 @@ void TextureFontPrivate::optimize()
m_inserted = 0; m_inserted = 0;
} }
struct FontVertex
{
FontVertex(float _x, float _y, float _u, float _v) :
x(_x), y(_y), u(_u), v(_v)
{}
float x, y;
float u, v;
};
/* /*
* Render text using the currently loaded font and currently set font size. * Render text using the currently loaded font and currently set font size.
* Rendering starts at coordinates (x, y), z is always 0. * Rendering starts at coordinates (x, y), z is always 0.
@ -354,6 +362,11 @@ float TextureFontPrivate::render(const string &s, float x, float y)
int len = s.length(); int len = s.length();
bool validChar = true; bool validChar = true;
int i = 0; int i = 0;
int first = true;
vector<FontVertex> vertices;
vector<unsigned short> indexes;
unsigned short index = 0;
while (i < len && validChar) while (i < len && validChar)
{ {
@ -379,14 +392,34 @@ float TextureFontPrivate::render(const string &s, float x, float y)
if (!w || !h) if (!w || !h)
continue; continue;
glBegin(GL_TRIANGLE_FAN); float tw = w / m_texWidth;
glTexCoord2f(g.tx, g.ty + g.bh / m_texHeight); glVertex2f(x2, y2); float th = h / m_texHeight;
glTexCoord2f(g.tx + g.bw / m_texWidth, g.ty + g.bh / m_texHeight); glVertex2f(x2 + w, y2); vertices.emplace_back(FontVertex(x2, y2, g.tx, g.ty + th));
glTexCoord2f(g.tx + g.bw / m_texWidth, g.ty); glVertex2f(x2 + w, y2 + h); vertices.emplace_back(FontVertex(x2 + w, y2, g.tx + tw, g.ty + th));
glTexCoord2f(g.tx, g.ty); glVertex2f(x2, y2 + h); vertices.emplace_back(FontVertex(x2, y2 + h, g.tx, g.ty));
glEnd(); vertices.emplace_back(FontVertex(x2 + w, y2 + h, g.tx + tw, g.ty));
indexes.push_back(index + 0);
indexes.push_back(index + 1);
indexes.push_back(index + 2);
indexes.push_back(index + 1);
indexes.push_back(index + 3);
indexes.push_back(index + 2);
index += 4;
} }
if (vertices.size() < 4)
return 0;
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].x);
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].u);
glDrawElements(GL_TRIANGLES, indexes.size(), GL_UNSIGNED_SHORT, indexes.data());
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
return x; return x;
} }
@ -396,17 +429,32 @@ float TextureFontPrivate::render(wchar_t ch, float xoffset, float yoffset)
auto& g = getGlyph(ch, L'?'); auto& g = getGlyph(ch, L'?');
// Calculate the vertex and texture coordinates // Calculate the vertex and texture coordinates
float x2 = xoffset + g.bl; const float x1 = xoffset + g.bl;
float y2 = yoffset + g.bt - g.bh; const float y1 = yoffset + g.bt - g.bh;
float w = g.bw; const float x2 = x1 + g.bw;
float h = g.bh; const float y2 = y1 + g.bh;
glBegin(GL_TRIANGLE_FAN); const float tx1 = g.tx;
glTexCoord2f(g.tx, g.ty + g.bh / m_texHeight); glVertex2f(x2, y2); const float ty1 = g.ty;
glTexCoord2f(g.tx + g.bw / m_texWidth, g.ty + g.bh / m_texHeight); glVertex2f(x2 + w, y2); const float tx2 = tx1 + static_cast<float>(g.bw) / m_texWidth;
glTexCoord2f(g.tx + g.bw / m_texWidth, g.ty); glVertex2f(x2 + w, y2 + h); const float ty2 = ty1 + static_cast<float>(g.bh) / m_texHeight;
glTexCoord2f(g.tx, g.ty); glVertex2f(x2, y2 + h);
glEnd(); FontVertex vertices[4] = {
{x1, y1, tx1, ty2},
{x2, y1, tx2, ty2},
{x1, y2, tx1, ty1},
{x2, y2, tx2, ty1}
};
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].x);
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].u);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
return g.ax; return g.ax;
} }

View File

@ -36,6 +36,15 @@ TextureFont::~TextureFont()
} }
struct FontVertex
{
FontVertex(float _x, float _y, float _u, float _v) :
x(_x), y(_y), u(_u), v(_v)
{}
float x, y;
float u, v;
};
/** Render a single character of the font. The modelview transform is /** Render a single character of the font. The modelview transform is
* automatically updated to advance to the next character. * automatically updated to advance to the next character.
*/ */
@ -45,16 +54,25 @@ void TextureFont::render(wchar_t ch) const
if (glyph == nullptr) glyph = getGlyph((wchar_t)'?'); if (glyph == nullptr) glyph = getGlyph((wchar_t)'?');
if (glyph != nullptr) if (glyph != nullptr)
{ {
glBegin(GL_QUADS); const float x1 = glyph->xoff;
glTexCoord2f(glyph->texCoords[0].u, glyph->texCoords[0].v); const float y1 = glyph->yoff;
glVertex2f(glyph->xoff, glyph->yoff); const float x2 = glyph->xoff + glyph->width;
glTexCoord2f(glyph->texCoords[1].u, glyph->texCoords[1].v); const float y2 = glyph->yoff + glyph->height;
glVertex2f(glyph->xoff + glyph->width, glyph->yoff); FontVertex vertices[4] = {
glTexCoord2f(glyph->texCoords[2].u, glyph->texCoords[2].v); {x1, y1, glyph->texCoords[0].u, glyph->texCoords[0].v},
glVertex2f(glyph->xoff + glyph->width, glyph->yoff + glyph->height); {x2, y1, glyph->texCoords[1].u, glyph->texCoords[1].v},
glTexCoord2f(glyph->texCoords[3].u, glyph->texCoords[3].v); {x2, y2, glyph->texCoords[2].u, glyph->texCoords[2].v},
glVertex2f(glyph->xoff, glyph->yoff + glyph->height); {x1, y2, glyph->texCoords[3].u, glyph->texCoords[3].v}
glEnd(); };
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].x);
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].u);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glTranslatef(glyph->advance, 0.0f, 0.0f); glTranslatef(glyph->advance, 0.0f, 0.0f);
} }
} }
@ -69,16 +87,25 @@ void TextureFont::render(wchar_t ch, float xoffset, float yoffset) const
if (glyph == nullptr) glyph = getGlyph((wchar_t)'?'); if (glyph == nullptr) glyph = getGlyph((wchar_t)'?');
if (glyph != nullptr) if (glyph != nullptr)
{ {
glBegin(GL_QUADS); const float x1 = glyph->xoff + xoffset;
glTexCoord2f(glyph->texCoords[0].u, glyph->texCoords[0].v); const float y1 = glyph->yoff + yoffset;
glVertex2f(glyph->xoff + xoffset, glyph->yoff + yoffset); const float x2 = glyph->xoff + glyph->width + xoffset;
glTexCoord2f(glyph->texCoords[1].u, glyph->texCoords[1].v); const float y2 = glyph->yoff + glyph->height + yoffset;
glVertex2f(glyph->xoff + glyph->width + xoffset, glyph->yoff + yoffset); FontVertex vertices[4] = {
glTexCoord2f(glyph->texCoords[2].u, glyph->texCoords[2].v); {x1, y1, glyph->texCoords[0].u, glyph->texCoords[0].v},
glVertex2f(glyph->xoff + glyph->width + xoffset, glyph->yoff + glyph->height + yoffset); {x2, y1, glyph->texCoords[1].u, glyph->texCoords[1].v},
glTexCoord2f(glyph->texCoords[3].u, glyph->texCoords[3].v); {x2, y2, glyph->texCoords[2].u, glyph->texCoords[2].v},
glVertex2f(glyph->xoff + xoffset, glyph->yoff + glyph->height + yoffset); {x1, y2, glyph->texCoords[3].u, glyph->texCoords[3].v}
glEnd(); };
glEnableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glEnableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
glVertexAttribPointer(CelestiaGLProgram::VertexCoordAttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].x);
glVertexAttribPointer(CelestiaGLProgram::TextureCoord0AttributeIndex,
2, GL_FLOAT, GL_FALSE, sizeof(FontVertex), &vertices[0].u);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray(CelestiaGLProgram::VertexCoordAttributeIndex);
glDisableVertexAttribArray(CelestiaGLProgram::TextureCoord0AttributeIndex);
} }
} }