require "mspdatafile";
require "mspmath";
require "mspgui";
- require "opengl";
+ if_arch "android"
+ {
+ require "opengles";
+ };
+ if_arch "!android"
+ {
+ require "opengl";
+ };
generate "GLEX"
{
out_suffix ".cpp";
out_suffix ".h";
command "scripts/extgen.py";
+ if_arch "android"
+ {
+ argument "gles2";
+ };
};
library "mspgl"
--- /dev/null
+extension EXT_unpack_subimage
--- /dev/null
+extension MSP_draw_buffer
--- /dev/null
+extension MSP_legacy_features
--- /dev/null
+extension MSP_sized_internal_formats
--- /dev/null
+extension MSP_stereo_rendering
--- /dev/null
+extension MSP_texture1D
--- /dev/null
+extension NV_non_square_matrices
</require>
</feature>
- <feature api="gl" name="MSPGL_REMOVE">
+ <feature api="gles2" name="MSPGLES">
+ <require>
+ <enum name="GL_FRAMEBUFFER_INCOMPLETE_FORMATS" />
+ </require>
+ </feature>
+
+ <feature name="MSPGL_REMOVE">
<remove>
<!-- These have no counterparts in the core version of
ARB_shader_objects. -->
<command name="glBindBufferBase" />
</require>
</extension>
+
+ <!-- Put GL_RED here for the benefit of OpenGL ES. -->
+ <extension name="GL_ARB_texture_rg" supported="gl|glcore">
+ <require>
+ <enum name="GL_RED" />
+ </require>
+ </extension>
+
+ <extension name="GL_MSP_legacy_features" supported="gl">
+ <require>
+ <command name="glEnableClientState" />
+ <command name="glDisableClientState" />
+
+ <enum name="GL_QUADS" />
+ <enum name="GL_QUAD_STRIP" />
+ <enum name="GL_LUMINANCE8" />
+ <enum name="GL_LUMINANCE8_ALPHA8" />
+
+ <enum name="GL_AMBIENT" />
+ <enum name="GL_DIFFUSE" />
+ <enum name="GL_SPECULAR" />
+ <enum name="GL_EMISSION" />
+ <enum name="GL_SHININESS" />
+ <enum name="GL_LIGHTING" />
+ <enum name="GL_LIGHT_MODEL_AMBIENT" />
+ <enum name="GL_LIGHT0" />
+ <enum name="GL_MAX_LIGHTS" />
+ <enum name="GL_POSITION" />
+ <enum name="GL_SPOT_DIRECTION" />
+ <enum name="GL_SPOT_EXPONENT" />
+ <enum name="GL_SPOT_CUTOFF" />
+ <enum name="GL_CONSTANT_ATTENUATION" />
+ <enum name="GL_LINEAR_ATTENUATION" />
+ <enum name="GL_QUADRATIC_ATTENUATION" />
+ <command name="glLightModelfv" />
+ <command name="glLightf" />
+ <command name="glLightfv" />
+ <command name="glMaterialf" />
+ <command name="glMaterialfv" />
+
+ <enum name="GL_MODELVIEW" />
+ <enum name="GL_PROJECTION" />
+ <command name="glMatrixMode" />
+ <command name="glLoadMatrixf" />
+
+ <!-- Can't reuse EXT_vertex_array for these, as the functions
+ defined there have different signatures. -->
+ <enum name="GL_VERTEX_ARRAY" />
+ <enum name="GL_NORMAL_ARRAY" />
+ <enum name="GL_COLOR_ARRAY" />
+ <enum name="GL_TEXTURE_COORD_ARRAY" />
+ <command name="glVertexPointer" />
+ <command name="glNormalPointer" />
+ <command name="glColorPointer" />
+ <command name="glTexCoordPointer" />
+ </require>
+ </extension>
+
+ <!-- OpenGL ES does not have glDrawBuffer. -->
+ <extension name="GL_MSP_draw_buffer" supported="gl">
+ <require>
+ <command name="glDrawBuffer" />
+ <command name="glReadBuffer" />
+ </require>
+ </extension>
+
+ <!-- Stereo rendering is not supported on OpenGL ES, but I'm not
+ certain enough of its uselessness to remove the constants outright. -->
+ <extension name="GL_MSP_stereo_rendering" supported="gl">
+ <require>
+ <enum name="GL_FRONT_LEFT" />
+ <enum name="GL_FRONT_RIGHT" />
+ <enum name="GL_BACK_LEFT" />
+ <enum name="GL_BACK_RIGHT" />
+ <enum name="GL_LEFT" />
+ <enum name="GL_RIGHT" />
+ </require>
+ </extension>
+
+ <!-- Sized internal formats were introduced in OpenGL ES 3.0, but are
+ not available as an extension. -->
+ <extension name="GL_MSP_sized_internal_formats" supported="gl|gles2">
+ <require>
+ <enum name="GL_RGB8" />
+ <enum name="GL_RGBA8" />
+ </require>
+ </extension>
+
+ <!-- 1D textures are not available in OpenGL ES, but could conceivably
+ be added at a later date. -->
+ <extension name="GL_MSP_texture1D" supported="gl">
+ <require>
+ <command name="glTexImage1D" />
+ <enum name="GL_TEXTURE_1D" />
+ </require>
+ </extension>
</extensions>
</registry>
#include <msp/gl/extensions/ext_draw_range_elements.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
#include <msp/gl/extensions/nv_primitive_restart.h>
#include "batch.h"
#include "bindable.h"
max_index(0),
restart(false)
{
+ /* Make sure we have glEnable/DisableClientState to go with
+ NV_primitive_restart */
+ if(NV_primitive_restart)
+ (bool)MSP_legacy_features;
}
Batch::~Batch()
#include <set>
-#if !defined(WIN32) && !defined(__APPLE__)
+#include <cstdlib>
+#if defined(__ANDROID__)
+#include <EGL/egl.h>
+#elif !defined(WIN32) && !defined(__APPLE__)
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>
#endif
return extensions.count(ext);
}
+GLApi get_gl_api()
+{
+#ifdef GL_ES_VERSION_2_0
+ return OPENGL_ES2;
+#else
+ return OPENGL;
+#endif
+}
+
inline Version _get_gl_version()
{
string gl_ver = reinterpret_cast<const char *>(glGetString(GL_VERSION));
+ if(!gl_ver.compare(0, 10, "OpenGL ES "))
+ gl_ver.erase(0, 10);
+
Version ver(gl_ver.substr(0, gl_ver.find(' ')));
if(const char *force_ver_ptr = getenv("MSPGL_FORCE_VERSION"))
inline Version _get_glsl_version()
{
string glsl_ver = reinterpret_cast<const char *>(glGetString(GL_SHADING_LANGUAGE_VERSION));
+ if(!glsl_ver.compare(0, 18, "OpenGL ES GLSL ES "))
+ glsl_ver.erase(0, 18);
+
Version ver(glsl_ver.substr(0, glsl_ver.find(' ')));
if(const char *force_ver_ptr = getenv("MSPGL_FORCE_GLSL_VERSION"))
#elif defined(__APPLE__)
(void)name;
return 0; // Not supported
+#elif defined(__ANDROID__)
+ return eglGetProcAddress(name.c_str());
#else
return glXGetProcAddressARB(reinterpret_cast<const unsigned char *>(name.c_str()));
#endif
namespace Msp {
namespace GL {
+enum GLApi
+{
+ OPENGL,
+ OPENGL_ES2
+};
+
+
struct Version
{
unsigned short major;
/** Indicates whether an extension is supported. */
bool is_supported(const std::string &);
+/** Returns the API for which the library was compiled. */
+GLApi get_gl_api();
+
/** Returns the OpenGL version number, as reported by the implementation. */
const Version &get_gl_version();
#include <msp/gl/extensions/arb_draw_buffers.h>
#include <msp/gl/extensions/ext_framebuffer_blit.h>
#include <msp/gl/extensions/ext_framebuffer_object.h>
+#include <msp/gl/extensions/msp_draw_buffer.h>
#include "error.h"
#include "framebuffer.h"
#include "misc.h"
GLenum first_buffer = (color_bufs.empty() ? GL_NONE : color_bufs.front());
if(ARB_draw_buffers)
glDrawBuffers(color_bufs.size(), &color_bufs[0]);
- else
+ else if(MSP_draw_buffer)
glDrawBuffer(first_buffer);
- glReadBuffer(first_buffer);
+ if(MSP_draw_buffer)
+ glReadBuffer(first_buffer);
}
else
dirty |= mask;
#include "gl.h"
#include "texturecube.h"
#include <msp/gl/extensions/ext_framebuffer_object.h>
+#include <msp/gl/extensions/msp_stereo_rendering.h>
namespace Msp {
namespace GL {
#ifndef MSP_GL_GL_H_
#define MSP_GL_GL_H_
-#ifdef WIN32
-#include <windows.h>
-#endif
#ifdef __APPLE__
#define extern extern __attribute__((weak_import))
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#undef extern
+#elif defined(__ANDROID__)
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+typedef double GLdouble;
#else
+#ifdef WIN32
+#include <windows.h>
+#endif
#include <GL/gl.h>
#include <GL/glext.h>
#endif
#include <stdexcept>
+#include <msp/gl/extensions/msp_legacy_features.h>
#include <msp/strings/format.h>
#include "light.h"
#include "lightunit.h"
void Light::bind_to(unsigned i) const
{
+ static Require _req(MSP_legacy_features);
+
LightUnit &unit = LightUnit::get_unit(i);
if(unit.set_light(this))
{
#include <stdexcept>
+#include <msp/gl/extensions/msp_legacy_features.h>
#include "error.h"
#include "light.h"
#include "lighting.h"
void Lighting::bind() const
{
+ static Require _req(MSP_legacy_features);
if(lights.size()>LightUnit::get_n_units())
throw invalid_operation("Lighting::bind");
#include <stdexcept>
+#include <msp/gl/extensions/msp_legacy_features.h>
#include "gl.h"
#include "misc.h"
#include "lightunit.h"
unsigned LightUnit::get_n_units()
{
- static int count = get_i(GL_MAX_LIGHTS);
+ static int count = (MSP_legacy_features ? get_i(GL_MAX_LIGHTS) : 0);
return count;
}
+#include <msp/gl/extensions/msp_legacy_features.h>
#include "gl.h"
#include "material.h"
#include "resources.h"
void Material::bind() const
{
+ static Require _req(MSP_legacy_features);
+
if(set_current(this))
update_parameter(-1);
}
#include <algorithm>
#include <cmath>
#include <msp/geometry/affinetransformation.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
#include "error.h"
#include "matrix.h"
if(!mode)
return;
+ static Require _req(MSP_legacy_features);
+
if(mode!=current_mode)
{
glMatrixMode(mode);
#include <msp/gl/extensions/arb_texture_float.h>
#include <msp/gl/extensions/ext_bgra.h>
#include <msp/gl/extensions/ext_texture_srgb.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
+#include <msp/gl/extensions/msp_sized_internal_formats.h>
namespace Msp {
namespace GL {
#include <algorithm>
#include <msp/gl/extensions/ext_texture3d.h>
+#include <msp/gl/extensions/ext_unpack_subimage.h>
#include "gl.h"
#include "pixelformat.h"
#include "pixelstore.h"
void PixelStore::set_canvas_size(unsigned w, unsigned h)
{
+ static Require _req(EXT_unpack_subimage);
row_length = w;
image_height = h;
update_parameter(SIZE);
void PixelStore::set_origin(unsigned x, unsigned y, unsigned z)
{
+ static Require _req(EXT_unpack_subimage);
if(z>0)
static Require _req3d(EXT_texture3D);
skip_pixels = x;
throw lexical_error(format("conversion of '%s' to PrimitiveType", conv.get()));
}
+void require_primitive_type(PrimitiveType type)
+{
+ if(type==QUADS || type==QUAD_STRIP)
+ static Require _req(MSP_legacy_features);
+}
+
} // namespace GL
} // namespace Msp
#define MSP_GL_PRIMITIVETYPE_H_
#include <msp/strings/lexicalcast.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
#include "gl.h"
namespace Msp {
void operator>>(const LexicalConverter &, PrimitiveType &);
+void require_primitive_type(PrimitiveType);
+
} // namespace GL
} // namespace Msp
#include <msp/gl/extensions/arb_uniform_buffer_object.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
#include <msp/gl/extensions/ext_gpu_shader4.h>
+#include <msp/gl/extensions/nv_non_square_matrices.h>
#include <msp/strings/format.h>
#include "buffer.h"
#include "error.h"
if(!features.legacy)
{
- prog.bind_fragment_data(0, "frag_color");
+ // OpenGL ES does not support binding fragment shader outputs
+ if(get_gl_api()!=OPENGL_ES2)
+ prog.bind_fragment_data(0, "frag_color");
+
prog.bind_attribute(VERTEX4, "vertex");
if(features.lighting)
prog.bind_attribute(NORMAL3, "normal");
if(!features.legacy)
{
- source += "#version 130\n";
- if(use_blocks)
- source += "#extension GL_ARB_uniform_buffer_object: require\n";
+ if(get_gl_api()==OPENGL_ES2)
+ {
+ if(use_blocks)
+ source += "#version 300 es\n";
+ }
+ else
+ {
+ source += "#version 130\n";
+ if(use_blocks)
+ source += "#extension GL_ARB_uniform_buffer_object: require\n";
+ }
}
set<const VariableDefinition *> declared_types;
+#include <msp/gl/extensions/msp_texture1d.h>
#include "bindable.h"
#include "error.h"
#include "texture1d.h"
ifmt(RGB),
width(0),
allocated(0)
-{ }
+{
+ static Require _req(MSP_texture1D);
+}
void Texture1D::storage(PixelFormat fmt, unsigned wd)
{
#include <msp/gl/extensions/arb_multitexture.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
#include "buffer.h"
#include "error.h"
#include "gl.h"
if(!use_legacy)
static Require _req(ARB_vertex_shader);
+ else if(legacy)
+ static Require _req(MSP_legacy_features);
const VertexArray *old = current();
/* If the array has been modified, apply it even if it was the last one to