]> git.tdb.fi Git - libs/gl.git/commitdiff
Support OpenGL ES on Android
authorMikko Rasa <tdb@tdb.fi>
Fri, 17 Oct 2014 20:49:10 +0000 (23:49 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 17 Oct 2014 20:49:10 +0000 (23:49 +0300)
Some features are still likely to be broken, but basic rendering works
at least.

28 files changed:
Build
extensions/ext_unpack_subimage.glext [new file with mode: 0644]
extensions/msp_draw_buffer.glext [new file with mode: 0644]
extensions/msp_legacy_features.glext [new file with mode: 0644]
extensions/msp_sized_internal_formats.glext [new file with mode: 0644]
extensions/msp_stereo_rendering.glext [new file with mode: 0644]
extensions/msp_texture1d.glext [new file with mode: 0644]
extensions/nv_non_square_matrices.glext [new file with mode: 0644]
gl.fixes.xml
source/batch.cpp
source/extension.cpp
source/extension.h
source/framebuffer.cpp
source/framebuffer.h
source/gl.h
source/light.cpp
source/lighting.cpp
source/lightunit.cpp
source/material.cpp
source/matrix.cpp
source/pixelformat.h
source/pixelstore.cpp
source/primitivetype.cpp
source/primitivetype.h
source/program.cpp
source/programbuilder.cpp
source/texture1d.cpp
source/vertexarray.cpp

diff --git a/Build b/Build
index 162e26ca6257bde4ab8b3f4c4d7b5e0e6af4542d..a20d21ccf4fbe2953e1250be1475d0638b187fe4 100644 (file)
--- a/Build
+++ b/Build
@@ -7,7 +7,14 @@ package "mspgl"
        require "mspdatafile";
        require "mspmath";
        require "mspgui";
-       require "opengl";
+       if_arch "android"
+       {
+               require "opengles";
+       };
+       if_arch "!android"
+       {
+               require "opengl";
+       };
 
        generate "GLEX"
        {
@@ -15,6 +22,10 @@ package "mspgl"
                out_suffix ".cpp";
                out_suffix ".h";
                command "scripts/extgen.py";
+               if_arch "android"
+               {
+                       argument "gles2";
+               };
        };
 
        library "mspgl"
diff --git a/extensions/ext_unpack_subimage.glext b/extensions/ext_unpack_subimage.glext
new file mode 100644 (file)
index 0000000..c366e60
--- /dev/null
@@ -0,0 +1 @@
+extension EXT_unpack_subimage
diff --git a/extensions/msp_draw_buffer.glext b/extensions/msp_draw_buffer.glext
new file mode 100644 (file)
index 0000000..1c52cfd
--- /dev/null
@@ -0,0 +1 @@
+extension MSP_draw_buffer
diff --git a/extensions/msp_legacy_features.glext b/extensions/msp_legacy_features.glext
new file mode 100644 (file)
index 0000000..7128081
--- /dev/null
@@ -0,0 +1 @@
+extension MSP_legacy_features
diff --git a/extensions/msp_sized_internal_formats.glext b/extensions/msp_sized_internal_formats.glext
new file mode 100644 (file)
index 0000000..23438c7
--- /dev/null
@@ -0,0 +1 @@
+extension MSP_sized_internal_formats
diff --git a/extensions/msp_stereo_rendering.glext b/extensions/msp_stereo_rendering.glext
new file mode 100644 (file)
index 0000000..cf278f1
--- /dev/null
@@ -0,0 +1 @@
+extension MSP_stereo_rendering
diff --git a/extensions/msp_texture1d.glext b/extensions/msp_texture1d.glext
new file mode 100644 (file)
index 0000000..00cd912
--- /dev/null
@@ -0,0 +1 @@
+extension MSP_texture1D
diff --git a/extensions/nv_non_square_matrices.glext b/extensions/nv_non_square_matrices.glext
new file mode 100644 (file)
index 0000000..9833f47
--- /dev/null
@@ -0,0 +1 @@
+extension NV_non_square_matrices
index 5f97fa3c54df46f679326a7e446bc1621741ef99..c6459cf3fc2535b0cfec21c908dafd6f1feffece 100644 (file)
         </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>
index 3cb0a6ce8dacd443210e47f57b45291611235420..859a6ad5468f0783240d094075063d276764ac0f 100644 (file)
@@ -1,4 +1,5 @@
 #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"
@@ -59,6 +60,10 @@ Batch::Batch(PrimitiveType t):
        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()
index efa4b1a29c9fab1d820b5749217d02515fdf25e6..023510da4bdce0d751317735800eb06329477559 100644 (file)
@@ -1,5 +1,8 @@
 #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
@@ -105,9 +108,21 @@ bool is_supported(const string &ext)
        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"))
@@ -129,6 +144,9 @@ const Version &get_gl_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"))
@@ -159,6 +177,8 @@ ExtFunc *get_proc_address(const string &name)
 #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
index e0fe3eff4bdcf4aa4c54428a0c18a356c09d2b73..671e4af9aac989afff2a30c9d6cec2a474120c98 100644 (file)
@@ -6,6 +6,13 @@
 namespace Msp {
 namespace GL {
 
+enum GLApi
+{
+       OPENGL,
+       OPENGL_ES2
+};
+
+
 struct Version
 {
        unsigned short major;
@@ -56,6 +63,9 @@ typedef void ExtFunc();
 /** 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();
 
index f4e5a9445e0bce678292c6da327995daef70cc0a..1c2ae519bade1ef1059df7ff1a43dbdd33a23440 100644 (file)
@@ -1,6 +1,7 @@
 #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"
@@ -115,10 +116,11 @@ void Framebuffer::update_attachment(unsigned mask) const
                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;
index 07cae8671d22ef153b927e5fb2e64bdbb5c11d30..ab91d9e7b0df08e4f2081d3b2becb18879c753bd 100644 (file)
@@ -6,6 +6,7 @@
 #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 {
index 255242bf12956fb0559730cd8d8885fdd5813c71..ae145457dff857d112a44c0b26d4ac7d9299df71 100644 (file)
@@ -1,15 +1,19 @@
 #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
index 968bffdf74894723bc620666bd56865b366637eb..a3b3d014c0a51a16762c7a82285f4a6a8960247c 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdexcept>
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include <msp/strings/format.h>
 #include "light.h"
 #include "lightunit.h"
@@ -116,6 +117,8 @@ void Light::update_shader_data(ProgramData &shdata, const Matrix &view_matrix, u
 
 void Light::bind_to(unsigned i) const
 {
+       static Require _req(MSP_legacy_features);
+
        LightUnit &unit = LightUnit::get_unit(i);
        if(unit.set_light(this))
        {
index 7f662c72d9ccf55bdb0e5e8831706b9781709360..d1fd9a70ffc0febe50bd9335b753c87418e32549 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdexcept>
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include "error.h"
 #include "light.h"
 #include "lighting.h"
@@ -71,6 +72,7 @@ void Lighting::update_shader_data(ProgramData &shdata, const Matrix &view_matrix
 
 void Lighting::bind() const
 {
+       static Require _req(MSP_legacy_features);
        if(lights.size()>LightUnit::get_n_units())
                throw invalid_operation("Lighting::bind");
 
index d33c9b25a12ef5cc50e8c53b0e2875981d3568ff..3eb32929859fe8bc51bfb4d5572e6b3d2b389372 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdexcept>
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include "gl.h"
 #include "misc.h"
 #include "lightunit.h"
@@ -24,7 +25,7 @@ bool LightUnit::set_light(const Light *l)
 
 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;
 }
 
index feb97bfa14b9d66023d52487803d7b15df2ccd2f..a2814cff1ad6ccfdac3347e14f5a3ce130451e45 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include "gl.h"
 #include "material.h"
 #include "resources.h"
@@ -75,6 +76,8 @@ void Material::set_reflectivity(float r)
 
 void Material::bind() const
 {
+       static Require _req(MSP_legacy_features);
+
        if(set_current(this))
                update_parameter(-1);
 }
index 4bf550aa090ffc44c2734992cd064e578ebb460a..b05d4bbc8ab6ff3de95e4f9cb6a35dacea80285d 100644 (file)
@@ -1,6 +1,7 @@
 #include <algorithm>
 #include <cmath>
 #include <msp/geometry/affinetransformation.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include "error.h"
 #include "matrix.h"
 
@@ -195,6 +196,8 @@ void MatrixStack::update()
        if(!mode)
                return;
 
+       static Require _req(MSP_legacy_features);
+
        if(mode!=current_mode)
        {
                glMatrixMode(mode);
index 6d68bbc170d0b9f2228087567ef0984bb951aa3d..0fa6609a1ead97d061ad7f45c9e2a97ff0c805ba 100644 (file)
@@ -7,6 +7,8 @@
 #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 {
index 629162cd890b1a9dfd760bc47ddc60a41ef784a9..e1a7cc0ef9ea378bce5db24f7035500b00829a36 100644 (file)
@@ -1,5 +1,6 @@
 #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"
@@ -52,6 +53,7 @@ void PixelStore::update_parameter(int mask) const
 
 void PixelStore::set_canvas_size(unsigned w, unsigned h)
 {
+       static Require _req(EXT_unpack_subimage);
        row_length = w;
        image_height = h;
        update_parameter(SIZE);
@@ -59,6 +61,7 @@ void PixelStore::set_canvas_size(unsigned w, unsigned h)
 
 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;
index 98053660e595cb4189e6b15fe016e6f31cbfd425..c9a827926a108805ef9c7e1b6aba8fc7c02f4699 100644 (file)
@@ -28,5 +28,11 @@ void operator>>(const LexicalConverter &conv, PrimitiveType &pt)
                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
index 777558a1ac9a22757ef9b043b5cea4ee17a939c1..9e65cbf711983c9da5c6f0b79f47a22ea828ef3f 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_PRIMITIVETYPE_H_
 
 #include <msp/strings/lexicalcast.h>
+#include <msp/gl/extensions/msp_legacy_features.h>
 #include "gl.h"
 
 namespace Msp {
@@ -22,6 +23,8 @@ enum PrimitiveType
 
 void operator>>(const LexicalConverter &, PrimitiveType &);
 
+void require_primitive_type(PrimitiveType);
+
 } // namespace GL
 } // namespace Msp
 
index a4358acb4d6d74e048c1c416107540f4fb9bdce9..f56beec73260b58a4eff644aacf4f8d89f4329e0 100644 (file)
@@ -7,6 +7,7 @@
 #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"
index 1e8f55773de8081a9ae99504289df7d7e5418f63..d8fe22ed14542fe8ce93fe670daeed566f122448 100644 (file)
@@ -345,7 +345,10 @@ void ProgramBuilder::add_shaders(Program &prog) const
 
        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");
@@ -369,9 +372,17 @@ string ProgramBuilder::create_source(const list<ShaderVariable *> &variables, Va
 
        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;
index f700d013b5dc6a55f88196695b8a8ec83b2242b9..a0876aced2d57f987d06f45660de8d8f9f456078 100644 (file)
@@ -1,3 +1,4 @@
+#include <msp/gl/extensions/msp_texture1d.h>
 #include "bindable.h"
 #include "error.h"
 #include "texture1d.h"
@@ -12,7 +13,9 @@ Texture1D::Texture1D():
        ifmt(RGB),
        width(0),
        allocated(0)
-{ }
+{
+       static Require _req(MSP_texture1D);
+}
 
 void Texture1D::storage(PixelFormat fmt, unsigned wd)
 {
index db102ab4c355bbdb5e6a8d0e59f71021ea9d59f9..5674bbe0ddda48472cc0423b5230fe754710b3fc 100644 (file)
@@ -1,5 +1,6 @@
 #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"
@@ -123,6 +124,8 @@ void VertexArray::apply(bool use_legacy) const
 
        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