From 9d98a43aafecd2f1e3c4b7a92ded23680cb62a36 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Sun, 6 Sep 2015 23:06:35 +0200 Subject: [PATCH 01/38] Enable new functionality of GL ES 2/3/3.1 via ifdefs --- libs/openFrameworks/gl/ofBufferObject.cpp | 4 +- libs/openFrameworks/gl/ofBufferObject.h | 16 +- .../gl/ofGLProgrammableRenderer.cpp | 306 +++++++++--------- libs/openFrameworks/gl/ofGLUtils.h | 2 +- libs/openFrameworks/gl/ofShader.cpp | 20 +- libs/openFrameworks/gl/ofShader.h | 15 +- libs/openFrameworks/gl/ofTexture.cpp | 2 +- libs/openFrameworks/gl/ofTexture.h | 4 +- libs/openFrameworks/utils/ofConstants.h | 25 +- 9 files changed, 206 insertions(+), 188 deletions(-) diff --git a/libs/openFrameworks/gl/ofBufferObject.cpp b/libs/openFrameworks/gl/ofBufferObject.cpp index db752728744..b27a51b4ce8 100644 --- a/libs/openFrameworks/gl/ofBufferObject.cpp +++ b/libs/openFrameworks/gl/ofBufferObject.cpp @@ -81,7 +81,7 @@ void ofBufferObject::unbind(GLenum target) const{ } } -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) void ofBufferObject::bindBase(GLenum target,GLuint index) const{ if(data){ glBindBufferBase(target,index,data->id); @@ -187,7 +187,9 @@ void * ofBufferObject::map(GLenum access){ return ret; } +#endif +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) void ofBufferObject::unmap(){ if(!this->data) return; diff --git a/libs/openFrameworks/gl/ofBufferObject.h b/libs/openFrameworks/gl/ofBufferObject.h index 637a5b318b1..65a237ff086 100644 --- a/libs/openFrameworks/gl/ofBufferObject.h +++ b/libs/openFrameworks/gl/ofBufferObject.h @@ -41,7 +41,8 @@ class ofBufferObject { /// binds the passed target to buffer 0 void unbind(GLenum target) const; -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) /// glBindBufferBase: https://www.opengl.org/sdk/docs/man4/html/glBindBufferBase.xhtml void bindBase(GLenum target,GLuint index) const; @@ -102,11 +103,6 @@ class ofBufferObject { /// for this buffer and mapping that target void * map(GLenum access); - /// glUnmapNamedBuffer: https://www.opengl.org/sdk/docs/man4/html/glUnmapBuffer.xhtml - /// before GL 4.5 emulates glUnmapNamedBuffer by unmapping and unbinding - /// the last known target for this buffer - void unmap(); - /// typed version of map, returns an array of T when used like: /// buffer.map(access) template @@ -114,6 +110,14 @@ class ofBufferObject { return static_cast(map(access)); } +#endif + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + /// glUnmapNamedBuffer: https://www.opengl.org/sdk/docs/man4/html/glUnmapBuffer.xhtml + /// before GL 4.5 emulates glUnmapNamedBuffer by unmapping and unbinding + /// the last known target for this buffer + void unmap(); + /// glMapNamedBufferRange: https://www.opengl.org/sdk/docs/man4/html/glMapBufferRange.xhtml /// before GL 4.5 emulates glMapNamedBufferRange by binding to last known target /// for this buffer and mapping that target diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index 9ee3712a725..ddcff4797ba 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -195,12 +195,12 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode drawMode = GL_POINTS; } } - + bool bConfigureForLinesShader = areLinesShadersEnabled() && (drawMode == GL_LINES || drawMode == GL_LINE_STRIP || drawMode == GL_LINE_LOOP); if( usingCustomShader || usingCustomShader || currentMaterial) { bConfigureForLinesShader = false; } - + if( bConfigureForLinesShader ) { mDrawMode = drawMode; tGoingToRenderLines = true; @@ -234,12 +234,12 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); break; } - + bool bConfigureForLinesShader = areLinesShadersEnabled() && (drawMode == GL_LINES || drawMode == GL_LINE_STRIP || drawMode == GL_LINE_LOOP); if( usingCustomShader || usingCustomShader || currentMaterial) { bConfigureForLinesShader = false; } - + if(bConfigureForLinesShader) { mDrawMode = drawMode; tGoingToRenderLines = true; @@ -257,7 +257,7 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode } #endif - + if( vboToRender != nullptr ) { if( tGoingToRenderLines ) { // Setting a bool here so that the setAttributes function does not try to switch the shaders because @@ -268,13 +268,13 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode drawMode = GL_TRIANGLES; } } - + if (vboToRender->getUsingIndices()) { drawElements(*vboToRender, drawMode, vboToRender->getNumIndices()); } else { draw(*vboToRender, drawMode, 0, vboToRender->getNumVertices()); } - + if( tGoingToRenderLines ) { mBRenderingLines = false; } @@ -344,7 +344,7 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVboMesh & mesh, ofPolyRende #if defined(TARGET_EMSCRIPTEN) } // close the if for checking for wireframe #endif - + // tig: note further that we could glGet() and store the current polygon mode, but don't, since that would // infer a massive performance hit. instead, we revert the glPolygonMode to mirror the current ofFill state // after we're finished drawing, following the principle of least surprise. @@ -412,11 +412,11 @@ void ofGLProgrammableRenderer::draw(const ofPolyline & poly) const { glDrawArrays(drawMode, 0, poly.size()); #else - + // polylineMesh.clear(); // polylineMesh.addVertices(poly.getVertices()); - - + + polylineMesh.getVertices() = poly.getVertices(); // check if it is closed and the last point is the same as the first if( poly.isClosed() ) { @@ -424,7 +424,7 @@ void ofGLProgrammableRenderer::draw(const ofPolyline & poly) const { polylineMesh.getVertices().pop_back(); } } - + if( currentTextureTarget != OF_NO_TEXTURE ) { // TODO: Should we be able to set tex coords on polylines somehow?? polylineMesh.getTexCoords().resize( polylineMesh.getNumVertices(), glm::vec2(0.f, 0.f)); @@ -440,12 +440,12 @@ void ofGLProgrammableRenderer::draw(const ofPolyline & poly) const { } else { polylineMesh.disableTextures(); } - + polylineMesh.setMode( poly.isClosed() ? OF_PRIMITIVE_LINE_LOOP : OF_PRIMITIVE_LINE_STRIP ); // draw(const ofMesh & vertexData, ofPolyRenderMode renderType, bool useColors, bool useTextures, bool useNormals) const; draw(polylineMesh, OF_MESH_FILL, false, false, false); - - + + // meshVbo.setVertexData(&poly.getVertices()[0], poly.size(), GL_DYNAMIC_DRAW); // meshVbo.draw(poly.isClosed() ? GL_LINE_LOOP : GL_LINE_STRIP, 0, poly.size()); // meshPolylineVbo.setVertexData(&poly.getVertices()[0], poly.size(), GL_DYNAMIC_DRAW); @@ -555,7 +555,7 @@ void ofGLProgrammableRenderer::draw(const ofBaseVideoDraws & video, float x, flo //---------------------------------------------------------- void ofGLProgrammableRenderer::draw(const ofVbo & vbo, GLuint drawMode, int first, int total) const { - if (vbo.getUsingVerts()) { + if (vbo.getUsingVerts()) { vbo.bind(); const_cast(this)->setAttributes(vbo.getUsingVerts(), vbo.getUsingColors(), vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); glDrawArrays(drawMode, first, total); @@ -568,7 +568,7 @@ void ofGLProgrammableRenderer::drawElements(const ofVbo & vbo, GLuint drawMode, if (vbo.getUsingVerts()) { vbo.bind(); const_cast(this)->setAttributes(vbo.getUsingVerts(), vbo.getUsingColors(), vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); -#ifdef TARGET_OPENGLES +#ifdef TARGET_OPENGLES && !defined(GL_ES_VERSION_2_0) glDrawElements(drawMode, amt, GL_UNSIGNED_SHORT, (void *)(sizeof(ofIndexType) * offsetelements)); #else glDrawElements(drawMode, amt, GL_UNSIGNED_INT, (void *)(sizeof(ofIndexType) * offsetelements)); @@ -582,12 +582,9 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVbo & vbo, GLuint drawMode, if (vbo.getUsingVerts()) { vbo.bind(); const_cast(this)->setAttributes(vbo.getUsingVerts(), vbo.getUsingColors(), vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); -#ifdef TARGET_OPENGLES - // todo: activate instancing once OPENGL ES supports instancing, starting with version 3.0 - // unfortunately there is currently no easy way within oF to query the current OpenGL version. +#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) // https://www.khronos.org/opengles/sdk/docs/man3/xhtml/glDrawElementsInstanced.xml ofLogWarning("ofVbo") << "drawInstanced(): hardware instancing is not supported on OpenGL ES < 3.0"; - // glDrawArraysInstanced(drawMode, first, total, primCount); #else glDrawArraysInstanced(drawMode, first, total, primCount); #endif @@ -600,12 +597,9 @@ void ofGLProgrammableRenderer::drawElementsInstanced(const ofVbo & vbo, GLuint d if (vbo.getUsingVerts()) { vbo.bind(); const_cast(this)->setAttributes(vbo.getUsingVerts(), vbo.getUsingColors(), vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); -#if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) // TODO: Check against OPENGL_ES Version - // todo: activate instancing once OPENGL ES supports instancing, starting with version 3.0 - // unfortunately there is currently no easy way within oF to query the current OpenGL version. +#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) // TODO: Check against OPENGL_ES Version // https://www.khronos.org/opengles/sdk/docs/man3/xhtml/glDrawElementsInstanced.xml ofLogWarning("ofVbo") << "drawElementsInstanced(): hardware instancing is not supported on OpenGL ES < 3.0"; - // glDrawElementsInstanced(drawMode, amt, GL_UNSIGNED_SHORT, nullptr, primCount); #else #if defined(TARGET_OPENGLES) glDrawElementsInstanced(drawMode, amt, GL_UNSIGNED_SHORT, nullptr, primCount); @@ -799,7 +793,7 @@ void ofGLProgrammableRenderer::setCircleResolution(int res) { circlePolyline.arc(0, 0, 0, 1, 1, 0, 360, res); circleMesh.getVertices() = circlePolyline.getVertices(); path.setCircleResolution(res); - + // for the outline polyline, we need a closed loop // so we make another line that is closed, excluding the same start and end points circleOutlinePolyline.clear(); @@ -808,10 +802,10 @@ void ofGLProgrammableRenderer::setCircleResolution(int res) { circleOutlinePolyline.addVertex(glm::vec3(cosf(ta),sinf(ta), 0.0f)); } // circleOutlinePolyline.setClosed(true); - + circleOutlineMesh.getVertices() = circleOutlinePolyline.getVertices(); - - + + } currentStyle.circleResolution = res; } @@ -1365,7 +1359,7 @@ void ofGLProgrammableRenderer::setStyle(const ofStyle & style) { //line width - finally! setLineWidth(style.lineWidth); - + setPointSize(style.pointSize); //ofSetDepthTest(style.depthTest); removed since it'll break old projects setting depth test through glEnable @@ -1410,14 +1404,14 @@ void ofGLProgrammableRenderer::setAttributes(bool vertices, bool color, bool tex texCoordsEnabled = tex; colorsEnabled = color; normalsEnabled = normals; - + // nh: we set a variable (mBRenderingLines) before calling set attributes() to disable // the setting of the draw mode. When rendering lines, the requested mode may be GL_LINES // but we use a shader with GL_TRIANGLES to create a mesh to render the lines of varying widths. if( !mBRenderingLines ) { mDrawMode = drawMode; } - + if( mDrawMode == GL_LINE_LOOP ) { // this uses the same line resources as GL_LINE_STRIP mDrawMode = GL_LINE_STRIP; @@ -1427,7 +1421,7 @@ void ofGLProgrammableRenderer::setAttributes(bool vertices, bool color, bool tex if( !areLinesShadersEnabled() ) { mDrawMode = GL_TRIANGLES; } - + // prevent a shader switch if we don't need it. if( mDrawMode != GL_TRIANGLES && mDrawMode != GL_POINTS && mDrawMode != GL_LINES && mDrawMode != GL_LINE_STRIP ) { mDrawMode = GL_TRIANGLES; @@ -1445,7 +1439,7 @@ void ofGLProgrammableRenderer::setAttributes(bool vertices, bool color, bool tex if (currentShader) currentShader->setUniform1f(USE_COLORS_UNIFORM, color); } - // if we switch the draw mode, lets set the textures + // if we switch the draw mode, lets set the textures if( prevDrawMode != mDrawMode ) { if (currentTextureTarget != OF_NO_TEXTURE && currentShader ) { // set all of the texture uniforms @@ -1468,7 +1462,7 @@ void ofGLProgrammableRenderer::setAttributes(bool vertices, bool color, bool tex } } } - + if (!usingCustomShader && currentShader && !uniqueShader && !currentMaterial) { if (mDrawMode == GL_POINTS && pointSpritesEnabled) { currentShader->setUniform1f("pointSize", currentStyle.pointSize ); @@ -1882,7 +1876,7 @@ void ofGLProgrammableRenderer::beginDefaultShader() { } else if (colorsEnabled && bUseTexture) { auto &shaderCollection = getShaderCollectionForMode(mDrawMode); - + switch (currentTextureTarget) { #ifndef TARGET_OPENGLES @@ -2022,7 +2016,7 @@ void ofGLProgrammableRenderer::drawCircle(float x, float y, float z, float radiu ofGLProgrammableRenderer * mutThis = const_cast(this); // use smoothness, if requested: if (currentStyle.smoothing && !currentStyle.bFill) mutThis->startSmoothing(); - + if( !currentStyle.bFill ) { // nh: We use the circleOutlineMesh to render a closed polyline // since the lines mesh creation and shader depends on it. @@ -2060,7 +2054,7 @@ void ofGLProgrammableRenderer::drawEllipse(float x, float y, float z, float widt // use smoothness, if requested: if (currentStyle.smoothing && !currentStyle.bFill) mutThis->startSmoothing(); - + if( !currentStyle.bFill ) { // nh: We use the circleOutlineMesh to render a closed polyline // since the lines mesh creation and shader depends on it. @@ -2319,16 +2313,16 @@ STRINGIFY( uniform mat4 modelViewMatrix; uniform mat4 textureMatrix; uniform mat4 modelViewProjectionMatrix; - + uniform float pointSize; - + IN vec4 position; IN vec2 texcoord; IN vec4 color; IN vec3 normal; - + OUT vec4 colorVarying; - + void main() { gl_PointSize = pointSize; @@ -2344,29 +2338,29 @@ STRINGIFY( uniform mat4 modelViewMatrix;\n uniform mat4 textureMatrix;\n uniform mat4 modelViewProjectionMatrix;\n - + uniform vec4 viewRect;\n uniform float uLineWidth;\n uniform float uUsePerspective;\n - + IN vec4 position; IN vec2 texcoord; IN vec4 color; IN vec3 normal; IN vec4 nextVertex; - + OUT vec4 colorVarying; OUT vec2 texCoordVarying; - + void main() { colorVarying = color; float pushDir = nextVertex.w; texCoordVarying = (textureMatrix*vec4(texcoord.x,texcoord.y, 0.0,1.0)).xy; - + // clip space vec4 cClipPos = modelViewProjectionMatrix * vec4(position.xyz, 1.0); vec4 nClipPos = modelViewProjectionMatrix * vec4(nextVertex.xyz, 1.0); - + vec2 cNdcPos = (cClipPos.xy / cClipPos.w); vec2 nNdcPos = (nClipPos.xy / nClipPos.w); /* @@ -2375,26 +2369,26 @@ STRINGIFY( */ cNdcPos = (cNdcPos + 1.0) * (0.5 * viewRect.zw); nNdcPos = (nNdcPos + 1.0) * (0.5 * viewRect.zw); - + float thickness = uLineWidth * 0.5; - - + + vec2 dir = normalize(cNdcPos - nNdcPos); dir = vec2(-dir.y, dir.x); dir = dir * thickness * pushDir; - + vec4 posScreen = cClipPos; posScreen.xy = cNdcPos; posScreen.xy += dir; posScreen.xy = posScreen.xy / viewRect.zw * 2.0 - 1.0; posScreen.xy *= posScreen.w; - + // perspective float vaspect = viewRect.w / viewRect.z; dir.x *= vaspect; vec4 posPersp = cClipPos; posPersp.xy += dir; - + gl_Position = mix( posScreen, posPersp, uUsePerspective ); } ); @@ -2406,21 +2400,21 @@ STRINGIFY( uniform mat4 modelViewMatrix;\n uniform mat4 textureMatrix; uniform mat4 modelViewProjectionMatrix; - + uniform vec4 viewRect; uniform float uLineWidth; uniform float uUsePerspective; - + IN vec4 position; IN vec2 texcoord; IN vec4 color; IN vec3 normal; IN vec4 prevVertex; IN vec4 nextVertex; - + OUT vec4 colorVarying; OUT vec2 texCoordVarying; - + float mapClamp( float value, float inMin, float inMax, float outMin, float outMax ) { float outVal = ( (value - inMin ) / ( inMax - inMin ) * ( outMax - outMin ) ) + outMin; if(outMax < outMin){ @@ -2432,29 +2426,29 @@ STRINGIFY( } return outVal; } - + void main() { colorVarying = color; texCoordVarying = (textureMatrix*vec4(texcoord.x, texcoord.y, 0.0,1.0)).xy; - + float thickness = uLineWidth;// * 0.5; float pushDir = nextVertex.w; float pushDirY = -prevVertex.w; - + // // clip space vec4 pClipPos = modelViewProjectionMatrix * vec4(prevVertex.xyz, 1.0); vec4 cClipPos = modelViewProjectionMatrix * vec4(position.xyz, 1.0); vec4 nClipPos = modelViewProjectionMatrix * vec4(nextVertex.xyz, 1.0); - + vec2 pNdcPos = (pClipPos.xy / pClipPos.w); vec2 cNdcPos = (cClipPos.xy / cClipPos.w); vec2 nNdcPos = (nClipPos.xy / nClipPos.w); - + // // convert to screen space pNdcPos = (pNdcPos + 1.0) * (0.5 * viewRect.zw); cNdcPos = (cNdcPos + 1.0) * (0.5 * viewRect.zw); nNdcPos = (nNdcPos + 1.0) * (0.5 * viewRect.zw); - + vec2 dir = vec2(1.0, 0.0); if( position.xyz == nextVertex.xyz ) { // this is the last point ( on a non-closed line ) @@ -2470,44 +2464,44 @@ STRINGIFY( vec2 pdir = normalize( cNdcPos-pNdcPos ); vec2 ndir = normalize( nNdcPos-cNdcPos ); vec2 tangent = normalize(pdir+ndir); - + // Miter code based on // https://blog.scottlogic.com/2019/11/18/drawing-lines-with-webgl.html // by Matt Stobbs - + vec2 miter = vec2(-tangent.y, tangent.x); vec2 normalA = vec2(-pdir.y, pdir.x); dir = miter; float miterLength = 1.0 / clamp(abs(dot(miter, normalA)), 0.01, 2.0); thickness = miterLength * thickness; - + vec2 point = normalize(pdir-ndir); float dmp = dot(miter, point); - + // float miterTooLongMix = clamp(step( 2.0, miterLength) * sign(pushDir * dmp), 0.0, 1.0); float miterTooLongMix = clamp(step( 2.0, miterLength), 0.0, 1.0); float pstr = mapClamp( miterLength, 2.0, 3.0, 0.0, 1.0 ); float thicknessL = mix( miterLength * uLineWidth, uLineWidth, pstr ); - + dir = mix( dir * pushDir, (pushDir * pushDirY) * normalA, pstr * miterTooLongMix ); thickness = mix( clamp(miterLength, 0.0, 3.0) * uLineWidth, thicknessL, miterTooLongMix ); } - + dir = dir * (thickness * 0.5 ); - + // we calculate both the screen pos and perspective to avoid an if statement vec4 posScreen = cClipPos; posScreen.xy = cNdcPos; posScreen.xy += dir;// * 0.5; posScreen.xy = posScreen.xy / viewRect.zw * 2.0 - 1.0; posScreen.xy *= posScreen.w; - + // perspective vec4 posPersp = cClipPos; float vaspect = viewRect.w / viewRect.z; dir.x *= vaspect; posPersp.xy += (dir); - + gl_Position = mix( posScreen, posPersp, uUsePerspective ); } ); @@ -2534,7 +2528,7 @@ R"( uniform vec4 globalColor; uniform float usingTexture; uniform float usingColors; - + IN vec4 colorVarying; void main(){ @@ -2542,7 +2536,7 @@ R"( float dist_sq = dot( centerPt, centerPt ); vec2 st = gl_PointCoord; - + #if defined(OF_USING_TEXTURE_RECT) st.x = gl_PointCoord.x * src_tex_unit0_dims.x; st.y = gl_PointCoord.y * src_tex_unit0_dims.y; @@ -2721,7 +2715,7 @@ static const string defaultFragmentShaderTex2DNoColor = fragment_shader_header + // ---------------------------------------------------------------------- static const string defaultFragmentShaderOESTexNoColor = fragment_shader_header + STRINGIFY( - + uniform samplerExternalOES src_tex_unit0; uniform float usingTexture; uniform float usingColors; @@ -2739,16 +2733,16 @@ static const string defaultFragmentShaderOESTexNoColor = fragment_shader_header // ---------------------------------------------------------------------- static const string defaultFragmentShaderOESTexColor = fragment_shader_header + STRINGIFY( - + uniform samplerExternalOES src_tex_unit0; uniform float usingTexture; uniform float usingColors; uniform vec4 globalColor; - + IN float depth; IN vec4 colorVarying; IN vec2 texCoordVarying; - + void main(){ FRAG_COLOR = TEXTURE(src_tex_unit0, texCoordVarying) * colorVarying; } @@ -2835,7 +2829,7 @@ static const string bitmapStringFragmentShader = fragment_shader_header + STRING // in desktop openGL these are not used but we declare it to avoid more ifdefs static const string uniqueVertexShader = vertex_shader_header + STRINGIFY( - + uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat4 textureMatrix; @@ -2862,7 +2856,7 @@ static const string uniqueVertexShader = vertex_shader_header + STRINGIFY( // ---------------------------------------------------------------------- static const string uniqueFragmentShader = fragment_shader_header + STRINGIFY( - + uniform sampler2D src_tex_unit0; uniform float usingTexture; uniform float bitmapText; @@ -3141,7 +3135,7 @@ void ofGLProgrammableRenderer::LinesBundle::setMeshDataToVbo() { if( mesh.getNumVertices() > 0 ) { // void setMesh(const ofMesh & mesh, int usage, bool useColors, bool useTextures, bool useNormals); vbo.setMesh( mesh, GL_DYNAMIC_DRAW, mesh.hasColors() && mesh.usingColors(), mesh.hasTexCoords() && mesh.usingTextures(), mesh.hasNormals() && mesh.usingNormals() ); - + if( lineMeshPrevVerts.size() > 0 ) { vbo.setAttributeData(vertAttribPrev, &lineMeshPrevVerts[0].x, 4, mesh.getNumVertices(), GL_DYNAMIC_DRAW); } @@ -3174,7 +3168,7 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { uniqueShader = false; #endif mDefaultShadersMap.clear(); - + mLinesBundleMap.clear(); if( mLinesBundleMap.count(GL_LINES) < 1 ) { mLinesBundleMap[GL_LINES] = LinesBundle(); @@ -3196,15 +3190,15 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { defaultUniqueShader.linkProgram(); beginDefaultShader(); } else { - + mDefaultShadersMap[GL_TRIANGLES] = std::make_shared(); mDefaultShadersMap[GL_POINTS] = std::make_shared(); mDefaultShadersMap[GL_LINES] = std::make_shared(); mDefaultShadersMap[GL_LINE_STRIP] = std::make_shared(); - - + + mDefaultShadersMap[GL_TRIANGLES]->setupAllVertexShaders(shaderSource(defaultVertexShader, major, minor)); - + #ifndef TARGET_OPENGLES // defaultTexRectColor.setupShaderFromSource(GL_VERTEX_SHADER, shaderSource(defaultVertexShader, major, minor)); // defaultTexRectNoColor.setupShaderFromSource(GL_VERTEX_SHADER, shaderSource(defaultVertexShader, major, minor)); @@ -3246,7 +3240,7 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { // defaultTex2DNoColor.bindDefaults(); // defaultNoTexNoColor.bindDefaults(); alphaMask2DShader.bindDefaults(); - + mDefaultShadersMap[GL_TRIANGLES]->bindDefaults(); mDefaultShadersMap[GL_TRIANGLES]->linkPrograms(); @@ -3276,19 +3270,19 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { defaultOESTexColor.linkProgram(); defaultOESTexNoColor.linkProgram(); #endif - - + + // now lets start setting up the points shaders mDefaultShadersMap[GL_POINTS]->setupAllVertexShaders(shaderSource(defaultPointsVertexShader, major, minor)); - + // ok, now lets setup the lines shaders // mDefaultShadersMap[GL_LINES]->setupAllVertexShaders(shaderSource(defaultLinesVertexShader, major, minor)); - + // ok, now lets setup the line strip shaders // mDefaultShadersMap[GL_LINE_STRIP]->setupAllVertexShaders(shaderSource(defaultLineStripVertexShader, major, minor)); - + // defaultFragmentShaderLines - + string alt_frag_header = fragment_shader_header; string defines = "#define OF_USING_TEXTURE_RECT 1\n#define OF_USING_VERTEX_COLORS 1\n"; std::string header_w_defines = alt_frag_header + defines; @@ -3299,7 +3293,7 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { shaderSource(header_w_defines + defaultFragmentShaderLines, major, minor)); mDefaultShadersMap[GL_LINE_STRIP]->texRectColor.setupShaderFromSource(GL_FRAGMENT_SHADER, shaderSource(header_w_defines + defaultFragmentShaderLines, major, minor)); - + defines = "#define OF_USING_TEXTURE_RECT 1\n"; header_w_defines = alt_frag_header + defines; mDefaultShadersMap[GL_POINTS]->texRectNoColor.setupShaderFromSource(GL_FRAGMENT_SHADER, @@ -3309,7 +3303,7 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { mDefaultShadersMap[GL_LINE_STRIP]->texRectNoColor.setupShaderFromSource(GL_FRAGMENT_SHADER, shaderSource(header_w_defines + defaultFragmentShaderLines, major, minor)); #endif - + defines = "#define OF_USING_TEXTURE_2D 1\n#define OF_USING_VERTEX_COLORS 1\n"; header_w_defines = alt_frag_header + defines; mDefaultShadersMap[GL_POINTS]->tex2DColor.setupShaderFromSource(GL_FRAGMENT_SHADER, @@ -3318,7 +3312,7 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { shaderSource(header_w_defines + defaultFragmentShaderLines, major, minor)); mDefaultShadersMap[GL_LINE_STRIP]->tex2DColor.setupShaderFromSource(GL_FRAGMENT_SHADER, shaderSource(header_w_defines + defaultFragmentShaderLines, major, minor)); - + defines = "#define OF_USING_TEXTURE_2D 1\n"; header_w_defines = alt_frag_header + defines; mDefaultShadersMap[GL_POINTS]->tex2DNoColor.setupShaderFromSource(GL_FRAGMENT_SHADER, @@ -3345,28 +3339,28 @@ void ofGLProgrammableRenderer::setup(int _major, int _minor) { shaderSource(header_w_defines + defaultFragmentShaderLines, major, minor)); mDefaultShadersMap[GL_LINE_STRIP]->noTexNoColor.setupShaderFromSource(GL_FRAGMENT_SHADER, shaderSource(header_w_defines + defaultFragmentShaderLines, major, minor)); - + mDefaultShadersMap[GL_POINTS]->bindDefaults(); mDefaultShadersMap[GL_POINTS]->linkPrograms(); - - + + mDefaultShadersMap[GL_LINES]->bindDefaults(); // now lets bind the vertex attribute for the next vertex mDefaultShadersMap[GL_LINES]->bindAttribute( mLinesBundleMap[GL_LINES].vertAttribNext, "nextVertex" ); mDefaultShadersMap[GL_LINES]->linkPrograms(); - - + + mDefaultShadersMap[GL_LINE_STRIP]->bindDefaults(); // now lets bind the vertex attribute for the previous and next vertex mDefaultShadersMap[GL_LINE_STRIP]->bindAttribute( mLinesBundleMap[GL_LINE_STRIP].vertAttribPrev, "prevVertex" ); mDefaultShadersMap[GL_LINE_STRIP]->bindAttribute( mLinesBundleMap[GL_LINE_STRIP].vertAttribNext, "nextVertex" ); mDefaultShadersMap[GL_LINE_STRIP]->linkPrograms(); - + // defaultPointsTex2DColor.bindDefaults(); // defaultPointsTex2DNoColor.bindDefaults(); // defaultPointsNoTexColor.bindDefaults(); // defaultPointsNoTexNoColor.bindDefaults(); -// +// // defaultPointsTex2DColor.linkProgram(); // defaultPointsTex2DNoColor.linkProgram(); // defaultPointsNoTexColor.linkProgram(); @@ -3644,16 +3638,16 @@ void ofGLProgrammableRenderer::configureMeshToMatchWithNewVertsAndIndices(const bool bUseColors = aSrcMesh.hasColors() && aSrcMesh.usingColors() && (aSrcMesh.getNumColors() == aSrcMesh.getNumVertices()); bool bUseNormals = aSrcMesh.hasNormals() && aSrcMesh.usingNormals() && (aSrcMesh.getNumNormals() == aSrcMesh.getNumVertices()); bool bUseTexCoords = aSrcMesh.hasTexCoords() && aSrcMesh.usingTextures() && (aSrcMesh.getNumTexCoords() == aSrcMesh.getNumVertices()); - + if (aDstMesh.getNumVertices() != aTargetNumVertices) { aDstMesh.getVertices().assign(aTargetNumVertices, glm::vec3(0.f, 0.f, 0.f)); } - + if( aDstMesh.getNumIndices() != aTargetNumIndices ) { aDstMesh.getIndices().assign(aTargetNumIndices, 0); } aDstMesh.enableIndices(); - + if (bUseColors) { if (aDstMesh.getNumColors() != aTargetNumVertices) { aDstMesh.getColors().assign(aTargetNumVertices, ofFloatColor(1.f)); @@ -3685,26 +3679,26 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB auto& polyMesh = aLinesBundle.mesh; auto& nextVerts = aLinesBundle.lineMeshNextVerts; auto& prevVerts = aLinesBundle.lineMeshPrevVerts; - + bool bClosed = (drawMode == GL_LINE_LOOP) && amesh.getNumVertices() > 2; bool srcHasIndices = amesh.getNumIndices() > 0 && amesh.usingIndices(); std::size_t srcNumVs = srcHasIndices ? amesh.getNumIndices() : amesh.getNumVertices(); - + std::size_t targetNumPs = (bClosed ? srcNumVs + 1 : srcNumVs); std::size_t numIndicesA = (targetNumPs - 1) * 6 + (targetNumPs) * 6; - + std::size_t numVertsPer = 4; - + if( drawMode == GL_LINES ) { numVertsPer = 2; std::size_t targetNumLines = srcNumVs / 2; numIndicesA = targetNumLines * 6; } std::size_t targetNumVs = targetNumPs * numVertsPer; - - + + configureMeshToMatchWithNewVertsAndIndices(amesh, polyMesh, targetNumVs, numIndicesA ); - + if( drawMode != GL_LINES ) { if( prevVerts.size() != targetNumVs ) { prevVerts.assign(targetNumVs, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); @@ -3713,61 +3707,61 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB if (nextVerts.size() != targetNumVs ) { nextVerts.assign(targetNumVs, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); } - + bool bUseColors = amesh.hasColors() && amesh.usingColors() && (amesh.getNumColors() == amesh.getNumVertices()); bool bUseNormals = amesh.hasNormals() && amesh.usingNormals() && (amesh.getNumNormals() == amesh.getNumVertices()); bool bUseTexCoords = amesh.hasTexCoords() && amesh.usingTextures() && (amesh.getNumTexCoords() == amesh.getNumVertices()); - - + + const auto *srcVerts = amesh.getVerticesPointer(); const auto *srcIndices = amesh.getIndexPointer(); const auto *srcColors = amesh.getColorsPointer(); const auto *srcNormals = amesh.getNormalsPointer(); const auto *srcTexCoords = amesh.getTexCoordsPointer(); std::size_t numPs = srcHasIndices ? amesh.getNumIndices() : amesh.getNumVertices(); - + auto &pmVerts = polyMesh.getVertices(); auto &pmIndices = polyMesh.getIndices(); auto *pmColors = polyMesh.getColorsPointer(); auto *pmNormals = polyMesh.getNormalsPointer(); auto *pmTexCoords = polyMesh.getTexCoordsPointer(); - + float texU = 1.0; if( currentTextureTarget != OF_NO_TEXTURE ) { if( mUniformsTex.size() > 0 ) { texU = mUniformsTex[0].texData.tex_u; } } - - + + glm::vec3 EPSILON_VEC3 = glm::vec3(0.00005f); - - + + if( drawMode == GL_LINES ) { std::size_t cindex1 = 0; std::size_t cindex2 = 0; std::size_t lineIndex = 0; - + std::size_t pmIndex = 0; std::size_t kindex = 0; std::size_t newIndex = 0; - + std::size_t k = 0; - + for (size_t i = 0; i < targetNumPs; i += 2) { cindex1 = (i % numPs); cindex2 = (i + 1) % numPs; - + lineIndex = i / 2; - + if (srcHasIndices) { // get the verts from the indices cindex1 = srcIndices[cindex1]; cindex2 = srcIndices[cindex2]; } - + pmIndex = i * 2; - + // duplicate the vertices // for(k = 0; k < 4; k++ ) { kindex = cindex2; @@ -3775,7 +3769,7 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB kindex = cindex1; } pmVerts[pmIndex + k] = srcVerts[kindex]; - + if (bUseColors) { pmColors[pmIndex + k] = srcColors[kindex]; } @@ -3792,23 +3786,23 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB } } } - + nextVerts[pmIndex + 0] = glm::vec4(srcVerts[cindex2], -1.0f); nextVerts[pmIndex + 1] = glm::vec4(srcVerts[cindex2], 1.0f); - + nextVerts[pmIndex + 2] = glm::vec4(srcVerts[cindex1], 1.0f); nextVerts[pmIndex + 3] = glm::vec4(srcVerts[cindex1], -1.0f); - + newIndex = lineIndex * 6; pmIndices[newIndex + 0] = pmIndex + 0; pmIndices[newIndex + 1] = pmIndex + 2; pmIndices[newIndex + 2] = pmIndex + 1; - + pmIndices[newIndex + 3] = pmIndex + 1; pmIndices[newIndex + 4] = pmIndex + 2; pmIndices[newIndex + 5] = pmIndex + 3; } - + aLinesBundle.setMeshDataToVbo(); } else { std::size_t nindex, pindex, cindex; @@ -3819,18 +3813,18 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB std::size_t k = 0; std::size_t newIndex = 0; std::size_t nextIndex = 0; - + // if we have vertices lying on top of each other, // lets create some way to store valid ones // might not be the best approach, but easier / faster than removing the vertices from the src mesh glm::vec3 cachedPrevVert = {0.f, 0.f, 0.f}; glm::vec3 cachedNextVert = {0.f, 0.f, 0.f}; - + for (size_t i = 0; i < targetNumPs; i++) { cindex = (i % numPs); nindex = (i + 1) % numPs; pindex = (i - 1) % numPs; - + if (i == 0) { if (bClosed) { cindex = 0; @@ -3844,26 +3838,26 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB nindex = numPs - 1; } } - + if (srcHasIndices) { // get the verts from the indices cindex = srcIndices[cindex]; nindex = srcIndices[nindex]; pindex = srcIndices[pindex]; } - + if( i == 0 ) { // just in case, lets init the cached verts to use cachedPrevVert = srcVerts[cindex]; cachedNextVert = srcVerts[cindex]; } - + // duplicate the vertices // pmIndex = i * numVertsPer; - + pvert = glm::vec4(srcVerts[pindex], 1.0f); nvert = glm::vec4(srcVerts[nindex], 1.0f); - + if( glm::all(glm::lessThan(glm::abs(srcVerts[cindex]-srcVerts[pindex]), EPSILON_VEC3 ))) { if( i != 0 || (i == 0 && bClosed )) { // loop through and find a good next vert // @@ -3883,9 +3877,9 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB } else { cachedPrevVert = srcVerts[pindex]; } - - - + + + if(glm::all(glm::lessThan(glm::abs(srcVerts[cindex]-srcVerts[nindex]), EPSILON_VEC3 )) ) { // nvert = glm::vec4(cachedNextVert, 1.f); if( i != targetNumPs - 1 || (i == targetNumPs - 1 && bClosed) ) { @@ -3906,7 +3900,7 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB } else { cachedNextVert = srcVerts[nindex]; } - + for(k = 0; k < numVertsPer; k++) { pmVerts[pmIndex + k] = srcVerts[cindex]; nextVerts[pmIndex + k] = nvert; @@ -3921,7 +3915,7 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB if (k < 2) { prevVerts[pmIndex + k].w = -1.0; } - + if (bUseColors) { pmColors[pmIndex + k] = srcColors[kindex]; } @@ -3933,39 +3927,39 @@ void ofGLProgrammableRenderer::configureLinesBundleFromMesh(LinesBundle& aLinesB // should be in relation to the top of the image pmTexCoords[pmIndex + k] = srcTexCoords[kindex]; } else { - // lets go down to the bottom of the texture + // lets go down to the bottom of the texture pmTexCoords[pmIndex + k] = glm::vec2(srcTexCoords[kindex].x, texU); } // pmTexCoords[pmIndex + k] = srcTexCoords[kindex]; } } - + newIndex = i * 2 * 6; pmIndices[newIndex + 0] = pmIndex + 0; pmIndices[newIndex + 1] = pmIndex + 2; pmIndices[newIndex + 2] = pmIndex + 1; - + pmIndices[newIndex + 3] = pmIndex + 1; pmIndices[newIndex + 4] = pmIndex + 2; pmIndices[newIndex + 5] = pmIndex + 3; - + nextIndex = (i+1); if( bClosed && i > targetNumPs -1 ) { nextIndex = 0; } - + if( nextIndex < targetNumPs) { std::size_t nextPmIndex = (nextIndex) * numVertsPer; pmIndices[newIndex + 6] = pmIndex + 2; pmIndices[newIndex + 7] = nextPmIndex + 0; pmIndices[newIndex + 8] = pmIndex + 3; - + pmIndices[newIndex + 9] = pmIndex + 3; pmIndices[newIndex + 10] = nextPmIndex + 0; pmIndices[newIndex + 11] = nextPmIndex + 1; } } - + aLinesBundle.setMeshDataToVbo(); } } diff --git a/libs/openFrameworks/gl/ofGLUtils.h b/libs/openFrameworks/gl/ofGLUtils.h index f777a7a32e3..45e2039b586 100644 --- a/libs/openFrameworks/gl/ofGLUtils.h +++ b/libs/openFrameworks/gl/ofGLUtils.h @@ -178,7 +178,7 @@ void ofDisableGLDebugLog(); #define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT32_OES #endif #endif - + #ifndef GL_RGBA32F #ifdef GL_RGBA32F_EXT #define GL_RGBA32F GL_RGBA32F_EXT diff --git a/libs/openFrameworks/gl/ofShader.cpp b/libs/openFrameworks/gl/ofShader.cpp index 9fc24210f4d..f3fdea5b238 100644 --- a/libs/openFrameworks/gl/ofShader.cpp +++ b/libs/openFrameworks/gl/ofShader.cpp @@ -213,7 +213,7 @@ bool ofShader::load(const of::filesystem::path & vertName, const of::filesystem: return linkProgram(); } -#if !defined(TARGET_OPENGLES) && defined(glDispatchCompute) +#if (!defined(TARGET_OPENGLES) && defined(glDispatchCompute)) || defined(GL_ES_VERSION_3_1) //-------------------------------------------------------------- bool ofShader::loadCompute(const of::filesystem::path & shaderName) { return setupShaderFromFile(GL_COMPUTE_SHADER, shaderName) && linkProgram(); @@ -851,7 +851,7 @@ void ofShader::end() const { ofGetGLRenderer()->unbind(*this); } -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) //-------------------------------------------------------------- void ofShader::beginTransformFeedback(GLenum mode) const { begin(); @@ -923,7 +923,7 @@ void ofShader::endTransformFeedback(const std::vector shaderFiles; std::unordered_map shaderSources; @@ -119,7 +119,7 @@ class ofShader { #endif bool setup(const ofShaderSettings & settings); -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) bool setup(const TransformFeedbackSettings & settings); #endif @@ -138,7 +138,8 @@ class ofShader { void begin() const; void end() const; -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) void beginTransformFeedback(GLenum mode) const; void beginTransformFeedback(GLenum mode, const TransformFeedbackRangeBinding & binding) const; void beginTransformFeedback(GLenum mode, const std::vector & binding) const; @@ -151,7 +152,7 @@ class ofShader { void endTransformFeedback(const std::vector & binding) const; #endif -#if !defined(TARGET_OPENGLES) && defined(glDispatchCompute) +#if (!defined(TARGET_OPENGLES) && defined(glDispatchCompute)) || defined(GL_ES_VERSION_3_1) void dispatchCompute(GLuint x, GLuint y, GLuint z) const; #endif @@ -200,11 +201,11 @@ class ofShader { // set attributes that vary per vertex (look up the location before glBegin) GLint getAttributeLocation(const std::string & name) const; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) #ifdef GLEW_ARB_uniform_buffer_object GLint getUniformBlockIndex(const std::string & name) const; GLint getUniformBlockBinding(const std::string & name) const; - void bindUniformBlock(GLuint bindind, const std::string & name) const; + void bindUniformBlock(GLuint binding, const std::string & name) const; void printActiveUniformBlocks() const; #endif #endif diff --git a/libs/openFrameworks/gl/ofTexture.cpp b/libs/openFrameworks/gl/ofTexture.cpp index 0c526bb7ab3..24288ce6c84 100644 --- a/libs/openFrameworks/gl/ofTexture.cpp +++ b/libs/openFrameworks/gl/ofTexture.cpp @@ -839,7 +839,7 @@ void ofTexture::unbind(int textureLocation) const{ ofGetGLRenderer()->unbind(*this,textureLocation); } -#if !defined(TARGET_OPENGLES) && defined(glBindImageTexture) +#if (!defined(TARGET_OPENGLES) && defined(glBindImageTexture)) || defined(GL_ES_VERSION_3_1) //---------------------------------------------------------- void ofTexture::bindAsImage(GLuint unit, GLenum access, GLint level, GLboolean layered, GLint layer){ glBindImageTexture(unit,texData.textureID,level,layered,layer,access,texData.glInternalFormat); diff --git a/libs/openFrameworks/gl/ofTexture.h b/libs/openFrameworks/gl/ofTexture.h index e0ec974ce7e..6ef58b0ebd1 100644 --- a/libs/openFrameworks/gl/ofTexture.h +++ b/libs/openFrameworks/gl/ofTexture.h @@ -725,7 +725,9 @@ class ofTexture : public ofBaseDraws { /// void unbind(int textureLocation=0) const; -#if !defined(TARGET_OPENGLES) && defined(glBindImageTexture) + // note: defined(someMethod) doesn't actually always work + // there is no reliable way to check for a function being defined just with the preprocessor +#if (!defined(TARGET_OPENGLES) && defined(glBindImageTexture)) || defined(GL_ES_VERSION_3_1) /// Calls glBindImageTexture on the texture /// /// Binds the texture as an read or write image, only available since OpenGL 4.2 diff --git a/libs/openFrameworks/utils/ofConstants.h b/libs/openFrameworks/utils/ofConstants.h index 83d903aaf9d..fff9bfd2938 100644 --- a/libs/openFrameworks/utils/ofConstants.h +++ b/libs/openFrameworks/utils/ofConstants.h @@ -230,6 +230,12 @@ enum ofTargetPlatform{ #include #include + #if defined(GL_ES_VERSION_3_0) + #include + #endif + #if defined(GL_ES_VERSION_3_1) + #include "GLES3/gl31.h" + #endif #include #include @@ -280,13 +286,19 @@ enum ofTargetPlatform{ #ifdef TARGET_ANDROID #include + #include #include #define GL_GLEXT_PROTOTYPES #include - + #if defined(GL_ES_VERSION_3_0) + #include "GLES3/gl3.h" + #include "GLES3/gl31.h" // only works on Android-21+ + #include "GLES3/gl3ext.h" + #endif + #ifndef __gl3_h_ #include #include - + #endif #define TARGET_LITTLE_ENDIAN #endif @@ -294,14 +306,17 @@ enum ofTargetPlatform{ #define GL_GLEXT_PROTOTYPES #include #include + #if defined(GL_ES_VERSION_3_0) + #include + #endif + #if defined(GL_ES_VERSION_3_1) + #include "GLES3/gl31.h" + #endif #include #include - #include #include - #include "EGL/egl.h" #include "EGL/eglext.h" - #define TARGET_LITTLE_ENDIAN #endif From 0ca6b92d9f63668b07832d91cdd8f2b9e45b3d86 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Sun, 6 Sep 2015 23:26:29 +0200 Subject: [PATCH 02/38] Android Studio 1.3/1.4 compatibility, and a fix. --- libs/openFrameworks/utils/ofConstants.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libs/openFrameworks/utils/ofConstants.h b/libs/openFrameworks/utils/ofConstants.h index fff9bfd2938..00dfb6e4381 100644 --- a/libs/openFrameworks/utils/ofConstants.h +++ b/libs/openFrameworks/utils/ofConstants.h @@ -290,10 +290,12 @@ enum ofTargetPlatform{ #include #define GL_GLEXT_PROTOTYPES #include - #if defined(GL_ES_VERSION_3_0) - #include "GLES3/gl3.h" - #include "GLES3/gl31.h" // only works on Android-21+ - #include "GLES3/gl3ext.h" + #if __ANDROID_API__ >= 21 + #if defined(GL_ES_VERSION_3_0) + #include "GLES3/gl3.h" + #include "GLES3/gl31.h" // only works on Android-21+ + #include "GLES3/gl3ext.h" + #endif #endif #ifndef __gl3_h_ #include From 5387cabaee1efe8c783bfb7421dcbcadc0fe0ef2 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Tue, 8 Sep 2015 22:22:57 +0200 Subject: [PATCH 03/38] Get an OpenGL ES 3.1 context if possible. --- .../cc/openframeworks/OFAndroidWindow.java | 321 ++++++++++ addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 40 +- libs/openFrameworks/app/ofAppRunner.cpp | 14 +- libs/openFrameworks/app/ofWindowSettings.h | 31 +- .../gl/ofGLProgrammableRenderer.cpp | 60 +- libs/openFrameworks/gl/ofGLRenderer.cpp | 3 + libs/openFrameworks/gl/ofGLUtils.cpp | 23 +- libs/openFrameworks/gl/ofMaterial.cpp | 332 +++++----- libs/openFrameworks/gl/ofTexture.cpp | 6 +- libs/openFrameworks/graphics/ofGraphics.cpp | 14 +- libs/openFrameworks/utils/ofConstants.h | 2 +- .../project/android/config.android.default.mk | 605 ++++++++++++++++++ 12 files changed, 1207 insertions(+), 244 deletions(-) create mode 100644 addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java create mode 100644 libs/openFrameworksCompiled/project/android/config.android.default.mk diff --git a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java new file mode 100644 index 00000000000..2f891d1f5f9 --- /dev/null +++ b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java @@ -0,0 +1,321 @@ +package cc.openframeworks; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL; +import javax.microedition.khronos.opengles.GL10; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.SurfaceHolder; + +class OFEGLConfigChooser implements GLSurfaceView.EGLConfigChooser { + + public OFEGLConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + mRedSize = r; + mGreenSize = g; + mBlueSize = b; + mAlphaSize = a; + mDepthSize = depth; + mStencilSize = stencil; + mGLESVersion = 0; + } + + public static void setGLESVersion(int version){ + if(version==1) EGL_OPENGL_ES_BIT=1; + else EGL_OPENGL_ES_BIT=4; // == EGL_OPENGL_ES2_BIT + mGLESVersion = version; + } + + public static int getGLESVersion(){ + if(mGLESVersion == 0) + throw new IllegalStateException("You need to set the GLES version!"); + return mGLESVersion; + } + + /* This EGL config specification is used to specify 1.x rendering. + * We use a minimum size of 4 bits for red/green/blue, but will + * perform actual matching in chooseConfig() below. + */ + private static boolean DEBUG = false; + private static int EGL_OPENGL_ES_BIT = 1; + private static int[] s_configAttribs2 = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL10.EGL_NONE + }; + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + + /* Get the number of minimally matching EGL configurations + */ + int[] num_config = new int[1]; + egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); + + int numConfigs = num_config[0]; + + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + + /* Allocate then read the array of minimally matching EGL configs + */ + EGLConfig[] configs = new EGLConfig[numConfigs]; + egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); + + if (DEBUG) { + printConfigs(egl, display, configs); + } + /* Now return the "best" one + */ + return chooseConfig(egl, display, configs); + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + for(EGLConfig config : configs) { + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + + // We need at least mDepthSize and mStencilSize bits + if (d < mDepthSize || s < mStencilSize) + continue; + + // We want an *exact* match for red/green/blue/alpha + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + + if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) + return config; + } + return null; + } + + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) { + + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { + return mValue[0]; + } + return defaultValue; + } + + private void printConfigs(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + int numConfigs = configs.length; + Log.w("OF", String.format("%d configurations", numConfigs)); + for (int i = 0; i < numConfigs; i++) { + Log.w("OF", String.format("Configuration %d:\n", i)); + printConfig(egl, display, configs[i]); + } + } + + private void printConfig(EGL10 egl, EGLDisplay display, + EGLConfig config) { + int[] attributes = { + EGL10.EGL_BUFFER_SIZE, + EGL10.EGL_ALPHA_SIZE, + EGL10.EGL_BLUE_SIZE, + EGL10.EGL_GREEN_SIZE, + EGL10.EGL_RED_SIZE, + EGL10.EGL_DEPTH_SIZE, + EGL10.EGL_STENCIL_SIZE, + EGL10.EGL_CONFIG_CAVEAT, + EGL10.EGL_CONFIG_ID, + EGL10.EGL_LEVEL, + EGL10.EGL_MAX_PBUFFER_HEIGHT, + EGL10.EGL_MAX_PBUFFER_PIXELS, + EGL10.EGL_MAX_PBUFFER_WIDTH, + EGL10.EGL_NATIVE_RENDERABLE, + EGL10.EGL_NATIVE_VISUAL_ID, + EGL10.EGL_NATIVE_VISUAL_TYPE, + 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, + EGL10.EGL_SAMPLES, + EGL10.EGL_SAMPLE_BUFFERS, + EGL10.EGL_SURFACE_TYPE, + EGL10.EGL_TRANSPARENT_TYPE, + EGL10.EGL_TRANSPARENT_RED_VALUE, + EGL10.EGL_TRANSPARENT_GREEN_VALUE, + EGL10.EGL_TRANSPARENT_BLUE_VALUE, + 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, + 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, + 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, + 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, + EGL10.EGL_LUMINANCE_SIZE, + EGL10.EGL_ALPHA_MASK_SIZE, + EGL10.EGL_COLOR_BUFFER_TYPE, + EGL10.EGL_RENDERABLE_TYPE, + 0x3042 // EGL10.EGL_CONFORMANT + }; + String[] names = { + "EGL_BUFFER_SIZE", + "EGL_ALPHA_SIZE", + "EGL_BLUE_SIZE", + "EGL_GREEN_SIZE", + "EGL_RED_SIZE", + "EGL_DEPTH_SIZE", + "EGL_STENCIL_SIZE", + "EGL_CONFIG_CAVEAT", + "EGL_CONFIG_ID", + "EGL_LEVEL", + "EGL_MAX_PBUFFER_HEIGHT", + "EGL_MAX_PBUFFER_PIXELS", + "EGL_MAX_PBUFFER_WIDTH", + "EGL_NATIVE_RENDERABLE", + "EGL_NATIVE_VISUAL_ID", + "EGL_NATIVE_VISUAL_TYPE", + "EGL_PRESERVED_RESOURCES", + "EGL_SAMPLES", + "EGL_SAMPLE_BUFFERS", + "EGL_SURFACE_TYPE", + "EGL_TRANSPARENT_TYPE", + "EGL_TRANSPARENT_RED_VALUE", + "EGL_TRANSPARENT_GREEN_VALUE", + "EGL_TRANSPARENT_BLUE_VALUE", + "EGL_BIND_TO_TEXTURE_RGB", + "EGL_BIND_TO_TEXTURE_RGBA", + "EGL_MIN_SWAP_INTERVAL", + "EGL_MAX_SWAP_INTERVAL", + "EGL_LUMINANCE_SIZE", + "EGL_ALPHA_MASK_SIZE", + "EGL_COLOR_BUFFER_TYPE", + "EGL_RENDERABLE_TYPE", + "EGL_CONFORMANT" + }; + int[] value = new int[1]; + for (int i = 0; i < attributes.length; i++) { + int attribute = attributes[i]; + String name = names[i]; + if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { + Log.w("OF", String.format(" %s: %d\n", name, value[0])); + } else { + // Log.w(TAG, String.format(" %s: failed\n", name)); + while (egl.eglGetError() != EGL10.EGL_SUCCESS); + } + } + } + + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + protected static int mGLESVersion; + private int[] mValue = new int[1]; +} + +class OFGLSurfaceView extends GLSurfaceView{ + public OFGLSurfaceView(Context context) { + super(context); + mRenderer = new OFAndroidWindow(getWidth(),getHeight()); + setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersion()); + getHolder().setFormat( PixelFormat.OPAQUE ); + OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); + setEGLConfigChooser(configChooser); + setRenderer(mRenderer); + } + + public OFGLSurfaceView(Context context,AttributeSet attributes) { + super(context,attributes); + mRenderer = new OFAndroidWindow(getWidth(),getHeight()); + setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersion()); + getHolder().setFormat( PixelFormat.OPAQUE ); + OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); + setEGLConfigChooser(configChooser); + setRenderer(mRenderer); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + super.surfaceDestroyed(holder); + OFAndroid.onSurfaceDestroyed(); + } + + boolean isSetup(){ + return mRenderer.isSetup(); + } + + private OFAndroidWindow mRenderer; +} + +class OFAndroidWindow implements GLSurfaceView.Renderer { + + public OFAndroidWindow(int w, int h){ + this.w = w; + this.h = h; + } + + @Override + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + Log.i("OF","onSurfaceCreated"); + OFAndroid.onSurfaceCreated(); + try{ + ((OFActivity)OFAndroid.getContext()).onGLSurfaceCreated(); + }catch(Exception e){ + Log.e("OF","couldn call onGLSurfaceCreated",e); + } + return; + + } + + @Override + public void onSurfaceChanged(GL10 gl, int w, int h) { + this.w = w; + this.h = h; + if(!setup && OFAndroid.unpackingDone){ + setup(); + } + OFGestureListener.swipe_Min_Distance = (int)(Math.max(w, h)*.04); + OFGestureListener.swipe_Max_Distance = (int)(Math.max(w, h)*.6); + OFAndroid.resize(w, h); + } + + private void setup(){ + OFAndroid.setup(w,h); + setup = true; + android.os.Process.setThreadPriority(8); + OFGestureListener.swipe_Min_Distance = (int)(Math.max(w, h)*.04); + OFGestureListener.swipe_Max_Distance = (int)(Math.max(w, h)*.6); + try{ + ((OFActivity)OFAndroid.getContext()).onGLSurfaceCreated(); + }catch(Exception e){ + Log.e("OF","couldn call onGLSurfaceCreated",e); + } + } + + @Override + public void onDrawFrame(GL10 gl) { + if(setup && OFAndroid.unpackingDone){ + OFAndroid.render(); + }else if(!setup && OFAndroid.unpackingDone){ + setup(); + }else{ + gl.glClear(GL10.GL_COLOR_BUFFER_BIT); + gl.glClearColor(.5f, .5f, .5f, 1.f); + } + } + + public boolean isSetup(){ + return setup; + } + + private static boolean setup; + private int w,h; +} diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index 72e47e93fa1..a20ad981efa 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -54,6 +54,8 @@ static bool accumulateAxisEvents = false; static bool multiWindowMode = false; AAssetManager* assetManager; +static int sGLESVersionMajor = 2; +static int sGLESVersionMinor = 0; void ofExitCallback(); @@ -122,7 +124,21 @@ ofAppAndroidWindow::ofAppAndroidWindow() { window = this; msaaSamples = 1; glesVersion = 2; - +#ifdef TARGET_PROGRAMMABLE_GL + :currentRenderer(new ofGLProgrammableRenderer(this)) { + #ifdef GL_ES_VERSION_3_0 + sGLESVersionMajor = 3; + #ifdef GL_ES_VERSION_3_1 + sGLESVersionMinor = 1; + #endif + #else + sGLESVersionMajor = 2; + #endif +#else + :currentRenderer(new ofGLRenderer(this)) { + sGLESVersionMajor = 1; +#endif + window = this; ofGetMainLoop()->setCurrentWindow(this); } @@ -164,17 +180,22 @@ ofAppAndroidWindow::~ofAppAndroidWindow() { // TODO Auto-generated destructor stub } +<<<<<<< HEAD bool ofAppAndroidWindow::isSurfaceDestroyed() { return surfaceDestroyed; } void ofAppAndroidWindow::setup(const ofGLESWindowSettings & settings) { + sGLESVersionMajor = settings.glesVersionMajor(); + sGLESVersionMinor = settings.glesVersionMinor(); setup( (const ofxAndroidWindowSettings &)settings ); } void ofAppAndroidWindow::setup(const ofxAndroidWindowSettings & settings){ + sGLESVersionMajor = settings.glesVersionMajor(); + sGLESVersionMinor = settings.glesVersionMinor(); if(window == nullptr) { ofLogError("ofAppAndroidWindow") << "Setup and Window is nullptr ! Fixing"; setCurrentWindow(); @@ -186,25 +207,18 @@ void ofAppAndroidWindow::setup(const ofxAndroidWindowSettings & settings){ }else{ currentRenderer = std::make_shared(this); } - jclass javaClass = ofGetJNIEnv()->FindClass("cc/openframeworks/OFAndroid"); - if(javaClass==nullptr){ ofLogError("ofAppAndroidWindow") << "setupOpenGL(): couldn't find OFAndroid java class"; return; } - makeCurrent(); - jmethodID method = ofGetJNIEnv()->GetStaticMethodID(javaClass,"setupGL","(IZ)V"); if(!method){ ofLogError("ofAppAndroidWindow") << "setupOpenGL(): couldn't find OFAndroid setupGL method"; return; } - ofGetJNIEnv()->CallStaticVoidMethod(javaClass,method,glesVersion,settings.preserveContextOnPause); - - } void ofAppAndroidWindow::update(){ @@ -465,7 +479,7 @@ Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ else { ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0"; - dynamic_cast(window->renderer().get())->setup(glesVersion,0); + dynamic_cast(window->renderer().get())->setup(glesVersion,sGLESVersionMinor); } }else{ @@ -478,7 +492,7 @@ Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ } else { ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0"; dynamic_cast(window->renderer().get())->setup( - glesVersion, 0); + glesVersion, sGLESVersionMinor); } } } @@ -554,25 +568,19 @@ Java_cc_openframeworks_OFAndroid_setAssetManager(JNIEnv *env, jclass thiz, jobject jAssetManager) { env->NewGlobalRef(jAssetManager); - AAssetManager *aaAssetManager = AAssetManager_fromJava(env, jAssetManager); if (aaAssetManager == nullptr) { ofLogError("ofAppAndroidWindow") << "Could not obtain the AAssetManager"; return; } - assetManager = aaAssetManager; if(window == nullptr || (window != nullptr && window->renderer() == nullptr)) { ofLogVerbose("ofAppAndroidWindow") << "setAssetManager window is null"; return; } - window->setAssetManager(assetManager); - - - } /* Call to render the next GL frame */ diff --git a/libs/openFrameworks/app/ofAppRunner.cpp b/libs/openFrameworks/app/ofAppRunner.cpp index df84e27ffbb..ed2f10a396a 100644 --- a/libs/openFrameworks/app/ofAppRunner.cpp +++ b/libs/openFrameworks/app/ofAppRunner.cpp @@ -206,7 +206,19 @@ int ofRunMainLoop(){ void ofSetupOpenGL(int w, int h, ofWindowMode screenMode){ #ifdef TARGET_OPENGLES ofGLESWindowSettings settings; - settings.glesVersion = 1; + #ifdef GL_ES_VERSION_3_0 + #ifdef GL_ES_VERSION_3_1 + settings.setGLESVersion(3,1); + #else + settings.setGLESVersion(3,0); + #endif + #else + #ifdef GL_ES_VERSION_2_0 + settings.setGLESVersion(2); + #else + settings.setGLESVersion(1); + #endif + #endif #else ofGLWindowSettings settings; settings.glVersionMajor = 2; diff --git a/libs/openFrameworks/app/ofWindowSettings.h b/libs/openFrameworks/app/ofWindowSettings.h index 9d13d24de05..8cf9ccb1193 100644 --- a/libs/openFrameworks/app/ofWindowSettings.h +++ b/libs/openFrameworks/app/ofWindowSettings.h @@ -125,22 +125,29 @@ class ofGLWindowSettings: public ofWindowSettings{ class ofGLESWindowSettings: public ofWindowSettings{ public: - ofGLESWindowSettings() - :glesVersion(1){} - - ofGLESWindowSettings(const ofWindowSettings & settings) - :ofWindowSettings(settings), glesVersion(1) { + ofGLESWindowSettings() + :mGlesVersionMajor(1), mGlesVersionMinor(0){} + + ofGLESWindowSettings(const ofWindowSettings & settings) + :ofWindowSettings(settings), mGlesVersionMajor(1), mGlesVersionMinor(0) { const ofGLESWindowSettings * glesSettings = dynamic_cast(&settings); if(glesSettings){ - glesVersion = glesSettings->glesVersion; + mGlesVersionMajor = glesSettings->mGlesVersionMajor; + mGlesVersionMinor = glesSettings->mGlesVersionMinor; } } + + virtual ~ofGLESWindowSettings(){}; + + void setGLESVersion(int versionMajor, int versionMinor = 0){ + mGlesVersionMajor = versionMajor; + mGlesVersionMinor = versionMinor; + } - virtual ~ofGLESWindowSettings(){}; - - void setGLESVersion(int version){ - glesVersion = version; - } + int glesVersionMajor() const { return mGlesVersionMajor; } + int glesVersionMinor() const { return mGlesVersionMinor ; } - int glesVersion; +private: + int mGlesVersionMajor; + int mGlesVersionMinor; }; diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index ddcff4797ba..5d8d6fa3569 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -2250,21 +2250,51 @@ void ofGLProgrammableRenderer::drawString(const ofTrueTypeFont & font, string te // http://www.opengl.org/registry/doc/GLSLangSpec.1.50.09.pdf #ifdef TARGET_OPENGLES -static const string vertex_shader_header = - "%extensions%\n" - "precision highp float;\n" - "#define IN attribute\n" - "#define OUT varying\n" - "#define TEXTURE texture2D\n" - "#define TARGET_OPENGLES\n"; -static const string fragment_shader_header = - "%extensions%\n" - "precision highp float;\n" - "#define IN varying\n" - "#define OUT\n" - "#define TEXTURE texture2D\n" - "#define FRAG_COLOR gl_FragColor\n" - "#define TARGET_OPENGLES\n"; + #if defined(GL_ES_VERSION_3_0) + static const string vertex_shader_header = + "#version %glsl_version% es\n" + "precision highp float;\n" + "#define IN in\n" + "#define OUT out\n" + "#define TEXTURE texture\n" + "#define TARGET_OPENGLES\n"; + + static const string fragment_shader_header = + "#version %glsl_version% es\n" + "precision highp float;\n" + "#define IN in\n" + "#define OUT out\n" + "#define TEXTURE texture\n" + "#define FRAG_COLOR outputColor\n" + "#define TARGET_OPENGLES\n" + "out vec4 outputColor;\n"; + #else + // OpenGL ES 2.0 / GLSL ES 1.00 + static const string vertex_shader_header = + "#version %glsl_version%\n" + "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" + "precision highp float;\n" + "#else\n" + "precision mediump float;\n" + "#endif\n" + "#define IN attribute\n" + "#define OUT varying\n" + "#define TEXTURE texture2D\n" + "#define TARGET_OPENGLES\n"; + + static const string fragment_shader_header = + "#version %glsl_version%\n" + "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" + "precision highp float;\n" + "#else\n" + "precision mediump float;\n" + "#endif\n" + "#define IN varying\n" + "#define OUT\n" + "#define TEXTURE texture2D\n" + "#define FRAG_COLOR gl_FragColor\n" + "#define TARGET_OPENGLES\n"; + #endif #else static const string vertex_shader_header = "#version %glsl_version%\n" diff --git a/libs/openFrameworks/gl/ofGLRenderer.cpp b/libs/openFrameworks/gl/ofGLRenderer.cpp index 293ce51ac66..b913e515c5f 100644 --- a/libs/openFrameworks/gl/ofGLRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLRenderer.cpp @@ -20,6 +20,7 @@ using std::vector; const std::string ofGLRenderer::TYPE = "GL"; +#if !defined(TARGET_OPENGLES) || !defined(TARGET_PROGRAMMABLE_GL) //---------------------------------------------------------- ofGLRenderer::ofGLRenderer(const ofAppBaseWindow * _window) : matrixStack(_window) @@ -2027,3 +2028,5 @@ const of3dGraphics & ofGLRenderer::get3dGraphics() const { of3dGraphics & ofGLRenderer::get3dGraphics() { return graphics3d; } + +#endif diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 87ae5219443..24bfecb8561 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -844,21 +844,22 @@ bool ofGLSupportsNPOTTextures(){ string ofGLSLVersionFromGL(int major, int minor){ #ifdef TARGET_OPENGLES + #ifdef TARGET_EMSCRIPTEN - if( major >= 2 ) { // for emscripten major version refers to WEBGL version - return "300 es"; - } else { - return "ES1"; - } + if(major >= 2) { // for emscripten major version refers to WEBGL version + return "300"; // WebGL2 = GLSL ES 3.00 (header adds " es") + } else { + return "100"; + } #else if(major == 1){ return "ES1"; }else if(major == 2){ - return "ES2"; + return "100"; }else if(major == 3){ - return "ES3"; + return "300"; }else { - return "ES1"; + return ofToString(major*100+minor*10); } #endif #else @@ -884,7 +885,7 @@ string ofGLSLVersionFromGL(int major, int minor){ string ofGLSLVersionFromGL(){ int major = 0; int minor = 0; - + auto glRenderer = std::dynamic_pointer_cast(ofGetCurrentRenderer()); if( glRenderer ){ major = glRenderer->getGLVersionMajor(); @@ -898,11 +899,11 @@ string ofGLSLGetDefaultHeader(){ string header = ""; auto glRenderer = std::dynamic_pointer_cast(ofGetCurrentRenderer()); - + if( glRenderer ){ string versionStr = ofGLSLVersionFromGL(glRenderer->getGLVersionMajor(), glRenderer->getGLVersionMinor()); header = "#version "+versionStr+"\n"; - + #ifdef TARGET_OPENGLES if( versionStr != "ES1" ){ header += "#extension GL_OES_standard_derivatives : enable\n"; diff --git a/libs/openFrameworks/gl/ofMaterial.cpp b/libs/openFrameworks/gl/ofMaterial.cpp index 27c5a53e54d..6a516eb772f 100644 --- a/libs/openFrameworks/gl/ofMaterial.cpp +++ b/libs/openFrameworks/gl/ofMaterial.cpp @@ -113,7 +113,7 @@ bool ofMaterial::isPBRSupported() { #if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) return false; #endif - + if( !ofIsGLProgrammableRenderer() ) { return false; } @@ -130,7 +130,7 @@ void ofMaterial::setPBR(bool ab) { data.isPbr = false; return; } - + #if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) if( ab ) { if( !bPrintedPBRRenderWarning ) { @@ -141,8 +141,8 @@ void ofMaterial::setPBR(bool ab) { return; } #endif - - + + data.isPbr = ab; } @@ -156,8 +156,8 @@ void ofMaterial::setColors(ofFloatColor oDiffuse, ofFloatColor oAmbient, ofFloat //---------------------------------------------------------- void ofMaterial::setup(const ofMaterialSettings & settings){ - if(settings.customUniforms != data.customUniforms || settings.postFragment != data.postFragment || - settings.mainVertexKey != data.mainVertexKey || settings.mainFragmentKey != data.mainFragmentKey || + if(settings.customUniforms != data.customUniforms || settings.postFragment != data.postFragment || + settings.mainVertexKey != data.mainVertexKey || settings.mainFragmentKey != data.mainFragmentKey || settings.isPbr != data.isPbr){ shaders.clear(); uniforms1f.clear(); @@ -182,9 +182,9 @@ void ofMaterial::setShaderMain(std::string aShaderSrc, GLenum atype, std::string ofLogWarning("ofMaterial::setShaderMain") << "only available on PBR materials."; return; } - + if(atype == GL_VERTEX_SHADER) { - // we would like to replace the current shader at key + // we would like to replace the current shader at key // using a skey instead of shadersrc as key so we can easily overwrite if( data.mainVertexKey == skey) { // delete previous shader here, whether frag shader has same key or not @@ -288,13 +288,13 @@ bool ofMaterial::loadTexture( const ofMaterialTextureType& aMaterialTextureType, //---------------------------------------------------------- bool ofMaterial::loadTexture( const ofMaterialTextureType& aMaterialTextureType, std::string apath, bool bTex2d, bool mirrorY ) { - + bool bWasUsingArb = ofGetUsingArbTex(); bTex2d ? ofDisableArbTex() : ofEnableArbTex(); - + auto tex { std::make_shared() }; bool bLoadOk = ofLoadImage(*tex, apath, mirrorY ); - + if( bLoadOk ) { // if there was a previous instance, then erase it, then replace it if( mLocalTextures.find(aMaterialTextureType) != mLocalTextures.end() ) { @@ -308,7 +308,7 @@ bool ofMaterial::loadTexture( const ofMaterialTextureType& aMaterialTextureType, } else { ofLogError("ofMaterial") << "loadTexture(): FAILED for " << getUniformName(aMaterialTextureType) << " at path: " << apath; } - + bWasUsingArb ? ofEnableArbTex() : ofDisableArbTex(); return bLoadOk; } @@ -348,8 +348,8 @@ void ofMaterial::setTexture(const ofMaterialTextureType& aMaterialTextureType,co setPBR(true); } } - - + + if(aMaterialTextureType == OF_MATERIAL_TEXTURE_CLEARCOAT || aMaterialTextureType == OF_MATERIAL_TEXTURE_CLEARCOAT_ROUGHNESS || @@ -439,7 +439,7 @@ void ofMaterial::setClearCoatTexture( const ofTexture& aTex ) { //---------------------------------------------------- void ofMaterial::setMetallic( const float& ametallic ) { data.metallic = ametallic; - + if( isBound() && isPBR() && currentRenderShader) { currentRenderShader->setUniform1f("mat_metallic", data.metallic ); } @@ -649,12 +649,12 @@ void ofMaterial::mergeCustomUniformTextures() { OF_MATERIAL_TEXTURE_ROUGHNESS, OF_MATERIAL_TEXTURE_METALLIC } ); - + mergeCustomUniformTextures(OF_MATERIAL_TEXTURE_ROUGHNESS_METALLIC, { OF_MATERIAL_TEXTURE_OCCLUSION, OF_MATERIAL_TEXTURE_ROUGHNESS_METALLIC } ); - + mergeCustomUniformTextures(OF_MATERIAL_TEXTURE_AO_ROUGHNESS_METALLIC, { OF_MATERIAL_TEXTURE_OCCLUSION, OF_MATERIAL_TEXTURE_ROUGHNESS, @@ -671,7 +671,7 @@ void ofMaterial::mergeCustomUniformTextures(ofMaterialTextureType mainType, std: int texTarget; bool bMatchingTextures = true; int minTexLocation = 99999; - + for(size_t i = 0; i < mtsSize; i++ ) { if(!hasTexture(mergeTypes[i])){ bHasAllMergeTypes = false; @@ -693,7 +693,7 @@ void ofMaterial::mergeCustomUniformTextures(ofMaterialTextureType mainType, std: } } } - + if(bHasAllMergeTypes && bMatchingTextures && minTexLocation < 1000){ for(size_t i = 0; i < mtsSize; i++ ) { removeCustomUniformTexture(mergeTypes[i]); @@ -757,9 +757,9 @@ void ofMaterial::initDepthShaders(ofGLProgrammableRenderer & renderer) const { depthShadersMap[&renderer].erase(sids.first); } } - + ofLogVerbose("ofMaterial :: initShaders : depth shaders: " ) << depthShadersMap.size() << " | " << ofGetFrameNum(); - + auto trendererShaders = mDepthShaders.find(&renderer); if( trendererShaders != mDepthShaders.end() ) { if(trendererShaders->second) { @@ -770,12 +770,12 @@ void ofMaterial::initDepthShaders(ofGLProgrammableRenderer & renderer) const { mDepthShaderIdsToRemove.clear(); } } - + // now lets check the depth shaders if( getDepthShaderStringId() != "" ) { auto depthShaders = mDepthShaders.find(&renderer); const std::string shaderId = getDepthShaderStringId(); - + if(depthShaders == mDepthShaders.end() || depthShaders->second->shaderId != shaderId ){ if(depthShadersMap[&renderer].find(shaderId) != depthShadersMap[&renderer].end()){ @@ -791,17 +791,17 @@ void ofMaterial::initDepthShaders(ofGLProgrammableRenderer & renderer) const { mDepthShaders[&renderer] = nullptr; } } - + if(mDepthShaders[&renderer] == nullptr){ ofLogVerbose("ofMaterial") << "initDepthShaders : allocating depth shaders | " << ofGetFrameNum(); - + mDepthShaders[&renderer].reset(new DepthShaders); mDepthShaders[&renderer]->shaderId = shaderId; - + depthShadersMap[&renderer][shaderId] = mDepthShaders[&renderer]; } } - + } //----------------------------------------------------------- @@ -810,28 +810,28 @@ const ofShader& ofMaterial::getShadowDepthShader( const ofShadow& ashadow, ofGLP // std::string shadowId = ofToString(ashadow.getData()->lightType, 0)+"_"+ofToString(ashadow.getNumShadowDepthPasses(), 0); unsigned int shadowShaderId = ashadow.getData()->lightType + ((ashadow.getNumShadowDepthPasses()+1)*100); auto shadowShader = mDepthShaders[&renderer]->shaders.find(shadowShaderId); - + if(shadowShader == mDepthShaders[&renderer]->shaders.end() || !mDepthShaders[&renderer]->shaders[shadowShaderId] ) { auto nDepthShader { std::make_shared() }; - + auto customUniforms = data.customUniforms; for( auto & custom : mCustomUniforms ){ customUniforms += custom.second + " " + custom.first + ";\n"; } - + std::string definesString = getDefinesString(); definesString += "#define SAMPLER sampler2D\n"; definesString += "#define TEXTURE texture\n"; std::string extraVertString = definesString; extraVertString += customUniforms; - + std::string srcMain = extraVertString+shaderDepthVertexSource(data); ofLogVerbose("--ofMaterial::getShadowDepthShader--"); if(!ashadow.setupShadowDepthShader( *nDepthShader, srcMain )) { ofLogError("ofMaterial :: getShadowDepthShader() : error loading depth shader: ") << data.mainDepthVertexKey; } ofLogVerbose(nDepthShader->getShaderSource(GL_VERTEX_SHADER)); - + mDepthShaders[&renderer]->shaders[shadowShaderId] = nDepthShader; } return *mDepthShaders[&renderer]->shaders[shadowShaderId]; @@ -839,139 +839,111 @@ const ofShader& ofMaterial::getShadowDepthShader( const ofShadow& ashadow, ofGLP //----------------------------------------------------------- void ofMaterial::initShaders(ofGLProgrammableRenderer & renderer) const{ - // remove any shaders that have their main source remove - { - if( mShaderIdsToRemove.size() ) { - for( auto& sids : mShaderIdsToRemove ) { - if(shadersMap[&renderer].find(sids.first)!=shadersMap[&renderer].end()){ - auto newShaders = shadersMap[&renderer][sids.first].lock(); - if( newShaders ) { - newShaders.reset(); - } - shadersMap[&renderer].erase(sids.first); - } - } - - ofLogVerbose("ofMaterial :: initShaders") << shadersMap.size() << " | " << ofGetFrameNum(); - - auto trendererShaders = shaders.find(&renderer); - if( trendererShaders != shaders.end() ) { - if(trendererShaders->second) { - trendererShaders->second.reset(); - } - shaders.erase(&renderer); - } - mShaderIdsToRemove.clear(); - } - } - + // remove any shaders that have their main source removed + { + if( mShaderIdsToRemove.size() ) { + for( auto& sids : mShaderIdsToRemove ) { + if(shadersMap[&renderer].find(sids.first)!=shadersMap[&renderer].end()){ + auto newShaders = shadersMap[&renderer][sids.first].lock(); + if( newShaders ) { + newShaders.reset(); + } + shadersMap[&renderer].erase(sids.first); + } + } + ofLogVerbose("ofMaterial :: initShaders") << shadersMap.size() << " | " << ofGetFrameNum(); + auto trendererShaders = shaders.find(&renderer); + if( trendererShaders != shaders.end() ) { + if(trendererShaders->second) { + trendererShaders->second.reset(); + } + shaders.erase(&renderer); + } + mShaderIdsToRemove.clear(); + } + } auto rendererShaders = shaders.find(&renderer); - - size_t numLights = ofLightsData().size(); - // only support for a single cube map at a time - size_t numCubeMaps = ofCubeMap::getCubeMapsData().size() > 0 ? 1 : 0; - const std::string shaderId = getShaderStringId(); - - if(rendererShaders == shaders.end() || - rendererShaders->second->numLights != numLights || - rendererShaders->second->numCubeMaps != numCubeMaps || - rendererShaders->second->shaderId != shaderId ){ - if(shadersMap[&renderer].find(shaderId)!=shadersMap[&renderer].end()){ - auto newShaders = shadersMap[&renderer][shaderId].lock(); - if(newShaders == nullptr || newShaders->numLights != numLights || newShaders->numCubeMaps != numCubeMaps ){ - shadersMap[&renderer].erase(shaderId); - shaders[&renderer] = nullptr; - }else{ - ofLogVerbose("ofMaterial") << "initShaders : swapping shaders | " << ofGetFrameNum(); - shaders[&renderer] = newShaders; - } - } else { - shaders[&renderer] = nullptr; - } - } + size_t numLights = ofLightsData().size(); + // only support for a single cube map at a time + size_t numCubeMaps = ofCubeMap::getCubeMapsData().size() > 0 ? 1 : 0; + const std::string shaderId = getShaderStringId(); + + if(rendererShaders == shaders.end() || + rendererShaders->second->numLights != numLights || + rendererShaders->second->numCubeMaps != numCubeMaps || + rendererShaders->second->shaderId != shaderId ){ + + if(shadersMap[&renderer].find(shaderId)!=shadersMap[&renderer].end()){ + auto newShaders = shadersMap[&renderer][shaderId].lock(); + if(newShaders == nullptr || newShaders->numLights != numLights || newShaders->numCubeMaps != numCubeMaps ){ + shadersMap[&renderer].erase(shaderId); + shaders[&renderer] = nullptr; + }else{ + ofLogVerbose("ofMaterial") << "initShaders : swapping shaders | " << ofGetFrameNum(); + shaders[&renderer] = newShaders; + } + } else { + shaders[&renderer] = nullptr; + } + } if(shaders[&renderer] == nullptr){ - ofLogVerbose("ofMaterial") << "initShaders : allocating shaders again | " << ofGetFrameNum(); + ofLogVerbose("ofMaterial") << "initShaders : allocating shaders again | " << ofGetFrameNum(); + //add the custom uniforms to the shader header auto customUniforms = data.customUniforms; for( auto & custom : mCustomUniforms ){ - customUniforms += custom.second + " " + custom.first + ";\n"; + customUniforms += custom.second + " " + custom.first + ";\n"; } + std::string definesString = getDefinesString(); + + std::string extraVertString = definesString; + extraVertString += customUniforms; - std::string definesString = getDefinesString(); - - ofLogVerbose("ofMaterial") << " defines--------------- " << std::endl; - ofLogVerbose("ofMaterial") << definesString; - ofLogVerbose("ofMaterial") << "textures --------------- " << uniformstex.size(); - for (auto & uniform : uniformstex) { - ofLogVerbose() << uniform.first << ", " << uniform.second.textureTarget <<", " << uniform.second.textureID << ", " << uniform.second.textureLocation << std::endl; - } - - std::string extraVertString = definesString; -// if( hasTexture(OF_MATERIAL_TEXTURE_DISPLACEMENT) ) { -// extraVertString += "\nuniform SAMPLER "+getUniformName(OF_MATERIAL_TEXTURE_DISPLACEMENT)+";\n"; -// } - extraVertString += customUniforms; - ofLogVerbose( "ofMaterial" ) << " extraVertString------------------- "; - ofLogVerbose() << extraVertString; - ofLogVerbose( "ofMaterial" ) << "! extraVertString !------------------- " << std::endl; - #ifndef TARGET_OPENGLES string vertexRectHeader = renderer.defaultVertexShaderHeader(GL_TEXTURE_RECTANGLE); string fragmentRectHeader = renderer.defaultFragmentShaderHeader(GL_TEXTURE_RECTANGLE); #endif string vertex2DHeader = renderer.defaultVertexShaderHeader(GL_TEXTURE_2D); string fragment2DHeader = renderer.defaultFragmentShaderHeader(GL_TEXTURE_2D); - - #if defined(TARGET_OPENGLES) && defined(TARGET_EMSCRIPTEN) - // TODO: Should this be in programmable renderer? - if(ofIsGLProgrammableRenderer()) { -// if(isPBR()) { -// header = "#version 300 es\n";// + header; - vertex2DHeader = "#version "+ofGLSLVersionFromGL(renderer.getGLVersionMajor(), renderer.getGLVersionMinor())+"\n"; - vertex2DHeader += "precision highp float;\n"; - vertex2DHeader += "precision highp int;\n"; - vertex2DHeader += "#define TARGET_OPENGLES\n"; - vertex2DHeader += "#define IN in\n"; - vertex2DHeader += "#define OUT out\n"; - vertex2DHeader += "#define TEXTURE texture\n"; - vertex2DHeader += "#define SAMPLER sampler2D\n"; - - fragment2DHeader = "#version "+ofGLSLVersionFromGL(renderer.getGLVersionMajor(), renderer.getGLVersionMinor())+"\n"; - fragment2DHeader += "precision highp float;\n"; - fragment2DHeader += "precision highp int;\n"; - fragment2DHeader += "#define TARGET_OPENGLES\n"; - fragment2DHeader += "#define IN in\n"; - fragment2DHeader += "#define OUT out\n"; - fragment2DHeader += "#define TEXTURE texture\n"; - fragment2DHeader += "#define FRAG_COLOR fragColor\n"; - fragment2DHeader += "out vec4 fragColor;\n"; - fragment2DHeader += "#define SAMPLER sampler2D\n"; - fragment2DHeader += "precision highp sampler2D;\n"; - fragment2DHeader += "precision highp samplerCube;\n"; - // we don't use any samplerCubeShadows - //fragment2DHeader += "precision highp samplerCubeShadow;\n"; - fragment2DHeader += "precision mediump sampler2DShadow;\n"; - #if defined( GL_TEXTURE_2D_ARRAY ) && defined(glTexImage3D) - fragment2DHeader += "precision mediump sampler2DArrayShadow;\n"; - #endif -// fragment2DHeader += "precision highp samplerCubeShadow;\n"; -// fragment2DHeader += "precision highp sampler2DShadow;\n"; -// fragment2DHeader += "precision highp sampler2DArrayShadow;\n"; -// } - } - #endif - - ofLogVerbose( "ofMaterial" ) << " fragment2DHeader------------------- "; - ofLogVerbose() << fragment2DHeader; - ofLogVerbose( "ofMaterial" ) << " fragment2DHeader "; + +#if defined(TARGET_OPENGLES) && defined(TARGET_EMSCRIPTEN) + // TODO: Should this be in programmable renderer? + if(ofIsGLProgrammableRenderer()) { + vertex2DHeader = "#version "+ofGLSLVersionFromGL(renderer.getGLVersionMajor(), renderer.getGLVersionMinor())+"\n"; + vertex2DHeader += "precision highp float;\n"; + vertex2DHeader += "precision highp int;\n"; + vertex2DHeader += "#define TARGET_OPENGLES\n"; + vertex2DHeader += "#define IN in\n"; + vertex2DHeader += "#define OUT out\n"; + vertex2DHeader += "#define TEXTURE texture\n"; + vertex2DHeader += "#define SAMPLER sampler2D\n"; + + fragment2DHeader = "#version "+ofGLSLVersionFromGL(renderer.getGLVersionMajor(), renderer.getGLVersionMinor())+"\n"; + fragment2DHeader += "precision highp float;\n"; + fragment2DHeader += "precision highp int;\n"; + fragment2DHeader += "#define TARGET_OPENGLES\n"; + fragment2DHeader += "#define IN in\n"; + fragment2DHeader += "#define OUT out\n"; + fragment2DHeader += "#define TEXTURE texture\n"; + fragment2DHeader += "#define FRAG_COLOR fragColor\n"; + fragment2DHeader += "out vec4 fragColor;\n"; + fragment2DHeader += "#define SAMPLER sampler2D\n"; + fragment2DHeader += "precision highp sampler2D;\n"; + fragment2DHeader += "precision highp samplerCube;\n"; + fragment2DHeader += "precision mediump sampler2DShadow;\n"; +#if defined( GL_TEXTURE_2D_ARRAY ) && defined(glTexImage3D) + fragment2DHeader += "precision mediump sampler2DArrayShadow;\n"; +#endif + } +#endif shaders[&renderer].reset(new Shaders); shaders[&renderer]->numLights = numLights; - shaders[&renderer]->numCubeMaps = numCubeMaps; - shaders[&renderer]->shaderId = shaderId; - + shaders[&renderer]->numCubeMaps = numCubeMaps; + shaders[&renderer]->shaderId = shaderId; + shaders[&renderer]->noTexture.setupShaderFromSource(GL_VERTEX_SHADER,vertexSource(isPBR(),vertex2DHeader,numLights,false,false,extraVertString,data)); shaders[&renderer]->noTexture.setupShaderFromSource(GL_FRAGMENT_SHADER,fragmentSource(isPBR(),fragment2DHeader, customUniforms, data,numLights,false,false, definesString)); shaders[&renderer]->noTexture.bindDefaults(); @@ -994,7 +966,6 @@ void ofMaterial::initShaders(ofGLProgrammableRenderer & renderer) const{ shaders[&renderer]->color.bindDefaults(); shaders[&renderer]->color.linkProgram(); - shaders[&renderer]->texture2DColor.setupShaderFromSource(GL_VERTEX_SHADER,vertexSource(isPBR(),vertex2DHeader,numLights,true,true,extraVertString,data)); shaders[&renderer]->texture2DColor.setupShaderFromSource(GL_FRAGMENT_SHADER,fragmentSource(isPBR(),fragment2DHeader, customUniforms, data,numLights,true,true,definesString)); shaders[&renderer]->texture2DColor.bindDefaults(); @@ -1007,18 +978,17 @@ void ofMaterial::initShaders(ofGLProgrammableRenderer & renderer) const{ shaders[&renderer]->textureRectColor.linkProgram(); #endif - shadersMap[&renderer][shaderId] = shaders[&renderer]; + shadersMap[&renderer][shaderId] = shaders[&renderer]; } - } const ofShader & ofMaterial::getShader(int textureTarget, bool geometryHasColor, ofGLProgrammableRenderer & renderer) const{ initShaders(renderer); - + if(bHasCustomShader && customShader){ return *customShader; } - + // override the textureTarget argument coming from the programmable renderer // the renderer is passing the textureTarget based on if there is a texture that is bound // if there is no texture bound, then go ahead and switch to the diffuse texture @@ -1027,7 +997,7 @@ const ofShader & ofMaterial::getShader(int textureTarget, bool geometryHasColor, const auto& dt = uniformstex.at(loc); textureTarget = dt.textureTarget; } - + switch(textureTarget){ case OF_NO_TEXTURE: if(geometryHasColor){ @@ -1055,10 +1025,10 @@ const ofShader & ofMaterial::getShader(int textureTarget, bool geometryHasColor, void ofMaterial::updateMaterial(const ofShader & shader,ofGLProgrammableRenderer & renderer) const{ currentRenderShader = &shader; - + shader.setUniform4fv("mat_emissive", &data.emissive.r); shader.setUniform2f("mat_texcoord_scale", data.texCoordScale ); - + if( isPBR() ) { shader.setUniform3f("uCameraPos", renderer.getCurrentEyePosition()); shader.setUniform4fv("mat_diffuse", &data.diffuse.r ); @@ -1068,7 +1038,7 @@ void ofMaterial::updateMaterial(const ofShader & shader,ofGLProgrammableRenderer if( isClearCoatEnabled() ) { shader.setUniform2f("mat_clearcoat", data.clearCoatStrength, data.clearCoatRoughness ); } - + if( hasTexture(OF_MATERIAL_TEXTURE_DISPLACEMENT) ) { shader.setUniform1f("mat_displacement_strength", data.displacementStrength ); shader.setUniform1f("mat_displacement_normals_strength", data.displacementNormalsStrength ); @@ -1076,7 +1046,7 @@ void ofMaterial::updateMaterial(const ofShader & shader,ofGLProgrammableRenderer if( hasTexture(OF_MATERIAL_TEXTURE_NORMAL) || hasTexture(OF_MATERIAL_TEXTURE_DISPLACEMENT) ) { shader.setUniform1f("mat_normal_mix", data.normalGeomToNormalMapMix ); } - + auto cubeMapData = ofCubeMap::getActiveData(); if( cubeMapData ) { shader.setUniform1f("mat_ibl_exposure", cubeMapData->exposure ); @@ -1087,7 +1057,7 @@ void ofMaterial::updateMaterial(const ofShader & shader,ofGLProgrammableRenderer shader.setUniform1f("uCubeMapEnabled", 0.0f ); shader.setUniform1f("uEnvMapMaxMips", 1.0f ); } - + } else { shader.setUniform4fv("mat_ambient", &data.ambient.r); shader.setUniform4fv("mat_diffuse", &data.diffuse.r); @@ -1208,7 +1178,7 @@ void ofMaterial::updateLights(const ofShader & shader,ofGLProgrammableRenderer & direction = direction - glm::vec3(lightEyePosition); shader.setUniform3f("lights["+idx+"].spotDirection", glm::normalize(direction)); } - + auto right = light->right; auto up = light->up; if( !isPBR() ) { @@ -1300,7 +1270,7 @@ void ofMaterial::setCustomUniformTexture(const std::string & name, const ofTextu //-------------------------------------------------------- void ofMaterial::setCustomUniformTexture(const std::string & name, int textureTarget, GLint textureID){ - + int textureLocation = -1; // if the texture uniform name is not registered, then try to find a new location // if( uniformstex.count(name) < 1 ) { @@ -1330,7 +1300,7 @@ void ofMaterial::setCustomUniformTexture(const std::string & name, int textureTa } else { textureLocation = uniformstex[name].textureLocation; } - + if( textureLocation > -1 ) { setCustomUniformTexture(name, textureTarget, textureID, textureLocation); } @@ -1397,7 +1367,7 @@ void ofMaterial::addShaderDefine( const std::string & aDefineName ) { //-------------------------------------------------------- void ofMaterial::addShaderDefine( const std::string & aDefineName, const std::string & aDefineValue ) { if( aDefineName.empty() ) return; - + bool bUpdateDefines = false; if( mDefines.count(aDefineName) < 1 ) { bUpdateDefines = true; @@ -1416,16 +1386,16 @@ void ofMaterial::addShaderDefine( const std::string & aDefineName, const std::st //-------------------------------------------------------- bool ofMaterial::removeShaderDefine( const std::string & aDefineName ) { if( aDefineName.empty() ) return false; - + if(mDefines.count(aDefineName) > 0 ) { mDefines.erase(aDefineName); - + // update the unique id using uniqueIdString string // data.uniqueIdString = ""; for( auto& def : mDefines ) { data.uniqueIdString += def.first; } - + return true; } return false; @@ -1437,7 +1407,7 @@ const std::string ofMaterial::getDefinesString() const { for( auto& diter : mDefines ) { definesString += "#define "+diter.first+" "+diter.second+"\n"; } - + if( isPBR() ) { #ifdef TARGET_OPENGLES definesString += "#define PBR_QUALITY_LEVEL_LOW 1 \n"; @@ -1445,12 +1415,12 @@ const std::string ofMaterial::getDefinesString() const { definesString += "#define PBR_QUALITY_LEVEL_HIGH 1\n"; #endif } - + if(isPBR() && ofCubeMap::getCubeMapsData().size() > 0 && ofIsGLProgrammableRenderer() ) { // const auto& cubeMapData = ofCubeMap::getActiveData(); - + definesString += "#define HAS_CUBE_MAP 1\n"; - + bool bHasIrradiance = false; bool bPreFilteredMap = false; bool bBrdfLutTex = false; @@ -1467,7 +1437,7 @@ const std::string ofMaterial::getDefinesString() const { bBrdfLutTex=true; } } - + if(bHasIrradiance) { definesString += "#define HAS_TEX_ENV_IRRADIANCE 1\n"; } @@ -1479,9 +1449,9 @@ const std::string ofMaterial::getDefinesString() const { } // need to add .0 to be read as a float in the shader for gl es //definesString += "#define ENV_MAP_MAX_MIPS "+ofToString(ofCubeMap::getNumMipMaps(),0)+".0\n"; - + } - + definesString += ofShadow::getShaderDefinesAsString(); return definesString; } @@ -1506,7 +1476,7 @@ namespace{ string shaderHeader(string header, int maxLights, bool hasTexture, bool hasColor){ // header += "#define MAX_LIGHTS " + ofToString(std::max(1,maxLights)) + "\n"; header += "#define MAX_LIGHTS " + ofToString(maxLights) + "\n"; - + if(hasTexture){ header += "#define HAS_TEXTURE 1\n"; } else { @@ -1517,7 +1487,7 @@ namespace{ } else { header += "#define HAS_COLOR 0\n"; } - + return header; } @@ -1544,7 +1514,7 @@ namespace{ string fragmentSource(bool bPBR, string defaultHeader, string customUniforms, const ofMaterialSettings& adata, int maxLights, bool hasTexture, bool hasColor, string definesString){ // string fragmentSource(bool bPBR, string defaultHeader, string customUniforms, string postFragment, int maxLights, bool hasTexture, bool hasColor, string definesString){ auto source = bPBR ? shader_pbr_frag : fragmentShader; - + string postFragment = adata.postFragment; if(postFragment.empty()){ postFragment = "vec4 postFragment(vec4 localColor){ return localColor; }"; @@ -1561,7 +1531,7 @@ namespace{ } ofStringReplace(source, "%mainFragment%", mainFrag); } - + if(bPBR) { string addIncludes = shader_utils; addIncludes += shader_pbr_material; @@ -1572,8 +1542,8 @@ namespace{ // set PBR includes here ofStringReplace(source, "%additional_includes%", addIncludes); } - - + + if( ofIsGLProgrammableRenderer() ) { #if defined(TARGET_OPENGLES) #if defined(TARGET_EMSCRIPTEN) @@ -1587,7 +1557,7 @@ namespace{ } else { ofStringReplace(source, "%shader_shadow_include%", "" ); } - + source = shaderHeader(defaultHeader, maxLights, hasTexture, hasColor) + definesString + source; return source; } @@ -1596,14 +1566,14 @@ namespace{ // auto source = bPBR ? shader_pbr_vert : vertexShader; string header = "#define IN in\n"; auto source = shader_pbr_vert; - + string mainVertex = adata.mainDepthVertex; if( mainVertex.empty() ) { mainVertex = shader_pbr_main_depth_vert; } ofStringReplace(source, "%mainVertex%", mainVertex); ofStringReplace(source, "%additional_includes%", ""); - + // if( bPBR ) { // ofStringReplace(source, "%additional_includes%", addShaderSrc); // } else { diff --git a/libs/openFrameworks/gl/ofTexture.cpp b/libs/openFrameworks/gl/ofTexture.cpp index 24288ce6c84..826879a0fa0 100644 --- a/libs/openFrameworks/gl/ofTexture.cpp +++ b/libs/openFrameworks/gl/ofTexture.cpp @@ -722,12 +722,16 @@ void ofTexture::generateMipmap(){ switch (texData.textureTarget) { /// OpenGL ES only supports mipmap for the following two texture targets: case GL_TEXTURE_2D: +#if defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) case GL_TEXTURE_CUBE_MAP: +#endif #ifndef TARGET_OPENGLES /// OpenGL supports mipmaps for additional texture targets: case GL_TEXTURE_1D: - case GL_TEXTURE_3D: case GL_TEXTURE_1D_ARRAY: +#endif +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: #endif { diff --git a/libs/openFrameworks/graphics/ofGraphics.cpp b/libs/openFrameworks/graphics/ofGraphics.cpp index b7e45922cd5..3bdfbbbdbd9 100644 --- a/libs/openFrameworks/graphics/ofGraphics.cpp +++ b/libs/openFrameworks/graphics/ofGraphics.cpp @@ -412,12 +412,14 @@ void ofBackgroundGradient(const ofFloatColor& start, const ofFloatColor& end, of float w = ofGetViewportWidth(), h = ofGetViewportHeight(); gradientMesh.clear(); gradientMesh.setMode(OF_PRIMITIVE_TRIANGLE_FAN); -#ifndef TARGET_EMSCRIPTEN - #ifdef TARGET_OPENGLES - if (ofIsGLProgrammableRenderer()) gradientMesh.setUsage(GL_STREAM_DRAW); - #else - gradientMesh.setUsage(GL_STREAM_DRAW); - #endif +#ifdef GL_STREAM_DRAW + #ifdef TARGET_OPENGLES + if(ofIsGLProgrammableRenderer()) { + gradientMesh.setUsage(GL_STREAM_DRAW); + } + #else + gradientMesh.setUsage(GL_STREAM_DRAW); + #endif #endif if (mode == OF_GRADIENT_CIRCULAR) { // this could be optimized by building a single mesh once, then copying diff --git a/libs/openFrameworks/utils/ofConstants.h b/libs/openFrameworks/utils/ofConstants.h index 00dfb6e4381..44ae9d6f430 100644 --- a/libs/openFrameworks/utils/ofConstants.h +++ b/libs/openFrameworks/utils/ofConstants.h @@ -288,7 +288,7 @@ enum ofTargetPlatform{ #include #include #include - #define GL_GLEXT_PROTOTYPES + #define GL_GLEXT_PROTOTYPES #include #if __ANDROID_API__ >= 21 #if defined(GL_ES_VERSION_3_0) diff --git a/libs/openFrameworksCompiled/project/android/config.android.default.mk b/libs/openFrameworksCompiled/project/android/config.android.default.mk new file mode 100644 index 00000000000..a3e4867c29a --- /dev/null +++ b/libs/openFrameworksCompiled/project/android/config.android.default.mk @@ -0,0 +1,605 @@ +################################################################################ +# CONFIGURE CORE PLATFORM MAKEFILE +# This file is where we make platform and architecture specific +# configurations. This file can be specified for a generic architecture or can +# be defined as variants. For instance, normally this file will be located in +# a platform specific subpath such as +# +# $(OF_ROOT)/libs/openFrameworksComplied/linux64 +# +# This file will then be a generic platform file like: +# +# configure.core.linux64.default.make +# +# Or it can specify a specific platform variant like: +# +# configure.core.linuxarmv6l.raspberrypi.make +# +################################################################################ + +################################################################################ +# PLATFORM SPECIFIC CHECKS +# This is a platform defined section to create internal flags to enable or +# disable the addition of various features within this makefile. For +# instance, on Linux, we check to see if there GTK+-2.0 is defined, allowing +# us to include that library and generate DEFINES that are interpreted as +# ifdefs within the openFrameworks core source code. +################################################################################ + +#check if mpg123 exists and add it +#HAS_SYSTEM_MPG123 = $(shell pkg-config libmpg123 --exists; echo $$?) + +include $(OF_ROOT)/libs/openFrameworksCompiled/project/android/paths.make +ARCH = android + +ifndef ABIS_TO_COMPILE_RELEASE + ABIS_TO_COMPILE_RELEASE = armv7 neon x86 +endif + +ifndef ABIS_TO_COMPILE_DEBUG + ABIS_TO_COMPILE_DEBUG = armv7 +endif + + +################################################################################ +# PLATFORM DEFINES +# Create a list of DEFINES for this platform. The list will be converted into +# CFLAGS with the "-D" flag later in the makefile. An example of fully +# qualified flag might look something like this: -DTARGET_OPENGLES2 +# +# DEFINES are used throughout the openFrameworks code, especially when making +# #ifdef decisions for cross-platform compatibility. For instance, when +# choosing a video playback framework, the openFrameworks base classes look at +# the DEFINES to determine what source files to include or what default player +# to use. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +PLATFORM_DEFINES = +PLATFORM_DEFINES = ANDROID + +ifndef $(NDK_PLATFORM) + NDK_PLATFORM = android-21 +endif + +ifndef $(SDK_TARGET) + SDK_TARGET = android-21 +endif + +ifndef $(GCC_VERSION) + GCC_VERSION = 4.9 +endif + +PROJECT_PATH=$(PWD) + + +ifeq ($(ABI),x86) +ANDROID_PREFIX=i686-linux-android- +TOOLCHAIN=x86-$(GCC_VERSION) +SYSROOT=$(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-x86/ +else +ANDROID_PREFIX=arm-linux-androideabi- +TOOLCHAIN=$(ANDROID_PREFIX)$(GCC_VERSION) +SYSROOT=$(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/ +endif + +ifeq ($(shell uname),Darwin) +ifneq ($(wildcard $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/darwin-x86_64),) + HOST_PLATFORM = darwin-x86_64 +else + HOST_PLATFORM = darwin-x86 +endif +else ifneq (,$(findstring MINGW32_NT,$(shell uname))) +ifneq ($(wildcard $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/windows-x86_64),) + HOST_PLATFORM = windows-x86_64 +else + HOST_PLATFORM = windows +endif + PWD = $(shell pwd) +else +ifneq ($(wildcard $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/linux-x86_64),) + HOST_PLATFORM = linux-x86_64 +else + HOST_PLATFORM = linux-x86 +endif +endif + +TOOLCHAIN_PATH=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/ + +DATA_FILES = $(shell find bin/data -type f 2>/dev/null) +RESNAME=$(shell echo $(APPNAME)Resources | tr '[A-Z]' '[a-z]') +RESFILE=$(RESNAME).zip + +ifeq ($(ABI),armv7) + ABI_PATH = armeabi-v7a + PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so + PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so +endif + +ifeq ($(ABI),armv5) + ABI_PATH = armeabi + PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so + PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so +endif + +ifeq ($(ABI),neon) + ABI_PATH = armeabi-v7a + PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp_neon.so + PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp_neon.so +endif + +ifeq ($(ABI),x86) + ABI_PATH = x86 + PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so + PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so +endif + +PLATFORM_CORELIB_RELEASE_TARGET = $(OF_CORE_LIB_PATH)/$(ABI)/libopenFrameworks.a +PLATFORM_CORELIB_DEBUG_TARGET = $(OF_CORE_LIB_PATH)/$(ABI)/libopenFrameworksDebug.a + + +# add OF_USING_MPG123 define IF we have it defined as a system library +#ifeq ($(HAS_SYSTEM_MPG123),0) +# PLATFORM_DEFINES += OF_USING_MPG123 +#endif + +################################################################################ +# PLATFORM REQUIRED ADDON +# This is a list of addons required for this platform. This list is used to +# EXCLUDE addon source files when compiling projects, while INCLUDING their +# header files. During core library compilation, this is used to include +# required addon header files as needed within the core. +# +# For instance, if you are compiling for Android, you would add ofxAndroid +# here. If you are compiling for Raspberry Pi, you would add ofxRaspberryPi +# here. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +PLATFORM_REQUIRED_ADDONS = ofxAndroid + +################################################################################ +# PLATFORM CFLAGS +# This is a list of fully qualified CFLAGS required when compiling for this +# platform. These flags will always be added when compiling a project or the +# core library. These flags are presented to the compiler AFTER the +# PLATFORM_OPTIMIZATION_CFLAGS below. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +# Warning Flags (http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html) +PLATFORM_CFLAGS = -Wall -std=c++14 + +# Code Generation Option Flags (http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html) +PLATFORM_CFLAGS += -nostdlib --sysroot=$(SYSROOT) -fno-short-enums -ffunction-sections -fdata-sections + + +ifeq ($(ABI),armv7) + PLATFORM_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 +endif + +ifeq ($(ABI),neon) + PLATFORM_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon +endif + +ifeq ($(ABI),x86) + PLATFORM_CFLAGS += -march=i686 -msse3 -mstackrealign -mfpmath=sse -fno-stack-protector +endif + +################################################################################ +# PLATFORM LDFLAGS +# This is a list of fully qualified LDFLAGS required when linking for this +# platform. These flags will always be added when linking a project. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +PLATFORM_LDFLAGS = +PLATFORM_LDFLAGS += --sysroot=$(SYSROOT) -nostdlib -L"$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(GCC_VERSION)/libs/$(ABI_PATH)" +#ifeq ($(HOST_PLATFORM),linux-x86) +# PLATFORM_LDFLAGS += -fuse-ld=gold +#endif + +ifneq ($(ABI),x86) +PLATFORM_LDFLAGS += -Wl,--fix-cortex-a8 +endif +PLATFORM_LDFLAGS += -shared -Wl,--no-undefined -Wl,--as-needed -Wl,--gc-sections -Wl,--exclude-libs,ALL + +################################################################################ +# PLATFORM OPTIMIZATION CFLAGS +# These are lists of CFLAGS that are target-specific. While any flags could +# be conditionally added, they are usually limited to optimization flags. +# These flags are added BEFORE the PLATFORM_CFLAGS. +# +# PLATFORM_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to +# RELEASE targets. +# +# PLATFORM_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to +# DEBUG targets. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +# RELEASE Debugging options (http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html) +PLATFORM_OPTIMIZATION_CFLAGS_RELEASE = -Os + +# RELEASE options +PLATFORM_OPTIMIZATION_LDFLAGS_RELEASE = -s + +# DEBUG Debugging options (http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html) +PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = -O0 -g -D_DEBUG + +################################################################################ +# PLATFORM CORE EXCLUSIONS +# During compilation, these makefiles will generate lists of sources, headers +# and third party libraries to be compiled and linked into a program or core +# library. The PLATFORM_CORE_EXCLUSIONS is a list of fully qualified file +# paths that will be used to exclude matching paths and files during list +# generation. +# +# Each item in the PLATFORM_CORE_EXCLUSIONS list will be treated as a complete +# string unless the user adds a wildcard (%) operator to match subdirectories. +# GNU make only allows one wildcard for matching. The second wildcard (%) is +# treated literally. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +PLATFORM_CORE_EXCLUSIONS = + +# core sources +PLATFORM_CORE_EXCLUSIONS += %.mm +PLATFORM_CORE_EXCLUSIONS += %.m +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofQtUtils.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofQuickTimeGrabber.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofQuickTimePlayer.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofDirectShowGrabber.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofDirectShowPlayer.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofGstUtils.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofGstVideoGrabber.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofGstVideoPlayer.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/app/ofAppGlutWindow.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/app/ofAppEGLWindow.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/app/ofAppGLFWWindow.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/graphics/ofCairoRenderer.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/sound/ofFmodSoundPlayer.cpp +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/sound/ofOpenALSoundPlayer.cpp + +# third party +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/glew/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/Poco +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/CppUnit +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/Poco/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/CppUnit/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/quicktime/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/videoInput/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/glu/include +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/fmodex/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/kiss/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/assimp/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/glut/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/portaudio/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/rtAudio/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/lib/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openssl/lib/% +PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/boost/include/boost/% + +# android project folders +PROJECT_EXCLUSIONS += ./gen +PROJECT_EXCLUSIONS += ./gen/% +PROJECT_EXCLUSIONS += ./jni +PROJECT_EXCLUSIONS += ./srcJava +PROJECT_EXCLUSIONS += ./srcJava/% +PROJECT_EXCLUSIONS += ./res +PROJECT_EXCLUSIONS += ./res/% +PROJECT_EXCLUSIONS += ./assets +PROJECT_EXCLUSIONS += ./assets/% +PROJECT_EXCLUSIONS += ./libs + + + +################################################################################ +# PLATFORM HEADER SEARCH PATHS +# These are header search paths that are platform specific and are specified +# using fully-qualified paths. The include flag (i.e. -I) is prefixed +# automatically. These are usually not required, but may be required by some +# experimental platforms such as the raspberry pi or other other embedded +# architectures. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +PLATFORM_HEADER_SEARCH_PATHS = +PLATFORM_HEADER_SEARCH_PATHS += "$(SYSROOT)/usr/include/" +PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/include" +PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(GCC_VERSION)/include" +PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/libs/$(ABI_PATH)/include" +PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(GCC_VERSION)/libs/$(ABI_PATH)/include" +PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/crystax/include/" +PLATFORM_HEADER_SEARCH_PATHS += "$(OF_ROOT)/libs/glu/include_android" +PLATFORM_HEADER_SEARCH_PATHS += "$(OF_ROOT)/addons/ofxAndroid/src" + +################################################################################ +# PLATFORM LIBRARIES +# These are library names/paths that are platform specific and are specified +# using names or paths. The library flag (i.e. -l) is prefixed automatically. +# +# PLATFORM_LIBRARIES are libraries that can be found in the library search +# paths. +# PLATFORM_STATIC_LIBRARIES is a list of required static libraries. +# PLATFORM_SHARED_LIBRARIES is a list of required shared libraries. +# PLATFORM_PKG_CONFIG_LIBRARIES is a list of required libraries that are +# under system control and are easily accesible via the package +# configuration utility (i.e. pkg-config) +# +# See the helpfile for the -l flag here for more information: +# http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +PLATFORM_LIBRARIES = +PLATFORM_LIBRARIES += OpenSLES +PLATFORM_LIBRARIES += supc++ +PLATFORM_LIBRARIES += z +PLATFORM_LIBRARIES += GLESv1_CM +PLATFORM_LIBRARIES += GLESv2 +PLATFORM_LIBRARIES += GLESv3 +PLATFORM_LIBRARIES += log +PLATFORM_LIBRARIES += dl +PLATFORM_LIBRARIES += m +PLATFORM_LIBRARIES += c +PLATFORM_LIBRARIES += gnustl_static +PLATFORM_LIBRARIES += gcc + +#static libraries (fully qualified paths) +PLATFORM_STATIC_LIBRARIES = +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoNetSSL.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoNet.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoCrypto.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoJSON.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoMongoDB.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoDataSQLite.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoData.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoUtil.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoXML.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoFoundation.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/openssl/lib/$(ABI_LIB_SUBPATH)/libssl.a +PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/openssl/lib/$(ABI_LIB_SUBPATH)/libcrypto.a + +# shared libraries +PLATFORM_SHARED_LIBRARIES = + +#openframeworks core third party +PLATFORM_PKG_CONFIG_LIBRARIES = + +# conditionally add mpg123 +#ifeq ($(HAS_SYSTEM_MPG123),0) +# PLATFORM_PKG_CONFIG_LIBRARIES += libmpg123 +#endif + +################################################################################ +# PLATFORM LIBRARY SEARCH PATHS +# These are library search paths that are platform specific and are specified +# using fully-qualified paths. The lib search flag (i.e. -L) is prefixed +# automatically. The -L paths are used to find libraries defined above with +# the -l flag. +# +# See the the following link for more information on the -L flag: +# http://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ + +PLATFORM_LIBRARY_SEARCH_PATHS = + +################################################################################ +# PLATFORM FRAMEWORKS +# These are a list of platform frameworks. +# These are used exclusively with Darwin/OSX. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +#PLATFORM_FRAMEWORKS = + +################################################################################ +# PLATFORM FRAMEWORK SEARCH PATHS +# These are a list of platform framework search paths. +# These are used exclusively with Darwin/OSX. +# +# Note: Leave a leading space when adding list items with the += operator +################################################################################ +#PLATFORM_FRAMEWORKS_SEARCH_PATHS = + +################################################################################ +# LOW LEVEL CONFIGURATION BELOW +# The following sections should only rarely be modified. They are meant for +# developers who need fine control when, for instance, creating a platform +# specific makefile for a new openFrameworks platform, such as raspberry pi. +################################################################################ + +################################################################################ +# PLATFORM CONFIGURATIONS +# These will override the architecture vars generated by configure.platform.make +################################################################################ +#PLATFORM_ARCH = +#PLATFORM_OS = +#PLATFORM_LIBS_PATH = + +################################################################################ +# PLATFORM CXX +# Don't want to use a default compiler? +################################################################################ +#PLATFORM_CXX= + +PLATFORM_CC=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)gcc +PLATFORM_CXX=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)g++ +PLATFORM_AR=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)ar + +#ifeq (,$(findstring MINGW32_NT,$(shell uname))) +ZIPWINDOWS=..\\..\\..\\..\\..\\libs\\openFrameworksCompiled\\project\\android\\windows\\zip -r ../../res/raw/$(RESFILE) +#endif + +afterplatform:$(RESFILE) + @if [ -f obj/$(BIN_NAME) ]; then rm obj/$(BIN_NAME); fi + + @echo copying debugging binaries for $(ABIS_TO_COMPILE) + @if [ "$(findstring neon,$(ABIS_TO_COMPILE))" = "neon" ]; then \ + cp $(OF_ROOT)/libs/openFrameworksCompiled/project/android/libneondetection.so libs/armeabi-v7a/; \ + cp $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver libs/armeabi-v7a; \ + fi + + @if [ "$(findstring armv5,$(ABIS_TO_COMPILE))" = "armv5" ]; then \ + cp $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver libs/armeabi; \ + fi + + @if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ]; then \ + cp $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver libs/armeabi-v7a; \ + fi + + @if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "x86" ]; then \ + cp $(NDK_ROOT)/prebuilt/android-x86/gdbserver/gdbserver libs/x86; \ + fi + + + @if [ "$(findstring armv5,$(ABIS_TO_COMPILE))" = "armv5" ]; then \ + echo create gdb.setup for armeabi; \ + echo "set solib-search-path $(PWD)/obj/local/armeabi:$(PWD)/libs/armeabi" > libs/armeabi/gdb.setup; \ + echo "set sysroot $(SYSROOT)" >> libs/armeabi/gdb.setup; \ + echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/armeabi/gdb.setup; \ + echo "directory $(PWD)/src" >> libs/armeabi/gdb.setup; \ + echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/armeabi/gdb.setup; \ + echo "directory $(PWD)/libs/armeabi" >> libs/armeabi/gdb.setup; \ + echo "" >> libs/armeabi/gdb.setup; \ + fi + + @if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ]; then \ + echo create gdb.setup for armeabi-v7a; \ + echo "set solib-search-path $(PWD)/obj/local/armeabi-v7a:$(PWD)/libs/armeabi-v7a" > libs/armeabi-v7a/gdb.setup; \ + echo "set sysroot $(SYSROOT)" >> libs/armeabi-v7a/gdb.setup; \ + echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/armeabi-v7a/gdb.setup; \ + echo "directory $(PWD)/src" >> libs/armeabi-v7a/gdb.setup; \ + echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/armeabi-v7a/gdb.setup; \ + echo "directory $(PWD)/libs/armeabi-v7a" >> libs/armeabi-v7a/gdb.setup ; \ + echo "" >> libs/armeabi-v7a/gdb.setup; \ + fi + + @if [ "$(findstring x86,$(ABIS_TO_COMPILE))" = "x86" ]; then \ + echo create gdb.setup for x86; \ + echo "set solib-search-path $(PWD)/obj/local/x86:$(PWD)/libs/x86" > libs/x86/gdb.setup; \ + echo "set sysroot $(SYSROOT)" >> libs/x86/gdb.setup; \ + echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/x86/gdb.setup; \ + echo "directory $(PWD)/src" >> libs/x86/gdb.setup; \ + echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/x86/gdb.setup; \ + echo "directory $(PWD)/libs/x86" >> libs/x86/gdb.setup ; \ + echo "" >> libs/x86/gdb.setup; \ + fi + + @echo creating Android.mk and Application.mk + @if [ ! -d jni ]; then mkdir jni; fi + @ABIS=""; \ + if [ "$(findstring armv5,$(ABIS_TO_COMPILE))" = "armv5" ]; then \ + ABIS="$$ABIS armeabi"; \ + else \ + rm -r libs/armeabi 2> /dev/null; \ + fi; \ + if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ] || [ "$(findstring neon,$(ABIS_TO_COMPILE))" = "neon" ]; then \ + ABIS="$$ABIS armeabi-v7a"; \ + elif [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ]; then \ + rm libs/armeabi-v7a/libOFAndroidApp_neon.so 2> /dev/null; \ + rm libs/armeabi-v7a/libneondetection.so 2> /dev/null; \ + elif [ "$(findstring neon,$(ABIS_TO_COMPILE))" = "neon" ]; then \ + rm libs/armeabi-v7a/libOFAndroidApp.so 2> /dev/null; \ + else \ + rm -r libs/armeabi-v7a 2> /dev/null; \ + fi; \ + if [ "$(findstring x86,$(ABIS_TO_COMPILE))" = "x86" ]; then \ + ABIS="$$ABIS x86"; \ + else \ + rm -r libs/x86 2> /dev/null; \ + fi; \ + echo "APP_ABI := $$ABIS" > jni/Application.mk; \ + echo "LOCAL_MODULE := OFAndroidApp" > jni/Android.mk + + + + #@echo updating ofAndroidLib project + #@cd $(OF_ROOT)/addons/ofxAndroid/ofAndroidLib; \ + #if [ "$(HOST_PLATFORM)" = "windows" ]; then \ + # cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ + #else \ + # $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ + #fi + + #@echo updating current project + #@cd $(PROJECT_PATH); \ + #if [ "$(HOST_PLATFORM)" = "windows" ]; then \ + # cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ + #else \ + # $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ + #fi + +$(RESFILE): $(DATA_FILES) + @echo compressing and copying resources from bin/data into res + cd "$(PROJECT_PATH)"; \ + if [ -d "bin/data" ]; then \ + mkdir -p res/raw; \ + rm res/raw/$(RESNAME).zip; \ + cd bin/data; \ + if [ "$(HOST_PLATFORM)" = "windows" ]; then \ + echo "Windows Platform. Running Zip..."; \ + cmd //c $(ZIPWINDOWS) * && exit; \ + else \ + zip -r ../../res/raw/$(RESNAME).zip *; \ + fi; \ + cd ../..; \ + fi + +install: + cd "$(OF_ROOT)/addons/ofxAndroid/ofAndroidLib"; \ + echo installing on $(HOST_PLATFORM); \ + if [ "$(HOST_PLATFORM)" = "windows" ]; then \ + cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ + else \ + $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ + fi + cd "$(PROJECT_PATH)"; \ + if [ -d "bin/data" ]; then \ + mkdir -p res/raw; \ + rm res/raw/$(RESNAME).zip; \ + cd bin/data; \ + if [ "$(HOST_PLATFORM)" = "windows" ]; then \ + echo "Windows Platform. Running Zip..."; \ + cmd //c $(ZIPWINDOWS) * && exit; \ + else \ + zip -r ../../res/raw/$(RESNAME).zip; *; \ + fi; \ + cd ../..; \ + fi + if [ -f obj/$(BIN_NAME) ]; then rm obj/$(BIN_NAME); fi + #touch AndroidManifest.xml + if [ "$(HOST_PLATFORM)" = "windows" ]; then \ + cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ + else \ + $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ + fi + + #rm -r $(addprefix bin/,$(shell ls bin/ | grep -v ^data$)) + + if [ "$(HOST_PLATFORM)" = "windows" ]; then \ + #$(ANT_BIN)/ant clean; \ + $(ANT_BIN)/ant debug install; \ + else \ + #ant clean; \ + ant debug install; \ + fi + cp bin/OFActivity-debug.apk bin/$(APPNAME).apk + #if [ "$(shell $(SDK_ROOT)/platform-tools/adb get-state)" = "device" ]; then + #$(SDK_ROOT)/platform-tools/adb uninstall $(PKGNAME) + $(SDK_ROOT)/platform-tools/adb install -r bin/$(APPNAME).apk; + #fi + $(SDK_ROOT)/platform-tools/adb shell am start -a android.intent.action.MAIN -n $(PKGNAME)/$(PKGNAME).OFActivity + From 5722bed313e19fee1eb8b3eca01be0836dbf8e50 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Tue, 8 Sep 2015 23:44:14 +0200 Subject: [PATCH 04/38] Fixes. --- libs/openFrameworks/gl/ofGLUtils.cpp | 399 ++++++++++++++------------- 1 file changed, 200 insertions(+), 199 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 24bfecb8561..4ed062a8c58 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -89,43 +89,37 @@ int ofGetGLInternalFormat(const ofShortPixels& pixels) { //--------------------------------- int ofGetGLInternalFormat(const ofFloatPixels& pixels) { #if defined(TARGET_EMSCRIPTEN) - switch(pixels.getNumChannels()) { - case 3: return GL_RGB16F; - case 4: return GL_RGBA16F; - case 2: - ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): two channel float textures not supported."; - return GL_RG16F; - default: - ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): single channel float textures not supported."; - return GL_R16F; - } -#elif !defined(TARGET_OPENGLES) - switch(pixels.getNumChannels()) { - case 3: return GL_RGB32F; - case 4: return GL_RGBA32F; - case 2: - if(ofIsGLProgrammableRenderer()){ - return GL_RG32F; - }else{ - return GL_LUMINANCE_ALPHA32F_ARB; - } - default: - if(ofIsGLProgrammableRenderer()){ - return GL_R32F; - }else{ - return GL_LUMINANCE32F_ARB; - } - } + // WebGL2 has unreliable / slower support for 32F float textures + // → we force 16F for stability and performance (matches current master) + switch(pixels.getNumChannels()) { + case 3: return GL_RGB16F; + case 4: return GL_RGBA16F; + case 2: + ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): two channel float textures not supported on Emscripten."; + return GL_RG16F; + default: + ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): single channel float textures not supported on Emscripten."; + return GL_R16F; + } +#elif !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // Desktop + native GLES 3.0+ → full 32F support + switch(pixels.getNumChannels()) { + case 3: return GL_RGB32F; + case 4: return GL_RGBA32F; + case 2: + return GL_RG32F; + default: + return GL_R32F; + } #else - ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): float textures not supported in OpenGL ES"; - switch(pixels.getNumChannels()) { - case 3: return GL_RGB; - case 4: return GL_RGBA; - case 2: - return GL_LUMINANCE_ALPHA; - default: - return GL_LUMINANCE; - } + // GLES 2.0 fallback + ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): float textures not supported in OpenGL ES < 3.0"; + switch(pixels.getNumChannels()) { + case 3: return GL_RGB; + case 4: return GL_RGBA; + case 2: return GL_LUMINANCE_ALPHA; + default: return GL_LUMINANCE; + } #endif } @@ -134,11 +128,11 @@ int ofGetGLInternalFormat(const ofFloatPixels& pixels) { string ofGetGLInternalFormatName(int glInternalFormat) { switch(glInternalFormat) { case GL_RGBA: return "GL_RGBA"; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_RGBA8: return "GL_RGBA8"; #endif case GL_RGB: return "GL_RGB"; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_RGB8: return "GL_RGB8"; #endif case GL_LUMINANCE: return "GL_LUMINANCE"; @@ -160,103 +154,97 @@ string ofGetGLInternalFormatName(int glInternalFormat) { } int ofGetGLFormatFromInternal(int glInternalFormat){ - switch(glInternalFormat) { - case GL_RGBA: - #if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_RGBA8: - case GL_RGBA16: - case GL_RGBA16F: - case GL_RGBA16I: - case GL_RGBA16UI: - case GL_RGBA32F: - case GL_RGBA32I: - case GL_RGBA32UI: - #endif - return GL_RGBA; -#ifdef TARGET_OF_IOS - case GL_BGRA: - return GL_BGRA; -#endif - - - case GL_RGB: - #if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_RGB8: - case GL_RGB16: - case GL_RGB16F: - case GL_RGB16I: - case GL_RGB16UI: - case GL_RGB32F: - case GL_RGB32I: - case GL_RGB32UI: - #endif - return GL_RGB; - + switch(glInternalFormat) { + case GL_RGBA: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGBA8: + case GL_RGBA16F: + #endif + #ifndef TARGET_OPENGLES + case GL_RGBA16: + case GL_RGBA32F_ARB: + case GL_RGBA16I: + case GL_RGBA16UI: + case GL_RGBA32I: + case GL_RGBA32UI: + #endif + return GL_RGBA; - case GL_LUMINANCE: - #if !defined(TARGET_OPENGLES) - case GL_LUMINANCE8: - case GL_LUMINANCE16: - case GL_LUMINANCE32F_ARB: - #endif - return GL_LUMINANCE; - - case GL_LUMINANCE_ALPHA: - #if !defined(TARGET_OPENGLES) - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE16_ALPHA16: - case GL_LUMINANCE_ALPHA32F_ARB: - #endif - return GL_LUMINANCE_ALPHA; - - - case GL_DEPTH_STENCIL: - return GL_DEPTH_STENCIL; - - case GL_DEPTH_COMPONENT: -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: -#endif - return GL_DEPTH_COMPONENT; - - case GL_STENCIL_INDEX: - return GL_STENCIL_INDEX; - -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_R8: - case GL_R16: - case GL_R16I: - case GL_R16UI: - case GL_R16F: - case GL_R32F: - case GL_R32I: - case GL_R32UI: - return GL_RED; - - case GL_RG8: - case GL_RG16: - case GL_RG16I: - case GL_RG16UI: - case GL_RG16F: - case GL_RG32F: - case GL_RG32I: - case GL_RG32UI: - return GL_RG; -#endif - -#ifndef TARGET_OPENGLES - case GL_ALPHA8: +#ifdef TARGET_OF_IOS + case GL_BGRA: + return GL_BGRA; #endif - case GL_ALPHA: - return GL_ALPHA; - default: - ofLogError("ofGLUtils") << "ofGetGLFormatFromInternal(): unknown internal format " << glInternalFormat << ", returning GL_RGBA"; - return GL_RGBA; + case GL_RGB: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGB8: + case GL_RGB16F: + #endif + #ifndef TARGET_OPENGLES + case GL_RGB16: + case GL_RGB32F_ARB: + #endif + return GL_RGB; - } + case GL_LUMINANCE: + #if !defined(TARGET_OPENGLES) + case GL_LUMINANCE8: + case GL_LUMINANCE16: + case GL_LUMINANCE32F_ARB: + #endif + return GL_LUMINANCE; + + case GL_LUMINANCE_ALPHA: + #if !defined(TARGET_OPENGLES) + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE16_ALPHA16: + case GL_LUMINANCE_ALPHA32F_ARB: + #endif + return GL_LUMINANCE_ALPHA; + + case GL_DEPTH_STENCIL: + return GL_DEPTH_STENCIL; + + case GL_DEPTH_COMPONENT: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + #endif + #if defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) + case GL_DEPTH_COMPONENT32F: + #endif + #ifndef TARGET_OPENGLES + case GL_DEPTH_COMPONENT32: + #endif + return GL_DEPTH_COMPONENT; + + case GL_STENCIL_INDEX: + return GL_STENCIL_INDEX; + + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_R8: + case GL_R16F: + case GL_R32F: + case GL_RG8: + case GL_RG16F: + case GL_RG32F: + #endif + #ifndef TARGET_OPENGLES + case GL_R16: + case GL_RG16: + #endif + return (glInternalFormat == GL_R8 || glInternalFormat == GL_R16F || glInternalFormat == GL_R32F || glInternalFormat == GL_R16) ? GL_RED : GL_RG; + + #ifndef TARGET_OPENGLES + case GL_ALPHA8: + #endif + case GL_ALPHA: + return GL_ALPHA; + + default: + ofLogError("ofGLUtils") << "ofGetGLFormatFromInternal(): unknown internal format " << glInternalFormat << ", returning GL_RGBA"; + return GL_RGBA; + } } int ofGetGLTypeFromInternal(int glInternalFormat){ @@ -267,14 +255,16 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: case GL_ALPHA: -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #ifndef TARGET_OPENGLES case GL_LUMINANCE8: case GL_LUMINANCE8_ALPHA8: + case GL_ALPHA8: + #endif case GL_R8: case GL_RG8: case GL_RGB8: case GL_RGBA8: - case GL_ALPHA8: #endif return GL_UNSIGNED_BYTE; @@ -381,57 +371,63 @@ int ofGetGLType(const ofFloatPixels & pixels) { //--------------------------------- ofImageType ofGetImageTypeFromGLType(int glType){ - switch(glType){ - case GL_LUMINANCE: -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_LUMINANCE8: - case GL_LUMINANCE16: - case GL_LUMINANCE32F_ARB: - case GL_R8: - case GL_R16: - case GL_R16F: - case GL_R16I: - case GL_R16UI: - case GL_R32F: - case GL_R32I: - case GL_R32UI: - case GL_DEPTH_COMPONENT32F: - case GL_DEPTH_COMPONENT32: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT: -#endif - return OF_IMAGE_GRAYSCALE; - - - case GL_RGB: -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_RGB8: - case GL_RGB16: - case GL_RGB16F: - case GL_RGB16I: - case GL_RGB16UI: - case GL_RGB32F: - case GL_RGB32I: - case GL_RGB32UI: -#endif - return OF_IMAGE_COLOR; - - - case GL_RGBA: -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_RGBA8: - case GL_RGBA16: - case GL_RGBA16F: - case GL_RGBA16I: - case GL_RGBA16UI: - case GL_RGBA32F: - case GL_RGBA32I: - case GL_RGBA32UI: -#endif - return OF_IMAGE_COLOR_ALPHA; - } - return OF_IMAGE_UNDEFINED; + switch(glType){ + case GL_LUMINANCE: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #ifndef TARGET_OPENGLES + case GL_LUMINANCE8: + case GL_LUMINANCE16: + case GL_LUMINANCE32F_ARB: + case GL_R8: + case GL_R16: + #endif + case GL_R16F: + case GL_R16I: + case GL_R16UI: + case GL_R32F: + case GL_R32I: + case GL_R32UI: + case GL_DEPTH_COMPONENT32F: + #ifndef TARGET_OPENGLES + case GL_DEPTH_COMPONENT32: + #endif + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT: + #endif + return OF_IMAGE_GRAYSCALE; + + case GL_RGB: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGB8: + #ifndef TARGET_OPENGLES + case GL_RGB16: + #endif + case GL_RGB16F: + case GL_RGB16I: + case GL_RGB16UI: + case GL_RGB32F: + case GL_RGB32I: + case GL_RGB32UI: + #endif + return OF_IMAGE_COLOR; + + case GL_RGBA: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGBA8: + #ifndef TARGET_OPENGLES + case GL_RGBA16: + #endif + case GL_RGBA16F: + case GL_RGBA16I: + case GL_RGBA16UI: + case GL_RGBA32F: + case GL_RGBA32I: + case GL_RGBA32UI: + #endif + return OF_IMAGE_COLOR_ALPHA; + } + return OF_IMAGE_UNDEFINED; } GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ @@ -578,14 +574,14 @@ int ofGetGLInternalFormatFromPixelFormat(ofPixelFormat pixelFormat){ switch(pixelFormat){ case OF_PIXELS_BGRA: case OF_PIXELS_RGBA: -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) return GL_RGBA8; #else return GL_RGBA; #endif case OF_PIXELS_RGB: case OF_PIXELS_BGR: -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) return GL_RGB8; #else return GL_RGB; @@ -606,26 +602,26 @@ int ofGetGLInternalFormatFromPixelFormat(ofPixelFormat pixelFormat){ case OF_PIXELS_Y: case OF_PIXELS_U: case OF_PIXELS_V: -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) if(ofIsGLProgrammableRenderer()){ return GL_R8; }else{ #endif return GL_LUMINANCE; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) } #endif case OF_PIXELS_GRAY_ALPHA: case OF_PIXELS_YUY2: case OF_PIXELS_UV: case OF_PIXELS_VU: -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) if(ofIsGLProgrammableRenderer()){ return GL_RG8; }else{ #endif return GL_LUMINANCE_ALPHA; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) } #endif default: @@ -663,30 +659,31 @@ int ofGetGLFormatFromPixelFormat(ofPixelFormat pixelFormat){ case OF_PIXELS_Y: case OF_PIXELS_U: case OF_PIXELS_V: -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) if(ofIsGLProgrammableRenderer()){ return GL_RED; }else{ #endif return GL_LUMINANCE; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) } #endif case OF_PIXELS_GRAY_ALPHA: case OF_PIXELS_YUY2: case OF_PIXELS_UV: case OF_PIXELS_VU: -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) if(ofIsGLProgrammableRenderer()){ return GL_RG; }else{ #endif return GL_LUMINANCE_ALPHA; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) } #endif default: -#ifndef TARGET_OPENGLES + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) if(ofIsGLProgrammableRenderer()){ ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format " << ofToString(pixelFormat) << ", returning GL_RED"; @@ -696,7 +693,7 @@ int ofGetGLFormatFromPixelFormat(ofPixelFormat pixelFormat){ ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format " << ofToString(pixelFormat) << ", returning GL_LUMINANCE"; return GL_LUMINANCE; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) } #endif } @@ -716,7 +713,7 @@ int ofGetNumChannelsFromGLFormat(int glFormat){ return 1; case GL_LUMINANCE_ALPHA: return 2; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_RED: return 1; case GL_RG: @@ -739,20 +736,24 @@ int ofGetBytesPerChannelFromGLType(int glType){ return 2; #endif -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) case GL_FLOAT: return 4; #endif +#ifndef TARGET_OPENGLES case GL_UNSIGNED_INT_24_8: return 4; +#endif -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) case GL_UNSIGNED_INT: return 4; #endif +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_HALF_FLOAT: return 2; +#endif default: ofLogError("ofGetBytesPerChannelFromGLType") << "unknown type returning 1"; From f0eb2395860266ae3a4f56b5ec9c317925a38004 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Sat, 12 Sep 2015 23:49:27 +0200 Subject: [PATCH 05/38] Misc fixes --- .../ofxAndroid/src/ofxAndroidVideoGrabber.cpp | 51 ++++++++-------- .../ofxAndroid/src/ofxAndroidVideoPlayer.cpp | 2 + libs/openFrameworks/gl/ofFbo.cpp | 61 +++++++++---------- libs/openFrameworks/gl/ofGLUtils.cpp | 50 +++++++++------ libs/openFrameworks/gl/ofTexture.h | 14 +++-- 5 files changed, 95 insertions(+), 83 deletions(-) diff --git a/addons/ofxAndroid/src/ofxAndroidVideoGrabber.cpp b/addons/ofxAndroid/src/ofxAndroidVideoGrabber.cpp index f5201c37fb8..4ec0683dcc7 100644 --- a/addons/ofxAndroid/src/ofxAndroidVideoGrabber.cpp +++ b/addons/ofxAndroid/src/ofxAndroidVideoGrabber.cpp @@ -132,35 +132,34 @@ ofxAndroidVideoGrabber::Data::~Data(){ } void ofxAndroidVideoGrabber::Data::loadTexture(){ - ofTextureData td; - GLuint texId[1]; - glGenTextures(1, texId); - - glEnable(GL_TEXTURE_EXTERNAL_OES); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId[0]); - - glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (!ofIsGLProgrammableRenderer()) { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } + ofTextureData td; + GLuint texId[1]; + glGenTextures(1, texId); + + glEnable(GL_TEXTURE_EXTERNAL_OES); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId[0]); - glDisable(GL_TEXTURE_EXTERNAL_OES); + glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - // Set the externally created texture reference - texture.setUseExternalTextureID(texId[0]); - texture.texData.width = width; - texture.texData.height = height; - texture.texData.tex_w = width; - texture.texData.tex_h = height; - texture.texData.tex_t = 1; // Hack! - texture.texData.tex_u = 1; - texture.texData.textureTarget = GL_TEXTURE_EXTERNAL_OES; - texture.texData.glInternalFormat = GL_RGBA; +#ifndef TARGET_PROGRAMMABLE_GL + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#endif + glDisable(GL_TEXTURE_EXTERNAL_OES); + // Set the externally created texture reference + texture.setUseExternalTextureID(texId[0]); + texture.texData.width = width; + texture.texData.height = height; + texture.texData.tex_w = width; + texture.texData.tex_h = height; + texture.texData.tex_t = 1; // Hack! + texture.texData.tex_u = 1; + texture.texData.textureTarget = GL_TEXTURE_EXTERNAL_OES; + texture.texData.glInternalFormat = GL_RGBA; } @@ -262,7 +261,7 @@ void ofxAndroidVideoGrabber::close(){ } else { ofLogError("ofxAndroidVideoGrabber") << "close(): couldn't get OFAndroidVideoGrabber close grabber method"; } - + data->bGrabberInited = false; } diff --git a/addons/ofxAndroid/src/ofxAndroidVideoPlayer.cpp b/addons/ofxAndroid/src/ofxAndroidVideoPlayer.cpp index 3e83236d352..0f834b6a030 100644 --- a/addons/ofxAndroid/src/ofxAndroidVideoPlayer.cpp +++ b/addons/ofxAndroid/src/ofxAndroidVideoPlayer.cpp @@ -26,7 +26,9 @@ void ofxAndroidVideoPlayer::reloadTexture(){ glTexParameterf(texture.texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(texture.texData.textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(texture.texData.textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#ifndef TARGET_PROGRAMMABLE_GL glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#endif glDisable(texture.texData.textureTarget); diff --git a/libs/openFrameworks/gl/ofFbo.cpp b/libs/openFrameworks/gl/ofFbo.cpp index edf6e842e5f..b82c9b84bfb 100644 --- a/libs/openFrameworks/gl/ofFbo.cpp +++ b/libs/openFrameworks/gl/ofFbo.cpp @@ -496,36 +496,34 @@ void ofFbo::destroy() { //-------------------------------------------------------------- bool ofFbo::checkGLSupport() { -#ifndef TARGET_OPENGLES - - if (!ofIsGLProgrammableRenderer()){ - if(ofGLCheckExtension("GL_EXT_framebuffer_object")){ - ofLogVerbose("ofFbo") << "GL frame buffer object supported"; - }else{ - ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; - return false; - } - } - - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &_maxColorAttachments); - glGetIntegerv(GL_MAX_DRAW_BUFFERS, &_maxDrawBuffers); - glGetIntegerv(GL_MAX_SAMPLES, &_maxSamples); - - ofLogVerbose("ofFbo") << "checkGLSupport(): " - << "maxColorAttachments: " << _maxColorAttachments << ", " - << "maxDrawBuffers: " << _maxDrawBuffers << ", " - << "maxSamples: " << _maxSamples; +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // Desktop + GLES 3.0+ (FBO is core spec — no extension check needed on ES3) + if (!ofIsGLProgrammableRenderer()){ + if(ofGLCheckExtension("GL_EXT_framebuffer_object")){ + ofLogVerbose("ofFbo") << "GL frame buffer object supported"; + }else{ + ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; + return false; + } + } + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &_maxColorAttachments); + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &_maxDrawBuffers); + glGetIntegerv(GL_MAX_SAMPLES, &_maxSamples); + + ofLogVerbose("ofFbo") << "checkGLSupport(): " + << "maxColorAttachments: " << _maxColorAttachments << ", " + << "maxDrawBuffers: " << _maxDrawBuffers << ", " + << "maxSamples: " << _maxSamples; #else - - if(ofIsGLProgrammableRenderer() || ofGLCheckExtension("GL_OES_framebuffer_object")){ - ofLogVerbose("ofFbo") << "GL frame buffer object supported"; - }else{ - ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; - return false; - } + // GLES 2.0 — FBO is still an extension (GL_OES_framebuffer_object) + if(ofIsGLProgrammableRenderer() || ofGLCheckExtension("GL_OES_framebuffer_object")){ + ofLogVerbose("ofFbo") << "GL frame buffer object supported"; + }else{ + ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; + return false; + } #endif - - return true; + return true; } @@ -669,6 +667,7 @@ void ofFbo::allocate(ofFboSettings _settings) { settings.minFilter = _settings.minFilter; // if we want MSAA, create a new fbo for textures + // FIXME: it is in fact possible to do multisampling with newer OpenGL ES (2.0+ ?) #ifndef TARGET_OPENGLES if(_settings.numSamples){ glGenFramebuffers(1, &fboTextures); @@ -942,7 +941,7 @@ int ofFbo::getNumTextures() const { //---------------------------------------------------------- void ofFbo::setActiveDrawBuffer(int i){ if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES +#ifndef TARGET_OPENGLES || defined(GL_ES_VERSION_3_0) vector activebuffers(1, i); setActiveDrawBuffers(activebuffers); #endif @@ -951,7 +950,7 @@ void ofFbo::setActiveDrawBuffer(int i){ //---------------------------------------------------------- void ofFbo::setActiveDrawBuffers(const vector& ids){ if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) int numBuffers = activeDrawBuffers.size(); activeDrawBuffers.clear(); activeDrawBuffers.resize(numBuffers, GL_NONE); // we initialise the vector with GL_NONE, so a buffer will not be written to unless activated. @@ -972,7 +971,7 @@ void ofFbo::setActiveDrawBuffers(const vector& ids){ //---------------------------------------------------------- void ofFbo::activateAllDrawBuffers(){ if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) vector activeBuffers(getNumTextures(),0); for(int i=0; i < getNumTextures(); i++){ activeBuffers[i] = i; diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 4ed062a8c58..9a843a49476 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -275,26 +275,36 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ break; #endif -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) - case GL_LUMINANCE32F_ARB: - case GL_LUMINANCE_ALPHA32F_ARB: - case GL_R32F: - case GL_RG32F: - case GL_RGB32F: - case GL_RGBA32F: - return GL_FLOAT; - - case GL_R16F: - case GL_RG16F: - case GL_RGB16F: - case GL_RGBA16F: - case GL_LUMINANCE16: - case GL_LUMINANCE16_ALPHA16: - case GL_R16: - case GL_RG16: - case GL_RGB16: - case GL_RGBA16: - return GL_HALF_FLOAT; + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // === HALF-FLOAT (16F) — these four formats === + case GL_R16F: + case GL_RG16F: + case GL_RGB16F: + case GL_RGBA16F: + #ifdef GL_HALF_FLOAT + return GL_HALF_FLOAT; // core in GLES 3.0+ + #else + return GL_HALF_FLOAT_OES; // fallback for older headers + #endif + // === FULL-FLOAT (32F) === + case GL_R32F: + case GL_RG32F: + case GL_RGB32F: + case GL_RGBA32F: + return GL_FLOAT; +#endif +#ifndef TARGET_OPENGLES + case GL_LUMINANCE32F_ARB: + case GL_LUMINANCE_ALPHA32F_ARB: + return GL_FLOAT; + case GL_LUMINANCE16: + case GL_LUMINANCE16_ALPHA16: + case GL_R16: + case GL_RG16: + case GL_RGB16: + case GL_RGBA16: + return GL_UNSIGNED_SHORT; #endif case GL_DEPTH_STENCIL: diff --git a/libs/openFrameworks/gl/ofTexture.h b/libs/openFrameworks/gl/ofTexture.h index 6ef58b0ebd1..fa150f5dca9 100644 --- a/libs/openFrameworks/gl/ofTexture.h +++ b/libs/openFrameworks/gl/ofTexture.h @@ -555,6 +555,7 @@ class ofTexture : public ofBaseDraws { /// \param glFormat GL pixel type: GL_RGBA, GL_LUMINANCE, etc. void loadData(const ofFloatPixels & pix, int glFormat); + /// \brief Load byte pixel data. /// /// glFormat can be different to the internal format of the texture on each @@ -567,8 +568,8 @@ class ofTexture : public ofBaseDraws { /// \param glFormat GL pixel type: GL_RGBA, GL_LUMINANCE, etc. /// \param glType the OpenGL type of the data. void loadData(const void * data, int w, int h, int glFormat, int glType); - -#ifndef TARGET_OPENGLES + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) /// \brief Load pixels from an ofBufferObject /// /// This is different to allocate(ofBufferObject,internal). That @@ -725,9 +726,10 @@ class ofTexture : public ofBaseDraws { /// void unbind(int textureLocation=0) const; - // note: defined(someMethod) doesn't actually always work - // there is no reliable way to check for a function being defined just with the preprocessor -#if (!defined(TARGET_OPENGLES) && defined(glBindImageTexture)) || defined(GL_ES_VERSION_3_1) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_1) +// TODO: check for availability of glBindImageTexture in a valid way +// defined(glBindImageTexture) does not actually work! +// there is no reliable way to check for a function being defined just with the preprocessor /// Calls glBindImageTexture on the texture /// /// Binds the texture as an read or write image, only available since OpenGL 4.2 @@ -954,7 +956,7 @@ class ofTexture : public ofBaseDraws { /// \sa generateMipmap() /// \sa enableMipmap() bool hasMipmap() const; - + /// \internal ofTextureData texData; ///< Internal texture data access. ///< For backwards compatibility. From 681c5283e451adb3c9c707967654c888ee7c272f Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Thu, 17 Sep 2015 16:05:44 +0200 Subject: [PATCH 06/38] Minor fixes when using GLES1. --- libs/openFrameworks/gl/ofGLRenderer.cpp | 1 - libs/openFrameworks/gl/ofGLUtils.cpp | 87 +++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLRenderer.cpp b/libs/openFrameworks/gl/ofGLRenderer.cpp index b913e515c5f..ca835488f83 100644 --- a/libs/openFrameworks/gl/ofGLRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLRenderer.cpp @@ -20,7 +20,6 @@ using std::vector; const std::string ofGLRenderer::TYPE = "GL"; -#if !defined(TARGET_OPENGLES) || !defined(TARGET_PROGRAMMABLE_GL) //---------------------------------------------------------- ofGLRenderer::ofGLRenderer(const ofAppBaseWindow * _window) : matrixStack(_window) diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 9a843a49476..34ea578b6ea 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -154,11 +154,88 @@ string ofGetGLInternalFormatName(int glInternalFormat) { } int ofGetGLFormatFromInternal(int glInternalFormat){ - switch(glInternalFormat) { - case GL_RGBA: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_RGBA8: - case GL_RGBA16F: + switch(glInternalFormat) { + case GL_RGBA: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGBA8: + case GL_RGBA16F: + #ifndef TARGET_OPENGLES + case GL_RGBA16: + case GL_RGBA32F_ARB: + #endif + #endif + return GL_RGBA; + + + case GL_RGB: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGB8: + #ifndef TARGET_OPENGLES + case GL_RGB16: + case GL_RGB32F_ARB: + #endif + #endif + return GL_RGB; + + + case GL_LUMINANCE: + #ifndef TARGET_OPENGLES + case GL_LUMINANCE8: + case GL_LUMINANCE16: + #ifndef TARGET_OPENGLES + case GL_LUMINANCE32F_ARB: + #endif + #endif + return GL_LUMINANCE; + + case GL_LUMINANCE_ALPHA: + #ifndef TARGET_OPENGLES + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE16_ALPHA16: + #ifndef TARGET_OPENGLES + case GL_LUMINANCE_ALPHA32F_ARB: + #endif + #endif + return GL_LUMINANCE_ALPHA; + + + case GL_DEPTH_STENCIL: + return GL_DEPTH_STENCIL; + + case GL_DEPTH_COMPONENT: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) + case GL_DEPTH_COMPONENT16: + #endif + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_DEPTH_COMPONENT24: + #endif + #if defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) + case GL_DEPTH_COMPONENT32F: + #endif + #ifndef TARGET_OPENGLES + case GL_DEPTH_COMPONENT32: + #endif + return GL_DEPTH_COMPONENT; + + case GL_STENCIL_INDEX: + return GL_STENCIL_INDEX; + + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_R8: + case GL_R16F: + case GL_R32F: +#ifndef TARGET_OPENGLES + case GL_R16: +#endif + return GL_RED; + #endif + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RG8: + case GL_RG16F: + case GL_RG32F: + #ifndef TARGET_OPENGLES + case GL_RG16: #endif #ifndef TARGET_OPENGLES case GL_RGBA16: From 0298e3f3962f836da12590cbac54dac9edf2ec98 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Thu, 17 Sep 2015 16:06:46 +0200 Subject: [PATCH 07/38] More consistent API. --- .../src/cc/openframeworks/OFAndroid.java | 1162 +++++++++++++++++ .../cc/openframeworks/OFAndroidWindow.java | 33 +- addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 67 +- 3 files changed, 1212 insertions(+), 50 deletions(-) create mode 100644 addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java diff --git a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java new file mode 100644 index 00000000000..eb68dfffa99 --- /dev/null +++ b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java @@ -0,0 +1,1162 @@ +package cc.openframeworks; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.hardware.SensorManager; +import android.media.AudioManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.Uri; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.MulticastLock; +import android.os.Environment; +import android.os.StatFs; +import android.util.Log; +import android.view.KeyEvent; +import android.view.ScaleGestureDetector; +import android.view.SurfaceView; +import android.view.View; +import android.view.WindowManager.LayoutParams; +import android.widget.ArrayAdapter; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.Toast; + +public class OFAndroid { + + // List based on http://bit.ly/NpkL4Q + private static final String[] mExternalStorageDirectories = new String[] { + "/mnt/sdcard-ext", + "/mnt/sdcard/external_sd", + "/sdcard/sd", + "/mnt/external_sd", + "/emmc", + "/mnt/sdcard/bpemmctest", + "/mnt/sdcard/_ExternalSD", + "/mnt/Removable/MicroSD", + "/Removable/MicroSD", + "/sdcard"}; + + public static String getRealExternalStorageDirectory(Context context) + { + // Standard way to get the external storage directory + String externalPath = context.getExternalFilesDir(null).getPath(); + File SDCardDir = new File(externalPath); + if(SDCardDir.exists() && SDCardDir.canWrite()) { + return externalPath; + } + + // This checks if any of the directories from mExternalStorageDirectories exist, if it does, it uses that one instead + for(int i = 0; i < mExternalStorageDirectories.length; i++) + { + //Log.i("OF", "Checking: " + mExternalStorageDirectories[i]); + SDCardDir = new File(mExternalStorageDirectories[i]); + if(SDCardDir.exists() && SDCardDir.canWrite()) { + externalPath = mExternalStorageDirectories[i]; // Found writable location + break; + } + } + + Log.i("OF", "Using storage location: " + externalPath); + return externalPath; + } + + public static String getOldExternalStorageDirectory(String packageName) + { + // Standard way to get the external storage directory + String externalPath = Environment.getExternalStorageDirectory().getPath(); + File SDCardDir = new File(externalPath); + if(SDCardDir.exists() && SDCardDir.canWrite()) { + return externalPath + "/Android/data/"+packageName; + } + + // This checks if any of the directories from mExternalStorageDirectories exist, if it does, it uses that one instead + for(int i = 0; i < mExternalStorageDirectories.length; i++) + { + //Log.i("OF", "Checking: " + mExternalStorageDirectories[i]); + SDCardDir = new File(mExternalStorageDirectories[i]); + if(SDCardDir.exists() && SDCardDir.canWrite()) { + externalPath = mExternalStorageDirectories[i]; // Found writable location + break; + } + } + + Log.i("OF", "Using storage location: " + externalPath); + return externalPath + "/Android/data/"+packageName; + } + + public static void moveOldData(String src, String dst){ + File srcFile = new File(src); + File dstFile = new File(dst); + + if(srcFile.equals(dstFile)) return; + + if(srcFile.isDirectory() && srcFile.listFiles().length>1){ + for(File f: srcFile.listFiles()){ + if(f.equals(dstFile)){ + moveOldData(f.getAbsolutePath(),dst+"/"+f.getName()); + continue; + } + f.renameTo(new File(dst+"/"+f.getName())); + } + } + } + + public static String getAppDataDirectory(){ + return dataPath; + } + + Thread resourcesExtractorThread; + Thread appInitThread; + + public OFAndroid(String appPackageName, OFActivity activity){ + Log.i("OF","OFAndroid init..."); + OFAndroid.ofActivity = activity; + ofActivity.setVolumeControlStream(AudioManager.STREAM_MUSIC); + //Log.i("OF","external files dir: "+ ofActivity.getApplicationContext().getExternalFilesDir(null)); + OFAndroid.packageName = appPackageName; + OFAndroidObject.setActivity(ofActivity); + instance = this; + //unpackingDone = false; + + if(unpackingDone){ + initView(); + return; + } + + + resourcesExtractorThread = new Thread(new Runnable(){ + @Override + public void run() { + Log.i("OF","starting resources extractor"); + Class raw = null; + boolean copydata = false; + Field[] files = null; + try { + + // try to find if R.raw class exists will throw + // an exception if not + raw = Class.forName(packageName+".R$raw"); + // if it exists copy all the raw resources + // to a folder in the sdcard + files = raw.getDeclaredFields(); + + SharedPreferences preferences = ofActivity.getPreferences(Context.MODE_PRIVATE); + long lastInstalled = preferences.getLong("installed", 0); + + PackageManager pm = ofActivity.getPackageManager(); + + ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); + + String appFile = appInfo.sourceDir; + long installed = new File(appFile).lastModified(); + if(installed>lastInstalled){ + Editor editor = preferences.edit(); + editor.putLong("installed", installed); + editor.commit(); + copydata = true; + } + } catch (NameNotFoundException e1) { + copydata = false; + } catch (ClassNotFoundException e1) { + } + + + ofActivity.onLoadPercent(.05f); + + dataPath=""; + try{ + Log.i("OF", "sd mounted: " + checkSDCardMounted()); + dataPath = getRealExternalStorageDirectory(ofActivity); + + Log.i("OF","creating app directory: " + dataPath); + try{ + File dir = new File(dataPath); + if(!(dir.mkdirs() || dir.isDirectory())){ + if(copydata){ + fatalErrorDialog("Error while copying resources to sdcard:\nCouldn't create directory " + dataPath); + Log.e("OF","error creating dir " + dataPath); + return; + }else{ + throw new Exception(); + } + } + }catch(Exception e){ + fatalErrorDialog("Error while copying resources to sdcard:\nCouldn't create directory " + dataPath + "\n"+e.getMessage()); + Log.e("OF","error creating dir " + dataPath,e); + } + moveOldData(getOldExternalStorageDirectory(packageName), dataPath); + OFAndroid.setAppDataDir(dataPath); + ofActivity.onLoadPercent(.10f); + }catch(Exception e){ + Log.e("OF","couldn't move app resources to data directory " + dataPath,e); + } + + + String app_name=""; + try { + int app_name_id = Class.forName(packageName+".R$string").getField("app_name").getInt(null); + app_name = ofActivity.getResources().getText(app_name_id).toString().toLowerCase(Locale.US); + Log.i("OF","app name: " + app_name); + + if(copydata){ + StatFs stat = new StatFs(dataPath); + double sdAvailSize = (double)stat.getAvailableBlocks() + * (double)stat.getBlockSize(); + for(int i=0; i=sdAvailSize){ + final int mbsize = totalZipSize/1024/1024; + fatalErrorDialog("Error while copying resources to sdcard:\nNot enough space available.("+mbsize+"Mb)\nMake more space by deleting some file in your sdcard"); + }else{ + from = ofActivity.getResources().openRawResource(fileId); + resourceszip = new ZipInputStream(from); + + + while ((entry = resourceszip.getNextEntry()) != null){ + String name = entry.getName(); + if( entry.isDirectory() ) + { + OFZipUtil.mkdirs(outdir,name); + continue; + } + String dir = OFZipUtil.dirpart(name); + if( dir != null ) + OFZipUtil.mkdirs(outdir,dir); + + OFZipUtil.extractFile(resourceszip, outdir, name); + ofActivity.onLoadPercent((float)(.10+i*.01)); + } + + resourceszip.close(); + ofActivity.onLoadPercent(.80f); + } + }catch(Exception e){ + fatalErrorDialog("Error while copying resources to sdcard:\nCheck that you have enough space available.\n"); + } + } + }catch (Exception e) { + Log.e("OF","error copying file",e); + } finally { + if (from != null) + try { + from.close(); + } catch (IOException e) { } + + if (to != null) + try { + to.close(); + } catch (IOException e) { } + } + } + }else{ + ofActivity.onLoadPercent(.80f); + } + } catch (Exception e) { + Log.e("OF","error retrieving app name",e); + } + + } + }); + + appInitThread = new Thread(new Runnable() { + @Override + public void run() { + OFAndroid.init(); + OFAndroid.onUnpackingResourcesDone(); + + } + }); + + resourcesExtractorThread.start(); + appInitThread.start(); + + } + + private void fatalErrorDialog(final String msg){ + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + new AlertDialog.Builder(ofActivity) + .setMessage(msg) + .setTitle("") + .setCancelable(false) + .setNeutralButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + ofActivity.finish(); + } + + }) + .show(); + } + }); + } + + + public void start(){ + Log.i("OF","onStart"); + enableTouchEvents(); + } + + public void restart(){ + Log.i("OF","onRestart"); + enableTouchEvents(); + onRestart(); + /*if(OFAndroidSoundStream.isInitialized() && OFAndroidSoundStream.wasStarted()) + OFAndroidSoundStream.getInstance().start();*/ + } + + private boolean resumed; + + public void pause(){ + Log.i("OF","onPause"); + disableTouchEvents(); + + onPause(); + + synchronized (OFAndroidObject.ofObjects) { + for(OFAndroidObject object : OFAndroidObject.ofObjects){ + object.onPause(); + } + } + if(mGLView!=null) mGLView.onPause(); + if(networkStateReceiver!=null){ + try{ + ofActivity.unregisterReceiver(networkStateReceiver); + }catch(java.lang.IllegalArgumentException e){ + + } + } + + sleepLocked=false; + resumed = false; + } + + public void resume(){ + if(mGLView==null || resumed) return; + resumed = true; + Log.i("OF","onResume"); + enableTouchEvents(); + mGLView.onResume(); + synchronized (OFAndroidObject.ofObjects) { + for(OFAndroidObject object : OFAndroidObject.ofObjects){ + object.onResume(); + } + + } + + + + if(mGLView.isSetup()){ + Log.i("OF","resume view and native"); + onResume(); + } + + if(OFAndroid.orientation!=-1) OFAndroid.setScreenOrientation(OFAndroid.orientation); + + if(networkStateReceiver!=null){ + monitorNetworkState(); + } + + } + + public void stop(){ + resumed = false; + Log.i("OF","onStop"); + disableTouchEvents(); + onStop(); + + synchronized (OFAndroidObject.ofObjects) { + for(OFAndroidObject object : OFAndroidObject.ofObjects){ + object.onStop(); + } + } + + + if(networkStateReceiver!=null){ + try{ + ofActivity.unregisterReceiver(networkStateReceiver); + }catch(java.lang.IllegalArgumentException e){ + + } + } + + sleepLocked=false; + } + + public void destroy(){ + Log.i("OF","onDestroy"); + onDestroy(); + } + + static public void onUnpackingResourcesDone(){ + unpackingDone = true; + ofActivity.onUnpackingResourcesDone(); + } + + static public boolean menuItemSelected(int id){ + try { + Class menu_ids = Class.forName(packageName+".R$id"); + Field[] fields = menu_ids.getFields(); + for(Field field: fields){ + Log.i("OF", "checking " + field.getName()); + if(id == field.getInt(null)){ + return onMenuItemSelected(field.getName()); + } + } + } catch (Exception e) { + Log.w("OF","Trying to get menu items ", e); + } + return false; + } + + static public boolean menuItemChecked(int id, boolean checked){ + try { + Class menu_ids = Class.forName(packageName+".R$id"); + Field[] fields = menu_ids.getFields(); + for(Field field: fields){ + if(id == field.getInt(null)){ + return onMenuItemChecked(field.getName(),checked); + } + } + } catch (Exception e) { + Log.w("OF","Trying to get menu items ", e); + } + return false; + } + + static public void setMenuItemChecked(String idStr, boolean checked){ + final String id = idStr; + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + try { + Class menu_ids = Class.forName(packageName+".R$id"); + Field field = menu_ids.getField(id); + //ofActivity.getMenuInflater(). + } catch (Exception e) { + Log.w("OF","Trying to get menu items ", e); + } + } + }); + } + + static public void setViewItemChecked(String idStr, boolean checked){ + final String id = idStr; + final boolean fchecked = checked; + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + try { + Class menu_ids = Class.forName(packageName+".R$id"); + Field field = menu_ids.getField(id); + CompoundButton checkbox = (CompoundButton) ofActivity.findViewById(field.getInt(null)); + checkbox.setChecked(fchecked); + } catch (Exception e) { + Log.w("OF","Trying to get menu items ", e); + } + } + }); + } + + static public String getStringRes(String idStr){ + Class string_ids; + try { + string_ids = Class.forName(packageName+".R$string"); + Field field = string_ids.getField(idStr); + int id = field.getInt(null); + return (String) ofActivity.getResources().getText(id); + } catch (Exception e) { + Log.e("OF","Couldn't get string resource",e); + } + return ""; + } + + static public boolean isOnline(){ + try{ + return isWifiOnline() || isMobileOnline(); + }catch(Exception e){ + Log.e("OF","error checking connection",e); + return false; + } + } + + static public boolean isWifiOnline(){ + try{ + ConnectivityManager conMgr = (ConnectivityManager)ofActivity.getSystemService(Context.CONNECTIVITY_SERVICE); + return conMgr!=null && ( conMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED ) ; + }catch(Exception e){ + Log.e("OF","error checking wifi connection",e); + return false; + } + } + + static public boolean isMobileOnline(){ + try{ + ConnectivityManager conMgr = (ConnectivityManager)ofActivity.getSystemService(Context.CONNECTIVITY_SERVICE); + + return conMgr!=null && ( conMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ) ; + }catch(Exception e){ + Log.e("OF","error checking mobile connection",e); + return false; + } + } + + static private BroadcastReceiver networkStateReceiver; + + static public void monitorNetworkState(){ + networkStateReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if(!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) return; + + boolean noConnectivity = + intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); + + if (noConnectivity) { + networkConnected(false); + } else { + networkConnected(true); + } + Log.w("Network Listener", "Network Type Changed"); + } + }; + IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); + ofActivity.registerReceiver(networkStateReceiver, filter); + networkConnected(isOnline()); + } + + static public void launchBrowser(String url){ + ofActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); + } + + + static Map progressDialogs = new HashMap(); + static int lastProgressID=0; + static public int progressBox(String msg){ + final String finmsg = msg; + final int id = lastProgressID++; + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + ProgressDialog d = new ProgressDialog(ofActivity); + d.setMessage(finmsg); + d.setCancelable(false); + d.show(); + progressDialogs.put(id,d); + } + }); + return id; + } + + static public void dismissProgressBox(int id){ + final int dId = id; + final ProgressDialog d = progressDialogs.get(id); + if(d!=null){ + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + d.dismiss(); + progressDialogs.remove(dId); + } + }); + } + } + + static public boolean checkSDCardMounted(){ + boolean canSaveExternal = false; + + String storageState = Environment.getExternalStorageState(); + + if (Environment.MEDIA_MOUNTED.equals(storageState)) + canSaveExternal = true; + else + canSaveExternal = false; + + return canSaveExternal; + } + + public static void onActivityResult(int requestCode, int resultCode,Intent intent){ + + synchronized (OFAndroidObject.ofObjects) { + for(OFAndroidObject object : OFAndroidObject.ofObjects){ + object.onActivityResult(requestCode,resultCode,intent); + } + } + } + + // native methods to call OF c++ callbacks + public static native void setAppDataDir(String data_dir); + public static native void init(); + public static native void onRestart(); + public static native void onPause(); + public static native void onResume(); + public static native void onStop(); + public static native void onDestroy(); + public static native void onSurfaceCreated(); + public static native void onSurfaceDestroyed(); + public static native void setup(int w, int h); + public static native void resize(int w, int h); + public static native void render(); + public static native void exit(); + + public static native void onTouchDown(int id,float x,float y,float pressure,float majoraxis,float minoraxis,float angle); + public static native void onTouchDoubleTap(int id,float x,float y,float pressure); + public static native void onTouchUp(int id,float x,float y,float pressure,float majoraxis,float minoraxis,float angle); + public static native void onTouchMoved(int id,float x,float y,float pressure,float majoraxis,float minoraxis,float angle); + public static native void onTouchCancelled(int id,float x,float y); + + public static native void onSwipe(int id, int swipeDir); + + public static native boolean onScaleBegin(ScaleGestureDetector detector); + public static native void onScaleEnd(ScaleGestureDetector detector); + public static native boolean onScale(ScaleGestureDetector detector); + + public static native void onKeyDown(int keyCode); + public static native void onKeyUp(int keyCode); + public static native boolean onBackPressed(); + + public static native boolean onMenuItemSelected(String menu_id); + public static native boolean onMenuItemChecked(String menu_id, boolean checked); + + public static native void okPressed(); + public static native void cancelPressed(); + + public static native void networkConnected(boolean conected); + + + // static methods to be called from OF c++ code + public static void setFullscreen(boolean fs){ + //ofActivity.requestWindowFeature(Window.FEATURE_NO_TITLE); + //ofActivity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + // WindowManager.LayoutParams.FLAG_FULLSCREEN); + /* if(fs) + { + ofActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + ofActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); + } + else + { + ofActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); + ofActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + }*/ + + //m_contentView.requestLayout(); + + //ofActivity.getWindow().setAttributes(attrs); + } + + + private static int orientation=-1; + public static void setScreenOrientation(int orientation){ + OFAndroid.orientation = orientation; + switch(orientation){ + case 0: + ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + break; + case 90: + ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + break; + case 270: + ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + break; + case 180: + ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + break; + case -1: + ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); + break; + } + } + + public static void pauseApp(){ + ofActivity.moveTaskToBack(true); + } + + + public static void setupAccelerometer(){ + if(accelerometer==null) + accelerometer = new OFAndroidAccelerometer((SensorManager)ofActivity.getSystemService(Context.SENSOR_SERVICE)); + } + + public static void setupGPS(){ + if(gps==null) + gps = new OFAndroidGPS(ofActivity); + gps.startGPS(); + } + + public static void stopGPS(){ + if(gps==null) + return; + gps.stopGPS(); + } + + static MulticastLock mcLock; + public static void enableMulticast(){ + WifiManager wifi = (WifiManager)ofActivity.getSystemService( Context.WIFI_SERVICE ); + if(wifi != null) + { + mcLock = wifi.createMulticastLock("mylock"); + mcLock.acquire(); + } + } + + public static void disableMulticast(){ + if(mcLock!=null){ + mcLock.release(); + } + } + + public static void alertBox(String msg){ + final String alertMsg = msg; + /*try{ + Looper.prepare(); + }catch(Exception e){ + + } + final Handler handler = new Handler() { + @Override + public void handleMessage(Message mesg) { + throw new RuntimeException(); + } + };*/ + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + new AlertDialog.Builder(ofActivity) + .setMessage(alertMsg) + .setTitle("") + .setCancelable(false) + .setNeutralButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + OFAndroid.okPressed(); + //handler.sendMessage(handler.obtainMessage()); + } + + }) + .show(); + } + }); + // loop till a runtime exception is triggered. + /*try { Looper.loop(); } + catch(RuntimeException e2) {}*/ + //alert.dismiss(); + } + + + + static public void positiveNegativeBox(String msg,final int positiveButton, final int negativeButton){ + final String alertMsg = msg; + /*try{ + Looper.prepare(); + }catch(Exception e){ + + } + final Handler handler = new Handler() { + @Override + public void handleMessage(Message mesg) { + throw new RuntimeException(); + } + };*/ + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + new AlertDialog.Builder(ofActivity) + .setMessage(alertMsg) + .setTitle("OF") + .setCancelable(false) + .setNeutralButton(positiveButton, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + OFAndroid.okPressed(); + //handler.sendMessage(handler.obtainMessage()); + } + + }) + .setNegativeButton(negativeButton, + + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + OFAndroid.cancelPressed(); + //handler.sendMessage(handler.obtainMessage()); + } + }) + .show(); + + } + }); + // loop till a runtime exception is triggered. + /*try { Looper.loop(); } + catch(RuntimeException e2) {}*/ + } + + public static void okCancelBox(String msg){ + positiveNegativeBox(msg,android.R.string.ok,android.R.string.cancel); + } + + public static void yesNoBox(String msg){ + positiveNegativeBox(msg,android.R.string.yes,android.R.string.no); + } + + private static String textBoxResult=""; + public static void alertTextBox(String question, String text){ + final String alertQuestion = question; + final String alertMsg = text; + /*try{ + Looper.prepare(); + }catch(Exception e){ + + } + final Handler handler = new Handler() { + @Override + public void handleMessage(Message mesg) { + throw new RuntimeException(); + } + };*/ + textBoxResult=text; + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + final EditText input = new EditText(ofActivity); + new AlertDialog.Builder(ofActivity) + .setMessage(alertMsg) + .setTitle(alertQuestion) + .setCancelable(false) + .setNeutralButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + textBoxResult = input.getText().toString(); + OFAndroid.okPressed(); + //handler.sendMessage(handler.obtainMessage()); + } + + }) + .setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + OFAndroid.cancelPressed(); + //handler.sendMessage(handler.obtainMessage()); + } + }) + .setView(input) + .show(); + } + }); + + // loop till a runtime exception is triggered. + /*try { Looper.loop(); } + catch(RuntimeException e2) {}*/ + //alert.dismiss(); + } + + public static String getLastTextBoxResult(){ + return textBoxResult; + } + + private static boolean alertListResult; + public static boolean alertListBox(String title, String[] list){ + final String[] alertList = list; + final String alertTitle = title; + /*Looper.prepare(); + final Handler handler = new Handler() { + @Override + public void handleMessage(Message mesg) { + throw new RuntimeException(); + } + };*/ + alertListResult=false; + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + final ListView listView = new ListView(ofActivity); + final ListAdapter adapter = new ArrayAdapter(ofActivity, android.R.layout.simple_list_item_1, alertList); + listView.setAdapter(adapter); + new AlertDialog.Builder(ofActivity) + .setTitle(alertTitle) + .setCancelable(false) + .setNeutralButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + alertListResult = true; + //OFAndroid.okPressed(); + //handler.sendMessage(handler.obtainMessage()); + } + + }) + /*.setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton){ + alertListResult = false; + OFAndroid.cancelPressed(); + //handler.sendMessage(handler.obtainMessage()); + } + })*/ + .setView(listView) + .show(); + } + }); + + // loop till a runtime exception is triggered. + //try { Looper.loop(); } + //catch(RuntimeException e2) {} + + return alertListResult; + } + + public static void toast(String msg){ + if(msg=="") return; + final String alertMsg = msg; + ofActivity.runOnUiThread(new Runnable(){ + public void run() { + Toast toast = Toast.makeText(ofActivity, alertMsg, Toast.LENGTH_SHORT); + toast.show(); + } + }); + } + + public static Context getContext(){ + return ofActivity; + } + + public static String toDataPath(String path){ + return dataPath + "/" + path; + } + + static boolean sleepLocked=false; + + public static void lockScreenSleep(){ + if(!sleepLocked){ + ofActivity.runOnUiThread(new Runnable() { + + @Override + public void run() { + try{ + sleepLocked=true; + ofActivity.getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); + }catch(Exception e){ + + } + + } + }); + } + } + + public static void unlockScreenSleep(){ + if(sleepLocked){ + ofActivity.runOnUiThread(new Runnable() { + + @Override + public void run() { + try{ + sleepLocked=false; + ofActivity.getWindow().clearFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); + }catch(Exception e){ + + } + + } + }); + } + } + + public static String getRandomUUID(){ + return UUID.randomUUID().toString(); + } + + public static boolean isApplicationSetup(){ + return mGLView!=null && mGLView.isSetup(); + } + + private static OFGLSurfaceView mGLView; + private static OFAndroidAccelerometer accelerometer; + private static OFAndroidGPS gps; + private static OFActivity ofActivity; + private static OFAndroid instance; + private static OFGestureListener gestureListener; + private static String packageName; + private static String dataPath; + public static boolean unpackingDone; + + public static native boolean hasNeon(); + + static { + try{ + Log.i("OF","static init"); + System.loadLibrary("neondetection"); + if(hasNeon()){ + Log.i("OF","loading neon optimized library"); + System.loadLibrary("OFAndroidApp_neon"); + }else{ + Log.i("OF","loading not-neon optimized library"); + System.loadLibrary("OFAndroidApp"); + } + }catch(Throwable e){ + Log.i("OF","failed neon detection, loading not-neon library",e); + System.loadLibrary("OFAndroidApp"); + } + Log.i("OF","initializing app"); + } + + + + public static SurfaceView getGLContentView() { + return mGLView; + } + + public static void disableTouchEvents(){ + if(mGLView!=null){ + mGLView.setOnClickListener(null); + mGLView.setOnTouchListener(null); + } + } + + public static void enableTouchEvents(){ + if(mGLView!=null){ + mGLView.setOnClickListener(gestureListener); + mGLView.setOnTouchListener(gestureListener.touchListener); + } + } + + public static void initView(){ + try { + Log.v("OF","trying to find class: "+packageName+".R$layout"); + Class layout = Class.forName(packageName+".R$layout"); + View view = ofActivity.getLayoutInflater().inflate(layout.getField("main_layout").getInt(null),null); + ofActivity.setContentView(view); + + Class id = Class.forName(packageName+".R$id"); + mGLView = (OFGLSurfaceView)ofActivity.findViewById(id.getField("of_gl_surface").getInt(null)); + + } catch (Exception e) { + Log.e("OF", "couldn't create view from layout falling back to GL only",e); + mGLView = new OFGLSurfaceView(ofActivity); + ofActivity.setContentView(mGLView); + } + } + + public static void setupGL(int versionMajor, int versionMinor){ + final int finalVersionMajor = versionMajor; + final int finalVersionMinor = versionMinor; + ofActivity.runOnUiThread(new Runnable() { + + @Override + public void run() { + gestureListener = new OFGestureListener(ofActivity); + OFEGLConfigChooser.setGLESVersion(finalVersionMajor, finalVersionMinor); + initView(); + instance.resume(); + + } + }); + + try { + Log.i("OF","joining"); + instance.resourcesExtractorThread.join(); + Log.i("OF","joined"); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + /** + * + * @param keyCode + * @param event + * @return true to say we handled this, false to tell Android to handle it + */ + public static boolean keyDown(int keyCode, KeyEvent event) { + if ((keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)) { + if( onBackPressed() ) { + return true; + } else { + // let the Android system handle the back button + return false; + } + } + + if (KeyEvent.isModifierKey(keyCode)) { + /* Android sends a shift keycode (for instance), + then the key that goes with the shift. We don't need the first + keycode, that info is in event.getMetaState() anyway */ + return false; + } + else + { + int unicodeChar = event.getUnicodeChar(); + onKeyDown(unicodeChar); + + // return false to let Android handle certain keys + // like the back and menu keys + return false; + } + } + + /** + * + * @param keyCode + * @param event + * @return true to say we handled this, false to tell Android to handle it + */ + public static boolean keyUp(int keyCode, KeyEvent event) { + if (KeyEvent.isModifierKey(keyCode)) { + /* Android sends a shift keycode (for instance), + then the key that goes with the shift. We don't need the first + keycode, that info is in event.getMetaState() anyway */ + return false; + } + else + { + int unicodeChar = event.getUnicodeChar(); + onKeyUp(unicodeChar); + + // return false to let Android handle certain keys + // like the back and menu keys + return false; + } + } +} + diff --git a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java index 2f891d1f5f9..704d46cf42b 100644 --- a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java +++ b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java @@ -22,19 +22,29 @@ public OFEGLConfigChooser(int r, int g, int b, int a, int depth, int stencil) { mAlphaSize = a; mDepthSize = depth; mStencilSize = stencil; - mGLESVersion = 0; + mGLESVersionMajor = 0; + mGLESVersionMinor = 0; } - public static void setGLESVersion(int version){ - if(version==1) EGL_OPENGL_ES_BIT=1; - else EGL_OPENGL_ES_BIT=4; // == EGL_OPENGL_ES2_BIT - mGLESVersion = version; + public static void setGLESVersion(int versionMajor, int versionMinor){ // versionMinor not needed, just here for consistency + if(versionMajor==1) EGL_OPENGL_ES_BIT=1; + else { + EGL_OPENGL_ES_BIT=4; // == EGL_OPENGL_ES2_BIT + s_configAttribs2[7] = 4; // might not be needed + } + mGLESVersionMajor = versionMajor; + mGLESVersionMinor = versionMinor; } - public static int getGLESVersion(){ - if(mGLESVersion == 0) + public static int getGLESVersionMajor(){ + if(mGLESVersionMajor == 0) + throw new IllegalStateException("You need to set the GLES version!"); + return mGLESVersionMajor; + } + public static int getGLESVersionMinor(){ + if(mGLESVersionMajor == 0) // yes throw new IllegalStateException("You need to set the GLES version!"); - return mGLESVersion; + return mGLESVersionMinor; } /* This EGL config specification is used to specify 1.x rendering. @@ -217,7 +227,8 @@ private void printConfig(EGL10 egl, EGLDisplay display, protected int mAlphaSize; protected int mDepthSize; protected int mStencilSize; - protected static int mGLESVersion; + protected static int mGLESVersionMajor; + protected static int mGLESVersionMinor; private int[] mValue = new int[1]; } @@ -225,7 +236,7 @@ class OFGLSurfaceView extends GLSurfaceView{ public OFGLSurfaceView(Context context) { super(context); mRenderer = new OFAndroidWindow(getWidth(),getHeight()); - setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersion()); + setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersionMajor()); getHolder().setFormat( PixelFormat.OPAQUE ); OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); setEGLConfigChooser(configChooser); @@ -235,7 +246,7 @@ public OFGLSurfaceView(Context context) { public OFGLSurfaceView(Context context,AttributeSet attributes) { super(context,attributes); mRenderer = new OFAndroidWindow(getWidth(),getHeight()); - setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersion()); + setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersionMajor()); getHolder().setFormat( PixelFormat.OPAQUE ); OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); setEGLConfigChooser(configChooser); diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index a20ad981efa..b2ca83fe343 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -180,7 +180,7 @@ ofAppAndroidWindow::~ofAppAndroidWindow() { // TODO Auto-generated destructor stub } -<<<<<<< HEAD + bool ofAppAndroidWindow::isSurfaceDestroyed() { return surfaceDestroyed; } @@ -219,6 +219,8 @@ void ofAppAndroidWindow::setup(const ofxAndroidWindowSettings & settings){ return; } ofGetJNIEnv()->CallStaticVoidMethod(javaClass,method,glesVersion,settings.preserveContextOnPause); + + } void ofAppAndroidWindow::update(){ @@ -458,46 +460,33 @@ Java_cc_openframeworks_OFAndroid_onSurfaceDestroyed( JNIEnv* env, jclass thiz } JNIEXPORT void JNICALL -Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ - if(appSetup){ - ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated"; - if(!surfaceDestroyed){ - ofNotifyEvent(ofxAndroidEvents().unloadGL); - } - ofNotifyEvent(ofxAndroidEvents().reloadGL); - window->renderer()->pushStyle(); - window->renderer()->setupGraphicDefaults(); - window->renderer()->popStyle(); - window->setThreadedEvents(false); - int glesVersion = window->getGlesVersion(); - bSetupScreen = true; - if( glesVersion < 2 ) - { - ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 1"; - dynamic_cast(window->renderer().get())->setup(); - } - else - { - ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0"; - dynamic_cast(window->renderer().get())->setup(glesVersion,sGLESVersionMinor); - } +Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ + ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated"; - }else{ - if(window != nullptr) { - int glesVersion = window->getGlesVersion(); - bSetupScreen = true; - if (glesVersion < 2) { - ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 1"; - dynamic_cast(window->renderer().get())->setup(); - } else { - ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0"; - dynamic_cast(window->renderer().get())->setup( - glesVersion, sGLESVersionMinor); - } - } - } + if(!surfaceDestroyed && appSetup){ + ofNotifyEvent(ofxAndroidEvents().unloadGL); + } + ofNotifyEvent(ofxAndroidEvents().reloadGL); + + if(appSetup){ + window->renderer()->pushStyle(); + window->renderer()->setupGraphicDefaults(); + window->renderer()->popStyle(); + window->setThreadedEvents(false); + } + + bSetupScreen = true; + int glesVersion = window->getGlesVersion(); + + if(glesVersion < 2){ + ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 1"; + dynamic_cast(window->renderer().get())->setup(); + }else{ + ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0+"; + dynamic_cast(window->renderer().get())->setup(glesVersion, sGLESVersionMinor); + } - surfaceDestroyed = false; + surfaceDestroyed = false; } JNIEXPORT jboolean JNICALL From 959fde7b47496809dd5e56a93b1d4940a7d3a612 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Thu, 17 Sep 2015 16:16:09 +0200 Subject: [PATCH 08/38] Update EGL window class to use new GLES settings class. TODO: iOS --- libs/openFrameworks/app/ofAppEGLWindow.cpp | 45 ++++++++++++---------- libs/openFrameworks/app/ofAppEGLWindow.h | 3 +- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/libs/openFrameworks/app/ofAppEGLWindow.cpp b/libs/openFrameworks/app/ofAppEGLWindow.cpp index 0aee905afe0..d19ea965a53 100644 --- a/libs/openFrameworks/app/ofAppEGLWindow.cpp +++ b/libs/openFrameworks/app/ofAppEGLWindow.cpp @@ -259,7 +259,8 @@ ofAppEGLWindow::ofAppEGLWindow() { x11Display = NULL; x11Screen = NULL; x11ScreenNum = 0l; - glesVersion = 1; + glesVersionMajor = 1; + glesVersionMinor = 0; if(instance!=NULL){ ofLogError("ofAppEGLWindow") << "trying to create more than one instance"; @@ -402,7 +403,8 @@ void ofAppEGLWindow::setup(const ofAppEGLWindowSettings & _settings) { eglConfig = NULL; eglVersionMajor = -1; eglVersionMinor = -1; - glesVersion = 1; + glesVersionMajor = 1; + glesVersionMinor = 0; // X11 check // char * pDisplay; @@ -439,7 +441,8 @@ void ofAppEGLWindow::setup(const ofAppEGLWindowSettings & _settings) { initNative(); - glesVersion = settings.glesVersion; + glesVersionMajor = settings.glesVersionMajor(); + glesVersionMinor = settings.glesVersionMinor(); // we set this here, and if we need to make a fullscreen // app, we do it during the first loop. windowMode = settings.windowMode; @@ -477,7 +480,7 @@ void ofAppEGLWindow::setup(const ofAppEGLWindowSettings & _settings) { makeCurrent(); if(currentRenderer->getType()==ofGLProgrammableRenderer::TYPE){ - static_cast(currentRenderer.get())->setup(settings.glesVersion,0); + static_cast(currentRenderer.get())->setup(settings.glesVersionMajor(),settings.glesVersionMinor()); }else{ static_cast(currentRenderer.get())->setup(); } @@ -547,7 +550,7 @@ bool ofAppEGLWindow::createSurface() { // success! } - EGLint glesVersion; + EGLint glesVersionBit; int glesVersionForContext; if(ofGetCurrentRenderer()) { @@ -556,12 +559,12 @@ bool ofAppEGLWindow::createSurface() { ofLogNotice("ofAppEGLWindow") << "createSurface(): no current renderer selected"; } - if(this->glesVersion==2){ - glesVersion = EGL_OPENGL_ES2_BIT; - glesVersionForContext = 2; - ofLogNotice("ofAppEGLWindow") << "createSurface(): GLES2 renderer detected"; + if(this->glesVersionMajor>=2){ + glesVersionBit = EGL_OPENGL_ES2_BIT; + glesVersionForContext = this->glesVersionMajor; + ofLogNotice("ofAppEGLWindow") << "createSurface(): GLES" << glesVersionForContext << " renderer detected"; }else{ - glesVersion = EGL_OPENGL_ES_BIT; + glesVersionBit = EGL_OPENGL_ES_BIT; glesVersionForContext = 1; ofLogNotice("ofAppEGLWindow") << "createSurface(): default renderer detected"; } @@ -580,7 +583,7 @@ bool ofAppEGLWindow::createSurface() { attribute_list_framebuffer_config[i++] = iter->second; } attribute_list_framebuffer_config[i++] = EGL_RENDERABLE_TYPE; - attribute_list_framebuffer_config[i++] = glesVersion; //openGL ES version + attribute_list_framebuffer_config[i++] = glesVersionBit; //openGL ES version attribute_list_framebuffer_config[i] = EGL_NONE; // add the terminator EGLint num_configs; @@ -1424,7 +1427,7 @@ void ofAppEGLWindow::setupNativeInput(){ tc.c_lflag &= ~ECHO; tc.c_lflag |= ECHONL; tcsetattr(STDIN_FILENO, TCSAFLUSH, &tc); - + mb.mouseButtonState = 0; kb.shiftPressed = false; @@ -1492,7 +1495,7 @@ void ofAppEGLWindow::printInput(){ void ofAppEGLWindow::destroyNativeInput(){ ofLogNotice("ofAppEGLWindow") << "destroyNativeInput()"; - + for(device::iterator iter = inputDevices.begin(); iter != inputDevices.end(); iter++){ if(iter->second >= 0){ ::close(iter->second); @@ -1514,7 +1517,7 @@ void ofAppEGLWindow::processInput(int fd, const char * node){ static ofMouseEventArgs mouseEvent; struct input_event ev; char key = 0; - + bool pushKeyEvent = false; bool pushMouseEvent = false; bool pushTouchEvent = false; @@ -1564,7 +1567,7 @@ void ofAppEGLWindow::processInput(int fd, const char * node){ pushMouseEvent = true; } }else if(ev.code == BTN_TOUCH){ - if(ev.value == 0){ // release + if(ev.value == 0){ // release touchEvent.type = ofTouchEventArgs::up; touchEvent.id = 0; mt[touchEvent.id] = 0; @@ -1728,7 +1731,7 @@ void ofAppEGLWindow::processInput(int fd, const char * node){ }else{ ofLogNotice("ofAppEGLWindow") << "readKeyboardEvents(): input_event.code is outside of our small range"; } - } + } } }else if (ev.type == EV_REL){ int axis = ev.code; @@ -1779,7 +1782,7 @@ void ofAppEGLWindow::processInput(int fd, const char * node){ pushTouchEvent = true; } } - else + else { if (mt[touchEvent.id] == 0){ touchEvent.type = ofTouchEventArgs::down; @@ -1837,8 +1840,8 @@ void ofAppEGLWindow::processInput(int fd, const char * node){ } } - - + + if(pushKeyEvent){ lock(); @@ -1846,7 +1849,7 @@ void ofAppEGLWindow::processInput(int fd, const char * node){ unlock(); pushKeyEvent = false; } - + if(pushMouseEvent){ // lock the thread for a moment while we copy the data lock(); @@ -1922,7 +1925,7 @@ void ofAppEGLWindow::readNativeUDevEvents() { removeInput(devnode); } } - + udev_device_unref(dev); }else{ ofLogNotice("ofAppEGLWindow") << "readNativeUDevEvents(): device returned by receive_device() is NULL"; diff --git a/libs/openFrameworks/app/ofAppEGLWindow.h b/libs/openFrameworks/app/ofAppEGLWindow.h index a70a35e2aff..991d344990f 100644 --- a/libs/openFrameworks/app/ofAppEGLWindow.h +++ b/libs/openFrameworks/app/ofAppEGLWindow.h @@ -269,7 +269,7 @@ class ofAppEGLWindow : public ofAppBaseGLESWindow, public ofThread { void readNativeUDevEvents(); void readNativeInputEvents(); - void processInput(int fd, const char * node); + void processInput(int fd, const char * node); void addInput(const char * node, bool isMouse); void removeInput(const char * node); void printInput(); @@ -279,6 +279,7 @@ class ofAppEGLWindow : public ofAppBaseGLESWindow, public ofThread { private: ofAppEGLWindowSettings settings; int glesVersion; ///< \brief Indicate the version of OpenGL for Embedded Systems. + int glesVersionMinor; bool keyboardDetected; bool mouseDetected; long threadTimeout; From 358c2662b28c7258a809c65beb0275bb7b39400a Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Fri, 18 Sep 2015 12:27:20 +0200 Subject: [PATCH 09/38] Fixed problem with broken textures. --- libs/openFrameworks/gl/ofGLUtils.cpp | 383 +++++++++++---------------- 1 file changed, 158 insertions(+), 225 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 34ea578b6ea..21d7559b972 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -154,88 +154,11 @@ string ofGetGLInternalFormatName(int glInternalFormat) { } int ofGetGLFormatFromInternal(int glInternalFormat){ - switch(glInternalFormat) { - case GL_RGBA: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_RGBA8: - case GL_RGBA16F: - #ifndef TARGET_OPENGLES - case GL_RGBA16: - case GL_RGBA32F_ARB: - #endif - #endif - return GL_RGBA; - - - case GL_RGB: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_RGB8: - #ifndef TARGET_OPENGLES - case GL_RGB16: - case GL_RGB32F_ARB: - #endif - #endif - return GL_RGB; - - - case GL_LUMINANCE: - #ifndef TARGET_OPENGLES - case GL_LUMINANCE8: - case GL_LUMINANCE16: - #ifndef TARGET_OPENGLES - case GL_LUMINANCE32F_ARB: - #endif - #endif - return GL_LUMINANCE; - - case GL_LUMINANCE_ALPHA: - #ifndef TARGET_OPENGLES - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE16_ALPHA16: - #ifndef TARGET_OPENGLES - case GL_LUMINANCE_ALPHA32F_ARB: - #endif - #endif - return GL_LUMINANCE_ALPHA; - - - case GL_DEPTH_STENCIL: - return GL_DEPTH_STENCIL; - - case GL_DEPTH_COMPONENT: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) - case GL_DEPTH_COMPONENT16: - #endif - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_DEPTH_COMPONENT24: - #endif - #if defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) - case GL_DEPTH_COMPONENT32F: - #endif - #ifndef TARGET_OPENGLES - case GL_DEPTH_COMPONENT32: - #endif - return GL_DEPTH_COMPONENT; - - case GL_STENCIL_INDEX: - return GL_STENCIL_INDEX; - - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_R8: - case GL_R16F: - case GL_R32F: -#ifndef TARGET_OPENGLES - case GL_R16: -#endif - return GL_RED; - #endif - -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_RG8: - case GL_RG16F: - case GL_RG32F: - #ifndef TARGET_OPENGLES - case GL_RG16: + switch(glInternalFormat) { + case GL_RGBA: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGBA8: + case GL_RGBA16F: #endif #ifndef TARGET_OPENGLES case GL_RGBA16: @@ -298,6 +221,7 @@ int ofGetGLFormatFromInternal(int glInternalFormat){ case GL_STENCIL_INDEX: return GL_STENCIL_INDEX; + // modern red / RG formats (used for float + half-float textures) #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_R8: case GL_R16F: @@ -325,112 +249,122 @@ int ofGetGLFormatFromInternal(int glInternalFormat){ } int ofGetGLTypeFromInternal(int glInternalFormat){ - - switch(glInternalFormat) { - case GL_RGB: - case GL_RGBA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_ALPHA: -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + switch(glInternalFormat) { + // 8-bit unsigned byte formats (most common on all platforms) + case GL_RGB: + case GL_RGBA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_ALPHA: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) #ifndef TARGET_OPENGLES - case GL_LUMINANCE8: - case GL_LUMINANCE8_ALPHA8: - case GL_ALPHA8: + case GL_LUMINANCE8: + case GL_LUMINANCE8_ALPHA8: + case GL_ALPHA8: #endif - case GL_R8: - case GL_RG8: - case GL_RGB8: - case GL_RGBA8: -#endif - return GL_UNSIGNED_BYTE; - - -#if !defined(TARGET_OPENGLES) && defined(GL_RGB565) - case GL_RGB565: - return GL_UNSIGNED_SHORT_5_6_5; - break; -#endif + case GL_R8: + case GL_RG8: + case GL_RGB8: + case GL_RGBA8: + #endif + return GL_UNSIGNED_BYTE; + // 16-bit integer formats (desktop only) + #ifndef TARGET_OPENGLES + case GL_LUMINANCE16: + case GL_LUMINANCE16_ALPHA16: + case GL_R16: + case GL_RG16: + case GL_RGB16: + case GL_RGBA16: + return GL_UNSIGNED_SHORT; + #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - // === HALF-FLOAT (16F) — these four formats === + // 16-bit half-float formats (GLES 3.0 core + Emscripten) + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_R16F: case GL_RG16F: case GL_RGB16F: case GL_RGBA16F: #ifdef GL_HALF_FLOAT - return GL_HALF_FLOAT; // core in GLES 3.0+ + return GL_HALF_FLOAT; // core in GLES 3.0+ #else - return GL_HALF_FLOAT_OES; // fallback for older headers + return GL_HALF_FLOAT_OES; // safe fallback for older headers #endif - // === FULL-FLOAT (32F) === + #endif + + // 32-bit full float formats (native ES3 + desktop) + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_R32F: case GL_RG32F: case GL_RGB32F: case GL_RGBA32F: return GL_FLOAT; -#endif -#ifndef TARGET_OPENGLES + #endif + + #ifndef TARGET_OPENGLES + // legacy desktop luminance float formats case GL_LUMINANCE32F_ARB: case GL_LUMINANCE_ALPHA32F_ARB: return GL_FLOAT; - case GL_LUMINANCE16: - case GL_LUMINANCE16_ALPHA16: - case GL_R16: - case GL_RG16: - case GL_RGB16: - case GL_RGBA16: - return GL_UNSIGNED_SHORT; -#endif + #endif - case GL_DEPTH_STENCIL: - return GL_UNSIGNED_INT_24_8; + // depth / stencil formats + case GL_DEPTH_STENCIL: + return GL_UNSIGNED_INT_24_8; - case GL_DEPTH_COMPONENT: -#ifndef TARGET_OPENGLES - case GL_DEPTH_COMPONENT16: - case GL_R16UI: - case GL_RG16UI: - case GL_RGB16UI: - case GL_RGBA16UI: -#endif - return GL_UNSIGNED_SHORT; + case GL_DEPTH_COMPONENT: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_DEPTH_COMPONENT16: + case GL_R16UI: + case GL_RG16UI: + case GL_RGB16UI: + case GL_RGBA16UI: + #endif + return GL_UNSIGNED_SHORT; -#ifndef TARGET_OPENGLES - case GL_R16I: - case GL_RG16I: - case GL_RGB16I: - case GL_RGBA16I: - return GL_SHORT; -#endif + #if defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) + case GL_DEPTH_COMPONENT24: + return GL_UNSIGNED_INT; + case GL_DEPTH_COMPONENT32F: + return GL_FLOAT; + #endif -#ifndef TARGET_OPENGLES - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - case GL_R32UI: - case GL_RG32UI: - case GL_RGB32UI: - case GL_RGBA32UI: - return GL_UNSIGNED_INT; -#endif + #ifndef TARGET_OPENGLES + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + case GL_R32UI: + case GL_RG32UI: + case GL_RGB32UI: + case GL_RGBA32UI: + return GL_UNSIGNED_INT; -#ifndef TARGET_OPENGLES - case GL_R32I: - case GL_RG32I: - case GL_RGB32I: - case GL_RGBA32I: - return GL_INT; -#endif + case GL_R16I: + case GL_RG16I: + case GL_RGB16I: + case GL_RGBA16I: + return GL_SHORT; + + case GL_R32I: + case GL_RG32I: + case GL_RGB32I: + case GL_RGBA32I: + return GL_INT; + #endif - case GL_STENCIL_INDEX: - return GL_UNSIGNED_BYTE; + case GL_STENCIL_INDEX: + return GL_UNSIGNED_BYTE; - default: - ofLogError("ofGLUtils") << "ofGetGLTypeFromInternal(): unknown internal format " << glInternalFormat << ", returning GL_UNSIGNED_BYTE"; - return GL_UNSIGNED_BYTE; + // legacy RGB565 (very old desktop/Android) + #if !defined(TARGET_OPENGLES) && defined(GL_RGB565) + case GL_RGB565: + return GL_UNSIGNED_SHORT_5_6_5; + #endif - } + default: + ofLogError("ofGLUtils") << "ofGetGLTypeFromInternal(): unknown internal format " << glInternalFormat << ", returning GL_UNSIGNED_BYTE"; + return GL_UNSIGNED_BYTE; + } } //--------------------------------- @@ -457,7 +391,7 @@ int ofGetGLType(const ofFloatPixels & pixels) { } //--------------------------------- -ofImageType ofGetImageTypeFromGLType(int glType){ +oofImageType ofGetImageTypeFromGLType(int glType){ switch(glType){ case GL_LUMINANCE: #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) @@ -689,26 +623,26 @@ int ofGetGLInternalFormatFromPixelFormat(ofPixelFormat pixelFormat){ case OF_PIXELS_Y: case OF_PIXELS_U: case OF_PIXELS_V: -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#ifndef TARGET_OPENGLES if(ofIsGLProgrammableRenderer()){ return GL_R8; }else{ #endif return GL_LUMINANCE; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#ifndef TARGET_OPENGLES } #endif case OF_PIXELS_GRAY_ALPHA: case OF_PIXELS_YUY2: case OF_PIXELS_UV: case OF_PIXELS_VU: -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#ifndef TARGET_OPENGLES if(ofIsGLProgrammableRenderer()){ return GL_RG8; }else{ #endif return GL_LUMINANCE_ALPHA; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#ifndef TARGET_OPENGLES } #endif default: @@ -719,71 +653,71 @@ int ofGetGLInternalFormatFromPixelFormat(ofPixelFormat pixelFormat){ } int ofGetGLFormatFromPixelFormat(ofPixelFormat pixelFormat){ - switch(pixelFormat){ - case OF_PIXELS_BGRA: -#ifdef TARGET_OPENGLES - return GL_BGRA_EXT; -#else + switch(pixelFormat){ + case OF_PIXELS_BGRA: + #ifdef TARGET_OPENGLES + return GL_BGRA_EXT; + #else return GL_BGRA; -#endif - case OF_PIXELS_RGB: - return GL_RGB; - case OF_PIXELS_BGR: -#ifdef TARGET_OPENGLES - return GL_RGB; -#else + #endif + + case OF_PIXELS_RGB: + return GL_RGB; + + case OF_PIXELS_BGR: + #ifdef TARGET_OPENGLES + return GL_RGB; // ES does not support GL_BGR + #else return GL_BGR; -#endif - case OF_PIXELS_RGBA: - return GL_RGBA; + #endif + + case OF_PIXELS_RGBA: + return GL_RGBA; + case OF_PIXELS_RGB565: return GL_RGB; - case OF_PIXELS_GRAY: + + case OF_PIXELS_GRAY: case OF_PIXELS_NV12: case OF_PIXELS_NV21: - case OF_PIXELS_YV12: - case OF_PIXELS_I420: - case OF_PIXELS_Y: - case OF_PIXELS_U: - case OF_PIXELS_V: -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - if(ofIsGLProgrammableRenderer()){ - return GL_RED; - }else{ -#endif - return GL_LUMINANCE; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - } -#endif + case OF_PIXELS_YV12: + case OF_PIXELS_I420: + case OF_PIXELS_Y: + case OF_PIXELS_U: + case OF_PIXELS_V: + #ifndef TARGET_OPENGLES + if(ofIsGLProgrammableRenderer()){ + return GL_RED; + }else{ + #endif + return GL_LUMINANCE; + #ifndef TARGET_OPENGLES + } + #endif + case OF_PIXELS_GRAY_ALPHA: - case OF_PIXELS_YUY2: - case OF_PIXELS_UV: - case OF_PIXELS_VU: -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - if(ofIsGLProgrammableRenderer()){ - return GL_RG; - }else{ -#endif - return GL_LUMINANCE_ALPHA; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - } -#endif - default: + case OF_PIXELS_YUY2: + case OF_PIXELS_UV: + case OF_PIXELS_VU: + #ifndef TARGET_OPENGLES + if(ofIsGLProgrammableRenderer()){ + return GL_RG; + }else{ + #endif + return GL_LUMINANCE_ALPHA; + #ifndef TARGET_OPENGLES + } + #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - if(ofIsGLProgrammableRenderer()){ - ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format " - << ofToString(pixelFormat) << ", returning GL_RED"; - return GL_RED; - }else{ -#endif - ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format " - << ofToString(pixelFormat) << ", returning GL_LUMINANCE"; - return GL_LUMINANCE; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - } -#endif - } + default: + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format " << pixelFormat << ", returning GL_RED"; + return ofIsGLProgrammableRenderer() ? GL_RED : GL_LUMINANCE; + #else + ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format " << pixelFormat << ", returning GL_LUMINANCE"; + return GL_LUMINANCE; + #endif + } } @@ -827,7 +761,7 @@ int ofGetBytesPerChannelFromGLType(int glType){ case GL_FLOAT: return 4; #endif -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_UNSIGNED_INT_24_8: return 4; #endif @@ -841,7 +775,6 @@ int ofGetBytesPerChannelFromGLType(int glType){ case GL_HALF_FLOAT: return 2; #endif - default: ofLogError("ofGetBytesPerChannelFromGLType") << "unknown type returning 1"; return 1; From 90fd1ae4b9e9c14731aabf0f343566c37c5888a5 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Thu, 1 Oct 2015 00:27:41 +0200 Subject: [PATCH 10/38] Smaller fixes --- .../src/cc/openframeworks/OFAndroid.java | 1 + .../cc/openframeworks/OFAndroidWindow.java | 14 ++++--- libs/openFrameworks/gl/ofFbo.cpp | 2 +- libs/openFrameworks/gl/ofGLUtils.cpp | 38 +++++++++++++++++++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java index eb68dfffa99..1e3bebde707 100644 --- a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java +++ b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java @@ -262,6 +262,7 @@ public void run() { while ((entry = resourceszip.getNextEntry()) != null){ String name = entry.getName(); + Log.i("OF","handling " + name); if( entry.isDirectory() ) { OFZipUtil.mkdirs(outdir,name); diff --git a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java index 704d46cf42b..c7b1d31dc9d 100644 --- a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java +++ b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java @@ -22,8 +22,8 @@ public OFEGLConfigChooser(int r, int g, int b, int a, int depth, int stencil) { mAlphaSize = a; mDepthSize = depth; mStencilSize = stencil; - mGLESVersionMajor = 0; - mGLESVersionMinor = 0; + mGLESVersionMajor = 3; + mGLESVersionMinor = 1; } public static void setGLESVersion(int versionMajor, int versionMinor){ // versionMinor not needed, just here for consistency @@ -37,13 +37,13 @@ public static void setGLESVersion(int versionMajor, int versionMinor){ // versio } public static int getGLESVersionMajor(){ - if(mGLESVersionMajor == 0) - throw new IllegalStateException("You need to set the GLES version!"); + // if(mGLESVersionMajor == 0) + // throw new IllegalStateException("You need to set the GLES version!"); return mGLESVersionMajor; } public static int getGLESVersionMinor(){ - if(mGLESVersionMajor == 0) // yes - throw new IllegalStateException("You need to set the GLES version!"); + // if(mGLESVersionMajor == 0) // yes + // throw new IllegalStateException("You need to set the GLES version!"); return mGLESVersionMinor; } @@ -236,6 +236,7 @@ class OFGLSurfaceView extends GLSurfaceView{ public OFGLSurfaceView(Context context) { super(context); mRenderer = new OFAndroidWindow(getWidth(),getHeight()); + Log.i("OF"," setting context version " + OFEGLConfigChooser.getGLESVersionMajor()); setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersionMajor()); getHolder().setFormat( PixelFormat.OPAQUE ); OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); @@ -246,6 +247,7 @@ public OFGLSurfaceView(Context context) { public OFGLSurfaceView(Context context,AttributeSet attributes) { super(context,attributes); mRenderer = new OFAndroidWindow(getWidth(),getHeight()); + Log.i("OF"," setting context version " + OFEGLConfigChooser.getGLESVersionMajor()); setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersionMajor()); getHolder().setFormat( PixelFormat.OPAQUE ); OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); diff --git a/libs/openFrameworks/gl/ofFbo.cpp b/libs/openFrameworks/gl/ofFbo.cpp index b82c9b84bfb..ceedfba085d 100644 --- a/libs/openFrameworks/gl/ofFbo.cpp +++ b/libs/openFrameworks/gl/ofFbo.cpp @@ -941,7 +941,7 @@ int ofFbo::getNumTextures() const { //---------------------------------------------------------- void ofFbo::setActiveDrawBuffer(int i){ if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) vector activebuffers(1, i); setActiveDrawBuffers(activebuffers); #endif diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 21d7559b972..846f21723d6 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -433,6 +433,7 @@ oofImageType ofGetImageTypeFromGLType(int glType){ #endif return OF_IMAGE_COLOR; +<<<<<<< HEAD case GL_RGBA: #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_RGBA8: @@ -449,6 +450,41 @@ oofImageType ofGetImageTypeFromGLType(int glType){ return OF_IMAGE_COLOR_ALPHA; } return OF_IMAGE_UNDEFINED; +======= + case GL_RGB: +#ifndef TARGET_OPENGLES + case GL_RGB16: +#endif +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGB8: + case GL_RGB16F: + case GL_RGB16I: + case GL_RGB16UI: + case GL_RGB32F: + case GL_RGB32I: + case GL_RGB32UI: +#endif + return OF_IMAGE_COLOR; + + + case GL_RGBA: +#ifndef TARGET_OPENGLES + case GL_RGBA16: +#endif +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_RGBA8: + case GL_RGBA16F: + case GL_RGBA16I: + case GL_RGBA16UI: + case GL_RGBA32F: + case GL_RGBA32I: + case GL_RGBA32UI: +#endif + return OF_IMAGE_COLOR_ALPHA; + } + ofLogError("ofGLUtils") << "ofGetImageTypeFromGLType(): unknown type " << glType << ", returning OF_IMAGE_UNDEFINED"; + return OF_IMAGE_UNDEFINED; +>>>>>>> b2409bdb7 (Smaller fixes) } GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ @@ -469,6 +505,7 @@ GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ break; } #else + ofLogError("ofGLUtils") << "ofGetGLPolyMode(): poly modes not supported in GLES"; return 0; #endif } @@ -491,6 +528,7 @@ ofPolyRenderMode ofGetOFPolyMode(GLuint mode){ break; } #else + ofLogError("ofGLUtils") << "ofGetOFPolyMode(): poly modes not supported in GLES. Returning OF_MESH_FILL"; return OF_MESH_FILL; #endif } From e3ca87766f39308ca15e993dcd4cb236a518e724 Mon Sep 17 00:00:00 2001 From: Marcel Ruegenberg Date: Thu, 1 Oct 2015 00:27:54 +0200 Subject: [PATCH 11/38] . --- addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index b2ca83fe343..e2a8f921cd9 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -219,8 +219,6 @@ void ofAppAndroidWindow::setup(const ofxAndroidWindowSettings & settings){ return; } ofGetJNIEnv()->CallStaticVoidMethod(javaClass,method,glesVersion,settings.preserveContextOnPause); - - } void ofAppAndroidWindow::update(){ @@ -459,6 +457,7 @@ Java_cc_openframeworks_OFAndroid_onSurfaceDestroyed( JNIEnv* env, jclass thiz } } + JNIEXPORT void JNICALL Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated"; From 45e936b373cc8db5f849af9b6662e4e3d6af617b Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Tue, 7 Apr 2026 00:19:07 +1000 Subject: [PATCH 12/38] Remove old android changes --- .../src/cc/openframeworks/OFAndroid.java | 1163 ----------------- .../cc/openframeworks/OFAndroidWindow.java | 334 ----- .../project/android/config.android.default.mk | 605 --------- 3 files changed, 2102 deletions(-) delete mode 100644 addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java delete mode 100644 addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java delete mode 100644 libs/openFrameworksCompiled/project/android/config.android.default.mk diff --git a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java deleted file mode 100644 index 1e3bebde707..00000000000 --- a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroid.java +++ /dev/null @@ -1,1163 +0,0 @@ -package cc.openframeworks; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.UUID; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.hardware.SensorManager; -import android.media.AudioManager; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.Uri; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.MulticastLock; -import android.os.Environment; -import android.os.StatFs; -import android.util.Log; -import android.view.KeyEvent; -import android.view.ScaleGestureDetector; -import android.view.SurfaceView; -import android.view.View; -import android.view.WindowManager.LayoutParams; -import android.widget.ArrayAdapter; -import android.widget.CompoundButton; -import android.widget.EditText; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.Toast; - -public class OFAndroid { - - // List based on http://bit.ly/NpkL4Q - private static final String[] mExternalStorageDirectories = new String[] { - "/mnt/sdcard-ext", - "/mnt/sdcard/external_sd", - "/sdcard/sd", - "/mnt/external_sd", - "/emmc", - "/mnt/sdcard/bpemmctest", - "/mnt/sdcard/_ExternalSD", - "/mnt/Removable/MicroSD", - "/Removable/MicroSD", - "/sdcard"}; - - public static String getRealExternalStorageDirectory(Context context) - { - // Standard way to get the external storage directory - String externalPath = context.getExternalFilesDir(null).getPath(); - File SDCardDir = new File(externalPath); - if(SDCardDir.exists() && SDCardDir.canWrite()) { - return externalPath; - } - - // This checks if any of the directories from mExternalStorageDirectories exist, if it does, it uses that one instead - for(int i = 0; i < mExternalStorageDirectories.length; i++) - { - //Log.i("OF", "Checking: " + mExternalStorageDirectories[i]); - SDCardDir = new File(mExternalStorageDirectories[i]); - if(SDCardDir.exists() && SDCardDir.canWrite()) { - externalPath = mExternalStorageDirectories[i]; // Found writable location - break; - } - } - - Log.i("OF", "Using storage location: " + externalPath); - return externalPath; - } - - public static String getOldExternalStorageDirectory(String packageName) - { - // Standard way to get the external storage directory - String externalPath = Environment.getExternalStorageDirectory().getPath(); - File SDCardDir = new File(externalPath); - if(SDCardDir.exists() && SDCardDir.canWrite()) { - return externalPath + "/Android/data/"+packageName; - } - - // This checks if any of the directories from mExternalStorageDirectories exist, if it does, it uses that one instead - for(int i = 0; i < mExternalStorageDirectories.length; i++) - { - //Log.i("OF", "Checking: " + mExternalStorageDirectories[i]); - SDCardDir = new File(mExternalStorageDirectories[i]); - if(SDCardDir.exists() && SDCardDir.canWrite()) { - externalPath = mExternalStorageDirectories[i]; // Found writable location - break; - } - } - - Log.i("OF", "Using storage location: " + externalPath); - return externalPath + "/Android/data/"+packageName; - } - - public static void moveOldData(String src, String dst){ - File srcFile = new File(src); - File dstFile = new File(dst); - - if(srcFile.equals(dstFile)) return; - - if(srcFile.isDirectory() && srcFile.listFiles().length>1){ - for(File f: srcFile.listFiles()){ - if(f.equals(dstFile)){ - moveOldData(f.getAbsolutePath(),dst+"/"+f.getName()); - continue; - } - f.renameTo(new File(dst+"/"+f.getName())); - } - } - } - - public static String getAppDataDirectory(){ - return dataPath; - } - - Thread resourcesExtractorThread; - Thread appInitThread; - - public OFAndroid(String appPackageName, OFActivity activity){ - Log.i("OF","OFAndroid init..."); - OFAndroid.ofActivity = activity; - ofActivity.setVolumeControlStream(AudioManager.STREAM_MUSIC); - //Log.i("OF","external files dir: "+ ofActivity.getApplicationContext().getExternalFilesDir(null)); - OFAndroid.packageName = appPackageName; - OFAndroidObject.setActivity(ofActivity); - instance = this; - //unpackingDone = false; - - if(unpackingDone){ - initView(); - return; - } - - - resourcesExtractorThread = new Thread(new Runnable(){ - @Override - public void run() { - Log.i("OF","starting resources extractor"); - Class raw = null; - boolean copydata = false; - Field[] files = null; - try { - - // try to find if R.raw class exists will throw - // an exception if not - raw = Class.forName(packageName+".R$raw"); - // if it exists copy all the raw resources - // to a folder in the sdcard - files = raw.getDeclaredFields(); - - SharedPreferences preferences = ofActivity.getPreferences(Context.MODE_PRIVATE); - long lastInstalled = preferences.getLong("installed", 0); - - PackageManager pm = ofActivity.getPackageManager(); - - ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); - - String appFile = appInfo.sourceDir; - long installed = new File(appFile).lastModified(); - if(installed>lastInstalled){ - Editor editor = preferences.edit(); - editor.putLong("installed", installed); - editor.commit(); - copydata = true; - } - } catch (NameNotFoundException e1) { - copydata = false; - } catch (ClassNotFoundException e1) { - } - - - ofActivity.onLoadPercent(.05f); - - dataPath=""; - try{ - Log.i("OF", "sd mounted: " + checkSDCardMounted()); - dataPath = getRealExternalStorageDirectory(ofActivity); - - Log.i("OF","creating app directory: " + dataPath); - try{ - File dir = new File(dataPath); - if(!(dir.mkdirs() || dir.isDirectory())){ - if(copydata){ - fatalErrorDialog("Error while copying resources to sdcard:\nCouldn't create directory " + dataPath); - Log.e("OF","error creating dir " + dataPath); - return; - }else{ - throw new Exception(); - } - } - }catch(Exception e){ - fatalErrorDialog("Error while copying resources to sdcard:\nCouldn't create directory " + dataPath + "\n"+e.getMessage()); - Log.e("OF","error creating dir " + dataPath,e); - } - moveOldData(getOldExternalStorageDirectory(packageName), dataPath); - OFAndroid.setAppDataDir(dataPath); - ofActivity.onLoadPercent(.10f); - }catch(Exception e){ - Log.e("OF","couldn't move app resources to data directory " + dataPath,e); - } - - - String app_name=""; - try { - int app_name_id = Class.forName(packageName+".R$string").getField("app_name").getInt(null); - app_name = ofActivity.getResources().getText(app_name_id).toString().toLowerCase(Locale.US); - Log.i("OF","app name: " + app_name); - - if(copydata){ - StatFs stat = new StatFs(dataPath); - double sdAvailSize = (double)stat.getAvailableBlocks() - * (double)stat.getBlockSize(); - for(int i=0; i=sdAvailSize){ - final int mbsize = totalZipSize/1024/1024; - fatalErrorDialog("Error while copying resources to sdcard:\nNot enough space available.("+mbsize+"Mb)\nMake more space by deleting some file in your sdcard"); - }else{ - from = ofActivity.getResources().openRawResource(fileId); - resourceszip = new ZipInputStream(from); - - - while ((entry = resourceszip.getNextEntry()) != null){ - String name = entry.getName(); - Log.i("OF","handling " + name); - if( entry.isDirectory() ) - { - OFZipUtil.mkdirs(outdir,name); - continue; - } - String dir = OFZipUtil.dirpart(name); - if( dir != null ) - OFZipUtil.mkdirs(outdir,dir); - - OFZipUtil.extractFile(resourceszip, outdir, name); - ofActivity.onLoadPercent((float)(.10+i*.01)); - } - - resourceszip.close(); - ofActivity.onLoadPercent(.80f); - } - }catch(Exception e){ - fatalErrorDialog("Error while copying resources to sdcard:\nCheck that you have enough space available.\n"); - } - } - }catch (Exception e) { - Log.e("OF","error copying file",e); - } finally { - if (from != null) - try { - from.close(); - } catch (IOException e) { } - - if (to != null) - try { - to.close(); - } catch (IOException e) { } - } - } - }else{ - ofActivity.onLoadPercent(.80f); - } - } catch (Exception e) { - Log.e("OF","error retrieving app name",e); - } - - } - }); - - appInitThread = new Thread(new Runnable() { - @Override - public void run() { - OFAndroid.init(); - OFAndroid.onUnpackingResourcesDone(); - - } - }); - - resourcesExtractorThread.start(); - appInitThread.start(); - - } - - private void fatalErrorDialog(final String msg){ - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - new AlertDialog.Builder(ofActivity) - .setMessage(msg) - .setTitle("") - .setCancelable(false) - .setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - ofActivity.finish(); - } - - }) - .show(); - } - }); - } - - - public void start(){ - Log.i("OF","onStart"); - enableTouchEvents(); - } - - public void restart(){ - Log.i("OF","onRestart"); - enableTouchEvents(); - onRestart(); - /*if(OFAndroidSoundStream.isInitialized() && OFAndroidSoundStream.wasStarted()) - OFAndroidSoundStream.getInstance().start();*/ - } - - private boolean resumed; - - public void pause(){ - Log.i("OF","onPause"); - disableTouchEvents(); - - onPause(); - - synchronized (OFAndroidObject.ofObjects) { - for(OFAndroidObject object : OFAndroidObject.ofObjects){ - object.onPause(); - } - } - if(mGLView!=null) mGLView.onPause(); - if(networkStateReceiver!=null){ - try{ - ofActivity.unregisterReceiver(networkStateReceiver); - }catch(java.lang.IllegalArgumentException e){ - - } - } - - sleepLocked=false; - resumed = false; - } - - public void resume(){ - if(mGLView==null || resumed) return; - resumed = true; - Log.i("OF","onResume"); - enableTouchEvents(); - mGLView.onResume(); - synchronized (OFAndroidObject.ofObjects) { - for(OFAndroidObject object : OFAndroidObject.ofObjects){ - object.onResume(); - } - - } - - - - if(mGLView.isSetup()){ - Log.i("OF","resume view and native"); - onResume(); - } - - if(OFAndroid.orientation!=-1) OFAndroid.setScreenOrientation(OFAndroid.orientation); - - if(networkStateReceiver!=null){ - monitorNetworkState(); - } - - } - - public void stop(){ - resumed = false; - Log.i("OF","onStop"); - disableTouchEvents(); - onStop(); - - synchronized (OFAndroidObject.ofObjects) { - for(OFAndroidObject object : OFAndroidObject.ofObjects){ - object.onStop(); - } - } - - - if(networkStateReceiver!=null){ - try{ - ofActivity.unregisterReceiver(networkStateReceiver); - }catch(java.lang.IllegalArgumentException e){ - - } - } - - sleepLocked=false; - } - - public void destroy(){ - Log.i("OF","onDestroy"); - onDestroy(); - } - - static public void onUnpackingResourcesDone(){ - unpackingDone = true; - ofActivity.onUnpackingResourcesDone(); - } - - static public boolean menuItemSelected(int id){ - try { - Class menu_ids = Class.forName(packageName+".R$id"); - Field[] fields = menu_ids.getFields(); - for(Field field: fields){ - Log.i("OF", "checking " + field.getName()); - if(id == field.getInt(null)){ - return onMenuItemSelected(field.getName()); - } - } - } catch (Exception e) { - Log.w("OF","Trying to get menu items ", e); - } - return false; - } - - static public boolean menuItemChecked(int id, boolean checked){ - try { - Class menu_ids = Class.forName(packageName+".R$id"); - Field[] fields = menu_ids.getFields(); - for(Field field: fields){ - if(id == field.getInt(null)){ - return onMenuItemChecked(field.getName(),checked); - } - } - } catch (Exception e) { - Log.w("OF","Trying to get menu items ", e); - } - return false; - } - - static public void setMenuItemChecked(String idStr, boolean checked){ - final String id = idStr; - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - try { - Class menu_ids = Class.forName(packageName+".R$id"); - Field field = menu_ids.getField(id); - //ofActivity.getMenuInflater(). - } catch (Exception e) { - Log.w("OF","Trying to get menu items ", e); - } - } - }); - } - - static public void setViewItemChecked(String idStr, boolean checked){ - final String id = idStr; - final boolean fchecked = checked; - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - try { - Class menu_ids = Class.forName(packageName+".R$id"); - Field field = menu_ids.getField(id); - CompoundButton checkbox = (CompoundButton) ofActivity.findViewById(field.getInt(null)); - checkbox.setChecked(fchecked); - } catch (Exception e) { - Log.w("OF","Trying to get menu items ", e); - } - } - }); - } - - static public String getStringRes(String idStr){ - Class string_ids; - try { - string_ids = Class.forName(packageName+".R$string"); - Field field = string_ids.getField(idStr); - int id = field.getInt(null); - return (String) ofActivity.getResources().getText(id); - } catch (Exception e) { - Log.e("OF","Couldn't get string resource",e); - } - return ""; - } - - static public boolean isOnline(){ - try{ - return isWifiOnline() || isMobileOnline(); - }catch(Exception e){ - Log.e("OF","error checking connection",e); - return false; - } - } - - static public boolean isWifiOnline(){ - try{ - ConnectivityManager conMgr = (ConnectivityManager)ofActivity.getSystemService(Context.CONNECTIVITY_SERVICE); - return conMgr!=null && ( conMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED ) ; - }catch(Exception e){ - Log.e("OF","error checking wifi connection",e); - return false; - } - } - - static public boolean isMobileOnline(){ - try{ - ConnectivityManager conMgr = (ConnectivityManager)ofActivity.getSystemService(Context.CONNECTIVITY_SERVICE); - - return conMgr!=null && ( conMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ) ; - }catch(Exception e){ - Log.e("OF","error checking mobile connection",e); - return false; - } - } - - static private BroadcastReceiver networkStateReceiver; - - static public void monitorNetworkState(){ - networkStateReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if(!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) return; - - boolean noConnectivity = - intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); - - if (noConnectivity) { - networkConnected(false); - } else { - networkConnected(true); - } - Log.w("Network Listener", "Network Type Changed"); - } - }; - IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); - ofActivity.registerReceiver(networkStateReceiver, filter); - networkConnected(isOnline()); - } - - static public void launchBrowser(String url){ - ofActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); - } - - - static Map progressDialogs = new HashMap(); - static int lastProgressID=0; - static public int progressBox(String msg){ - final String finmsg = msg; - final int id = lastProgressID++; - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - ProgressDialog d = new ProgressDialog(ofActivity); - d.setMessage(finmsg); - d.setCancelable(false); - d.show(); - progressDialogs.put(id,d); - } - }); - return id; - } - - static public void dismissProgressBox(int id){ - final int dId = id; - final ProgressDialog d = progressDialogs.get(id); - if(d!=null){ - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - d.dismiss(); - progressDialogs.remove(dId); - } - }); - } - } - - static public boolean checkSDCardMounted(){ - boolean canSaveExternal = false; - - String storageState = Environment.getExternalStorageState(); - - if (Environment.MEDIA_MOUNTED.equals(storageState)) - canSaveExternal = true; - else - canSaveExternal = false; - - return canSaveExternal; - } - - public static void onActivityResult(int requestCode, int resultCode,Intent intent){ - - synchronized (OFAndroidObject.ofObjects) { - for(OFAndroidObject object : OFAndroidObject.ofObjects){ - object.onActivityResult(requestCode,resultCode,intent); - } - } - } - - // native methods to call OF c++ callbacks - public static native void setAppDataDir(String data_dir); - public static native void init(); - public static native void onRestart(); - public static native void onPause(); - public static native void onResume(); - public static native void onStop(); - public static native void onDestroy(); - public static native void onSurfaceCreated(); - public static native void onSurfaceDestroyed(); - public static native void setup(int w, int h); - public static native void resize(int w, int h); - public static native void render(); - public static native void exit(); - - public static native void onTouchDown(int id,float x,float y,float pressure,float majoraxis,float minoraxis,float angle); - public static native void onTouchDoubleTap(int id,float x,float y,float pressure); - public static native void onTouchUp(int id,float x,float y,float pressure,float majoraxis,float minoraxis,float angle); - public static native void onTouchMoved(int id,float x,float y,float pressure,float majoraxis,float minoraxis,float angle); - public static native void onTouchCancelled(int id,float x,float y); - - public static native void onSwipe(int id, int swipeDir); - - public static native boolean onScaleBegin(ScaleGestureDetector detector); - public static native void onScaleEnd(ScaleGestureDetector detector); - public static native boolean onScale(ScaleGestureDetector detector); - - public static native void onKeyDown(int keyCode); - public static native void onKeyUp(int keyCode); - public static native boolean onBackPressed(); - - public static native boolean onMenuItemSelected(String menu_id); - public static native boolean onMenuItemChecked(String menu_id, boolean checked); - - public static native void okPressed(); - public static native void cancelPressed(); - - public static native void networkConnected(boolean conected); - - - // static methods to be called from OF c++ code - public static void setFullscreen(boolean fs){ - //ofActivity.requestWindowFeature(Window.FEATURE_NO_TITLE); - //ofActivity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, - // WindowManager.LayoutParams.FLAG_FULLSCREEN); - /* if(fs) - { - ofActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - ofActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); - } - else - { - ofActivity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); - ofActivity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - }*/ - - //m_contentView.requestLayout(); - - //ofActivity.getWindow().setAttributes(attrs); - } - - - private static int orientation=-1; - public static void setScreenOrientation(int orientation){ - OFAndroid.orientation = orientation; - switch(orientation){ - case 0: - ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - break; - case 90: - ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - break; - case 270: - ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - break; - case 180: - ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - break; - case -1: - ofActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); - break; - } - } - - public static void pauseApp(){ - ofActivity.moveTaskToBack(true); - } - - - public static void setupAccelerometer(){ - if(accelerometer==null) - accelerometer = new OFAndroidAccelerometer((SensorManager)ofActivity.getSystemService(Context.SENSOR_SERVICE)); - } - - public static void setupGPS(){ - if(gps==null) - gps = new OFAndroidGPS(ofActivity); - gps.startGPS(); - } - - public static void stopGPS(){ - if(gps==null) - return; - gps.stopGPS(); - } - - static MulticastLock mcLock; - public static void enableMulticast(){ - WifiManager wifi = (WifiManager)ofActivity.getSystemService( Context.WIFI_SERVICE ); - if(wifi != null) - { - mcLock = wifi.createMulticastLock("mylock"); - mcLock.acquire(); - } - } - - public static void disableMulticast(){ - if(mcLock!=null){ - mcLock.release(); - } - } - - public static void alertBox(String msg){ - final String alertMsg = msg; - /*try{ - Looper.prepare(); - }catch(Exception e){ - - } - final Handler handler = new Handler() { - @Override - public void handleMessage(Message mesg) { - throw new RuntimeException(); - } - };*/ - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - new AlertDialog.Builder(ofActivity) - .setMessage(alertMsg) - .setTitle("") - .setCancelable(false) - .setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - OFAndroid.okPressed(); - //handler.sendMessage(handler.obtainMessage()); - } - - }) - .show(); - } - }); - // loop till a runtime exception is triggered. - /*try { Looper.loop(); } - catch(RuntimeException e2) {}*/ - //alert.dismiss(); - } - - - - static public void positiveNegativeBox(String msg,final int positiveButton, final int negativeButton){ - final String alertMsg = msg; - /*try{ - Looper.prepare(); - }catch(Exception e){ - - } - final Handler handler = new Handler() { - @Override - public void handleMessage(Message mesg) { - throw new RuntimeException(); - } - };*/ - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - new AlertDialog.Builder(ofActivity) - .setMessage(alertMsg) - .setTitle("OF") - .setCancelable(false) - .setNeutralButton(positiveButton, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - OFAndroid.okPressed(); - //handler.sendMessage(handler.obtainMessage()); - } - - }) - .setNegativeButton(negativeButton, - - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - OFAndroid.cancelPressed(); - //handler.sendMessage(handler.obtainMessage()); - } - }) - .show(); - - } - }); - // loop till a runtime exception is triggered. - /*try { Looper.loop(); } - catch(RuntimeException e2) {}*/ - } - - public static void okCancelBox(String msg){ - positiveNegativeBox(msg,android.R.string.ok,android.R.string.cancel); - } - - public static void yesNoBox(String msg){ - positiveNegativeBox(msg,android.R.string.yes,android.R.string.no); - } - - private static String textBoxResult=""; - public static void alertTextBox(String question, String text){ - final String alertQuestion = question; - final String alertMsg = text; - /*try{ - Looper.prepare(); - }catch(Exception e){ - - } - final Handler handler = new Handler() { - @Override - public void handleMessage(Message mesg) { - throw new RuntimeException(); - } - };*/ - textBoxResult=text; - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - final EditText input = new EditText(ofActivity); - new AlertDialog.Builder(ofActivity) - .setMessage(alertMsg) - .setTitle(alertQuestion) - .setCancelable(false) - .setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - textBoxResult = input.getText().toString(); - OFAndroid.okPressed(); - //handler.sendMessage(handler.obtainMessage()); - } - - }) - .setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - OFAndroid.cancelPressed(); - //handler.sendMessage(handler.obtainMessage()); - } - }) - .setView(input) - .show(); - } - }); - - // loop till a runtime exception is triggered. - /*try { Looper.loop(); } - catch(RuntimeException e2) {}*/ - //alert.dismiss(); - } - - public static String getLastTextBoxResult(){ - return textBoxResult; - } - - private static boolean alertListResult; - public static boolean alertListBox(String title, String[] list){ - final String[] alertList = list; - final String alertTitle = title; - /*Looper.prepare(); - final Handler handler = new Handler() { - @Override - public void handleMessage(Message mesg) { - throw new RuntimeException(); - } - };*/ - alertListResult=false; - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - final ListView listView = new ListView(ofActivity); - final ListAdapter adapter = new ArrayAdapter(ofActivity, android.R.layout.simple_list_item_1, alertList); - listView.setAdapter(adapter); - new AlertDialog.Builder(ofActivity) - .setTitle(alertTitle) - .setCancelable(false) - .setNeutralButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - alertListResult = true; - //OFAndroid.okPressed(); - //handler.sendMessage(handler.obtainMessage()); - } - - }) - /*.setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton){ - alertListResult = false; - OFAndroid.cancelPressed(); - //handler.sendMessage(handler.obtainMessage()); - } - })*/ - .setView(listView) - .show(); - } - }); - - // loop till a runtime exception is triggered. - //try { Looper.loop(); } - //catch(RuntimeException e2) {} - - return alertListResult; - } - - public static void toast(String msg){ - if(msg=="") return; - final String alertMsg = msg; - ofActivity.runOnUiThread(new Runnable(){ - public void run() { - Toast toast = Toast.makeText(ofActivity, alertMsg, Toast.LENGTH_SHORT); - toast.show(); - } - }); - } - - public static Context getContext(){ - return ofActivity; - } - - public static String toDataPath(String path){ - return dataPath + "/" + path; - } - - static boolean sleepLocked=false; - - public static void lockScreenSleep(){ - if(!sleepLocked){ - ofActivity.runOnUiThread(new Runnable() { - - @Override - public void run() { - try{ - sleepLocked=true; - ofActivity.getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); - }catch(Exception e){ - - } - - } - }); - } - } - - public static void unlockScreenSleep(){ - if(sleepLocked){ - ofActivity.runOnUiThread(new Runnable() { - - @Override - public void run() { - try{ - sleepLocked=false; - ofActivity.getWindow().clearFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); - }catch(Exception e){ - - } - - } - }); - } - } - - public static String getRandomUUID(){ - return UUID.randomUUID().toString(); - } - - public static boolean isApplicationSetup(){ - return mGLView!=null && mGLView.isSetup(); - } - - private static OFGLSurfaceView mGLView; - private static OFAndroidAccelerometer accelerometer; - private static OFAndroidGPS gps; - private static OFActivity ofActivity; - private static OFAndroid instance; - private static OFGestureListener gestureListener; - private static String packageName; - private static String dataPath; - public static boolean unpackingDone; - - public static native boolean hasNeon(); - - static { - try{ - Log.i("OF","static init"); - System.loadLibrary("neondetection"); - if(hasNeon()){ - Log.i("OF","loading neon optimized library"); - System.loadLibrary("OFAndroidApp_neon"); - }else{ - Log.i("OF","loading not-neon optimized library"); - System.loadLibrary("OFAndroidApp"); - } - }catch(Throwable e){ - Log.i("OF","failed neon detection, loading not-neon library",e); - System.loadLibrary("OFAndroidApp"); - } - Log.i("OF","initializing app"); - } - - - - public static SurfaceView getGLContentView() { - return mGLView; - } - - public static void disableTouchEvents(){ - if(mGLView!=null){ - mGLView.setOnClickListener(null); - mGLView.setOnTouchListener(null); - } - } - - public static void enableTouchEvents(){ - if(mGLView!=null){ - mGLView.setOnClickListener(gestureListener); - mGLView.setOnTouchListener(gestureListener.touchListener); - } - } - - public static void initView(){ - try { - Log.v("OF","trying to find class: "+packageName+".R$layout"); - Class layout = Class.forName(packageName+".R$layout"); - View view = ofActivity.getLayoutInflater().inflate(layout.getField("main_layout").getInt(null),null); - ofActivity.setContentView(view); - - Class id = Class.forName(packageName+".R$id"); - mGLView = (OFGLSurfaceView)ofActivity.findViewById(id.getField("of_gl_surface").getInt(null)); - - } catch (Exception e) { - Log.e("OF", "couldn't create view from layout falling back to GL only",e); - mGLView = new OFGLSurfaceView(ofActivity); - ofActivity.setContentView(mGLView); - } - } - - public static void setupGL(int versionMajor, int versionMinor){ - final int finalVersionMajor = versionMajor; - final int finalVersionMinor = versionMinor; - ofActivity.runOnUiThread(new Runnable() { - - @Override - public void run() { - gestureListener = new OFGestureListener(ofActivity); - OFEGLConfigChooser.setGLESVersion(finalVersionMajor, finalVersionMinor); - initView(); - instance.resume(); - - } - }); - - try { - Log.i("OF","joining"); - instance.resourcesExtractorThread.join(); - Log.i("OF","joined"); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - } - - /** - * - * @param keyCode - * @param event - * @return true to say we handled this, false to tell Android to handle it - */ - public static boolean keyDown(int keyCode, KeyEvent event) { - if ((keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)) { - if( onBackPressed() ) { - return true; - } else { - // let the Android system handle the back button - return false; - } - } - - if (KeyEvent.isModifierKey(keyCode)) { - /* Android sends a shift keycode (for instance), - then the key that goes with the shift. We don't need the first - keycode, that info is in event.getMetaState() anyway */ - return false; - } - else - { - int unicodeChar = event.getUnicodeChar(); - onKeyDown(unicodeChar); - - // return false to let Android handle certain keys - // like the back and menu keys - return false; - } - } - - /** - * - * @param keyCode - * @param event - * @return true to say we handled this, false to tell Android to handle it - */ - public static boolean keyUp(int keyCode, KeyEvent event) { - if (KeyEvent.isModifierKey(keyCode)) { - /* Android sends a shift keycode (for instance), - then the key that goes with the shift. We don't need the first - keycode, that info is in event.getMetaState() anyway */ - return false; - } - else - { - int unicodeChar = event.getUnicodeChar(); - onKeyUp(unicodeChar); - - // return false to let Android handle certain keys - // like the back and menu keys - return false; - } - } -} - diff --git a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java b/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java deleted file mode 100644 index c7b1d31dc9d..00000000000 --- a/addons/ofxAndroid/ofAndroidLib/src/cc/openframeworks/OFAndroidWindow.java +++ /dev/null @@ -1,334 +0,0 @@ -package cc.openframeworks; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.opengles.GL; -import javax.microedition.khronos.opengles.GL10; - -import android.content.Context; -import android.graphics.PixelFormat; -import android.opengl.GLSurfaceView; -import android.util.AttributeSet; -import android.util.Log; -import android.view.SurfaceHolder; - -class OFEGLConfigChooser implements GLSurfaceView.EGLConfigChooser { - - public OFEGLConfigChooser(int r, int g, int b, int a, int depth, int stencil) { - mRedSize = r; - mGreenSize = g; - mBlueSize = b; - mAlphaSize = a; - mDepthSize = depth; - mStencilSize = stencil; - mGLESVersionMajor = 3; - mGLESVersionMinor = 1; - } - - public static void setGLESVersion(int versionMajor, int versionMinor){ // versionMinor not needed, just here for consistency - if(versionMajor==1) EGL_OPENGL_ES_BIT=1; - else { - EGL_OPENGL_ES_BIT=4; // == EGL_OPENGL_ES2_BIT - s_configAttribs2[7] = 4; // might not be needed - } - mGLESVersionMajor = versionMajor; - mGLESVersionMinor = versionMinor; - } - - public static int getGLESVersionMajor(){ - // if(mGLESVersionMajor == 0) - // throw new IllegalStateException("You need to set the GLES version!"); - return mGLESVersionMajor; - } - public static int getGLESVersionMinor(){ - // if(mGLESVersionMajor == 0) // yes - // throw new IllegalStateException("You need to set the GLES version!"); - return mGLESVersionMinor; - } - - /* This EGL config specification is used to specify 1.x rendering. - * We use a minimum size of 4 bits for red/green/blue, but will - * perform actual matching in chooseConfig() below. - */ - private static boolean DEBUG = false; - private static int EGL_OPENGL_ES_BIT = 1; - private static int[] s_configAttribs2 = - { - EGL10.EGL_RED_SIZE, 4, - EGL10.EGL_GREEN_SIZE, 4, - EGL10.EGL_BLUE_SIZE, 4, - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, - EGL10.EGL_NONE - }; - - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { - - /* Get the number of minimally matching EGL configurations - */ - int[] num_config = new int[1]; - egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); - - int numConfigs = num_config[0]; - - if (numConfigs <= 0) { - throw new IllegalArgumentException("No configs match configSpec"); - } - - /* Allocate then read the array of minimally matching EGL configs - */ - EGLConfig[] configs = new EGLConfig[numConfigs]; - egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); - - if (DEBUG) { - printConfigs(egl, display, configs); - } - /* Now return the "best" one - */ - return chooseConfig(egl, display, configs); - } - - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, - EGLConfig[] configs) { - for(EGLConfig config : configs) { - int d = findConfigAttrib(egl, display, config, - EGL10.EGL_DEPTH_SIZE, 0); - int s = findConfigAttrib(egl, display, config, - EGL10.EGL_STENCIL_SIZE, 0); - - // We need at least mDepthSize and mStencilSize bits - if (d < mDepthSize || s < mStencilSize) - continue; - - // We want an *exact* match for red/green/blue/alpha - int r = findConfigAttrib(egl, display, config, - EGL10.EGL_RED_SIZE, 0); - int g = findConfigAttrib(egl, display, config, - EGL10.EGL_GREEN_SIZE, 0); - int b = findConfigAttrib(egl, display, config, - EGL10.EGL_BLUE_SIZE, 0); - int a = findConfigAttrib(egl, display, config, - EGL10.EGL_ALPHA_SIZE, 0); - - if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) - return config; - } - return null; - } - - private int findConfigAttrib(EGL10 egl, EGLDisplay display, - EGLConfig config, int attribute, int defaultValue) { - - if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { - return mValue[0]; - } - return defaultValue; - } - - private void printConfigs(EGL10 egl, EGLDisplay display, - EGLConfig[] configs) { - int numConfigs = configs.length; - Log.w("OF", String.format("%d configurations", numConfigs)); - for (int i = 0; i < numConfigs; i++) { - Log.w("OF", String.format("Configuration %d:\n", i)); - printConfig(egl, display, configs[i]); - } - } - - private void printConfig(EGL10 egl, EGLDisplay display, - EGLConfig config) { - int[] attributes = { - EGL10.EGL_BUFFER_SIZE, - EGL10.EGL_ALPHA_SIZE, - EGL10.EGL_BLUE_SIZE, - EGL10.EGL_GREEN_SIZE, - EGL10.EGL_RED_SIZE, - EGL10.EGL_DEPTH_SIZE, - EGL10.EGL_STENCIL_SIZE, - EGL10.EGL_CONFIG_CAVEAT, - EGL10.EGL_CONFIG_ID, - EGL10.EGL_LEVEL, - EGL10.EGL_MAX_PBUFFER_HEIGHT, - EGL10.EGL_MAX_PBUFFER_PIXELS, - EGL10.EGL_MAX_PBUFFER_WIDTH, - EGL10.EGL_NATIVE_RENDERABLE, - EGL10.EGL_NATIVE_VISUAL_ID, - EGL10.EGL_NATIVE_VISUAL_TYPE, - 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, - EGL10.EGL_SAMPLES, - EGL10.EGL_SAMPLE_BUFFERS, - EGL10.EGL_SURFACE_TYPE, - EGL10.EGL_TRANSPARENT_TYPE, - EGL10.EGL_TRANSPARENT_RED_VALUE, - EGL10.EGL_TRANSPARENT_GREEN_VALUE, - EGL10.EGL_TRANSPARENT_BLUE_VALUE, - 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, - 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, - 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, - 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, - EGL10.EGL_LUMINANCE_SIZE, - EGL10.EGL_ALPHA_MASK_SIZE, - EGL10.EGL_COLOR_BUFFER_TYPE, - EGL10.EGL_RENDERABLE_TYPE, - 0x3042 // EGL10.EGL_CONFORMANT - }; - String[] names = { - "EGL_BUFFER_SIZE", - "EGL_ALPHA_SIZE", - "EGL_BLUE_SIZE", - "EGL_GREEN_SIZE", - "EGL_RED_SIZE", - "EGL_DEPTH_SIZE", - "EGL_STENCIL_SIZE", - "EGL_CONFIG_CAVEAT", - "EGL_CONFIG_ID", - "EGL_LEVEL", - "EGL_MAX_PBUFFER_HEIGHT", - "EGL_MAX_PBUFFER_PIXELS", - "EGL_MAX_PBUFFER_WIDTH", - "EGL_NATIVE_RENDERABLE", - "EGL_NATIVE_VISUAL_ID", - "EGL_NATIVE_VISUAL_TYPE", - "EGL_PRESERVED_RESOURCES", - "EGL_SAMPLES", - "EGL_SAMPLE_BUFFERS", - "EGL_SURFACE_TYPE", - "EGL_TRANSPARENT_TYPE", - "EGL_TRANSPARENT_RED_VALUE", - "EGL_TRANSPARENT_GREEN_VALUE", - "EGL_TRANSPARENT_BLUE_VALUE", - "EGL_BIND_TO_TEXTURE_RGB", - "EGL_BIND_TO_TEXTURE_RGBA", - "EGL_MIN_SWAP_INTERVAL", - "EGL_MAX_SWAP_INTERVAL", - "EGL_LUMINANCE_SIZE", - "EGL_ALPHA_MASK_SIZE", - "EGL_COLOR_BUFFER_TYPE", - "EGL_RENDERABLE_TYPE", - "EGL_CONFORMANT" - }; - int[] value = new int[1]; - for (int i = 0; i < attributes.length; i++) { - int attribute = attributes[i]; - String name = names[i]; - if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { - Log.w("OF", String.format(" %s: %d\n", name, value[0])); - } else { - // Log.w(TAG, String.format(" %s: failed\n", name)); - while (egl.eglGetError() != EGL10.EGL_SUCCESS); - } - } - } - - // Subclasses can adjust these values: - protected int mRedSize; - protected int mGreenSize; - protected int mBlueSize; - protected int mAlphaSize; - protected int mDepthSize; - protected int mStencilSize; - protected static int mGLESVersionMajor; - protected static int mGLESVersionMinor; - private int[] mValue = new int[1]; -} - -class OFGLSurfaceView extends GLSurfaceView{ - public OFGLSurfaceView(Context context) { - super(context); - mRenderer = new OFAndroidWindow(getWidth(),getHeight()); - Log.i("OF"," setting context version " + OFEGLConfigChooser.getGLESVersionMajor()); - setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersionMajor()); - getHolder().setFormat( PixelFormat.OPAQUE ); - OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); - setEGLConfigChooser(configChooser); - setRenderer(mRenderer); - } - - public OFGLSurfaceView(Context context,AttributeSet attributes) { - super(context,attributes); - mRenderer = new OFAndroidWindow(getWidth(),getHeight()); - Log.i("OF"," setting context version " + OFEGLConfigChooser.getGLESVersionMajor()); - setEGLContextClientVersion(OFEGLConfigChooser.getGLESVersionMajor()); - getHolder().setFormat( PixelFormat.OPAQUE ); - OFEGLConfigChooser configChooser = new OFEGLConfigChooser(8,8,8,0,16,0); - setEGLConfigChooser(configChooser); - setRenderer(mRenderer); - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - super.surfaceDestroyed(holder); - OFAndroid.onSurfaceDestroyed(); - } - - boolean isSetup(){ - return mRenderer.isSetup(); - } - - private OFAndroidWindow mRenderer; -} - -class OFAndroidWindow implements GLSurfaceView.Renderer { - - public OFAndroidWindow(int w, int h){ - this.w = w; - this.h = h; - } - - @Override - public void onSurfaceCreated(GL10 gl, EGLConfig config) { - Log.i("OF","onSurfaceCreated"); - OFAndroid.onSurfaceCreated(); - try{ - ((OFActivity)OFAndroid.getContext()).onGLSurfaceCreated(); - }catch(Exception e){ - Log.e("OF","couldn call onGLSurfaceCreated",e); - } - return; - - } - - @Override - public void onSurfaceChanged(GL10 gl, int w, int h) { - this.w = w; - this.h = h; - if(!setup && OFAndroid.unpackingDone){ - setup(); - } - OFGestureListener.swipe_Min_Distance = (int)(Math.max(w, h)*.04); - OFGestureListener.swipe_Max_Distance = (int)(Math.max(w, h)*.6); - OFAndroid.resize(w, h); - } - - private void setup(){ - OFAndroid.setup(w,h); - setup = true; - android.os.Process.setThreadPriority(8); - OFGestureListener.swipe_Min_Distance = (int)(Math.max(w, h)*.04); - OFGestureListener.swipe_Max_Distance = (int)(Math.max(w, h)*.6); - try{ - ((OFActivity)OFAndroid.getContext()).onGLSurfaceCreated(); - }catch(Exception e){ - Log.e("OF","couldn call onGLSurfaceCreated",e); - } - } - - @Override - public void onDrawFrame(GL10 gl) { - if(setup && OFAndroid.unpackingDone){ - OFAndroid.render(); - }else if(!setup && OFAndroid.unpackingDone){ - setup(); - }else{ - gl.glClear(GL10.GL_COLOR_BUFFER_BIT); - gl.glClearColor(.5f, .5f, .5f, 1.f); - } - } - - public boolean isSetup(){ - return setup; - } - - private static boolean setup; - private int w,h; -} diff --git a/libs/openFrameworksCompiled/project/android/config.android.default.mk b/libs/openFrameworksCompiled/project/android/config.android.default.mk deleted file mode 100644 index a3e4867c29a..00000000000 --- a/libs/openFrameworksCompiled/project/android/config.android.default.mk +++ /dev/null @@ -1,605 +0,0 @@ -################################################################################ -# CONFIGURE CORE PLATFORM MAKEFILE -# This file is where we make platform and architecture specific -# configurations. This file can be specified for a generic architecture or can -# be defined as variants. For instance, normally this file will be located in -# a platform specific subpath such as -# -# $(OF_ROOT)/libs/openFrameworksComplied/linux64 -# -# This file will then be a generic platform file like: -# -# configure.core.linux64.default.make -# -# Or it can specify a specific platform variant like: -# -# configure.core.linuxarmv6l.raspberrypi.make -# -################################################################################ - -################################################################################ -# PLATFORM SPECIFIC CHECKS -# This is a platform defined section to create internal flags to enable or -# disable the addition of various features within this makefile. For -# instance, on Linux, we check to see if there GTK+-2.0 is defined, allowing -# us to include that library and generate DEFINES that are interpreted as -# ifdefs within the openFrameworks core source code. -################################################################################ - -#check if mpg123 exists and add it -#HAS_SYSTEM_MPG123 = $(shell pkg-config libmpg123 --exists; echo $$?) - -include $(OF_ROOT)/libs/openFrameworksCompiled/project/android/paths.make -ARCH = android - -ifndef ABIS_TO_COMPILE_RELEASE - ABIS_TO_COMPILE_RELEASE = armv7 neon x86 -endif - -ifndef ABIS_TO_COMPILE_DEBUG - ABIS_TO_COMPILE_DEBUG = armv7 -endif - - -################################################################################ -# PLATFORM DEFINES -# Create a list of DEFINES for this platform. The list will be converted into -# CFLAGS with the "-D" flag later in the makefile. An example of fully -# qualified flag might look something like this: -DTARGET_OPENGLES2 -# -# DEFINES are used throughout the openFrameworks code, especially when making -# #ifdef decisions for cross-platform compatibility. For instance, when -# choosing a video playback framework, the openFrameworks base classes look at -# the DEFINES to determine what source files to include or what default player -# to use. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -PLATFORM_DEFINES = -PLATFORM_DEFINES = ANDROID - -ifndef $(NDK_PLATFORM) - NDK_PLATFORM = android-21 -endif - -ifndef $(SDK_TARGET) - SDK_TARGET = android-21 -endif - -ifndef $(GCC_VERSION) - GCC_VERSION = 4.9 -endif - -PROJECT_PATH=$(PWD) - - -ifeq ($(ABI),x86) -ANDROID_PREFIX=i686-linux-android- -TOOLCHAIN=x86-$(GCC_VERSION) -SYSROOT=$(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-x86/ -else -ANDROID_PREFIX=arm-linux-androideabi- -TOOLCHAIN=$(ANDROID_PREFIX)$(GCC_VERSION) -SYSROOT=$(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/ -endif - -ifeq ($(shell uname),Darwin) -ifneq ($(wildcard $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/darwin-x86_64),) - HOST_PLATFORM = darwin-x86_64 -else - HOST_PLATFORM = darwin-x86 -endif -else ifneq (,$(findstring MINGW32_NT,$(shell uname))) -ifneq ($(wildcard $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/windows-x86_64),) - HOST_PLATFORM = windows-x86_64 -else - HOST_PLATFORM = windows -endif - PWD = $(shell pwd) -else -ifneq ($(wildcard $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/linux-x86_64),) - HOST_PLATFORM = linux-x86_64 -else - HOST_PLATFORM = linux-x86 -endif -endif - -TOOLCHAIN_PATH=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/ - -DATA_FILES = $(shell find bin/data -type f 2>/dev/null) -RESNAME=$(shell echo $(APPNAME)Resources | tr '[A-Z]' '[a-z]') -RESFILE=$(RESNAME).zip - -ifeq ($(ABI),armv7) - ABI_PATH = armeabi-v7a - PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so - PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so -endif - -ifeq ($(ABI),armv5) - ABI_PATH = armeabi - PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so - PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so -endif - -ifeq ($(ABI),neon) - ABI_PATH = armeabi-v7a - PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp_neon.so - PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp_neon.so -endif - -ifeq ($(ABI),x86) - ABI_PATH = x86 - PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so - PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp.so -endif - -PLATFORM_CORELIB_RELEASE_TARGET = $(OF_CORE_LIB_PATH)/$(ABI)/libopenFrameworks.a -PLATFORM_CORELIB_DEBUG_TARGET = $(OF_CORE_LIB_PATH)/$(ABI)/libopenFrameworksDebug.a - - -# add OF_USING_MPG123 define IF we have it defined as a system library -#ifeq ($(HAS_SYSTEM_MPG123),0) -# PLATFORM_DEFINES += OF_USING_MPG123 -#endif - -################################################################################ -# PLATFORM REQUIRED ADDON -# This is a list of addons required for this platform. This list is used to -# EXCLUDE addon source files when compiling projects, while INCLUDING their -# header files. During core library compilation, this is used to include -# required addon header files as needed within the core. -# -# For instance, if you are compiling for Android, you would add ofxAndroid -# here. If you are compiling for Raspberry Pi, you would add ofxRaspberryPi -# here. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -PLATFORM_REQUIRED_ADDONS = ofxAndroid - -################################################################################ -# PLATFORM CFLAGS -# This is a list of fully qualified CFLAGS required when compiling for this -# platform. These flags will always be added when compiling a project or the -# core library. These flags are presented to the compiler AFTER the -# PLATFORM_OPTIMIZATION_CFLAGS below. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -# Warning Flags (http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html) -PLATFORM_CFLAGS = -Wall -std=c++14 - -# Code Generation Option Flags (http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html) -PLATFORM_CFLAGS += -nostdlib --sysroot=$(SYSROOT) -fno-short-enums -ffunction-sections -fdata-sections - - -ifeq ($(ABI),armv7) - PLATFORM_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -endif - -ifeq ($(ABI),neon) - PLATFORM_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon -endif - -ifeq ($(ABI),x86) - PLATFORM_CFLAGS += -march=i686 -msse3 -mstackrealign -mfpmath=sse -fno-stack-protector -endif - -################################################################################ -# PLATFORM LDFLAGS -# This is a list of fully qualified LDFLAGS required when linking for this -# platform. These flags will always be added when linking a project. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -PLATFORM_LDFLAGS = -PLATFORM_LDFLAGS += --sysroot=$(SYSROOT) -nostdlib -L"$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(GCC_VERSION)/libs/$(ABI_PATH)" -#ifeq ($(HOST_PLATFORM),linux-x86) -# PLATFORM_LDFLAGS += -fuse-ld=gold -#endif - -ifneq ($(ABI),x86) -PLATFORM_LDFLAGS += -Wl,--fix-cortex-a8 -endif -PLATFORM_LDFLAGS += -shared -Wl,--no-undefined -Wl,--as-needed -Wl,--gc-sections -Wl,--exclude-libs,ALL - -################################################################################ -# PLATFORM OPTIMIZATION CFLAGS -# These are lists of CFLAGS that are target-specific. While any flags could -# be conditionally added, they are usually limited to optimization flags. -# These flags are added BEFORE the PLATFORM_CFLAGS. -# -# PLATFORM_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to -# RELEASE targets. -# -# PLATFORM_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to -# DEBUG targets. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -# RELEASE Debugging options (http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html) -PLATFORM_OPTIMIZATION_CFLAGS_RELEASE = -Os - -# RELEASE options -PLATFORM_OPTIMIZATION_LDFLAGS_RELEASE = -s - -# DEBUG Debugging options (http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html) -PLATFORM_OPTIMIZATION_CFLAGS_DEBUG = -O0 -g -D_DEBUG - -################################################################################ -# PLATFORM CORE EXCLUSIONS -# During compilation, these makefiles will generate lists of sources, headers -# and third party libraries to be compiled and linked into a program or core -# library. The PLATFORM_CORE_EXCLUSIONS is a list of fully qualified file -# paths that will be used to exclude matching paths and files during list -# generation. -# -# Each item in the PLATFORM_CORE_EXCLUSIONS list will be treated as a complete -# string unless the user adds a wildcard (%) operator to match subdirectories. -# GNU make only allows one wildcard for matching. The second wildcard (%) is -# treated literally. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -PLATFORM_CORE_EXCLUSIONS = - -# core sources -PLATFORM_CORE_EXCLUSIONS += %.mm -PLATFORM_CORE_EXCLUSIONS += %.m -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofQtUtils.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofQuickTimeGrabber.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofQuickTimePlayer.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofDirectShowGrabber.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofDirectShowPlayer.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofGstUtils.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofGstVideoGrabber.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/video/ofGstVideoPlayer.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/app/ofAppGlutWindow.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/app/ofAppEGLWindow.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/app/ofAppGLFWWindow.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/graphics/ofCairoRenderer.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/sound/ofFmodSoundPlayer.cpp -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openFrameworks/sound/ofOpenALSoundPlayer.cpp - -# third party -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/glew/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/Poco -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/CppUnit -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/Poco/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/include/CppUnit/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/quicktime/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/videoInput/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/glu/include -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/fmodex/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/kiss/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/assimp/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/glut/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/portaudio/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/rtAudio/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/poco/lib/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/openssl/lib/% -PLATFORM_CORE_EXCLUSIONS += $(OF_LIBS_PATH)/boost/include/boost/% - -# android project folders -PROJECT_EXCLUSIONS += ./gen -PROJECT_EXCLUSIONS += ./gen/% -PROJECT_EXCLUSIONS += ./jni -PROJECT_EXCLUSIONS += ./srcJava -PROJECT_EXCLUSIONS += ./srcJava/% -PROJECT_EXCLUSIONS += ./res -PROJECT_EXCLUSIONS += ./res/% -PROJECT_EXCLUSIONS += ./assets -PROJECT_EXCLUSIONS += ./assets/% -PROJECT_EXCLUSIONS += ./libs - - - -################################################################################ -# PLATFORM HEADER SEARCH PATHS -# These are header search paths that are platform specific and are specified -# using fully-qualified paths. The include flag (i.e. -I) is prefixed -# automatically. These are usually not required, but may be required by some -# experimental platforms such as the raspberry pi or other other embedded -# architectures. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -PLATFORM_HEADER_SEARCH_PATHS = -PLATFORM_HEADER_SEARCH_PATHS += "$(SYSROOT)/usr/include/" -PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/include" -PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(GCC_VERSION)/include" -PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/libs/$(ABI_PATH)/include" -PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(GCC_VERSION)/libs/$(ABI_PATH)/include" -PLATFORM_HEADER_SEARCH_PATHS += "$(NDK_ROOT)/sources/crystax/include/" -PLATFORM_HEADER_SEARCH_PATHS += "$(OF_ROOT)/libs/glu/include_android" -PLATFORM_HEADER_SEARCH_PATHS += "$(OF_ROOT)/addons/ofxAndroid/src" - -################################################################################ -# PLATFORM LIBRARIES -# These are library names/paths that are platform specific and are specified -# using names or paths. The library flag (i.e. -l) is prefixed automatically. -# -# PLATFORM_LIBRARIES are libraries that can be found in the library search -# paths. -# PLATFORM_STATIC_LIBRARIES is a list of required static libraries. -# PLATFORM_SHARED_LIBRARIES is a list of required shared libraries. -# PLATFORM_PKG_CONFIG_LIBRARIES is a list of required libraries that are -# under system control and are easily accesible via the package -# configuration utility (i.e. pkg-config) -# -# See the helpfile for the -l flag here for more information: -# http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -PLATFORM_LIBRARIES = -PLATFORM_LIBRARIES += OpenSLES -PLATFORM_LIBRARIES += supc++ -PLATFORM_LIBRARIES += z -PLATFORM_LIBRARIES += GLESv1_CM -PLATFORM_LIBRARIES += GLESv2 -PLATFORM_LIBRARIES += GLESv3 -PLATFORM_LIBRARIES += log -PLATFORM_LIBRARIES += dl -PLATFORM_LIBRARIES += m -PLATFORM_LIBRARIES += c -PLATFORM_LIBRARIES += gnustl_static -PLATFORM_LIBRARIES += gcc - -#static libraries (fully qualified paths) -PLATFORM_STATIC_LIBRARIES = -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoNetSSL.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoNet.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoCrypto.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoJSON.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoMongoDB.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoDataSQLite.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoData.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoUtil.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoXML.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/poco/lib/$(ABI_LIB_SUBPATH)/libPocoFoundation.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/openssl/lib/$(ABI_LIB_SUBPATH)/libssl.a -PLATFORM_STATIC_LIBRARIES += $(OF_LIBS_PATH)/openssl/lib/$(ABI_LIB_SUBPATH)/libcrypto.a - -# shared libraries -PLATFORM_SHARED_LIBRARIES = - -#openframeworks core third party -PLATFORM_PKG_CONFIG_LIBRARIES = - -# conditionally add mpg123 -#ifeq ($(HAS_SYSTEM_MPG123),0) -# PLATFORM_PKG_CONFIG_LIBRARIES += libmpg123 -#endif - -################################################################################ -# PLATFORM LIBRARY SEARCH PATHS -# These are library search paths that are platform specific and are specified -# using fully-qualified paths. The lib search flag (i.e. -L) is prefixed -# automatically. The -L paths are used to find libraries defined above with -# the -l flag. -# -# See the the following link for more information on the -L flag: -# http://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ - -PLATFORM_LIBRARY_SEARCH_PATHS = - -################################################################################ -# PLATFORM FRAMEWORKS -# These are a list of platform frameworks. -# These are used exclusively with Darwin/OSX. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -#PLATFORM_FRAMEWORKS = - -################################################################################ -# PLATFORM FRAMEWORK SEARCH PATHS -# These are a list of platform framework search paths. -# These are used exclusively with Darwin/OSX. -# -# Note: Leave a leading space when adding list items with the += operator -################################################################################ -#PLATFORM_FRAMEWORKS_SEARCH_PATHS = - -################################################################################ -# LOW LEVEL CONFIGURATION BELOW -# The following sections should only rarely be modified. They are meant for -# developers who need fine control when, for instance, creating a platform -# specific makefile for a new openFrameworks platform, such as raspberry pi. -################################################################################ - -################################################################################ -# PLATFORM CONFIGURATIONS -# These will override the architecture vars generated by configure.platform.make -################################################################################ -#PLATFORM_ARCH = -#PLATFORM_OS = -#PLATFORM_LIBS_PATH = - -################################################################################ -# PLATFORM CXX -# Don't want to use a default compiler? -################################################################################ -#PLATFORM_CXX= - -PLATFORM_CC=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)gcc -PLATFORM_CXX=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)g++ -PLATFORM_AR=$(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(HOST_PLATFORM)/bin/$(ANDROID_PREFIX)ar - -#ifeq (,$(findstring MINGW32_NT,$(shell uname))) -ZIPWINDOWS=..\\..\\..\\..\\..\\libs\\openFrameworksCompiled\\project\\android\\windows\\zip -r ../../res/raw/$(RESFILE) -#endif - -afterplatform:$(RESFILE) - @if [ -f obj/$(BIN_NAME) ]; then rm obj/$(BIN_NAME); fi - - @echo copying debugging binaries for $(ABIS_TO_COMPILE) - @if [ "$(findstring neon,$(ABIS_TO_COMPILE))" = "neon" ]; then \ - cp $(OF_ROOT)/libs/openFrameworksCompiled/project/android/libneondetection.so libs/armeabi-v7a/; \ - cp $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver libs/armeabi-v7a; \ - fi - - @if [ "$(findstring armv5,$(ABIS_TO_COMPILE))" = "armv5" ]; then \ - cp $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver libs/armeabi; \ - fi - - @if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ]; then \ - cp $(NDK_ROOT)/prebuilt/android-arm/gdbserver/gdbserver libs/armeabi-v7a; \ - fi - - @if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "x86" ]; then \ - cp $(NDK_ROOT)/prebuilt/android-x86/gdbserver/gdbserver libs/x86; \ - fi - - - @if [ "$(findstring armv5,$(ABIS_TO_COMPILE))" = "armv5" ]; then \ - echo create gdb.setup for armeabi; \ - echo "set solib-search-path $(PWD)/obj/local/armeabi:$(PWD)/libs/armeabi" > libs/armeabi/gdb.setup; \ - echo "set sysroot $(SYSROOT)" >> libs/armeabi/gdb.setup; \ - echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/armeabi/gdb.setup; \ - echo "directory $(PWD)/src" >> libs/armeabi/gdb.setup; \ - echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/armeabi/gdb.setup; \ - echo "directory $(PWD)/libs/armeabi" >> libs/armeabi/gdb.setup; \ - echo "" >> libs/armeabi/gdb.setup; \ - fi - - @if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ]; then \ - echo create gdb.setup for armeabi-v7a; \ - echo "set solib-search-path $(PWD)/obj/local/armeabi-v7a:$(PWD)/libs/armeabi-v7a" > libs/armeabi-v7a/gdb.setup; \ - echo "set sysroot $(SYSROOT)" >> libs/armeabi-v7a/gdb.setup; \ - echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/armeabi-v7a/gdb.setup; \ - echo "directory $(PWD)/src" >> libs/armeabi-v7a/gdb.setup; \ - echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/armeabi-v7a/gdb.setup; \ - echo "directory $(PWD)/libs/armeabi-v7a" >> libs/armeabi-v7a/gdb.setup ; \ - echo "" >> libs/armeabi-v7a/gdb.setup; \ - fi - - @if [ "$(findstring x86,$(ABIS_TO_COMPILE))" = "x86" ]; then \ - echo create gdb.setup for x86; \ - echo "set solib-search-path $(PWD)/obj/local/x86:$(PWD)/libs/x86" > libs/x86/gdb.setup; \ - echo "set sysroot $(SYSROOT)" >> libs/x86/gdb.setup; \ - echo "directory $(NDK_ROOT)/platforms/$(NDK_PLATFORM)/arch-arm/usr/include" >> libs/x86/gdb.setup; \ - echo "directory $(PWD)/src" >> libs/x86/gdb.setup; \ - echo "directory $(NDK_ROOT)/sources/cxx-stl/system" >> libs/x86/gdb.setup; \ - echo "directory $(PWD)/libs/x86" >> libs/x86/gdb.setup ; \ - echo "" >> libs/x86/gdb.setup; \ - fi - - @echo creating Android.mk and Application.mk - @if [ ! -d jni ]; then mkdir jni; fi - @ABIS=""; \ - if [ "$(findstring armv5,$(ABIS_TO_COMPILE))" = "armv5" ]; then \ - ABIS="$$ABIS armeabi"; \ - else \ - rm -r libs/armeabi 2> /dev/null; \ - fi; \ - if [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ] || [ "$(findstring neon,$(ABIS_TO_COMPILE))" = "neon" ]; then \ - ABIS="$$ABIS armeabi-v7a"; \ - elif [ "$(findstring armv7,$(ABIS_TO_COMPILE))" = "armv7" ]; then \ - rm libs/armeabi-v7a/libOFAndroidApp_neon.so 2> /dev/null; \ - rm libs/armeabi-v7a/libneondetection.so 2> /dev/null; \ - elif [ "$(findstring neon,$(ABIS_TO_COMPILE))" = "neon" ]; then \ - rm libs/armeabi-v7a/libOFAndroidApp.so 2> /dev/null; \ - else \ - rm -r libs/armeabi-v7a 2> /dev/null; \ - fi; \ - if [ "$(findstring x86,$(ABIS_TO_COMPILE))" = "x86" ]; then \ - ABIS="$$ABIS x86"; \ - else \ - rm -r libs/x86 2> /dev/null; \ - fi; \ - echo "APP_ABI := $$ABIS" > jni/Application.mk; \ - echo "LOCAL_MODULE := OFAndroidApp" > jni/Android.mk - - - - #@echo updating ofAndroidLib project - #@cd $(OF_ROOT)/addons/ofxAndroid/ofAndroidLib; \ - #if [ "$(HOST_PLATFORM)" = "windows" ]; then \ - # cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ - #else \ - # $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ - #fi - - #@echo updating current project - #@cd $(PROJECT_PATH); \ - #if [ "$(HOST_PLATFORM)" = "windows" ]; then \ - # cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ - #else \ - # $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ - #fi - -$(RESFILE): $(DATA_FILES) - @echo compressing and copying resources from bin/data into res - cd "$(PROJECT_PATH)"; \ - if [ -d "bin/data" ]; then \ - mkdir -p res/raw; \ - rm res/raw/$(RESNAME).zip; \ - cd bin/data; \ - if [ "$(HOST_PLATFORM)" = "windows" ]; then \ - echo "Windows Platform. Running Zip..."; \ - cmd //c $(ZIPWINDOWS) * && exit; \ - else \ - zip -r ../../res/raw/$(RESNAME).zip *; \ - fi; \ - cd ../..; \ - fi - -install: - cd "$(OF_ROOT)/addons/ofxAndroid/ofAndroidLib"; \ - echo installing on $(HOST_PLATFORM); \ - if [ "$(HOST_PLATFORM)" = "windows" ]; then \ - cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ - else \ - $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ - fi - cd "$(PROJECT_PATH)"; \ - if [ -d "bin/data" ]; then \ - mkdir -p res/raw; \ - rm res/raw/$(RESNAME).zip; \ - cd bin/data; \ - if [ "$(HOST_PLATFORM)" = "windows" ]; then \ - echo "Windows Platform. Running Zip..."; \ - cmd //c $(ZIPWINDOWS) * && exit; \ - else \ - zip -r ../../res/raw/$(RESNAME).zip; *; \ - fi; \ - cd ../..; \ - fi - if [ -f obj/$(BIN_NAME) ]; then rm obj/$(BIN_NAME); fi - #touch AndroidManifest.xml - if [ "$(HOST_PLATFORM)" = "windows" ]; then \ - cmd //c $(SDK_ROOT)/tools/android.bat update project --target $(SDK_TARGET) --path .; \ - else \ - $(SDK_ROOT)/tools/android update project --target $(SDK_TARGET) --path .; \ - fi - - #rm -r $(addprefix bin/,$(shell ls bin/ | grep -v ^data$)) - - if [ "$(HOST_PLATFORM)" = "windows" ]; then \ - #$(ANT_BIN)/ant clean; \ - $(ANT_BIN)/ant debug install; \ - else \ - #ant clean; \ - ant debug install; \ - fi - cp bin/OFActivity-debug.apk bin/$(APPNAME).apk - #if [ "$(shell $(SDK_ROOT)/platform-tools/adb get-state)" = "device" ]; then - #$(SDK_ROOT)/platform-tools/adb uninstall $(PKGNAME) - $(SDK_ROOT)/platform-tools/adb install -r bin/$(APPNAME).apk; - #fi - $(SDK_ROOT)/platform-tools/adb shell am start -a android.intent.action.MAIN -n $(PKGNAME)/$(PKGNAME).OFActivity - From 0050001c866d56aeb97eafec6c26c529c0cacc69 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Tue, 7 Apr 2026 13:11:23 +1000 Subject: [PATCH 13/38] ofImageType --- libs/openFrameworks/gl/ofGLUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 846f21723d6..abbe4d497d0 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -391,7 +391,7 @@ int ofGetGLType(const ofFloatPixels & pixels) { } //--------------------------------- -oofImageType ofGetImageTypeFromGLType(int glType){ +ofImageType ofGetImageTypeFromGLType(int glType){ switch(glType){ case GL_LUMINANCE: #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) From 1f1c5f21001422c2d43412d242b0bcd7b8dedc99 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Tue, 7 Apr 2026 13:19:09 +1000 Subject: [PATCH 14/38] ofGLRenderer --- libs/openFrameworks/gl/ofGLRenderer.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLRenderer.cpp b/libs/openFrameworks/gl/ofGLRenderer.cpp index ca835488f83..e5fa8cf748f 100644 --- a/libs/openFrameworks/gl/ofGLRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLRenderer.cpp @@ -42,21 +42,19 @@ ofGLRenderer::ofGLRenderer(const ofAppBaseWindow * _window) void ofGLRenderer::setup() { #ifdef TARGET_OPENGLES - // OpenGL ES might have set a default frame buffer for - // MSAA rendering to the window, bypassing ofFbo, so we - // can't trust ofFbo to have correctly tracked the bind - // state. Therefore, we are forced to use the slower glGet() method - // to be sure to get the correct default framebuffer. - GLint currentFrameBuffer; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFrameBuffer); - defaultFramebufferId = currentFrameBuffer; + // OpenGL ES might have set a default frame buffer for MSAA rendering to the window, + // bypassing ofFbo, so we can't trust ofFbo to have correctly tracked the bind state. + // Therefore we are forced to use the slower glGet() method to be sure. + GLint currentFramebuffer; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFramebuffer); + defaultFramebufferId = currentFramebuffer; currentFramebufferId = defaultFramebufferId; #endif + setupGraphicDefaults(); viewport(); setupScreenPerspective(); } - void ofGLRenderer::startRender() { currentFramebufferId = defaultFramebufferId; framebufferIdStack.push_back(defaultFramebufferId); @@ -2027,5 +2025,3 @@ const of3dGraphics & ofGLRenderer::get3dGraphics() const { of3dGraphics & ofGLRenderer::get3dGraphics() { return graphics3d; } - -#endif From 45e3974d59dbea6d29b757d7f6bd4d00f8ca840b Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Tue, 7 Apr 2026 13:56:09 +1000 Subject: [PATCH 15/38] Update ofAppEGLWindow.cpp --- libs/openFrameworks/app/ofAppEGLWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openFrameworks/app/ofAppEGLWindow.cpp b/libs/openFrameworks/app/ofAppEGLWindow.cpp index d19ea965a53..24a62277aa2 100644 --- a/libs/openFrameworks/app/ofAppEGLWindow.cpp +++ b/libs/openFrameworks/app/ofAppEGLWindow.cpp @@ -404,7 +404,7 @@ void ofAppEGLWindow::setup(const ofAppEGLWindowSettings & _settings) { eglVersionMajor = -1; eglVersionMinor = -1; glesVersionMajor = 1; - glesVersionMinor = 0; + glesVersionMinor = 0; // X11 check // char * pDisplay; From 9641d7c7cdfeb34dd179eca001b2ba8ece26e37b Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Tue, 7 Apr 2026 18:55:23 +1000 Subject: [PATCH 16/38] ofGLUtils fix --- libs/openFrameworks/gl/ofGLUtils.cpp | 36 ---------------------------- 1 file changed, 36 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index abbe4d497d0..8a17b81b059 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -433,7 +433,6 @@ ofImageType ofGetImageTypeFromGLType(int glType){ #endif return OF_IMAGE_COLOR; -<<<<<<< HEAD case GL_RGBA: #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_RGBA8: @@ -450,41 +449,6 @@ ofImageType ofGetImageTypeFromGLType(int glType){ return OF_IMAGE_COLOR_ALPHA; } return OF_IMAGE_UNDEFINED; -======= - case GL_RGB: -#ifndef TARGET_OPENGLES - case GL_RGB16: -#endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_RGB8: - case GL_RGB16F: - case GL_RGB16I: - case GL_RGB16UI: - case GL_RGB32F: - case GL_RGB32I: - case GL_RGB32UI: -#endif - return OF_IMAGE_COLOR; - - - case GL_RGBA: -#ifndef TARGET_OPENGLES - case GL_RGBA16: -#endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_RGBA8: - case GL_RGBA16F: - case GL_RGBA16I: - case GL_RGBA16UI: - case GL_RGBA32F: - case GL_RGBA32I: - case GL_RGBA32UI: -#endif - return OF_IMAGE_COLOR_ALPHA; - } - ofLogError("ofGLUtils") << "ofGetImageTypeFromGLType(): unknown type " << glType << ", returning OF_IMAGE_UNDEFINED"; - return OF_IMAGE_UNDEFINED; ->>>>>>> b2409bdb7 (Smaller fixes) } GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ From 8c80fc8a392a0c518d5932e917a7b08a39e3a4fc Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Tue, 7 Apr 2026 22:14:33 +1000 Subject: [PATCH 17/38] OpenGLES 3 changes for ofFbo and ofGLProgrammableRenderer --- libs/openFrameworks/gl/ofFbo.cpp | 441 +++++++++--------- libs/openFrameworks/gl/ofFbo.h | 22 +- .../gl/ofGLProgrammableRenderer.cpp | 429 +++++++---------- .../gl/ofGLProgrammableRenderer.h | 2 +- 4 files changed, 411 insertions(+), 483 deletions(-) diff --git a/libs/openFrameworks/gl/ofFbo.cpp b/libs/openFrameworks/gl/ofFbo.cpp index ceedfba085d..b70ac608daf 100644 --- a/libs/openFrameworks/gl/ofFbo.cpp +++ b/libs/openFrameworks/gl/ofFbo.cpp @@ -34,7 +34,7 @@ using std::vector; */ -#if defined(TARGET_OPENGLES) & !defined(TARGET_EMSCRIPTEN) +#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) bool ofFbo::bglFunctionsInitialized=false; typedef void (* glGenFramebuffersType) (GLsizei n, GLuint* framebuffers); @@ -246,7 +246,7 @@ dirty(false), defaultTextureIndex(0), bIsAllocated(false) { -#if defined(TARGET_OPENGLES) & !defined(TARGET_EMSCRIPTEN) +#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) if(!bglFunctionsInitialized){ if(ofIsGLProgrammableRenderer()){ glGenFramebuffers = (glGenFramebuffersType)dlsym(RTLD_DEFAULT, "glGenFramebuffers"); @@ -302,12 +302,12 @@ ofFbo::ofFbo(const ofFbo & mom){ textures = mom.textures; dirty = mom.dirty; defaultTextureIndex = mom.defaultTextureIndex; - activeDrawBuffers = mom.activeDrawBuffers; - if(fbo!=0){ - #ifdef TARGET_ANDROID - ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); - #endif - } + activeDrawBuffers = mom.activeDrawBuffers; + if(fbo!=0){ + #ifdef TARGET_ANDROID + ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); + #endif + } } //-------------------------------------------------------------- @@ -322,11 +322,11 @@ ofFbo & ofFbo::operator=(const ofFbo & mom){ fboTextures = mom.fboTextures; if(settings.numSamples){ retainFB(fboTextures); - } - if(mom.settings.depthStencilAsTexture){ - depthBufferTex = mom.depthBufferTex; - }else{ - depthBuffer = mom.depthBuffer; + } + if(mom.settings.depthStencilAsTexture){ + depthBufferTex = mom.depthBufferTex; + }else{ + depthBuffer = mom.depthBuffer; retainRB(depthBuffer); } stencilBuffer = mom.stencilBuffer; @@ -339,12 +339,12 @@ ofFbo & ofFbo::operator=(const ofFbo & mom){ textures = mom.textures; dirty = mom.dirty; defaultTextureIndex = mom.defaultTextureIndex; - activeDrawBuffers = mom.activeDrawBuffers; - if(fbo!=0){ - #ifdef TARGET_ANDROID - ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); - #endif - } + activeDrawBuffers = mom.activeDrawBuffers; + if(fbo!=0){ + #ifdef TARGET_ANDROID + ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); + #endif + } return *this; } @@ -361,47 +361,47 @@ ofFbo::ofFbo(ofFbo && mom) ,dirty(std::move(mom.dirty)) ,defaultTextureIndex(std::move(mom.defaultTextureIndex)) ,bIsAllocated(std::move(mom.bIsAllocated)){ - if(fbo!=0){ - #ifdef TARGET_ANDROID - ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); - #endif - } - mom.fbo = 0; - mom.depthBuffer = 0; - mom.fboTextures = 0; - mom.stencilBuffer = 0; + if(fbo!=0){ + #ifdef TARGET_ANDROID + ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); + #endif + } + mom.fbo = 0; + mom.depthBuffer = 0; + mom.fboTextures = 0; + mom.stencilBuffer = 0; } ofFbo & ofFbo::operator=(ofFbo && mom){ - if(&mom==this) return *this; - clear(); - settings = std::move(mom.settings); - bIsAllocated = std::move(mom.bIsAllocated); - - fbo = mom.fbo; - fboTextures = mom.fboTextures; - if(mom.settings.depthStencilAsTexture){ - depthBufferTex = std::move(mom.depthBufferTex); - }else{ - depthBuffer = mom.depthBuffer; - } - stencilBuffer = std::move(mom.stencilBuffer); - - colorBuffers = std::move(mom.colorBuffers); - textures = std::move(mom.textures); - dirty = std::move(mom.dirty); - defaultTextureIndex = std::move(mom.defaultTextureIndex); - - if(fbo!=0){ - #ifdef TARGET_ANDROID - ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); - #endif - } - mom.fbo = 0; - mom.depthBuffer = 0; - mom.fboTextures = 0; - mom.stencilBuffer = 0; - return *this; + if(&mom==this) return *this; + clear(); + settings = std::move(mom.settings); + bIsAllocated = std::move(mom.bIsAllocated); + + fbo = mom.fbo; + fboTextures = mom.fboTextures; + if(mom.settings.depthStencilAsTexture){ + depthBufferTex = std::move(mom.depthBufferTex); + }else{ + depthBuffer = mom.depthBuffer; + } + stencilBuffer = std::move(mom.stencilBuffer); + + colorBuffers = std::move(mom.colorBuffers); + textures = std::move(mom.textures); + dirty = std::move(mom.dirty); + defaultTextureIndex = std::move(mom.defaultTextureIndex); + + if(fbo!=0){ + #ifdef TARGET_ANDROID + ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); + #endif + } + mom.fbo = 0; + mom.depthBuffer = 0; + mom.fboTextures = 0; + mom.stencilBuffer = 0; + return *this; } //-------------------------------------------------------------- @@ -462,7 +462,7 @@ void ofFbo::clear() { } -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) //-------------------------------------------------------------- void ofFbo::clearColorBuffer(const ofFloatColor & color){ glClearBufferfv(GL_COLOR, 0, &color.r); @@ -497,54 +497,58 @@ void ofFbo::destroy() { //-------------------------------------------------------------- bool ofFbo::checkGLSupport() { #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - // Desktop + GLES 3.0+ (FBO is core spec — no extension check needed on ES3) - if (!ofIsGLProgrammableRenderer()){ - if(ofGLCheckExtension("GL_EXT_framebuffer_object")){ - ofLogVerbose("ofFbo") << "GL frame buffer object supported"; - }else{ - ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; - return false; - } - } - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &_maxColorAttachments); - glGetIntegerv(GL_MAX_DRAW_BUFFERS, &_maxDrawBuffers); - glGetIntegerv(GL_MAX_SAMPLES, &_maxSamples); - - ofLogVerbose("ofFbo") << "checkGLSupport(): " - << "maxColorAttachments: " << _maxColorAttachments << ", " - << "maxDrawBuffers: " << _maxDrawBuffers << ", " - << "maxSamples: " << _maxSamples; + // Desktop + GLES 3.0+ (FBO is core spec — no extension check needed on ES3) + if (!ofIsGLProgrammableRenderer()){ + if(ofGLCheckExtension("GL_EXT_framebuffer_object")){ + ofLogVerbose("ofFbo") << "GL frame buffer object supported"; + }else{ + ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; + return false; + } + } + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &_maxColorAttachments); + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &_maxDrawBuffers); + glGetIntegerv(GL_MAX_SAMPLES, &_maxSamples); + + ofLogVerbose("ofFbo") << "checkGLSupport(): " + << "maxColorAttachments: " << _maxColorAttachments << ", " + << "maxDrawBuffers: " << _maxDrawBuffers << ", " + << "maxSamples: " << _maxSamples; #else - // GLES 2.0 — FBO is still an extension (GL_OES_framebuffer_object) - if(ofIsGLProgrammableRenderer() || ofGLCheckExtension("GL_OES_framebuffer_object")){ - ofLogVerbose("ofFbo") << "GL frame buffer object supported"; - }else{ - ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; - return false; - } + // GLES 2.0 — FBO is still an extension (GL_OES_framebuffer_object) + if(ofIsGLProgrammableRenderer() || ofGLCheckExtension("GL_OES_framebuffer_object")){ + ofLogVerbose("ofFbo") << "GL frame buffer object supported"; + }else{ + ofLogError("ofFbo") << "GL frame buffer object not supported by this graphics card"; + return false; + } #endif - return true; + return true; } //-------------------------------------------------------------- void ofFbo::allocate(int width, int height, int internalformat, int numSamples) { - settings.width = width; - settings.height = height; - settings.internalformat = internalformat; - settings.numSamples = numSamples; + settings.width = width; + settings.height = height; + settings.internalformat = internalformat; + settings.numSamples = numSamples; #ifdef TARGET_OPENGLES - settings.useDepth = false; - settings.useStencil = false; - //we do this as the fbo and the settings object it contains could be created before the user had the chance to disable or enable arb rect. - settings.textureTarget = GL_TEXTURE_2D; + settings.textureTarget = GL_TEXTURE_2D; +#else + settings.textureTarget = ofGetUsingArbTex() ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D; +#endif + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // GLES 3.0+ (and desktop) can safely default to depth + stencil + settings.useDepth = true; + settings.useStencil = true; #else - settings.useDepth = true; - settings.useStencil = true; //we do this as the fbo and the settings object it contains could be created before the user had the chance to disable or enable arb rect. - settings.textureTarget = ofGetUsingArbTex() ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D; + settings.useDepth = false; + settings.useStencil = false; #endif allocate(settings); @@ -578,14 +582,14 @@ void ofFbo::allocate(ofFboSettings _settings) { //currently depth only works if stencil is enabled. // http://forum.openframeworks.cc/index.php/topic,6837.0.html -#ifdef TARGET_OPENGLES +#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) if(_settings.useDepth){ - _settings.useStencil = true; + _settings.useStencil = true; + } + if( _settings.depthStencilAsTexture ){ + _settings.depthStencilAsTexture = false; + ofLogWarning("ofFbo") << "allocate(): depthStencilAsTexture is not available for iOS"; } - if( _settings.depthStencilAsTexture ){ - _settings.depthStencilAsTexture = false; - ofLogWarning("ofFbo") << "allocate(): depthStencilAsTexture is not available for iOS"; - } #endif GLenum depthAttachment = GL_DEPTH_ATTACHMENT; @@ -643,32 +647,31 @@ void ofFbo::allocate(ofFboSettings _settings) { }else{ if(_settings.useDepth || _settings.useStencil){ createAndAttachDepthStencilTexture(_settings.textureTarget,_settings.depthStencilInternalFormat,depthAttachment); - #ifdef TARGET_OPENGLES - // if there's depth and stencil the texture should be attached as - // depth and stencil attachments - // http://www.khronos.org/registry/gles/extensions/OES/OES_packed_depth_stencil.txt - if(_settings.useDepth && _settings.useStencil){ - glFramebufferTexture2D(GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_TEXTURE_2D, depthBufferTex.texData.textureID, 0); - } + #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + // GLES 2.0 only: OES_packed_depth_stencil extension requires separate stencil attachment + // http://www.khronos.org/registry/gles/extensions/OES/OES_packed_depth_stencil.txt + if(_settings.useDepth && _settings.useStencil){ + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_STENCIL_ATTACHMENT, + GL_TEXTURE_2D, depthBufferTex.texData.textureID, 0); + } #endif } } - settings.useDepth = _settings.useDepth; - settings.useStencil = _settings.useStencil; - settings.depthStencilInternalFormat = _settings.depthStencilInternalFormat; - settings.depthStencilAsTexture = _settings.depthStencilAsTexture; - settings.textureTarget = _settings.textureTarget; - settings.wrapModeHorizontal = _settings.wrapModeHorizontal; - settings.wrapModeVertical = _settings.wrapModeVertical; - settings.maxFilter = _settings.maxFilter; - settings.minFilter = _settings.minFilter; + settings.useDepth = _settings.useDepth; + settings.useStencil = _settings.useStencil; + settings.depthStencilInternalFormat = _settings.depthStencilInternalFormat; + settings.depthStencilAsTexture = _settings.depthStencilAsTexture; + settings.textureTarget = _settings.textureTarget; + settings.wrapModeHorizontal = _settings.wrapModeHorizontal; + settings.wrapModeVertical = _settings.wrapModeVertical; + settings.maxFilter = _settings.maxFilter; + settings.minFilter = _settings.minFilter; // if we want MSAA, create a new fbo for textures - // FIXME: it is in fact possible to do multisampling with newer OpenGL ES (2.0+ ?) - #ifndef TARGET_OPENGLES + // (supported on desktop + GLES 3.0+; pure GLES 2.0 does not support multisampled FBOs reliably) + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) if(_settings.numSamples){ glGenFramebuffers(1, &fboTextures); retainFB(fboTextures); @@ -678,7 +681,7 @@ void ofFbo::allocate(ofFboSettings _settings) { #else fboTextures = fbo; if(_settings.numSamples){ - ofLogWarning("ofFbo") << "allocate(): multisampling not supported in OpenGL ES"; + ofLogWarning("ofFbo") << "allocate(): multisampling not supported in OpenGL ES < 3.0"; } #endif @@ -710,12 +713,12 @@ void ofFbo::allocate(ofFboSettings _settings) { // restore previous framebuffer id glBindFramebuffer(GL_FRAMEBUFFER, previousFboId); - /* UNCOMMENT OUTSIDE OF DOING RELEASES + /* UNCOMMENT OUTSIDE OF DOING RELEASES - // this should never happen + // this should never happen if(settings != _settings) ofLogWarning("ofFbo") << "allocation not complete, passed settings not equal to created ones, this is an internal OF bug"; - */ + */ #ifdef TARGET_ANDROID ofAddListener(ofxAndroidEvents().reloadGL,this,&ofFbo::reloadFbo); #endif @@ -738,23 +741,29 @@ GLuint ofFbo::createAndAttachRenderbuffer(GLenum internalFormat, GLenum attachme GLuint buffer; glGenRenderbuffers(1, &buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer); -#ifndef TARGET_OPENGLES - if (settings.numSamples==0) { + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // Desktop + GLES 3.0+ support full multisampled renderbuffers + if (settings.numSamples == 0) { glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, settings.width, settings.height); } else { glRenderbufferStorageMultisample(GL_RENDERBUFFER, settings.numSamples, internalFormat, settings.width, settings.height); } #else - if(ofGLSupportsNPOTTextures()){ + // Pure GLES 2.0 — no reliable MSAA + sometimes needs power-of-two textures + if (ofGLSupportsNPOTTextures()) { glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, settings.width, settings.height); - }else{ + } else { glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, ofNextPow2(settings.width), ofNextPow2(settings.height)); } + if (settings.numSamples > 0) { + ofLogWarning("ofFbo") << "createAndAttachRenderbuffer(): multisampling not supported in OpenGL ES < 3.0"; + } #endif + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentPoint, GL_RENDERBUFFER, buffer); return buffer; } - //---------------------------------------------------------- void ofFbo::createAndAttachTexture(GLenum internalFormat, GLenum attachmentPoint) { @@ -773,23 +782,23 @@ void ofFbo::createAndAttachTexture(GLenum internalFormat, GLenum attachmentPoint ofTexture tex; tex.allocate(texData); - attachTexture(tex, internalFormat, attachmentPoint); + attachTexture(tex, internalFormat, attachmentPoint); dirty.push_back(true); activeDrawBuffers.push_back(GL_COLOR_ATTACHMENT0 + attachmentPoint); } //---------------------------------------------------------- void ofFbo::attachTexture(ofTexture & tex, GLenum internalFormat, GLenum attachmentPoint) { - // bind fbo for textures (if using MSAA this is the newly created fbo, otherwise its the same fbo as before) + // bind fbo for textures (if using MSAA this is the newly created fbo, otherwise its the same fbo as before) GLint temp; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &temp); glBindFramebuffer(GL_FRAMEBUFFER, fboTextures); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachmentPoint, tex.texData.textureTarget, tex.texData.textureID, 0); - if(attachmentPoint >= textures.size()) { - textures.resize(attachmentPoint+1); - } - textures[attachmentPoint] = tex; + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachmentPoint, tex.texData.textureTarget, tex.texData.textureID, 0); + if(attachmentPoint >= textures.size()) { + textures.resize(attachmentPoint+1); + } + textures[attachmentPoint] = tex; settings.colorFormats.resize(attachmentPoint + 1); settings.colorFormats[attachmentPoint] = internalFormat; @@ -842,20 +851,20 @@ void ofFbo::createAndAttachDepthStencilTexture(GLenum target, GLint internalform void ofFbo::begin(bool setupScreen) const{ auto renderer = settings.renderer.lock(); if(renderer){ - if(setupScreen){ - renderer->begin(*this, OF_FBOMODE_PERSPECTIVE | OF_FBOMODE_MATRIXFLIP); - }else{ - renderer->begin(*this, OF_FBOMODE_NODEFAULTS); - } + if(setupScreen){ + renderer->begin(*this, OF_FBOMODE_PERSPECTIVE | OF_FBOMODE_MATRIXFLIP); + }else{ + renderer->begin(*this, OF_FBOMODE_NODEFAULTS); + } } } void ofFbo::begin(ofFboMode mode) const{ - auto renderer = settings.renderer.lock(); - if(renderer){ - renderer->begin(*this, mode); - } + auto renderer = settings.renderer.lock(); + if(renderer){ + renderer->begin(*this, mode); + } } @@ -950,21 +959,24 @@ void ofFbo::setActiveDrawBuffer(int i){ //---------------------------------------------------------- void ofFbo::setActiveDrawBuffers(const vector& ids){ if(!bIsAllocated) return; + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - int numBuffers = activeDrawBuffers.size(); + int numBuffers = activeDrawBuffers.size(); activeDrawBuffers.clear(); activeDrawBuffers.resize(numBuffers, GL_NONE); // we initialise the vector with GL_NONE, so a buffer will not be written to unless activated. - for(int i=0; i < (int)ids.size(); i++){ - int id = ids[i]; - if (id < getNumTextures()){ - GLenum e = GL_COLOR_ATTACHMENT0 + id; - activeDrawBuffers[id] = e; // activate requested buffers - dirty[id] = true; // dirty activated draw buffers. - }else{ - ofLogWarning("ofFbo") << "setActiveDrawBuffers(): fbo " << fbo << " couldn't set texture " << i << ", only " << getNumTextures() << "allocated"; - } - } - glDrawBuffers(activeDrawBuffers.size(),&activeDrawBuffers[0]); + + for(int i = 0; i < (int)ids.size(); i++){ + int id = ids[i]; + if(id < getNumTextures()){ + GLenum e = GL_COLOR_ATTACHMENT0 + id; + activeDrawBuffers[id] = e; // activate requested buffers + dirty[id] = true; // dirty activated draw buffers + }else{ + ofLogWarning("ofFbo") << "setActiveDrawBuffers(): fbo " << fbo << " couldn't set texture " << i << ", only " << getNumTextures() << " allocated"; + } + } + + glDrawBuffers(activeDrawBuffers.size(), &activeDrawBuffers[0]); #endif } @@ -972,11 +984,11 @@ void ofFbo::setActiveDrawBuffers(const vector& ids){ void ofFbo::activateAllDrawBuffers(){ if(!bIsAllocated) return; #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - vector activeBuffers(getNumTextures(),0); - for(int i=0; i < getNumTextures(); i++){ - activeBuffers[i] = i; - } - setActiveDrawBuffers(activeBuffers); + vector activeBuffers(getNumTextures(), 0); + for(int i = 0; i < getNumTextures(); i++){ + activeBuffers[i] = i; + } + setActiveDrawBuffers(activeBuffers); #endif } @@ -1021,7 +1033,7 @@ ofTexture& ofFbo::getTexture(){ ofTexture& ofFbo::getTexture(int attachmentPoint) { updateTexture(attachmentPoint); - return textures[attachmentPoint]; + return textures[attachmentPoint]; } //---------------------------------------------------------- @@ -1034,7 +1046,7 @@ const ofTexture& ofFbo::getTexture(int attachmentPoint) const{ ofFbo * mutThis = const_cast(this); mutThis->updateTexture(attachmentPoint); - return textures[attachmentPoint]; + return textures[attachmentPoint]; } //---------------------------------------------------------- @@ -1055,13 +1067,15 @@ void ofFbo::resetAnchor(){ //---------------------------------------------------------- void ofFbo::readToPixels(ofPixels & pixels, int attachmentPoint) const{ if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // Desktop + GLES 3.0+ getTexture(attachmentPoint).readToPixels(pixels); #else - pixels.allocate(settings.width,settings.height,ofGetImageTypeFromGLType(settings.internalformat)); + // GLES 2.0 — glReadPixels is still required + pixels.allocate(settings.width, settings.height, ofGetImageTypeFromGLType(settings.internalformat)); bind(); int format = ofGetGLFormatFromInternal(settings.internalformat); - glReadPixels(0,0,settings.width, settings.height, format, GL_UNSIGNED_BYTE, pixels.getData()); + glReadPixels(0, 0, settings.width, settings.height, format, GL_UNSIGNED_BYTE, pixels.getData()); unbind(); #endif } @@ -1069,13 +1083,13 @@ void ofFbo::readToPixels(ofPixels & pixels, int attachmentPoint) const{ //---------------------------------------------------------- void ofFbo::readToPixels(ofShortPixels & pixels, int attachmentPoint) const{ if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) getTexture(attachmentPoint).readToPixels(pixels); #else - pixels.allocate(settings.width,settings.height,ofGetImageTypeFromGLType(settings.internalformat)); + pixels.allocate(settings.width, settings.height, ofGetImageTypeFromGLType(settings.internalformat)); bind(); int format = ofGetGLFormatFromInternal(settings.internalformat); - glReadPixels(0,0,settings.width, settings.height, format, GL_UNSIGNED_SHORT, pixels.getData()); + glReadPixels(0, 0, settings.width, settings.height, format, GL_UNSIGNED_SHORT, pixels.getData()); unbind(); #endif } @@ -1083,7 +1097,7 @@ void ofFbo::readToPixels(ofShortPixels & pixels, int attachmentPoint) const{ //---------------------------------------------------------- void ofFbo::readToPixels(ofFloatPixels & pixels, int attachmentPoint) const{ if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) getTexture(attachmentPoint).readToPixels(pixels); #else pixels.allocate(settings.width,settings.height,ofGetImageTypeFromGLType(settings.internalformat)); @@ -1094,7 +1108,7 @@ void ofFbo::readToPixels(ofFloatPixels & pixels, int attachmentPoint) const{ #endif } -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) //---------------------------------------------------------- void ofFbo::copyTo(ofBufferObject & buffer) const{ if(!bIsAllocated) return; @@ -1109,15 +1123,15 @@ void ofFbo::copyTo(ofBufferObject & buffer) const{ //---------------------------------------------------------- void ofFbo::updateTexture(int attachmentPoint) { if(!bIsAllocated) return; -#ifndef TARGET_OPENGLES + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) if(fbo != fboTextures && dirty[attachmentPoint]) { // if fbo != fboTextures, we are dealing with an MSAA enabled FBO. - // and we need to blit one fbo into another to see get the texture - // content + // we need to blit one fbo into another to update the texture content if (!ofIsGLProgrammableRenderer()){ - // save current drawbuffer + // save current drawbuffer (fixed-function desktop only) glPushAttrib(GL_COLOR_BUFFER_BIT); } @@ -1126,7 +1140,7 @@ void ofFbo::updateTexture(int attachmentPoint) { GLint readBuffer; glGetIntegerv(GL_READ_BUFFER, &readBuffer); - renderer->bindForBlitting(*this,*this,attachmentPoint); + renderer->bindForBlitting(*this, *this, attachmentPoint); glBlitFramebuffer(0, 0, settings.width, settings.height, 0, 0, settings.width, settings.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); renderer->unbind(*this); @@ -1137,6 +1151,7 @@ void ofFbo::updateTexture(int attachmentPoint) { // restore current drawbuffer glPopAttrib(); } + dirty[attachmentPoint] = false; } #endif @@ -1150,7 +1165,7 @@ void ofFbo::draw(float x, float y) const{ //---------------------------------------------------------- void ofFbo::draw(float x, float y, float width, float height) const{ if(!bIsAllocated || settings.numColorbuffers==0) return; - getTexture().draw(x, y, width, height); + getTexture().draw(x, y, width, height); } //---------------------------------------------------------- @@ -1184,46 +1199,50 @@ float ofFbo::getHeight() const { bool ofFbo::checkStatus() const { GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch(status) { - case GL_FRAMEBUFFER_COMPLETE: - ofLogVerbose("ofFbo") << "FRAMEBUFFER_COMPLETE - OK"; - return true; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; - break; + case GL_FRAMEBUFFER_COMPLETE: + ofLogVerbose("ofFbo") << "FRAMEBUFFER_COMPLETE - OK"; + return true; + + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; + break; + #ifndef TARGET_PROGRAMMABLE_GL - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: - ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_FORMATS"; - break; + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: + ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_FORMATS"; + break; #endif - case GL_FRAMEBUFFER_UNSUPPORTED: - ofLogError("ofFbo") << "FRAMEBUFFER_UNSUPPORTED"; - break; -#ifndef TARGET_OPENGLES - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - ofLogWarning("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - ofLogError("ofFbo") << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; - break; + + case GL_FRAMEBUFFER_UNSUPPORTED: + ofLogError("ofFbo") << "FRAMEBUFFER_UNSUPPORTED"; + break; + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // these error codes are available on desktop + GLES 3.0+ + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + ofLogWarning("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + ofLogError("ofFbo") << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; + break; #endif - default: - ofLogError("ofFbo") << "UNKNOWN ERROR " << status; - break; + default: + ofLogError("ofFbo") << "UNKNOWN ERROR " << status; + break; } return false; } - //---------------------------------------------------------- ofTexture & ofFbo::getDepthTexture(){ if(!settings.depthStencilAsTexture){ @@ -1240,4 +1259,4 @@ const ofTexture & ofFbo::getDepthTexture() const{ return depthBufferTex; } -//#endif + diff --git a/libs/openFrameworks/gl/ofFbo.h b/libs/openFrameworks/gl/ofFbo.h index 67221fb4a67..d587f9cfd2d 100644 --- a/libs/openFrameworks/gl/ofFbo.h +++ b/libs/openFrameworks/gl/ofFbo.h @@ -65,7 +65,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { void destroy(); void clear(); -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) /// glClearBufferfv(GL_COLOR, 0...) /// /// @see: https://www.opengl.org/wiki/GLAPI/glClearBuffer @@ -122,7 +122,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { /// Sets up the framebuffer and binds it for rendering. /// - /// \warning This is a convenience method, and is considered unsafe + /// \warning This is a convenience method, and is considered unsafe /// in multi-window and/or multi-renderer scenarios. /// If you use more than one renderer, use each renderer's /// explicit void ofBaseGLRenderer::begin(const ofFbo & fbo, ofFboMode mode) @@ -166,7 +166,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { void readToPixels(ofShortPixels & pixels, int attachmentPoint = 0) const; void readToPixels(ofFloatPixels & pixels, int attachmentPoint = 0) const; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) /// \brief Copy the fbo to an ofBufferObject. /// \param buffer the target buffer to copy to. void copyTo(ofBufferObject & buffer) const; @@ -189,7 +189,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { /// \sa virtual void ofBaseGLRenderer::bind(const ofFbo & fbo) void bind() const; - /// \brief Unbinds OpenGL framebuffer target and restores the OpenGL framebuffer + /// \brief Unbinds OpenGL framebuffer target and restores the OpenGL framebuffer /// render target to whatever this ofFbo stores in previousFramebufferBinding. /// \sa bind() /// \sa void setPreviousFramebufferBinding(const GLuint& previousFramebufferBinding_) const @@ -197,9 +197,9 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { void flagDirty() const; ///< check whether attached MSAA buffers need updating - /// \brief Explicityl resolve MSAA render buffers into textures - /// \note if using MSAA, we will have rendered into a colorbuffer, not directly - /// into the texture call this to blit from the colorbuffer into the texture + /// \brief Explicityl resolve MSAA render buffers into textures + /// \note if using MSAA, we will have rendered into a colorbuffer, not directly + /// into the texture call this to blit from the colorbuffer into the texture /// so we can use the results for rendering, or input to a shader etc. /// \note This will get called implicitly upon getTexture(); void updateTexture(int attachmentPoint); @@ -244,7 +244,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { GLuint stencilBuffer; std::vector colorBuffers; - std::vector textures; + std::vector textures; ofTexture depthBufferTex; @@ -255,9 +255,9 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { std::vector activeDrawBuffers; ///< table of currently active color draw buffers, allocate() defaults it to size(textures), with GL_COLOR_ATTACHMENT0..n as members, in order of allocation /// \brief Flags used internally to keep track of MSAA renderbuffers / textures - /// \note The dirty flags are only used when dealing if the framebuffer has MSAA + /// \note The dirty flags are only used when dealing if the framebuffer has MSAA /// enabled attachments, i.e. numSamples is > 0 and extra Textures have - /// been bound so that the multisampled renderbuffers can be resolved to + /// been bound so that the multisampled renderbuffers can be resolved to /// textures. /// The flags are read whenever an attached texture is accessed. If the texture /// is dirty, i.e. it has not yet been resolved from its associated renderbuffer @@ -267,7 +267,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { int defaultTextureIndex; //used for getTextureReference bool bIsAllocated; void reloadFbo(); -#ifdef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) static bool bglFunctionsInitialized; #endif diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index 5d8d6fa3569..8cb367e0f20 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -119,15 +119,8 @@ void ofGLProgrammableRenderer::finishRender() { void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode renderType, bool useColors, bool useTextures, bool useNormals) const { if (vertexData.getVertices().empty()) return; - // tig: note that for GL3+ we use glPolygonMode to draw wireframes or filled meshes, and not the primitive mode. - // the reason is not purely aesthetic, but more conformant with the behaviour of ofGLRenderer. Whereas - // gles2.0 doesn't allow for a polygonmode. - // Also gles2 still supports vertex array syntax for uploading data to attributes and it seems to be faster than - // vbo's for meshes that are updated frequently so let's use that instead - - //if (bSmoothHinted) startSmoothing(); - -#if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) +#ifdef TARGET_OPENGLES + // OpenGL ES path - use vertex attrib arrays (fast for frequently updated meshes) glEnableVertexAttribArray(ofShader::POSITION_ATTRIBUTE); glVertexAttribPointer(ofShader::POSITION_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(typename ofMesh::VertexType), vertexData.getVerticesPointer()); @@ -155,61 +148,44 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode glDisableVertexAttribArray(ofShader::TEXCOORD_ATTRIBUTE); } - // const_cast(this)->setAttributes(true, useColors, useTextures, useNormals); - GLenum drawMode; switch (renderType) { - case OF_MESH_POINTS: - drawMode = GL_POINTS; - break; - case OF_MESH_WIREFRAME: - drawMode = GL_LINES; - break; - case OF_MESH_FILL: - drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); - break; - default: - drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); - break; + case OF_MESH_POINTS: drawMode = GL_POINTS; break; + case OF_MESH_WIREFRAME: drawMode = GL_LINES; break; + case OF_MESH_FILL: drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); break; + default: drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); break; } - const_cast(this)->setAttributes(true, useColors, useTextures, useNormals, drawMode); + + const_cast(this)->setAttributes(true, useColors, useTextures, useNormals); if (vertexData.getNumIndices()) { glDrawElements(drawMode, vertexData.getNumIndices(), GL_UNSIGNED_SHORT, vertexData.getIndexPointer()); } else { glDrawArrays(drawMode, 0, vertexData.getNumVertices()); } + #else - + // Desktop GL path - VBO + optional lines shader bundle ofVbo* vboToRender = nullptr; bool tGoingToRenderLines = false; -#ifndef TARGET_OPENGLES -// meshVbo.setMesh(vertexData, GL_STREAM_DRAW, useColors, useTextures, useNormals); + glPolygonMode(GL_FRONT_AND_BACK, ofGetGLPolyMode(renderType)); GLenum drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); - // if the render type is different than the primitive mode - // ie. mesh mode is triangles but we called mesh.drawVertices() which uses GL_POINT for the render type - // however, we need GL_POINTS for rendering point sprites - if (pointSpritesEnabled && !usingCustomShader && !uniqueShader) { - if (renderType == OF_MESH_POINTS) { - drawMode = GL_POINTS; - } - } bool bConfigureForLinesShader = areLinesShadersEnabled() && (drawMode == GL_LINES || drawMode == GL_LINE_STRIP || drawMode == GL_LINE_LOOP); - if( usingCustomShader || usingCustomShader || currentMaterial) { + if (usingCustomShader || currentMaterial) { bConfigureForLinesShader = false; } - if( bConfigureForLinesShader ) { + if (bConfigureForLinesShader) { mDrawMode = drawMode; tGoingToRenderLines = true; ofGLProgrammableRenderer * mutThis = const_cast(this); - if( drawMode == GL_LINES ) { - mutThis->configureLinesBundleFromMesh( mutThis->mLinesBundleMap[GL_LINES], drawMode, vertexData); + if (drawMode == GL_LINES) { + mutThis->configureLinesBundleFromMesh(mutThis->mLinesBundleMap[GL_LINES], drawMode, vertexData); vboToRender = &mutThis->mLinesBundleMap[GL_LINES].vbo; } else { - mutThis->configureLinesBundleFromMesh( mutThis->mLinesBundleMap[GL_LINE_STRIP], drawMode, vertexData); + mutThis->configureLinesBundleFromMesh(mutThis->mLinesBundleMap[GL_LINE_STRIP], drawMode, vertexData); vboToRender = &mutThis->mLinesBundleMap[GL_LINE_STRIP].vbo; } } else { @@ -217,54 +193,11 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode vboToRender = &meshVbo; } -#else -// meshVbo.setMesh(vertexData, GL_STATIC_DRAW, useColors, useTextures, useNormals); - GLenum drawMode; - switch (renderType) { - case OF_MESH_POINTS: - drawMode = GL_POINTS; - break; - case OF_MESH_WIREFRAME: - drawMode = GL_LINE_STRIP; - break; - case OF_MESH_FILL: - drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); - break; - default: - drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); - break; - } - - bool bConfigureForLinesShader = areLinesShadersEnabled() && (drawMode == GL_LINES || drawMode == GL_LINE_STRIP || drawMode == GL_LINE_LOOP); - if( usingCustomShader || usingCustomShader || currentMaterial) { - bConfigureForLinesShader = false; - } - - if(bConfigureForLinesShader) { - mDrawMode = drawMode; - tGoingToRenderLines = true; - ofGLProgrammableRenderer * mutThis = const_cast(this); - if( drawMode == GL_LINES ) { - mutThis->configureLinesBundleFromMesh( mutThis->mLinesBundleMap[GL_LINES], drawMode, vertexData); - vboToRender = &mutThis->mLinesBundleMap[GL_LINES].vbo; - } else { - mutThis->configureLinesBundleFromMesh( mutThis->mLinesBundleMap[GL_LINE_STRIP], drawMode, vertexData); - vboToRender = &mutThis->mLinesBundleMap[GL_LINE_STRIP].vbo; - } - } else { - meshVbo.setMesh(vertexData, GL_STATIC_DRAW, useColors, useTextures, useNormals); - vboToRender = &meshVbo; - } - - #endif - - if( vboToRender != nullptr ) { - if( tGoingToRenderLines ) { - // Setting a bool here so that the setAttributes function does not try to switch the shaders because - // we are going to draw the mesh as triangles and we need the lines shader - // we are rendering lines, and the meshes we constructed are made of triangles + if (vboToRender != nullptr) { + if (tGoingToRenderLines) { + // Setting a bool here so that the setAttributes function does not try to switch the shaders mBRenderingLines = true; - if( renderType == OF_MESH_FILL ) { + if (renderType == OF_MESH_FILL) { drawMode = GL_TRIANGLES; } } @@ -275,24 +208,14 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode draw(*vboToRender, drawMode, 0, vboToRender->getNumVertices()); } - if( tGoingToRenderLines ) { + if (tGoingToRenderLines) { mBRenderingLines = false; } } - // tig: note further that we could glGet() and store the current polygon mode, but don't, since that would - // infer a massive performance hit. instead, we revert the glPolygonMode to mirror the current ofFill state - // after we're finished drawing, following the principle of least surprise. - // ideally the glPolygonMode (or the polygon draw mode) should be part of ofStyle so that we can keep track - // of its state on the client side... - - #ifndef TARGET_OPENGLES + // restore polygon mode to match current fill state glPolygonMode(GL_FRONT_AND_BACK, currentStyle.bFill ? GL_FILL : GL_LINE); - #endif - #endif - - //if (bSmoothHinted) endSmoothing(); } //---------------------------------------------------------- @@ -303,8 +226,10 @@ void ofGLProgrammableRenderer::draw(const ofVboMesh & mesh, ofPolyRenderMode ren //---------------------------------------------------------- void ofGLProgrammableRenderer::drawInstanced(const ofVboMesh & mesh, ofPolyRenderMode renderType, int primCount) const { if (mesh.getNumVertices() == 0) return; + GLuint mode = ofGetGLPrimitiveMode(mesh.getMode()); - // nh: if the render type is different than the primitive mode + + // if the render type is different than the primitive mode // ie. mesh mode is triangles but we called mesh.drawVertices() which uses GL_POINT for the render type // however, we need GL_POINTS for rendering point sprites if (pointSpritesEnabled) { @@ -312,48 +237,30 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVboMesh & mesh, ofPolyRende mode = GL_POINTS; } } -#if !defined( TARGET_OPENGLES ) || defined(TARGET_EMSCRIPTEN) - #if !defined(TARGET_EMSCRIPTEN) + +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // Desktop + GLES 3.0+ (including Emscripten) — full polygon mode + instancing support glPolygonMode(GL_FRONT_AND_BACK, ofGetGLPolyMode(renderType)); - #else - // nh: glPolygonMode is not supported via emscripten, - // we can not render wire frames with vbos. - // this is not the best solution, but does provide some information - // and does not render as solid when wireframe mode is requested. - if (renderType == OF_MESH_WIREFRAME) { - if (mesh.getNumIndices()) { - drawElements(mesh.getVbo(), GL_LINES, mesh.getNumIndices()); + + if (mesh.getNumIndices() && renderType != OF_MESH_POINTS) { + if (primCount <= 1) { + drawElements(mesh.getVbo(), mode, mesh.getNumIndices()); } else { - draw(mesh.getVbo(), GL_LINES, 0, mesh.getNumVertices()); + drawElementsInstanced(mesh.getVbo(), mode, mesh.getNumIndices(), primCount); } } else { - #endif - if (mesh.getNumIndices() && renderType != OF_MESH_POINTS) { - if (primCount <= 1) { - drawElements(mesh.getVbo(), mode, mesh.getNumIndices()); - } else { - drawElementsInstanced(mesh.getVbo(), mode, mesh.getNumIndices(), primCount); - } + if (primCount <= 1) { + draw(mesh.getVbo(), mode, 0, mesh.getNumVertices()); } else { - if (primCount <= 1) { - draw(mesh.getVbo(), mode, 0, mesh.getNumVertices()); - } else { - drawInstanced(mesh.getVbo(), mode, 0, mesh.getNumVertices(), primCount); - } + drawInstanced(mesh.getVbo(), mode, 0, mesh.getNumVertices(), primCount); } - #if defined(TARGET_EMSCRIPTEN) - } // close the if for checking for wireframe - #endif + } + + // restore polygon mode to match current fill state + glPolygonMode(GL_FRONT_AND_BACK, currentStyle.bFill ? GL_FILL : GL_LINE); - // tig: note further that we could glGet() and store the current polygon mode, but don't, since that would - // infer a massive performance hit. instead, we revert the glPolygonMode to mirror the current ofFill state - // after we're finished drawing, following the principle of least surprise. - // ideally the glPolygonMode (or the polygon draw mode) should be part of ofStyle so that we can keep track - // of its state on the client side... - #if !defined(TARGET_EMSCRIPTEN) - glPolygonMode(GL_FRONT_AND_BACK, currentStyle.bFill ? GL_FILL : GL_LINE); - #endif #else + // Pure GLES 2.0 fallback — no polygon mode, no instancing if (renderType == OF_MESH_POINTS) { draw(mesh.getVbo(), GL_POINTS, 0, mesh.getNumVertices()); } else if (renderType == OF_MESH_WIREFRAME) { @@ -371,7 +278,6 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVboMesh & mesh, ofPolyRende } #endif } - //---------------------------------------------------------- void ofGLProgrammableRenderer::draw(const of3dPrimitive & model, ofPolyRenderMode renderType) const { const_cast(this)->pushMatrix(); @@ -567,8 +473,13 @@ void ofGLProgrammableRenderer::draw(const ofVbo & vbo, GLuint drawMode, int firs void ofGLProgrammableRenderer::drawElements(const ofVbo & vbo, GLuint drawMode, int amt, int offsetelements) const { if (vbo.getUsingVerts()) { vbo.bind(); - const_cast(this)->setAttributes(vbo.getUsingVerts(), vbo.getUsingColors(), vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); -#ifdef TARGET_OPENGLES && !defined(GL_ES_VERSION_2_0) + const_cast(this)->setAttributes( + vbo.getUsingVerts(), + vbo.getUsingColors(), + vbo.getUsingTexCoords(), + vbo.getUsingNormals(), drawMode); + +#ifdef TARGET_OPENGLES glDrawElements(drawMode, amt, GL_UNSIGNED_SHORT, (void *)(sizeof(ofIndexType) * offsetelements)); #else glDrawElements(drawMode, amt, GL_UNSIGNED_INT, (void *)(sizeof(ofIndexType) * offsetelements)); @@ -1104,15 +1015,15 @@ void ofGLProgrammableRenderer::setFillMode(ofFillFlag fill) { if (currentStyle.bFill) { path.setFilled(true); path.setStrokeWidth(0); -#ifndef TARGET_OPENGLES - // GLES does not support glPolygonMode +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // GLES 3.0+ (and desktop) support glPolygonMode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif } else { path.setFilled(false); path.setStrokeWidth(currentStyle.lineWidth); -#ifndef TARGET_OPENGLES - // GLES does not support glPolygonMode +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // GLES 3.0+ (and desktop) support glPolygonMode glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #endif } @@ -1221,20 +1132,19 @@ void ofGLProgrammableRenderer::setBlendMode(ofBlendMode blendMode) { case OF_BLENDMODE_MAX: glEnable(GL_BLEND); -#ifdef TARGET_OPENGLES - ofLogWarning("ofGLProgrammableRenderer") << "OF_BLENDMODE_MAX not currently supported on OpenGL ES"; -#else +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) glBlendEquation(GL_MAX); +#else + ofLogWarning("ofGLProgrammableRenderer") << "OF_BLENDMODE_MAX not currently supported on OpenGL ES < 3.0"; #endif - break; case OF_BLENDMODE_MIN: glEnable(GL_BLEND); -#ifdef TARGET_OPENGLES - ofLogWarning("ofGLProgrammableRenderer") << "OF_BLENDMODE_MIN not currently supported on OpenGL ES"; -#else +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) glBlendEquation(GL_MIN); +#else + ofLogWarning("ofGLProgrammableRenderer") << "OF_BLENDMODE_MIN not currently supported on OpenGL ES < 3.0"; #endif break; @@ -1247,37 +1157,33 @@ void ofGLProgrammableRenderer::setBlendMode(ofBlendMode blendMode) { //---------------------------------------------------------- void ofGLProgrammableRenderer::enablePointSprites() { pointSpritesEnabled = true; -#ifdef TARGET_OPENGLES -#ifndef TARGET_PROGRAMMABLE_GL - glEnable(GL_POINT_SPRITE_OES); -#endif +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + glEnable(GL_PROGRAM_POINT_SIZE); #else - glEnable(GL_PROGRAM_POINT_SIZE); + glEnable(GL_POINT_SPRITE_OES); #endif } //---------------------------------------------------------- void ofGLProgrammableRenderer::disablePointSprites() { -#ifdef TARGET_OPENGLES - #ifndef TARGET_PROGRAMMABLE_GL - glEnable(GL_POINT_SPRITE_OES); - #endif -#else + pointSpritesEnabled = false; +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) glDisable(GL_PROGRAM_POINT_SIZE); +#else + glDisable(GL_POINT_SPRITE_OES); #endif - pointSpritesEnabled = false; } //---------------------------------------------------------- void ofGLProgrammableRenderer::enableAntiAliasing() { -#if !defined(TARGET_PROGRAMMABLE_GL) || !defined(TARGET_OPENGLES) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) glEnable(GL_MULTISAMPLE); #endif } //---------------------------------------------------------- void ofGLProgrammableRenderer::disableAntiAliasing() { -#if !defined(TARGET_PROGRAMMABLE_GL) || !defined(TARGET_OPENGLES) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) glDisable(GL_MULTISAMPLE); #endif } @@ -1443,7 +1349,6 @@ void ofGLProgrammableRenderer::setAttributes(bool vertices, bool color, bool tex if( prevDrawMode != mDrawMode ) { if (currentTextureTarget != OF_NO_TEXTURE && currentShader ) { // set all of the texture uniforms - // setUniformTexture(const string & name, int textureTarget, GLint textureID, int textureLocation) const { for (auto &texUniform : mUniformsTex ) { currentShader->setUniformTexture(texUniform.uniformName, texUniform.texData, texUniform.textureLocation); } @@ -1452,7 +1357,6 @@ void ofGLProgrammableRenderer::setAttributes(bool vertices, bool color, bool tex auto &texUniform = mUniformsTex[0]; #if !defined(TARGET_OPENGLES) if (currentTextureTarget == GL_TEXTURE_RECTANGLE_ARB) { - // set the size of the texture, since gl_PointCoord is normalized currentShader->setUniform2f("src_tex_unit0_dims", texUniform.texData.width, texUniform.texData.height); } #endif @@ -1635,7 +1539,7 @@ void ofGLProgrammableRenderer::bind(const ofFbo & fbo) { glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferId); } -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) //---------------------------------------------------------- void ofGLProgrammableRenderer::bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint) { if (currentFramebufferId == fboSrc.getId()) { @@ -1761,12 +1665,15 @@ void ofGLProgrammableRenderer::bind(const ofTexture & texture, int location) { pushMatrix(); glm::mat4 m = glm::mat4(1.0); -#ifndef TARGET_OPENGLES - if (texture.texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB) +#if !defined(TARGET_OPENGLES) + if (texture.texData.textureTarget == GL_TEXTURE_RECTANGLE_ARB) { m = glm::scale(m, glm::vec3(texture.texData.width, texture.texData.height, 1.0f)); + } else #endif + { m = glm::scale(m, glm::vec3(texture.texData.width / texture.texData.tex_w, texture.texData.height / texture.texData.tex_h, 1.0f)); + } loadMatrix(m); matrixMode(OF_MATRIX_MODELVIEW); @@ -1849,97 +1756,86 @@ void ofGLProgrammableRenderer::setDefaultUniforms() { //---------------------------------------------------------- void ofGLProgrammableRenderer::beginDefaultShader() { if (usingCustomShader && !currentMaterial && !currentShadow) return; - if (currentShadow && bCustomShadowShader) return; - - const ofShader * nextShader = nullptr; - - bool bUseTexture = texCoordsEnabled; - if( mDrawMode == GL_POINTS ){ - // if we are drawing points, we don't need tex coords and would like to use the texture - if (currentTextureTarget != OF_NO_TEXTURE ) { - bUseTexture = true; - } - } - - if (!uniqueShader || currentMaterial || currentShadow) - { - if (currentShadow) { - if (currentMaterial && currentMaterial->hasDepthShader()) { - nextShader = ¤tMaterial->getShadowDepthShader(*currentShadow, *this); - } else { - nextShader = ¤tShadow->getDepthShader(*this); - } - } else if (currentMaterial) { - nextShader = ¤tMaterial->getShader(currentTextureTarget, colorsEnabled, *this); - } else if (bitmapStringEnabled) { - nextShader = &bitmapStringShader; - - } else if (colorsEnabled && bUseTexture) { - auto &shaderCollection = getShaderCollectionForMode(mDrawMode); - - switch (currentTextureTarget) - { -#ifndef TARGET_OPENGLES - case GL_TEXTURE_RECTANGLE_ARB: - nextShader = &shaderCollection->texRectColor; - // nextShader = &defaultTexRectColor; - break; -#endif - case GL_TEXTURE_2D: - nextShader = &shaderCollection->tex2DColor; - // nextShader = &defaultTex2DColor; - break; - case OF_NO_TEXTURE: - nextShader = &shaderCollection->noTexColor; - // nextShader = &defaultNoTexColor; - break; -#ifdef TARGET_ANDROID - case GL_TEXTURE_EXTERNAL_OES: - nextShader = &defaultOESTexColor; - break; -#endif - } - } else if (colorsEnabled) { - nextShader = &getShaderCollectionForMode(mDrawMode)->noTexColor; - // nextShader = &defaultNoTexColor; - } else if (bUseTexture) { - auto &shaderCollection = getShaderCollectionForMode(mDrawMode); - switch (currentTextureTarget) { -#ifndef TARGET_OPENGLES - case GL_TEXTURE_RECTANGLE_ARB: - nextShader = &shaderCollection->texRectNoColor; - // nextShader = &defaultTexRectNoColor; - break; -#endif - case GL_TEXTURE_2D: - nextShader = &shaderCollection->tex2DNoColor; - // nextShader = &defaultTex2DNoColor; - break; - case OF_NO_TEXTURE: - nextShader = &shaderCollection->noTexNoColor; - // nextShader = &defaultNoTexNoColor; - break; -#ifdef TARGET_ANDROID - case GL_TEXTURE_EXTERNAL_OES: - nextShader = &defaultOESTexNoColor; - break; -#endif - } - } else { - nextShader = &getShaderCollectionForMode(mDrawMode)->noTexNoColor; - // nextShader = &defaultNoTexNoColor; - } - } else { - nextShader = &defaultUniqueShader; - } - - if (nextShader) { - if (!currentShader || *currentShader != *nextShader) { - settingDefaultShader = true; - bind(*nextShader); - settingDefaultShader = false; - } - } + if (currentShadow && bCustomShadowShader) return; + + const ofShader * nextShader = nullptr; + + bool bUseTexture = texCoordsEnabled; + if (mDrawMode == GL_POINTS) { + // if we are drawing points, we don't need tex coords and would like to use the texture + if (currentTextureTarget != OF_NO_TEXTURE) { + bUseTexture = true; + } + } + + if (!uniqueShader || currentMaterial || currentShadow) { + if (currentShadow) { + if (currentMaterial && currentMaterial->hasDepthShader()) { + nextShader = ¤tMaterial->getShadowDepthShader(*currentShadow, *this); + } else { + nextShader = ¤tShadow->getDepthShader(*this); + } + } else if (currentMaterial) { + nextShader = ¤tMaterial->getShader(currentTextureTarget, colorsEnabled, *this); + } else if (bitmapStringEnabled) { + nextShader = &bitmapStringShader; + } else if (colorsEnabled && bUseTexture) { + auto &shaderCollection = getShaderCollectionForMode(mDrawMode); + + switch (currentTextureTarget) { + #ifndef TARGET_OPENGLES + case GL_TEXTURE_RECTANGLE_ARB: + nextShader = &shaderCollection->texRectColor; + break; + #endif + case GL_TEXTURE_2D: + nextShader = &shaderCollection->tex2DColor; + break; + case OF_NO_TEXTURE: + nextShader = &shaderCollection->noTexColor; + break; + #ifdef TARGET_ANDROID + case GL_TEXTURE_EXTERNAL_OES: + nextShader = &defaultOESTexColor; + break; + #endif + } + } else if (colorsEnabled) { + nextShader = &getShaderCollectionForMode(mDrawMode)->noTexColor; + } else if (bUseTexture) { + auto &shaderCollection = getShaderCollectionForMode(mDrawMode); + switch (currentTextureTarget) { + #ifndef TARGET_OPENGLES + case GL_TEXTURE_RECTANGLE_ARB: + nextShader = &shaderCollection->texRectNoColor; + break; + #endif + case GL_TEXTURE_2D: + nextShader = &shaderCollection->tex2DNoColor; + break; + case OF_NO_TEXTURE: + nextShader = &shaderCollection->noTexNoColor; + break; + #ifdef TARGET_ANDROID + case GL_TEXTURE_EXTERNAL_OES: + nextShader = &defaultOESTexNoColor; + break; + #endif + } + } else { + nextShader = &getShaderCollectionForMode(mDrawMode)->noTexNoColor; + } + } else { + nextShader = &defaultUniqueShader; + } + + if (nextShader) { + if (!currentShader || *currentShader != *nextShader) { + settingDefaultShader = true; + bind(*nextShader); + settingDefaultShader = false; + } + } } //---------------------------------------------------------- @@ -3009,15 +2905,22 @@ static const string FRAGMENT_SHADER_PLANAR_YUV = STRINGIFY( static string defaultShaderHeader(string header, GLenum textureTarget, int major, int minor) { ofStringReplace(header, "%glsl_version%", ofGLSLVersionFromGL(major, minor)); -#ifndef TARGET_OPENGLES + +#if !defined(TARGET_OPENGLES) + // Desktop only: rectangle texture extension (needed for older GL < 4.2) if (major < 4 && minor < 2) { ofStringReplace(header, "%extensions%", "#extension GL_ARB_texture_rectangle : enable"); } else { ofStringReplace(header, "%extensions%", ""); } #else + #if !defined(GL_ES_VERSION_3_0) ofStringReplace(header, "%extensions%", "#extension GL_OES_standard_derivatives : enable"); + #else + ofStringReplace(header, "%extensions%", ""); + #endif #endif + if (textureTarget == GL_TEXTURE_2D) { header += "#define SAMPLER sampler2D\n"; } else { @@ -3029,15 +2932,21 @@ static string defaultShaderHeader(string header, GLenum textureTarget, int major static string shaderSource(const string & src, int major, int minor) { string shaderSrc = src; ofStringReplace(shaderSrc, "%glsl_version%", ofGLSLVersionFromGL(major, minor)); -#ifndef TARGET_OPENGLES + +#if !defined(TARGET_OPENGLES) if (major < 4 && minor < 2) { ofStringReplace(shaderSrc, "%extensions%", "#extension GL_ARB_texture_rectangle : enable"); } else { ofStringReplace(shaderSrc, "%extensions%", ""); } #else - ofStringReplace(shaderSrc, "%extensions%", ""); + #if !defined(GL_ES_VERSION_3_0) + ofStringReplace(header, "%extensions%", "#extension GL_OES_standard_derivatives : enable"); + #else + ofStringReplace(header, "%extensions%", ""); + #endif #endif + return shaderSrc; } diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.h b/libs/openFrameworks/gl/ofGLProgrammableRenderer.h index 4adac96f4ba..efe1131e953 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.h +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.h @@ -204,7 +204,7 @@ class ofGLProgrammableRenderer: public ofBaseGLRenderer{ void unbind(const ofCamera & camera); void bind(const ofFbo & fbo); -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) void bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint); #endif void unbind(const ofFbo & fbo); From 03bbcee25e2e6dd220f2115fd8b5904de6bc9474 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 01:20:46 +1000 Subject: [PATCH 18/38] Refactor GLES version variables in ofGLESWindowSettings --- libs/openFrameworks/app/ofWindowSettings.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libs/openFrameworks/app/ofWindowSettings.h b/libs/openFrameworks/app/ofWindowSettings.h index 8cf9ccb1193..459a2a5ee7b 100644 --- a/libs/openFrameworks/app/ofWindowSettings.h +++ b/libs/openFrameworks/app/ofWindowSettings.h @@ -126,28 +126,28 @@ class ofGLWindowSettings: public ofWindowSettings{ class ofGLESWindowSettings: public ofWindowSettings{ public: ofGLESWindowSettings() - :mGlesVersionMajor(1), mGlesVersionMinor(0){} + :glesVersion(1), glesVersionMinor(0){} ofGLESWindowSettings(const ofWindowSettings & settings) - :ofWindowSettings(settings), mGlesVersionMajor(1), mGlesVersionMinor(0) { + :ofWindowSettings(settings), glesVersion(1), glesVersionMinor(0) { const ofGLESWindowSettings * glesSettings = dynamic_cast(&settings); if(glesSettings){ - mGlesVersionMajor = glesSettings->mGlesVersionMajor; - mGlesVersionMinor = glesSettings->mGlesVersionMinor; + glesVersion = glesSettings->glesVersion; + glesVersionMinor = glesSettings->mGlesVersionMinor; } } virtual ~ofGLESWindowSettings(){}; void setGLESVersion(int versionMajor, int versionMinor = 0){ - mGlesVersionMajor = versionMajor; - mGlesVersionMinor = versionMinor; + glesVersion = versionMajor; + glesVersionMinor = versionMinor; } - int glesVersionMajor() const { return mGlesVersionMajor; } - int glesVersionMinor() const { return mGlesVersionMinor ; } + int glesVersionMajor() const { return glesVersion; } + int glesVersionMinor() const { return glesVersionMinor ; } private: - int mGlesVersionMajor; - int mGlesVersionMinor; + int glesVersion; + int glesVersionMinor; }; From e38707beefadc70107476974434588cd393c55c4 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 01:21:50 +1000 Subject: [PATCH 19/38] OpenGLES 3.0 and Emscripten --- .../gl/ofGLProgrammableRenderer.cpp | 45 ++++---------- libs/openFrameworks/gl/ofGLUtils.cpp | 62 +++++++------------ libs/openFrameworks/gl/ofGLUtils.h | 5 ++ libs/openFrameworks/gl/ofMaterial.cpp | 44 ++++++------- libs/openFrameworks/gl/ofShader.cpp | 4 +- libs/openFrameworks/gl/ofShadow.cpp | 24 +++---- 6 files changed, 70 insertions(+), 114 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index 8cb367e0f20..5ded7173b17 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -302,43 +302,32 @@ void ofGLProgrammableRenderer::draw(const ofNode & node) const { void ofGLProgrammableRenderer::draw(const ofPolyline & poly) const { if (poly.getVertices().empty()) return; - // use smoothness, if requested: - //if (bSmoothHinted) startSmoothing(); - -#if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) - +#if defined(TARGET_OPENGLES) + // OpenGL ES path - direct vertex attrib arrays (fast for frequently updated polylines) glEnableVertexAttribArray(ofShader::POSITION_ATTRIBUTE); glVertexAttribPointer(ofShader::POSITION_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(typename ofPolyline::VertexType), &poly[0]); - // const_cast(this)->setAttributes(true, false, false, false); - GLenum drawMode = poly.isClosed() ? GL_LINE_LOOP : GL_LINE_STRIP; - const_cast(this)->setAttributes(true, false, false, false, drawMode); - + const_cast(this)->setAttributes(true, false, false, false); glDrawArrays(drawMode, 0, poly.size()); #else - -// polylineMesh.clear(); -// polylineMesh.addVertices(poly.getVertices()); - - + // Desktop GL path - use VBO mesh polylineMesh.getVertices() = poly.getVertices(); - // check if it is closed and the last point is the same as the first - if( poly.isClosed() ) { - if(polylineMesh.getNumVertices() > 1 && polylineMesh.getVertices().front() == polylineMesh.getVertices().back() ) { + if (poly.isClosed()) { + if (polylineMesh.getNumVertices() > 1 && polylineMesh.getVertices().front() == polylineMesh.getVertices().back()) { polylineMesh.getVertices().pop_back(); } } - if( currentTextureTarget != OF_NO_TEXTURE ) { + if (currentTextureTarget != OF_NO_TEXTURE) { // TODO: Should we be able to set tex coords on polylines somehow?? - polylineMesh.getTexCoords().resize( polylineMesh.getNumVertices(), glm::vec2(0.f, 0.f)); + polylineMesh.getTexCoords().resize(polylineMesh.getNumVertices(), glm::vec2(0.f, 0.f)); auto& tcs = polylineMesh.getTexCoords(); int numtxs = (int)polylineMesh.getNumVertices(); float numTxsF = (float)numtxs - 1.f; - if( numTxsF > 0.0f ) { - for( int ix = 0; ix < numtxs; ix++ ) { + if (numTxsF > 0.0f) { + for (int ix = 0; ix < numtxs; ix++) { tcs[ix].x = (float)ix / numTxsF; } } @@ -346,22 +335,12 @@ void ofGLProgrammableRenderer::draw(const ofPolyline & poly) const { } else { polylineMesh.disableTextures(); } - - polylineMesh.setMode( poly.isClosed() ? OF_PRIMITIVE_LINE_LOOP : OF_PRIMITIVE_LINE_STRIP ); -// draw(const ofMesh & vertexData, ofPolyRenderMode renderType, bool useColors, bool useTextures, bool useNormals) const; + polylineMesh.setMode(poly.isClosed() ? OF_PRIMITIVE_LINE_LOOP : OF_PRIMITIVE_LINE_STRIP); draw(polylineMesh, OF_MESH_FILL, false, false, false); - - -// meshVbo.setVertexData(&poly.getVertices()[0], poly.size(), GL_DYNAMIC_DRAW); -// meshVbo.draw(poly.isClosed() ? GL_LINE_LOOP : GL_LINE_STRIP, 0, poly.size()); -// meshPolylineVbo.setVertexData(&poly.getVertices()[0], poly.size(), GL_DYNAMIC_DRAW); -// meshPolylineVbo.draw(poly.isClosed() ? GL_LINE_LOOP : GL_LINE_STRIP, 0, poly.size()); - #endif - // use smoothness, if requested: - //if (bSmoothHinted) endSmoothing(); } + //---------------------------------------------------------- void ofGLProgrammableRenderer::draw(const ofPath & shape) const { ofFloatColor prevColor; diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 8a17b81b059..eff3ec0e6f6 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -452,52 +452,43 @@ ofImageType ofGetImageTypeFromGLType(int glType){ } GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) switch(mode){ - case(OF_MESH_POINTS): + case OF_MESH_POINTS: return GL_POINT; - break; - case(OF_MESH_WIREFRAME): + case OF_MESH_WIREFRAME: return GL_LINE; - break; - case(OF_MESH_FILL): + case OF_MESH_FILL: return GL_FILL; - break; default: ofLogError("ofGLUtils") << "ofGetGLPolyMode(): unknown OF poly mode " << ofToString(mode) << ", returning GL_FILL"; return GL_FILL; - break; } #else - ofLogError("ofGLUtils") << "ofGetGLPolyMode(): poly modes not supported in GLES"; - return 0; + ofLogError("ofGLUtils") << "ofGetGLPolyMode(): poly modes not supported in OpenGL ES < 3.0"; + return GL_FILL; #endif } ofPolyRenderMode ofGetOFPolyMode(GLuint mode){ -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) switch(mode){ - case(GL_POINT): + case GL_POINT: return OF_MESH_POINTS; - break; - case(GL_LINE): + case GL_LINE: return OF_MESH_WIREFRAME; - break; - case(GL_FILL): + case GL_FILL: return OF_MESH_FILL; - break; default: ofLogError("ofGLUtils") << "ofGetOFPolyMode(): unknown GL poly mode " << ofToString(mode) << ", returning OF_MESH_FILL"; return OF_MESH_FILL; - break; } #else - ofLogError("ofGLUtils") << "ofGetOFPolyMode(): poly modes not supported in GLES. Returning OF_MESH_FILL"; + ofLogError("ofGLUtils") << "ofGetOFPolyMode(): poly modes not supported in OpenGL ES < 3.0. Returning OF_MESH_FILL"; return OF_MESH_FILL; #endif } - GLuint ofGetGLPrimitiveMode(ofPrimitiveMode mode){ switch(mode){ case OF_PRIMITIVE_TRIANGLES: @@ -784,11 +775,6 @@ int ofGetBytesPerChannelFromGLType(int glType){ } } -// Rounds an integer value up to the next multiple of 2,4 and 8. -#define OF_ROUND_UP_2(num) (((num)+1)&~1) -#define OF_ROUND_UP_4(num) (((num)+3)&~3) -#define OF_ROUND_UP_8(num) (((num)+7)&~7) - void ofSetPixelStoreiAlignment(GLenum pname, int w, int bpc, int numChannels){ int stride = w * numChannels * bpc; ofSetPixelStoreiAlignment(pname,stride); @@ -841,27 +827,27 @@ bool ofGLCheckExtension(string searchName){ } bool ofGLSupportsNPOTTextures(){ -#ifndef TARGET_OPENGLES - return GL_ARB_texture_rectangle; -#elif !defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + // Desktop + GLES 3.0+ support NPOT textures natively (core feature) + return true; +#else + // Pure GLES 2.0 — check extensions at runtime static bool npotChecked = false; static bool npotSupported = false; if(!npotChecked){ vector extensionsList = ofGLSupportedExtensions(); - std::set extensionsSet; - extensionsSet.insert(extensionsList.begin(),extensionsList.end()); - - npotSupported = extensionsSet.find("GL_OES_texture_npot")!=extensionsSet.end() || - extensionsSet.find("APPLE_texture_2D_limited_npot")!=extensionsSet.end() || - extensionsSet.find("GL_NV_texture_npot_2D_mipmap")!=extensionsSet.end() || - extensionsSet.find("GL_IMG_texture_npot")!=extensionsSet.end() || - extensionsSet.find("GL_ARB_texture_non_power_of_two")!=extensionsSet.end(); + std::set extensionsSet(extensionsList.begin(), extensionsList.end()); + + npotSupported = extensionsSet.find("GL_OES_texture_npot") != extensionsSet.end() || + extensionsSet.find("APPLE_texture_2D_limited_npot") != extensionsSet.end() || + extensionsSet.find("GL_NV_texture_npot_2D_mipmap") != extensionsSet.end() || + extensionsSet.find("GL_IMG_texture_npot") != extensionsSet.end() || + extensionsSet.find("GL_ARB_texture_non_power_of_two") != extensionsSet.end(); + npotChecked = true; } return npotSupported; -#else - return true; #endif } diff --git a/libs/openFrameworks/gl/ofGLUtils.h b/libs/openFrameworks/gl/ofGLUtils.h index 45e2039b586..9f6b1b6c4a3 100644 --- a/libs/openFrameworks/gl/ofGLUtils.h +++ b/libs/openFrameworks/gl/ofGLUtils.h @@ -205,3 +205,8 @@ void ofDisableGLDebugLog(); #endif #endif #endif + +// Rounds an integer value up to the next multiple of 2,4 and 8. +#define OF_ROUND_UP_2(num) (((num)+1)&~1) +#define OF_ROUND_UP_4(num) (((num)+3)&~3) +#define OF_ROUND_UP_8(num) (((num)+7)&~7) diff --git a/libs/openFrameworks/gl/ofMaterial.cpp b/libs/openFrameworks/gl/ofMaterial.cpp index 6a516eb772f..e2b93ff489f 100644 --- a/libs/openFrameworks/gl/ofMaterial.cpp +++ b/libs/openFrameworks/gl/ofMaterial.cpp @@ -110,39 +110,34 @@ std::string ofMaterial::getTextureTypeAsString(const ofMaterialTextureType & aMa //---------------------------------------------------------- bool ofMaterial::isPBRSupported() { - #if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) - return false; + #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + return false; // pure GLES 2.0 does not support PBR #endif - - if( !ofIsGLProgrammableRenderer() ) { - return false; - } - return true; + return ofIsGLProgrammableRenderer(); } //---------------------------------------------------------- void ofMaterial::setPBR(bool ab) { - if( ab && !ofIsGLProgrammableRenderer() ) { - if( !bPrintedPBRRenderWarning ) { - bPrintedPBRRenderWarning=true; - ofLogWarning("ofMaterial::setPBR") << " PBR material must be used with Programmable Renderer."; + if (ab && !ofIsGLProgrammableRenderer()) { + if (!bPrintedPBRRenderWarning) { + bPrintedPBRRenderWarning = true; + ofLogWarning("ofMaterial::setPBR") << "PBR material must be used with Programmable Renderer."; } data.isPbr = false; return; } - #if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) - if( ab ) { - if( !bPrintedPBRRenderWarning ) { - bPrintedPBRRenderWarning=true; - ofLogWarning("ofMaterial::setPBR") << " PBR material is not supported on this OPENGL ES platform."; + #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + if (ab) { + if (!bPrintedPBRRenderWarning) { + bPrintedPBRRenderWarning = true; + ofLogWarning("ofMaterial::setPBR") << "PBR material is not supported on OpenGL ES < 3.0."; } data.isPbr = false; return; } #endif - data.isPbr = ab; } @@ -1544,18 +1539,15 @@ namespace{ } - if( ofIsGLProgrammableRenderer() ) { - #if defined(TARGET_OPENGLES) - #if defined(TARGET_EMSCRIPTEN) - ofStringReplace(source, "%shader_shadow_include%", shadow_shader_include ); - #else - ofStringReplace(source, "%shader_shadow_include%", "" ); - #endif + if (ofIsGLProgrammableRenderer()) { + // Shadows require programmable renderer + GLES 3.0+ (or desktop) + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + ofStringReplace(source, "%shader_shadow_include%", shadow_shader_include); #else - ofStringReplace(source, "%shader_shadow_include%", shadow_shader_include ); + ofStringReplace(source, "%shader_shadow_include%", ""); #endif } else { - ofStringReplace(source, "%shader_shadow_include%", "" ); + ofStringReplace(source, "%shader_shadow_include%", ""); } source = shaderHeader(defaultHeader, maxLights, hasTexture, hasColor) + definesString + source; diff --git a/libs/openFrameworks/gl/ofShader.cpp b/libs/openFrameworks/gl/ofShader.cpp index f3fdea5b238..4fa42ec4b95 100644 --- a/libs/openFrameworks/gl/ofShader.cpp +++ b/libs/openFrameworks/gl/ofShader.cpp @@ -83,7 +83,7 @@ static void releaseProgram(GLuint id) { } } -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) //-------------------------------------------------------------- ofShader::TransformFeedbackRangeBinding::TransformFeedbackRangeBinding(const ofBufferObject & buffer, GLuint offset, GLuint size) : offset(offset) @@ -251,7 +251,7 @@ bool ofShader::setup(const ofShaderSettings & settings) { return linkProgram(); } -#if !defined(TARGET_OPENGLES) || defined(TARGET_EMSCRIPTEN) +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) //-------------------------------------------------------------- bool ofShader::setup(const TransformFeedbackSettings & settings) { for (auto shader : settings.shaderFiles) { diff --git a/libs/openFrameworks/gl/ofShadow.cpp b/libs/openFrameworks/gl/ofShadow.cpp index 6b1445804fb..6377d4a11fb 100644 --- a/libs/openFrameworks/gl/ofShadow.cpp +++ b/libs/openFrameworks/gl/ofShadow.cpp @@ -341,14 +341,11 @@ std::string ofShadow::getShaderDefinesAsString() { //-------------------------------------------------------------- bool ofShadow::areShadowsSupported() { - #if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) - return false; + #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + return false; // GLES 2.0 does not support shadows #endif - - if(!ofIsGLProgrammableRenderer() ) { - return false; - } - return true; + + return ofIsGLProgrammableRenderer(); } //-------------------------------------------------------------- @@ -987,15 +984,12 @@ void ofShadow::_allocateFbo() { GLenum gl_read_status = GL_FRAMEBUFFER_UNSUPPORTED; GLenum textureTarget = getTextureTarget(data->lightType); -#if !defined(TARGET_OPENGLES) - int depthComponent = GL_DEPTH_COMPONENT32F; - int glType = GL_FLOAT; -#elif defined(TARGET_EMSCRIPTEN) - int depthComponent = GL_DEPTH_COMPONENT24; - int glType = GL_UNSIGNED_INT; +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + GLenum depthComponent = GL_DEPTH_COMPONENT32F; + GLenum glType = GL_FLOAT; #else - int depthComponent = GL_DEPTH_COMPONENT; - int glType = GL_UNSIGNED_SHORT; + GLenum depthComponent = GL_DEPTH_COMPONENT; + GLenum glType = GL_UNSIGNED_SHORT; #endif glBindTexture(textureTarget, getDepthMapTexId() ); From 0150608d6e235b3be5c9442f9ef1c9253478e6d1 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 11:58:15 +1000 Subject: [PATCH 20/38] ofBufferObject OpenGLES 3 fixes --- libs/openFrameworks/gl/ofBufferObject.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/openFrameworks/gl/ofBufferObject.cpp b/libs/openFrameworks/gl/ofBufferObject.cpp index b27a51b4ce8..cd8dc15f646 100644 --- a/libs/openFrameworks/gl/ofBufferObject.cpp +++ b/libs/openFrameworks/gl/ofBufferObject.cpp @@ -264,9 +264,15 @@ void ofBufferObject::copyTo(ofBufferObject & dstBuffer, int readOffset, int writ void ofBufferObject::invalidate(){ - glInvalidateBufferData(data->id); +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_1) + // Desktop + GLES 3.1+ support glInvalidateBufferData + if (data && data->id != 0) { + glInvalidateBufferData(data->id); + } +#endif + // On GLES 2.0 / GLES 3.0 (including iOS with MetalANGLE) this is a no-op + // (the driver is free to ignore the hint anyway) } - #endif GLsizeiptr ofBufferObject::size() const{ From 4c14964c704d6611506baac79dfff08e24bd5e21 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 11:58:33 +1000 Subject: [PATCH 21/38] ofVbo and ofFbo OpenGLES 3 fixes --- libs/openFrameworks/gl/ofFbo.cpp | 11 ++- libs/openFrameworks/gl/ofVbo.cpp | 136 ++++++++++++++++--------------- 2 files changed, 81 insertions(+), 66 deletions(-) diff --git a/libs/openFrameworks/gl/ofFbo.cpp b/libs/openFrameworks/gl/ofFbo.cpp index b70ac608daf..758f2a7077f 100644 --- a/libs/openFrameworks/gl/ofFbo.cpp +++ b/libs/openFrameworks/gl/ofFbo.cpp @@ -1130,10 +1130,13 @@ void ofFbo::updateTexture(int attachmentPoint) { // if fbo != fboTextures, we are dealing with an MSAA enabled FBO. // we need to blit one fbo into another to update the texture content +#ifndef TARGET_OPENGLES + // glPushAttrib / glPopAttrib are desktop fixed-function only + // save current drawbuffer (fixed-function desktop only) if (!ofIsGLProgrammableRenderer()){ - // save current drawbuffer (fixed-function desktop only) glPushAttrib(GL_COLOR_BUFFER_BIT); } +#endif auto renderer = settings.renderer.lock(); if(renderer){ @@ -1147,10 +1150,12 @@ void ofFbo::updateTexture(int attachmentPoint) { glReadBuffer(readBuffer); } +#ifndef TARGET_OPENGLES if(!ofIsGLProgrammableRenderer()){ // restore current drawbuffer glPopAttrib(); } +#endif dirty[attachmentPoint] = false; } @@ -1223,7 +1228,7 @@ bool ofFbo::checkStatus() const { ofLogError("ofFbo") << "FRAMEBUFFER_UNSUPPORTED"; break; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) // these error codes are available on desktop + GLES 3.0+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: ofLogWarning("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; @@ -1231,6 +1236,8 @@ bool ofFbo::checkStatus() const { case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break; +#endif +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: ofLogError("ofFbo") << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break; diff --git a/libs/openFrameworks/gl/ofVbo.cpp b/libs/openFrameworks/gl/ofVbo.cpp index b9743c13505..1afdc7740c4 100644 --- a/libs/openFrameworks/gl/ofVbo.cpp +++ b/libs/openFrameworks/gl/ofVbo.cpp @@ -837,110 +837,118 @@ const ofBufferObject & ofVbo::getIndexBuffer() const{ } //-------------------------------------------------------------- -void ofVbo::bind() const{ +void ofVbo::bind() const { bool programmable = ofIsGLProgrammableRenderer(); - if(programmable && (vaoSupported || !vaoChecked)){ - if(vaoID==0){ - #if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) - if(glGenVertexArrays==0 && !vaoChecked){ + + // VAO handling + if (programmable && (vaoSupported || !vaoChecked)) { + if (vaoID == 0) { +#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + // Pure GLES 2.0 — try to load VAO extension via dlsym + if (glGenVertexArrays == 0 && !vaoChecked) { glGenVertexArrays = (glGenVertexArraysType)dlsym(RTLD_DEFAULT, "glGenVertexArrays"); glDeleteVertexArrays = (glDeleteVertexArraysType)dlsym(RTLD_DEFAULT, "glDeleteVertexArrays"); glBindVertexArray = (glBindVertexArrayType)dlsym(RTLD_DEFAULT, "glBindVertexArray"); vaoChecked = true; - vaoSupported = glGenVertexArrays; + vaoSupported = glGenVertexArrays != nullptr; } - #elif defined(TARGET_EMSCRIPTEN) - vaoChecked = true; - vaoSupported = false; - #else - vaoChecked = true; - vaoSupported = true; - #endif - if(vaoSupported) glGenVertexArrays(1, &const_cast(this)->vaoID); - if(vaoID!=0){ +#elif defined(TARGET_EMSCRIPTEN) + // Emscripten (WebGL2) does not reliably support VAOs in this context + vaoChecked = true; + vaoSupported = false; +#else + // Desktop + GLES 3.0+ — VAOs are core + vaoChecked = true; + vaoSupported = true; +#endif + + if (vaoSupported) { + glGenVertexArrays(1, &const_cast(this)->vaoID); + } + if (vaoID != 0) { retainVAO(vaoID); vaoChanged = true; } } - if(vaoSupported) glBindVertexArray(vaoID); - }else{ + + if (vaoSupported) { + glBindVertexArray(vaoID); + } + } else { vaoSupported = false; } - if(vaoChanged || !vaoSupported){ - if(bUsingVerts){ - if(!programmable){ - positionAttribute.bind(); - #ifndef TARGET_PROGRAMMABLE_GL + // attribute setup + if (vaoChanged || !vaoSupported) { + if (bUsingVerts) { + positionAttribute.bind(); + if (programmable) { + positionAttribute.enable(); + } else { +#ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(positionAttribute.numCoords, GL_FLOAT, - positionAttribute.stride, - (void*)positionAttribute.offset); - #endif - }else{ - positionAttribute.enable(); + positionAttribute.stride, (void*)positionAttribute.offset); +#endif } - }else if(programmable){ + } else if (programmable) { positionAttribute.disable(); } - if(bUsingColors) { - if(!programmable){ - colorAttribute.bind(); - #ifndef TARGET_PROGRAMMABLE_GL + if (bUsingColors) { + colorAttribute.bind(); + if (programmable) { + colorAttribute.enable(); + } else { +#ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_COLOR_ARRAY); glColorPointer(colorAttribute.numCoords, GL_FLOAT, - colorAttribute.stride, - (void*)colorAttribute.offset); - #endif - }else{ - colorAttribute.enable(); + colorAttribute.stride, (void*)colorAttribute.offset); +#endif } - }else if(programmable){ + } else if (programmable) { colorAttribute.disable(); } - if(bUsingNormals) { - if(!programmable){ - normalAttribute.bind(); - #ifndef TARGET_PROGRAMMABLE_GL + if (bUsingNormals) { + normalAttribute.bind(); + if (programmable) { + normalAttribute.enable(); + } else { +#ifndef TARGET_PROGRAMMABLE_GL glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, normalAttribute.stride, (void*)normalAttribute.offset); - #endif - }else{ - normalAttribute.enable(); +#endif } - }else if(programmable){ + } else if (programmable) { normalAttribute.disable(); } - if(bUsingTexCoords) { - if(!programmable){ - texCoordAttribute.bind(); - #ifndef TARGET_PROGRAMMABLE_GL - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(texCoordAttribute.numCoords, - GL_FLOAT, texCoordAttribute.stride, - (void*)texCoordAttribute.offset); - #endif - }else{ + if (bUsingTexCoords) { + texCoordAttribute.bind(); + if (programmable) { texCoordAttribute.enable(); + } else { +#ifndef TARGET_PROGRAMMABLE_GL + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(texCoordAttribute.numCoords, GL_FLOAT, + texCoordAttribute.stride, (void*)texCoordAttribute.offset); +#endif } - }else if(programmable){ + } else if (programmable) { texCoordAttribute.disable(); } - if (bUsingIndices) { - indexAttribute.bind(); - } + if (bUsingIndices) { + indexAttribute.bind(); + } - unordered_map::const_iterator it; - for(it = customAttributes.begin();it!=customAttributes.end();it++){ - it->second.enable(); + for (auto& it : customAttributes) { + it.second.enable(); } - vaoChanged=false; + vaoChanged = false; } } From be38559456468d9736556aa136a46d84d61654a5 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 11:58:51 +1000 Subject: [PATCH 22/38] ofWindowSettings fix for scope --- libs/openFrameworks/app/ofWindowSettings.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libs/openFrameworks/app/ofWindowSettings.h b/libs/openFrameworks/app/ofWindowSettings.h index 459a2a5ee7b..39d8fe46687 100644 --- a/libs/openFrameworks/app/ofWindowSettings.h +++ b/libs/openFrameworks/app/ofWindowSettings.h @@ -133,7 +133,7 @@ class ofGLESWindowSettings: public ofWindowSettings{ const ofGLESWindowSettings * glesSettings = dynamic_cast(&settings); if(glesSettings){ glesVersion = glesSettings->glesVersion; - glesVersionMinor = glesSettings->mGlesVersionMinor; + glesVersionMinor = glesSettings->glesVersionMinor; } } @@ -144,10 +144,9 @@ class ofGLESWindowSettings: public ofWindowSettings{ glesVersionMinor = versionMinor; } - int glesVersionMajor() const { return glesVersion; } - int glesVersionMinor() const { return glesVersionMinor ; } + int getGLESVersionMajor() const { return glesVersion; } + int getGLESVersionMinor() const { return glesVersionMinor ; } -private: int glesVersion; int glesVersionMinor; }; From 0e76c6ce8071de8969b76aa5742b0e301403ef2e Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 11:59:16 +1000 Subject: [PATCH 23/38] OpenGLES 3 fixes for ofGLProgrammableRenderer and BaseTypes --- libs/openFrameworks/gl/ofGLBaseTypes.h | 2 +- .../gl/ofGLProgrammableRenderer.cpp | 21 +++++++------ libs/openFrameworks/gl/ofGLUtils.cpp | 31 ++++++++++--------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLBaseTypes.h b/libs/openFrameworks/gl/ofGLBaseTypes.h index 5fae80f2b59..d03f5664efd 100644 --- a/libs/openFrameworks/gl/ofGLBaseTypes.h +++ b/libs/openFrameworks/gl/ofGLBaseTypes.h @@ -516,7 +516,7 @@ class ofBaseGLRenderer: public ofBaseRenderer{ /// \param fbo The frame buffer that is currently bound to this renderer. virtual void unbind(const ofFbo & fbo)=0; -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) /// \brief Bind source and destination frame buffers for blitting. /// /// \param fboSrc The source frame buffer to bind for blitting. diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index 5ded7173b17..c148c651a1d 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -156,7 +156,7 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode default: drawMode = ofGetGLPrimitiveMode(vertexData.getMode()); break; } - const_cast(this)->setAttributes(true, useColors, useTextures, useNormals); + const_cast(this)->setAttributes(true, useColors, useTextures, useNormals, drawMode); if (vertexData.getNumIndices()) { glDrawElements(drawMode, vertexData.getNumIndices(), GL_UNSIGNED_SHORT, vertexData.getIndexPointer()); @@ -239,9 +239,11 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVboMesh & mesh, ofPolyRende } #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - // Desktop + GLES 3.0+ (including Emscripten) — full polygon mode + instancing support + +#ifndef TARGET_OPENGLES glPolygonMode(GL_FRONT_AND_BACK, ofGetGLPolyMode(renderType)); - +#endif + if (mesh.getNumIndices() && renderType != OF_MESH_POINTS) { if (primCount <= 1) { drawElements(mesh.getVbo(), mode, mesh.getNumIndices()); @@ -255,10 +257,11 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVboMesh & mesh, ofPolyRende drawInstanced(mesh.getVbo(), mode, 0, mesh.getNumVertices(), primCount); } } - +#ifndef TARGET_OPENGLES // restore polygon mode to match current fill state glPolygonMode(GL_FRONT_AND_BACK, currentStyle.bFill ? GL_FILL : GL_LINE); - +#endif + #else // Pure GLES 2.0 fallback — no polygon mode, no instancing if (renderType == OF_MESH_POINTS) { @@ -308,7 +311,7 @@ void ofGLProgrammableRenderer::draw(const ofPolyline & poly) const { glVertexAttribPointer(ofShader::POSITION_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(typename ofPolyline::VertexType), &poly[0]); GLenum drawMode = poly.isClosed() ? GL_LINE_LOOP : GL_LINE_STRIP; - const_cast(this)->setAttributes(true, false, false, false); + const_cast(this)->setAttributes(true, false, false, false, drawMode); glDrawArrays(drawMode, 0, poly.size()); #else @@ -994,15 +997,13 @@ void ofGLProgrammableRenderer::setFillMode(ofFillFlag fill) { if (currentStyle.bFill) { path.setFilled(true); path.setStrokeWidth(0); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - // GLES 3.0+ (and desktop) support glPolygonMode +#ifndef TARGET_OPENGLES glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif } else { path.setFilled(false); path.setStrokeWidth(currentStyle.lineWidth); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - // GLES 3.0+ (and desktop) support glPolygonMode +#ifndef TARGET_OPENGLES glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); #endif } diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index eff3ec0e6f6..adcf674fd26 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -222,19 +222,20 @@ int ofGetGLFormatFromInternal(int glInternalFormat){ return GL_STENCIL_INDEX; // modern red / RG formats (used for float + half-float textures) - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_R8: - case GL_R16F: - case GL_R32F: - case GL_RG8: - case GL_RG16F: - case GL_RG32F: - #endif - #ifndef TARGET_OPENGLES - case GL_R16: - case GL_RG16: - #endif - return (glInternalFormat == GL_R8 || glInternalFormat == GL_R16F || glInternalFormat == GL_R32F || glInternalFormat == GL_R16) ? GL_RED : GL_RG; + #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + case GL_R8: + case GL_R16F: + case GL_R32F: + case GL_RG8: + case GL_RG16F: + case GL_RG32F: + #endif + #ifndef TARGET_OPENGLES + case GL_R16: + case GL_RG16: + #endif + // only use constants that exist on GLES + return (glInternalFormat == GL_R8 || glInternalFormat == GL_R16F || glInternalFormat == GL_R32F) ? GL_RED : GL_RG; #ifndef TARGET_OPENGLES case GL_ALPHA8: @@ -452,7 +453,7 @@ ofImageType ofGetImageTypeFromGLType(int glType){ } GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) switch(mode){ case OF_MESH_POINTS: return GL_POINT; @@ -471,7 +472,7 @@ GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ } ofPolyRenderMode ofGetOFPolyMode(GLuint mode){ -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) switch(mode){ case GL_POINT: return OF_MESH_POINTS; From af4c34e510310d5bbf2595287de6272e277af7e4 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 12:26:18 +1000 Subject: [PATCH 24/38] OpenGLES 3 --- .../gl/ofGLProgrammableRenderer.cpp | 21 +++--- libs/openFrameworks/gl/ofGLRenderer.cpp | 15 ++-- libs/openFrameworks/gl/ofGLRenderer.h | 2 +- libs/openFrameworks/gl/ofGLUtils.cpp | 2 +- libs/openFrameworks/gl/ofGLUtils.h | 70 +++++++++++++++++-- 5 files changed, 87 insertions(+), 23 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index c148c651a1d..85affc171f8 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -1137,7 +1137,7 @@ void ofGLProgrammableRenderer::setBlendMode(ofBlendMode blendMode) { //---------------------------------------------------------- void ofGLProgrammableRenderer::enablePointSprites() { pointSpritesEnabled = true; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) glEnable(GL_PROGRAM_POINT_SIZE); #else glEnable(GL_POINT_SPRITE_OES); @@ -1147,7 +1147,7 @@ void ofGLProgrammableRenderer::enablePointSprites() { //---------------------------------------------------------- void ofGLProgrammableRenderer::disablePointSprites() { pointSpritesEnabled = false; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) glDisable(GL_PROGRAM_POINT_SIZE); #else glDisable(GL_POINT_SPRITE_OES); @@ -1527,17 +1527,18 @@ void ofGLProgrammableRenderer::bindForBlitting(const ofFbo & fboSrc, ofFbo & fbo << "Most probably you forgot to end() the current framebuffer before calling getTexture()."; return; } - // this method could just as well have been placed in ofBaseGLRenderer - // and shared over both programmable and fixed function renderer. - // I'm keeping it here, so that if we want to do more fancyful - // named framebuffers with GL 4.5+, we can have - // different implementations. + framebufferIdStack.push_back(currentFramebufferId); currentFramebufferId = fboSrc.getId(); + glBindFramebuffer(GL_READ_FRAMEBUFFER, currentFramebufferId); - glReadBuffer(GL_COLOR_ATTACHMENT0 + attachmentPoint); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboDst.getIdDrawBuffer()); + +#ifndef TARGET_OPENGLES + // glReadBuffer / glDrawBuffer are desktop-only (deprecated on iOS GLES) + glReadBuffer(GL_COLOR_ATTACHMENT0 + attachmentPoint); glDrawBuffer(GL_COLOR_ATTACHMENT0 + attachmentPoint); +#endif } #endif @@ -2921,9 +2922,9 @@ static string shaderSource(const string & src, int major, int minor) { } #else #if !defined(GL_ES_VERSION_3_0) - ofStringReplace(header, "%extensions%", "#extension GL_OES_standard_derivatives : enable"); + ofStringReplace(shaderSrc, "%extensions%", "#extension GL_OES_standard_derivatives : enable"); #else - ofStringReplace(header, "%extensions%", ""); + ofStringReplace(shaderSrc, "%extensions%", ""); #endif #endif diff --git a/libs/openFrameworks/gl/ofGLRenderer.cpp b/libs/openFrameworks/gl/ofGLRenderer.cpp index e5fa8cf748f..e533a961a9c 100644 --- a/libs/openFrameworks/gl/ofGLRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLRenderer.cpp @@ -507,7 +507,7 @@ void ofGLRenderer::bind(const ofFbo & fbo) { glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferId); } -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) //---------------------------------------------------------- void ofGLRenderer::bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint) { if (currentFramebufferId == fboSrc.getId()) { @@ -515,17 +515,18 @@ void ofGLRenderer::bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int att << "Most probably you forgot to end() the current framebuffer before calling getTexture()."; return; } - // this method could just as well have been placed in ofBaseGLRenderer - // and shared over both programmable and fixed function renderer. - // I'm keeping it here, so that if we want to do more fancyful - // named framebuffers with GL 4.5+, we can have - // different implementations. + framebufferIdStack.push_back(currentFramebufferId); currentFramebufferId = fboSrc.getId(); + glBindFramebuffer(GL_READ_FRAMEBUFFER, currentFramebufferId); - glReadBuffer(GL_COLOR_ATTACHMENT0 + attachmentPoint); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboDst.getIdDrawBuffer()); + +#ifndef TARGET_OPENGLES + // glReadBuffer / glDrawBuffer are desktop-only + glReadBuffer(GL_COLOR_ATTACHMENT0 + attachmentPoint); glDrawBuffer(GL_COLOR_ATTACHMENT0 + attachmentPoint); +#endif } #endif diff --git a/libs/openFrameworks/gl/ofGLRenderer.h b/libs/openFrameworks/gl/ofGLRenderer.h index 9371c516376..ef1666059bc 100644 --- a/libs/openFrameworks/gl/ofGLRenderer.h +++ b/libs/openFrameworks/gl/ofGLRenderer.h @@ -211,7 +211,7 @@ class ofGLRenderer: public ofBaseGLRenderer{ void end(const ofFbo & fbo); void bind(const ofFbo & fbo); -#ifndef TARGET_OPENGLES +#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) void bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint); #endif void unbind(const ofFbo & fbo); diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index adcf674fd26..537e771126b 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -467,7 +467,7 @@ GLuint ofGetGLPolyMode(ofPolyRenderMode mode){ } #else ofLogError("ofGLUtils") << "ofGetGLPolyMode(): poly modes not supported in OpenGL ES < 3.0"; - return GL_FILL; + return 0; #endif } diff --git a/libs/openFrameworks/gl/ofGLUtils.h b/libs/openFrameworks/gl/ofGLUtils.h index 9f6b1b6c4a3..b0cf93ec178 100644 --- a/libs/openFrameworks/gl/ofGLUtils.h +++ b/libs/openFrameworks/gl/ofGLUtils.h @@ -192,13 +192,75 @@ void ofDisableGLDebugLog(); #ifndef GL_HALF_FLOAT #define GL_HALF_FLOAT GL_HALF_FLOAT_OES #endif - #ifndef GL_TEXTURE_CUBE_MAP - #ifdef GL_TEXTURE_CUBE_MAP_OES - #define GL_TEXTURE_CUBE_MAP GL_TEXTURE_CUBE_MAP_OES + #ifndef GL_TEXTURE_CUBE_MAP + #ifdef GL_TEXTURE_CUBE_MAP_OES + #define GL_TEXTURE_CUBE_MAP GL_TEXTURE_CUBE_MAP_OES + #endif #endif - #endif #endif + + #if defined(GL_ES_VERSION_3_0) + // === GLES 3.0 / 3.1 additional fallbacks === + // High-precision depth (very useful for shadows / FBOs) + #ifndef GL_DEPTH_COMPONENT32F + #ifdef GL_DEPTH_COMPONENT32F_EXT + #define GL_DEPTH_COMPONENT32F GL_DEPTH_COMPONENT32F_EXT + #endif + #endif + + // Half-float textures (16F) — core in GLES 3.0 but often exposed via EXT + #ifndef GL_R16F + #ifdef GL_R16F_EXT + #define GL_R16F GL_R16F_EXT + #endif + #endif + #ifndef GL_RG16F + #ifdef GL_RG16F_EXT + #define GL_RG16F GL_RG16F_EXT + #endif + #endif + #ifndef GL_RGB16F + #ifdef GL_RGB16F_EXT + #define GL_RGB16F GL_RGB16F_EXT + #endif + #endif + #ifndef GL_RGBA16F + #ifdef GL_RGBA16F_EXT + #define GL_RGBA16F GL_RGBA16F_EXT + #endif + #endif + + // 32-bit float textures (also core in GLES 3.0) + #ifndef GL_R32F + #ifdef GL_R32F_EXT + #define GL_R32F GL_R32F_EXT + #endif + #endif + #ifndef GL_RG32F + #ifdef GL_RG32F_EXT + #define GL_RG32F GL_RG32F_EXT + #endif + #endif + #ifndef GL_RGB32F + #ifdef GL_RGB32F_EXT + #define GL_RGB32F GL_RGB32F_EXT + #endif + #endif + #ifndef GL_RGBA32F + #ifdef GL_RGBA32F_EXT + #define GL_RGBA32F GL_RGBA32F_EXT + #endif + #endif + + // Renderbuffer storage for multisampled FBOs (GLES 3.0+) + #ifndef glRenderbufferStorageMultisample + #ifdef glRenderbufferStorageMultisampleEXT + #define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT + #endif + #endif + #endif + #ifndef glTexStorage2D #ifdef glTexStorage2DEXT #define glTexStorage2D glTexStorage2DEXT From 2d65880a4d5490cbb024e8ebe6a7f0679ad54fa7 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 14:26:55 +1000 Subject: [PATCH 25/38] OpenGLES fixes --- addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 27 +++++++++----------- libs/openFrameworks/gl/ofFbo.h | 2 +- libs/openFrameworks/gl/ofVbo.cpp | 9 ++++--- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index e2a8f921cd9..b817f5d4c81 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -125,18 +125,16 @@ ofAppAndroidWindow::ofAppAndroidWindow() { msaaSamples = 1; glesVersion = 2; #ifdef TARGET_PROGRAMMABLE_GL - :currentRenderer(new ofGLProgrammableRenderer(this)) { #ifdef GL_ES_VERSION_3_0 - sGLESVersionMajor = 3; + glesVersion = 3; #ifdef GL_ES_VERSION_3_1 - sGLESVersionMinor = 1; + glesVersionMinor = 1; #endif #else - sGLESVersionMajor = 2; + glesVersion = 2; #endif #else - :currentRenderer(new ofGLRenderer(this)) { - sGLESVersionMajor = 1; + glesVersion = 1; #endif window = this; ofGetMainLoop()->setCurrentWindow(this); @@ -187,15 +185,15 @@ bool ofAppAndroidWindow::isSurfaceDestroyed() { void ofAppAndroidWindow::setup(const ofGLESWindowSettings & settings) { - sGLESVersionMajor = settings.glesVersionMajor(); - sGLESVersionMinor = settings.glesVersionMinor(); + glesVersion = settings.glesVersionMajor(); + glesVersionMinor = settings.glesVersionMinor(); setup( (const ofxAndroidWindowSettings &)settings ); } void ofAppAndroidWindow::setup(const ofxAndroidWindowSettings & settings){ - sGLESVersionMajor = settings.glesVersionMajor(); - sGLESVersionMinor = settings.glesVersionMinor(); + glesVersion = settings.glesVersionMajor(); + glesVersionMinor = settings.glesVersionMinor(); if(window == nullptr) { ofLogError("ofAppAndroidWindow") << "Setup and Window is nullptr ! Fixing"; setCurrentWindow(); @@ -344,7 +342,6 @@ int ofAppAndroidWindow::getGlesVersion() return glesVersion; } - extern "C"{ JNIEXPORT jint JNICALL @@ -491,11 +488,11 @@ Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ JNIEXPORT jboolean JNICALL Java_cc_openframeworks_OFAndroid_isWindowReady( JNIEnv* env, jclass thiz) { - if(window != nullptr && window->renderer() != nullptr) { - return true; - } else { + if(window != nullptr && window->renderer() != nullptr) { + return true; + } else { return false; - } + } } JNIEXPORT void JNICALL diff --git a/libs/openFrameworks/gl/ofFbo.h b/libs/openFrameworks/gl/ofFbo.h index d587f9cfd2d..911487cb7bd 100644 --- a/libs/openFrameworks/gl/ofFbo.h +++ b/libs/openFrameworks/gl/ofFbo.h @@ -267,7 +267,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { int defaultTextureIndex; //used for getTextureReference bool bIsAllocated; void reloadFbo(); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) static bool bglFunctionsInitialized; #endif diff --git a/libs/openFrameworks/gl/ofVbo.cpp b/libs/openFrameworks/gl/ofVbo.cpp index 1afdc7740c4..2f0b21d2ccb 100644 --- a/libs/openFrameworks/gl/ofVbo.cpp +++ b/libs/openFrameworks/gl/ofVbo.cpp @@ -843,7 +843,7 @@ void ofVbo::bind() const { // VAO handling if (programmable && (vaoSupported || !vaoChecked)) { if (vaoID == 0) { -#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) // Pure GLES 2.0 — try to load VAO extension via dlsym if (glGenVertexArrays == 0 && !vaoChecked) { glGenVertexArrays = (glGenVertexArraysType)dlsym(RTLD_DEFAULT, "glGenVertexArrays"); @@ -862,16 +862,19 @@ void ofVbo::bind() const { vaoSupported = true; #endif - if (vaoSupported) { + if (vaoSupported && glGenVertexArrays != nullptr) { glGenVertexArrays(1, &const_cast(this)->vaoID); + } else if (vaoSupported && glGenVertexArrays == nullptr) { + vaoSupported = false; } + if (vaoID != 0) { retainVAO(vaoID); vaoChanged = true; } } - if (vaoSupported) { + if (vaoSupported && glBindVertexArray != nullptr) { glBindVertexArray(vaoID); } } else { From ef91f76beeb061a8d436f2acdc4a7495eb4fd3aa Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 14:30:08 +1000 Subject: [PATCH 26/38] OpenGLES shader defaults fixed --- .../gl/ofGLProgrammableRenderer.cpp | 63 ++++++------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index 85affc171f8..d7f8bf435c3 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -2126,52 +2126,23 @@ void ofGLProgrammableRenderer::drawString(const ofTrueTypeFont & font, string te // tig: GLSL #150 shaders written against spec: // http://www.opengl.org/registry/doc/GLSLangSpec.1.50.09.pdf + #ifdef TARGET_OPENGLES - #if defined(GL_ES_VERSION_3_0) - static const string vertex_shader_header = - "#version %glsl_version% es\n" - "precision highp float;\n" - "#define IN in\n" - "#define OUT out\n" - "#define TEXTURE texture\n" - "#define TARGET_OPENGLES\n"; - - static const string fragment_shader_header = - "#version %glsl_version% es\n" - "precision highp float;\n" - "#define IN in\n" - "#define OUT out\n" - "#define TEXTURE texture\n" - "#define FRAG_COLOR outputColor\n" - "#define TARGET_OPENGLES\n" - "out vec4 outputColor;\n"; - #else - // OpenGL ES 2.0 / GLSL ES 1.00 - static const string vertex_shader_header = - "#version %glsl_version%\n" - "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" - "precision highp float;\n" - "#else\n" - "precision mediump float;\n" - "#endif\n" - "#define IN attribute\n" - "#define OUT varying\n" - "#define TEXTURE texture2D\n" - "#define TARGET_OPENGLES\n"; - - static const string fragment_shader_header = - "#version %glsl_version%\n" - "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" - "precision highp float;\n" - "#else\n" - "precision mediump float;\n" - "#endif\n" - "#define IN varying\n" - "#define OUT\n" - "#define TEXTURE texture2D\n" - "#define FRAG_COLOR gl_FragColor\n" - "#define TARGET_OPENGLES\n"; - #endif +static const string vertex_shader_header = + "%extensions%\n" + "precision highp float;\n" + "#define IN attribute\n" + "#define OUT varying\n" + "#define TEXTURE texture2D\n" + "#define TARGET_OPENGLES\n"; +static const string fragment_shader_header = + "%extensions%\n" + "precision highp float;\n" + "#define IN varying\n" + "#define OUT\n" + "#define TEXTURE texture2D\n" + "#define FRAG_COLOR gl_FragColor\n" + "#define TARGET_OPENGLES\n"; #else static const string vertex_shader_header = "#version %glsl_version%\n" @@ -2189,6 +2160,8 @@ static const string fragment_shader_header = "out vec4 fragColor;\n"; #endif + + static const string defaultVertexShader = vertex_shader_header + STRINGIFY( uniform mat4 projectionMatrix; uniform mat4 modelViewMatrix; From bd1d23480264ad1fa7ae90c2ff15392e496a53e2 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 14:47:20 +1000 Subject: [PATCH 27/38] ofMaterial fixes --- libs/openFrameworks/gl/ofMaterial.cpp | 35 ++------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/libs/openFrameworks/gl/ofMaterial.cpp b/libs/openFrameworks/gl/ofMaterial.cpp index e2b93ff489f..363c71e12c3 100644 --- a/libs/openFrameworks/gl/ofMaterial.cpp +++ b/libs/openFrameworks/gl/ofMaterial.cpp @@ -897,43 +897,12 @@ void ofMaterial::initShaders(ofGLProgrammableRenderer & renderer) const{ extraVertString += customUniforms; #ifndef TARGET_OPENGLES - string vertexRectHeader = renderer.defaultVertexShaderHeader(GL_TEXTURE_RECTANGLE); - string fragmentRectHeader = renderer.defaultFragmentShaderHeader(GL_TEXTURE_RECTANGLE); + string vertexRectHeader = renderer.defaultVertexShaderHeader(GL_TEXTURE_RECTANGLE); + string fragmentRectHeader = renderer.defaultFragmentShaderHeader(GL_TEXTURE_RECTANGLE); #endif string vertex2DHeader = renderer.defaultVertexShaderHeader(GL_TEXTURE_2D); string fragment2DHeader = renderer.defaultFragmentShaderHeader(GL_TEXTURE_2D); -#if defined(TARGET_OPENGLES) && defined(TARGET_EMSCRIPTEN) - // TODO: Should this be in programmable renderer? - if(ofIsGLProgrammableRenderer()) { - vertex2DHeader = "#version "+ofGLSLVersionFromGL(renderer.getGLVersionMajor(), renderer.getGLVersionMinor())+"\n"; - vertex2DHeader += "precision highp float;\n"; - vertex2DHeader += "precision highp int;\n"; - vertex2DHeader += "#define TARGET_OPENGLES\n"; - vertex2DHeader += "#define IN in\n"; - vertex2DHeader += "#define OUT out\n"; - vertex2DHeader += "#define TEXTURE texture\n"; - vertex2DHeader += "#define SAMPLER sampler2D\n"; - - fragment2DHeader = "#version "+ofGLSLVersionFromGL(renderer.getGLVersionMajor(), renderer.getGLVersionMinor())+"\n"; - fragment2DHeader += "precision highp float;\n"; - fragment2DHeader += "precision highp int;\n"; - fragment2DHeader += "#define TARGET_OPENGLES\n"; - fragment2DHeader += "#define IN in\n"; - fragment2DHeader += "#define OUT out\n"; - fragment2DHeader += "#define TEXTURE texture\n"; - fragment2DHeader += "#define FRAG_COLOR fragColor\n"; - fragment2DHeader += "out vec4 fragColor;\n"; - fragment2DHeader += "#define SAMPLER sampler2D\n"; - fragment2DHeader += "precision highp sampler2D;\n"; - fragment2DHeader += "precision highp samplerCube;\n"; - fragment2DHeader += "precision mediump sampler2DShadow;\n"; -#if defined( GL_TEXTURE_2D_ARRAY ) && defined(glTexImage3D) - fragment2DHeader += "precision mediump sampler2DArrayShadow;\n"; -#endif - } -#endif - shaders[&renderer].reset(new Shaders); shaders[&renderer]->numLights = numLights; shaders[&renderer]->numCubeMaps = numCubeMaps; From 2f5c374534bad19b77fbd506e2cdf428cd288fc8 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 14:51:57 +1000 Subject: [PATCH 28/38] Android Window --- addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index b817f5d4c81..9c280d6c7ff 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -185,15 +185,15 @@ bool ofAppAndroidWindow::isSurfaceDestroyed() { void ofAppAndroidWindow::setup(const ofGLESWindowSettings & settings) { - glesVersion = settings.glesVersionMajor(); - glesVersionMinor = settings.glesVersionMinor(); + glesVersion = settings.getGLESVersionMajor(); + glesVersionMinor = settings.getGLESVersionMinor(); setup( (const ofxAndroidWindowSettings &)settings ); } void ofAppAndroidWindow::setup(const ofxAndroidWindowSettings & settings){ - glesVersion = settings.glesVersionMajor(); - glesVersionMinor = settings.glesVersionMinor(); + glesVersion = settings.getGLESVersionMajor(); + glesVersionMinor = settings.getGLESVersionMinor(); if(window == nullptr) { ofLogError("ofAppAndroidWindow") << "Setup and Window is nullptr ! Fixing"; setCurrentWindow(); From 5130bd0f7dc32fc6bc74305642b79ec4d5dfada1 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 16:50:04 +1000 Subject: [PATCH 29/38] ofAppAndroidWindow Fix --- addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 7 +++++-- addons/ofxAndroid/src/ofAppAndroidWindow.h | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index 9c280d6c7ff..5b0cfb36503 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -54,8 +54,6 @@ static bool accumulateAxisEvents = false; static bool multiWindowMode = false; AAssetManager* assetManager; -static int sGLESVersionMajor = 2; -static int sGLESVersionMinor = 0; void ofExitCallback(); @@ -342,6 +340,11 @@ int ofAppAndroidWindow::getGlesVersion() return glesVersion; } +int ofAppAndroidWindow::getGlesVersionMinor() +{ + return glesVersionMinor; +} + extern "C"{ JNIEXPORT jint JNICALL diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.h b/addons/ofxAndroid/src/ofAppAndroidWindow.h index cae62bac8c0..d31554a98f2 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.h +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.h @@ -110,16 +110,20 @@ class ofAppAndroidWindow: public ofAppBaseGLESWindow { int getGlesVersion(); + int getGlesVersionMinor(); AAssetManager& getAssetManager(); void setAssetManager(AAssetManager* assetManager); + int glesVersion; + int glesVersionMinor; + private: ofCoreEvents coreEvents; std::shared_ptr currentRenderer; - int glesVersion; + int msaaSamples; AAssetManager* assetManager = nullptr; From 9dca43fffb9e19c44b03fd2ebac08728e86dd996 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 17:02:37 +1000 Subject: [PATCH 30/38] ofAppAndroidWindow --- addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index 5b0cfb36503..50ca5fd14e9 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -482,7 +482,7 @@ Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ dynamic_cast(window->renderer().get())->setup(); }else{ ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 2.0+"; - dynamic_cast(window->renderer().get())->setup(glesVersion, sGLESVersionMinor); + dynamic_cast(window->renderer().get())->setup(glesVersion, glesVersionMinor); } surfaceDestroyed = false; From 3a6b3cd7438738d9ad9a2ad2d4490aa07b28655b Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 17:39:50 +1000 Subject: [PATCH 31/38] Android Window --- addons/ofxAndroid/src/ofAppAndroidWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp index 50ca5fd14e9..eef5eb79b69 100644 --- a/addons/ofxAndroid/src/ofAppAndroidWindow.cpp +++ b/addons/ofxAndroid/src/ofAppAndroidWindow.cpp @@ -476,6 +476,7 @@ Java_cc_openframeworks_OFAndroid_onSurfaceCreated( JNIEnv* env, jclass thiz ){ bSetupScreen = true; int glesVersion = window->getGlesVersion(); + int glesVersionMinor = window->getGlesVersionMinor(); if(glesVersion < 2){ ofLogVerbose("ofAppAndroidWindow") << "onSurfaceCreated OpenGLES 1"; From e85136e17ebaaa596aa3701251fb7af5d854f860 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Wed, 8 Apr 2026 18:55:49 +1000 Subject: [PATCH 32/38] ofGLUtils Android Fix --- libs/openFrameworks/gl/ofGLUtils.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index 537e771126b..a6d6ea22c99 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -233,9 +233,13 @@ int ofGetGLFormatFromInternal(int glInternalFormat){ #ifndef TARGET_OPENGLES case GL_R16: case GL_RG16: - #endif - // only use constants that exist on GLES return (glInternalFormat == GL_R8 || glInternalFormat == GL_R16F || glInternalFormat == GL_R32F) ? GL_RED : GL_RG; + #endif + + #if !defined(TARGET_OPENGLES) && defined(GL_RGB565) + case GL_RGB565: + return GL_UNSIGNED_SHORT_5_6_5; + #endif #ifndef TARGET_OPENGLES case GL_ALPHA8: From 2eeedd82dabf2dd6c87689028fba065000d2efa9 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Thu, 9 Apr 2026 00:46:30 +1000 Subject: [PATCH 33/38] OpenGLES 3.0 --- .../gl/ofGLProgrammableRenderer.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index d7f8bf435c3..89e0c3cdf10 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -158,8 +158,14 @@ void ofGLProgrammableRenderer::draw(const ofMesh & vertexData, ofPolyRenderMode const_cast(this)->setAttributes(true, useColors, useTextures, useNormals, drawMode); + #if defined(TARGET_EMSCRIPTEN) || defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) + GLenum indexType = GL_UNSIGNED_INT; + #else + GLenum indexType = GL_UNSIGNED_SHORT; + #endif + if (vertexData.getNumIndices()) { - glDrawElements(drawMode, vertexData.getNumIndices(), GL_UNSIGNED_SHORT, vertexData.getIndexPointer()); + glDrawElements(drawMode, vertexData.getNumIndices(), indexType, vertexData.getIndexPointer()); } else { glDrawArrays(drawMode, 0, vertexData.getNumVertices()); } @@ -238,7 +244,7 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVboMesh & mesh, ofPolyRende } } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) #ifndef TARGET_OPENGLES glPolygonMode(GL_FRONT_AND_BACK, ofGetGLPolyMode(renderType)); @@ -461,11 +467,11 @@ void ofGLProgrammableRenderer::drawElements(const ofVbo & vbo, GLuint drawMode, vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); -#ifdef TARGET_OPENGLES - glDrawElements(drawMode, amt, GL_UNSIGNED_SHORT, (void *)(sizeof(ofIndexType) * offsetelements)); -#else - glDrawElements(drawMode, amt, GL_UNSIGNED_INT, (void *)(sizeof(ofIndexType) * offsetelements)); -#endif + #if defined(TARGET_EMSCRIPTEN) || defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0 == 1 + glDrawElements(drawMode, amt, GL_UNSIGNED_INT, (void *)(sizeof(ofIndexType) * offsetelements)); + #else + glDrawElements(drawMode, amt, GL_UNSIGNED_SHORT, (void *)(sizeof(ofIndexType) * offsetelements)); + #endif vbo.unbind(); } } @@ -494,10 +500,11 @@ void ofGLProgrammableRenderer::drawElementsInstanced(const ofVbo & vbo, GLuint d // https://www.khronos.org/opengles/sdk/docs/man3/xhtml/glDrawElementsInstanced.xml ofLogWarning("ofVbo") << "drawElementsInstanced(): hardware instancing is not supported on OpenGL ES < 3.0"; #else - #if defined(TARGET_OPENGLES) - glDrawElementsInstanced(drawMode, amt, GL_UNSIGNED_SHORT, nullptr, primCount); + + #if defined(TARGET_EMSCRIPTEN) || defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0 == 1 + glDrawElements(drawMode, amt, GL_UNSIGNED_INT, nullptr, primCount); #else - glDrawElementsInstanced(drawMode, amt, GL_UNSIGNED_INT, nullptr, primCount); + glDrawElements(drawMode, amt, GL_UNSIGNED_SHORT, nullptr, primCount); #endif #endif vbo.unbind(); From d41735f06a57c075693c50ba2b04203962ec7caf Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Thu, 9 Apr 2026 14:24:47 +1000 Subject: [PATCH 34/38] ofWindowSettings with hidpi c++ default cpy ctor --- libs/openFrameworks/app/ofWindowSettings.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/libs/openFrameworks/app/ofWindowSettings.h b/libs/openFrameworks/app/ofWindowSettings.h index 39d8fe46687..dd14368e026 100644 --- a/libs/openFrameworks/app/ofWindowSettings.h +++ b/libs/openFrameworks/app/ofWindowSettings.h @@ -49,7 +49,10 @@ class ofWindowSettings{ ,height(768) ,sizeSet(false) ,position(0,0) - ,positionSet(false){} + ,positionSet(false) + ,hiDPI(false) {} + + ofWindowSettings(const ofWindowSettings& other) = default; virtual ~ofWindowSettings(){}; @@ -87,12 +90,21 @@ class ofWindowSettings{ return positionSet; } + bool isHiDPI() const { + return hiDPI; + } + + void setHiDPI(const bool isHighDPI=true) { + hiDPI=isHighDPI; + } + protected: int width; int height; bool sizeSet; glm::vec2 position; bool positionSet; + bool hiDPI; }; class ofGLWindowSettings: public ofWindowSettings{ @@ -101,6 +113,8 @@ class ofGLWindowSettings: public ofWindowSettings{ :glVersionMajor(2) ,glVersionMinor(1){} + ofGLWindowSettings(const ofGLWindowSettings& other) = default; + ofGLWindowSettings(const ofWindowSettings & settings) :ofWindowSettings(settings) ,glVersionMajor(2) @@ -127,6 +141,8 @@ class ofGLESWindowSettings: public ofWindowSettings{ public: ofGLESWindowSettings() :glesVersion(1), glesVersionMinor(0){} + + ofGLESWindowSettings(const ofGLESWindowSettings& other) = default; ofGLESWindowSettings(const ofWindowSettings & settings) :ofWindowSettings(settings), glesVersion(1), glesVersionMinor(0) { From be8fc37edc794f89f4d64fe9c85f611f9c9eb19e Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Thu, 9 Apr 2026 14:26:07 +1000 Subject: [PATCH 35/38] OpenGLES defines with targetable undefs in ofConstants --- libs/openFrameworks/gl/ofBufferObject.cpp | 4 +- libs/openFrameworks/gl/ofBufferObject.h | 4 +- libs/openFrameworks/gl/ofFbo.cpp | 42 ++++----- libs/openFrameworks/gl/ofFbo.h | 6 +- libs/openFrameworks/gl/ofGLBaseTypes.h | 2 +- .../gl/ofGLProgrammableRenderer.cpp | 31 +++--- .../gl/ofGLProgrammableRenderer.h | 2 +- libs/openFrameworks/gl/ofGLRenderer.cpp | 2 +- libs/openFrameworks/gl/ofGLRenderer.h | 2 +- libs/openFrameworks/gl/ofGLUtils.cpp | 94 +++++++++---------- libs/openFrameworks/gl/ofGLUtils.h | 2 +- libs/openFrameworks/gl/ofMaterial.cpp | 6 +- libs/openFrameworks/gl/ofShader.cpp | 10 +- libs/openFrameworks/gl/ofShader.h | 12 +-- libs/openFrameworks/gl/ofShadow.cpp | 4 +- libs/openFrameworks/gl/ofTexture.cpp | 4 +- libs/openFrameworks/gl/ofTexture.h | 2 +- libs/openFrameworks/utils/ofConstants.h | 22 +++++ 18 files changed, 133 insertions(+), 118 deletions(-) diff --git a/libs/openFrameworks/gl/ofBufferObject.cpp b/libs/openFrameworks/gl/ofBufferObject.cpp index cd8dc15f646..3517efecca1 100644 --- a/libs/openFrameworks/gl/ofBufferObject.cpp +++ b/libs/openFrameworks/gl/ofBufferObject.cpp @@ -81,7 +81,7 @@ void ofBufferObject::unbind(GLenum target) const{ } } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) void ofBufferObject::bindBase(GLenum target,GLuint index) const{ if(data){ glBindBufferBase(target,index,data->id); @@ -189,7 +189,7 @@ void * ofBufferObject::map(GLenum access){ } #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) void ofBufferObject::unmap(){ if(!this->data) return; diff --git a/libs/openFrameworks/gl/ofBufferObject.h b/libs/openFrameworks/gl/ofBufferObject.h index 65a237ff086..1210b729492 100644 --- a/libs/openFrameworks/gl/ofBufferObject.h +++ b/libs/openFrameworks/gl/ofBufferObject.h @@ -42,7 +42,7 @@ class ofBufferObject { void unbind(GLenum target) const; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) /// glBindBufferBase: https://www.opengl.org/sdk/docs/man4/html/glBindBufferBase.xhtml void bindBase(GLenum target,GLuint index) const; @@ -112,7 +112,7 @@ class ofBufferObject { #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) /// glUnmapNamedBuffer: https://www.opengl.org/sdk/docs/man4/html/glUnmapBuffer.xhtml /// before GL 4.5 emulates glUnmapNamedBuffer by unmapping and unbinding /// the last known target for this buffer diff --git a/libs/openFrameworks/gl/ofFbo.cpp b/libs/openFrameworks/gl/ofFbo.cpp index 758f2a7077f..2d2b7715dcc 100644 --- a/libs/openFrameworks/gl/ofFbo.cpp +++ b/libs/openFrameworks/gl/ofFbo.cpp @@ -34,7 +34,7 @@ using std::vector; */ -#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) || !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) bool ofFbo::bglFunctionsInitialized=false; typedef void (* glGenFramebuffersType) (GLsizei n, GLuint* framebuffers); @@ -246,7 +246,7 @@ dirty(false), defaultTextureIndex(0), bIsAllocated(false) { -#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) if(!bglFunctionsInitialized){ if(ofIsGLProgrammableRenderer()){ glGenFramebuffers = (glGenFramebuffersType)dlsym(RTLD_DEFAULT, "glGenFramebuffers"); @@ -462,7 +462,7 @@ void ofFbo::clear() { } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) //-------------------------------------------------------------- void ofFbo::clearColorBuffer(const ofFloatColor & color){ glClearBufferfv(GL_COLOR, 0, &color.r); @@ -496,7 +496,7 @@ void ofFbo::destroy() { //-------------------------------------------------------------- bool ofFbo::checkGLSupport() { -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // Desktop + GLES 3.0+ (FBO is core spec — no extension check needed on ES3) if (!ofIsGLProgrammableRenderer()){ if(ofGLCheckExtension("GL_EXT_framebuffer_object")){ @@ -541,7 +541,7 @@ void ofFbo::allocate(int width, int height, int internalformat, int numSamples) settings.textureTarget = ofGetUsingArbTex() ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D; #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // GLES 3.0+ (and desktop) can safely default to depth + stencil settings.useDepth = true; settings.useStencil = true; @@ -582,7 +582,7 @@ void ofFbo::allocate(ofFboSettings _settings) { //currently depth only works if stencil is enabled. // http://forum.openframeworks.cc/index.php/topic,6837.0.html -#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) if(_settings.useDepth){ _settings.useStencil = true; } @@ -647,7 +647,7 @@ void ofFbo::allocate(ofFboSettings _settings) { }else{ if(_settings.useDepth || _settings.useStencil){ createAndAttachDepthStencilTexture(_settings.textureTarget,_settings.depthStencilInternalFormat,depthAttachment); - #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + #if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // GLES 2.0 only: OES_packed_depth_stencil extension requires separate stencil attachment // http://www.khronos.org/registry/gles/extensions/OES/OES_packed_depth_stencil.txt if(_settings.useDepth && _settings.useStencil){ @@ -671,7 +671,7 @@ void ofFbo::allocate(ofFboSettings _settings) { // if we want MSAA, create a new fbo for textures // (supported on desktop + GLES 3.0+; pure GLES 2.0 does not support multisampled FBOs reliably) - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) if(_settings.numSamples){ glGenFramebuffers(1, &fboTextures); retainFB(fboTextures); @@ -692,11 +692,11 @@ void ofFbo::allocate(ofFboSettings _settings) { for(int i=0; i<_settings.numColorbuffers; i++) createAndAttachTexture(_settings.internalformat, i); _settings.colorFormats = settings.colorFormats; } else { -#ifndef TARGET_OPENGLES + #ifndef TARGET_OPENGLES glDrawBuffer(GL_NONE); -#else + #else ofLogWarning("ofFbo") << "allocate(): no color buffers specified for frame buffer object " << fbo; -#endif + #endif } settings.internalformat = _settings.internalformat; @@ -742,7 +742,7 @@ GLuint ofFbo::createAndAttachRenderbuffer(GLenum internalFormat, GLenum attachme glGenRenderbuffers(1, &buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // Desktop + GLES 3.0+ support full multisampled renderbuffers if (settings.numSamples == 0) { glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, settings.width, settings.height); @@ -950,7 +950,7 @@ int ofFbo::getNumTextures() const { //---------------------------------------------------------- void ofFbo::setActiveDrawBuffer(int i){ if(!bIsAllocated) return; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) vector activebuffers(1, i); setActiveDrawBuffers(activebuffers); #endif @@ -960,7 +960,7 @@ void ofFbo::setActiveDrawBuffer(int i){ void ofFbo::setActiveDrawBuffers(const vector& ids){ if(!bIsAllocated) return; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) int numBuffers = activeDrawBuffers.size(); activeDrawBuffers.clear(); activeDrawBuffers.resize(numBuffers, GL_NONE); // we initialise the vector with GL_NONE, so a buffer will not be written to unless activated. @@ -983,7 +983,7 @@ void ofFbo::setActiveDrawBuffers(const vector& ids){ //---------------------------------------------------------- void ofFbo::activateAllDrawBuffers(){ if(!bIsAllocated) return; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) vector activeBuffers(getNumTextures(), 0); for(int i = 0; i < getNumTextures(); i++){ activeBuffers[i] = i; @@ -1067,7 +1067,7 @@ void ofFbo::resetAnchor(){ //---------------------------------------------------------- void ofFbo::readToPixels(ofPixels & pixels, int attachmentPoint) const{ if(!bIsAllocated) return; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // Desktop + GLES 3.0+ getTexture(attachmentPoint).readToPixels(pixels); #else @@ -1083,7 +1083,7 @@ void ofFbo::readToPixels(ofPixels & pixels, int attachmentPoint) const{ //---------------------------------------------------------- void ofFbo::readToPixels(ofShortPixels & pixels, int attachmentPoint) const{ if(!bIsAllocated) return; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) getTexture(attachmentPoint).readToPixels(pixels); #else pixels.allocate(settings.width, settings.height, ofGetImageTypeFromGLType(settings.internalformat)); @@ -1097,7 +1097,7 @@ void ofFbo::readToPixels(ofShortPixels & pixels, int attachmentPoint) const{ //---------------------------------------------------------- void ofFbo::readToPixels(ofFloatPixels & pixels, int attachmentPoint) const{ if(!bIsAllocated) return; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) getTexture(attachmentPoint).readToPixels(pixels); #else pixels.allocate(settings.width,settings.height,ofGetImageTypeFromGLType(settings.internalformat)); @@ -1108,7 +1108,7 @@ void ofFbo::readToPixels(ofFloatPixels & pixels, int attachmentPoint) const{ #endif } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) //---------------------------------------------------------- void ofFbo::copyTo(ofBufferObject & buffer) const{ if(!bIsAllocated) return; @@ -1124,7 +1124,7 @@ void ofFbo::copyTo(ofBufferObject & buffer) const{ void ofFbo::updateTexture(int attachmentPoint) { if(!bIsAllocated) return; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) if(fbo != fboTextures && dirty[attachmentPoint]) { // if fbo != fboTextures, we are dealing with an MSAA enabled FBO. @@ -1237,7 +1237,7 @@ bool ofFbo::checkStatus() const { ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break; #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: ofLogError("ofFbo") << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; break; diff --git a/libs/openFrameworks/gl/ofFbo.h b/libs/openFrameworks/gl/ofFbo.h index 911487cb7bd..9cbea2a8e41 100644 --- a/libs/openFrameworks/gl/ofFbo.h +++ b/libs/openFrameworks/gl/ofFbo.h @@ -65,7 +65,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { void destroy(); void clear(); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) /// glClearBufferfv(GL_COLOR, 0...) /// /// @see: https://www.opengl.org/wiki/GLAPI/glClearBuffer @@ -166,7 +166,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { void readToPixels(ofShortPixels & pixels, int attachmentPoint = 0) const; void readToPixels(ofFloatPixels & pixels, int attachmentPoint = 0) const; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) /// \brief Copy the fbo to an ofBufferObject. /// \param buffer the target buffer to copy to. void copyTo(ofBufferObject & buffer) const; @@ -267,7 +267,7 @@ class ofFbo : public ofBaseDraws, public ofBaseHasTexture { int defaultTextureIndex; //used for getTextureReference bool bIsAllocated; void reloadFbo(); -#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) static bool bglFunctionsInitialized; #endif diff --git a/libs/openFrameworks/gl/ofGLBaseTypes.h b/libs/openFrameworks/gl/ofGLBaseTypes.h index d03f5664efd..8009887e9e7 100644 --- a/libs/openFrameworks/gl/ofGLBaseTypes.h +++ b/libs/openFrameworks/gl/ofGLBaseTypes.h @@ -516,7 +516,7 @@ class ofBaseGLRenderer: public ofBaseRenderer{ /// \param fbo The frame buffer that is currently bound to this renderer. virtual void unbind(const ofFbo & fbo)=0; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) /// \brief Bind source and destination frame buffers for blitting. /// /// \param fboSrc The source frame buffer to bind for blitting. diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index 89e0c3cdf10..6e27f86c4a5 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -467,7 +467,7 @@ void ofGLProgrammableRenderer::drawElements(const ofVbo & vbo, GLuint drawMode, vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); - #if defined(TARGET_EMSCRIPTEN) || defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0 == 1 + #if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) glDrawElements(drawMode, amt, GL_UNSIGNED_INT, (void *)(sizeof(ofIndexType) * offsetelements)); #else glDrawElements(drawMode, amt, GL_UNSIGNED_SHORT, (void *)(sizeof(ofIndexType) * offsetelements)); @@ -481,9 +481,9 @@ void ofGLProgrammableRenderer::drawInstanced(const ofVbo & vbo, GLuint drawMode, if (vbo.getUsingVerts()) { vbo.bind(); const_cast(this)->setAttributes(vbo.getUsingVerts(), vbo.getUsingColors(), vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); -#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_1) && defined(TARGET_OPENGLES_3_1)) // https://www.khronos.org/opengles/sdk/docs/man3/xhtml/glDrawElementsInstanced.xml - ofLogWarning("ofVbo") << "drawInstanced(): hardware instancing is not supported on OpenGL ES < 3.0"; + ofLogWarning("ofVbo") << "drawInstanced(): hardware instancing is not supported on OpenGL ES <= 3.1"; #else glDrawArraysInstanced(drawMode, first, total, primCount); #endif @@ -496,16 +496,11 @@ void ofGLProgrammableRenderer::drawElementsInstanced(const ofVbo & vbo, GLuint d if (vbo.getUsingVerts()) { vbo.bind(); const_cast(this)->setAttributes(vbo.getUsingVerts(), vbo.getUsingColors(), vbo.getUsingTexCoords(), vbo.getUsingNormals(), drawMode); -#if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) // TODO: Check against OPENGL_ES Version +#if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_1) && defined(TARGET_OPENGLES_3_1)) // https://www.khronos.org/opengles/sdk/docs/man3/xhtml/glDrawElementsInstanced.xml - ofLogWarning("ofVbo") << "drawElementsInstanced(): hardware instancing is not supported on OpenGL ES < 3.0"; + ofLogWarning("ofVbo") << "drawElementsInstanced(): hardware instancing is not supported on OpenGL ES <= 3.1"; #else - - #if defined(TARGET_EMSCRIPTEN) || defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0 == 1 - glDrawElements(drawMode, amt, GL_UNSIGNED_INT, nullptr, primCount); - #else - glDrawElements(drawMode, amt, GL_UNSIGNED_SHORT, nullptr, primCount); - #endif + glDrawElementsInstanced(drawMode, amt, indexType, nullptr, primCount); #endif vbo.unbind(); } @@ -1119,7 +1114,7 @@ void ofGLProgrammableRenderer::setBlendMode(ofBlendMode blendMode) { case OF_BLENDMODE_MAX: glEnable(GL_BLEND); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) glBlendEquation(GL_MAX); #else ofLogWarning("ofGLProgrammableRenderer") << "OF_BLENDMODE_MAX not currently supported on OpenGL ES < 3.0"; @@ -1128,7 +1123,7 @@ void ofGLProgrammableRenderer::setBlendMode(ofBlendMode blendMode) { case OF_BLENDMODE_MIN: glEnable(GL_BLEND); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) glBlendEquation(GL_MIN); #else ofLogWarning("ofGLProgrammableRenderer") << "OF_BLENDMODE_MIN not currently supported on OpenGL ES < 3.0"; @@ -1163,14 +1158,14 @@ void ofGLProgrammableRenderer::disablePointSprites() { //---------------------------------------------------------- void ofGLProgrammableRenderer::enableAntiAliasing() { -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) glEnable(GL_MULTISAMPLE); #endif } //---------------------------------------------------------- void ofGLProgrammableRenderer::disableAntiAliasing() { -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) glDisable(GL_MULTISAMPLE); #endif } @@ -1526,7 +1521,7 @@ void ofGLProgrammableRenderer::bind(const ofFbo & fbo) { glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferId); } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) //---------------------------------------------------------- void ofGLProgrammableRenderer::bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint) { if (currentFramebufferId == fboSrc.getId()) { @@ -2875,7 +2870,7 @@ static string defaultShaderHeader(string header, GLenum textureTarget, int major ofStringReplace(header, "%extensions%", ""); } #else - #if !defined(GL_ES_VERSION_3_0) + #if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) ofStringReplace(header, "%extensions%", "#extension GL_OES_standard_derivatives : enable"); #else ofStringReplace(header, "%extensions%", ""); @@ -2901,7 +2896,7 @@ static string shaderSource(const string & src, int major, int minor) { ofStringReplace(shaderSrc, "%extensions%", ""); } #else - #if !defined(GL_ES_VERSION_3_0) + #if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) ofStringReplace(shaderSrc, "%extensions%", "#extension GL_OES_standard_derivatives : enable"); #else ofStringReplace(shaderSrc, "%extensions%", ""); diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.h b/libs/openFrameworks/gl/ofGLProgrammableRenderer.h index efe1131e953..22f00e1e775 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.h +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.h @@ -204,7 +204,7 @@ class ofGLProgrammableRenderer: public ofBaseGLRenderer{ void unbind(const ofCamera & camera); void bind(const ofFbo & fbo); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) void bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint); #endif void unbind(const ofFbo & fbo); diff --git a/libs/openFrameworks/gl/ofGLRenderer.cpp b/libs/openFrameworks/gl/ofGLRenderer.cpp index e533a961a9c..5fb433691e2 100644 --- a/libs/openFrameworks/gl/ofGLRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLRenderer.cpp @@ -507,7 +507,7 @@ void ofGLRenderer::bind(const ofFbo & fbo) { glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferId); } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) //---------------------------------------------------------- void ofGLRenderer::bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint) { if (currentFramebufferId == fboSrc.getId()) { diff --git a/libs/openFrameworks/gl/ofGLRenderer.h b/libs/openFrameworks/gl/ofGLRenderer.h index ef1666059bc..ba3e924f35d 100644 --- a/libs/openFrameworks/gl/ofGLRenderer.h +++ b/libs/openFrameworks/gl/ofGLRenderer.h @@ -211,7 +211,7 @@ class ofGLRenderer: public ofBaseGLRenderer{ void end(const ofFbo & fbo); void bind(const ofFbo & fbo); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) void bindForBlitting(const ofFbo & fboSrc, ofFbo & fboDst, int attachmentPoint); #endif void unbind(const ofFbo & fbo); diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index a6d6ea22c99..df78e483bc4 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -101,7 +101,8 @@ int ofGetGLInternalFormat(const ofFloatPixels& pixels) { ofLogWarning("ofGLUtils") << "ofGetGLInternalFormat(): single channel float textures not supported on Emscripten."; return GL_R16F; } -#elif !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#endif +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // Desktop + native GLES 3.0+ → full 32F support switch(pixels.getNumChannels()) { case 3: return GL_RGB32F; @@ -128,11 +129,11 @@ int ofGetGLInternalFormat(const ofFloatPixels& pixels) { string ofGetGLInternalFormatName(int glInternalFormat) { switch(glInternalFormat) { case GL_RGBA: return "GL_RGBA"; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_RGBA8: return "GL_RGBA8"; #endif case GL_RGB: return "GL_RGB"; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_RGB8: return "GL_RGB8"; #endif case GL_LUMINANCE: return "GL_LUMINANCE"; @@ -156,7 +157,7 @@ string ofGetGLInternalFormatName(int glInternalFormat) { int ofGetGLFormatFromInternal(int glInternalFormat){ switch(glInternalFormat) { case GL_RGBA: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_RGBA8: case GL_RGBA16F: #endif @@ -176,7 +177,7 @@ int ofGetGLFormatFromInternal(int glInternalFormat){ #endif case GL_RGB: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_RGB8: case GL_RGB16F: #endif @@ -206,11 +207,11 @@ int ofGetGLFormatFromInternal(int glInternalFormat){ return GL_DEPTH_STENCIL; case GL_DEPTH_COMPONENT: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: #endif - #if defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_DEPTH_COMPONENT32F: #endif #ifndef TARGET_OPENGLES @@ -222,7 +223,7 @@ int ofGetGLFormatFromInternal(int glInternalFormat){ return GL_STENCIL_INDEX; // modern red / RG formats (used for float + half-float textures) - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_R8: case GL_R16F: case GL_R32F: @@ -261,7 +262,7 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: case GL_ALPHA: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) #ifndef TARGET_OPENGLES case GL_LUMINANCE8: case GL_LUMINANCE8_ALPHA8: @@ -286,7 +287,7 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ #endif // 16-bit half-float formats (GLES 3.0 core + Emscripten) - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_R16F: case GL_RG16F: case GL_RGB16F: @@ -299,7 +300,7 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ #endif // 32-bit full float formats (native ES3 + desktop) - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_R32F: case GL_RG32F: case GL_RGB32F: @@ -319,7 +320,7 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ return GL_UNSIGNED_INT_24_8; case GL_DEPTH_COMPONENT: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_DEPTH_COMPONENT16: case GL_R16UI: case GL_RG16UI: @@ -328,7 +329,7 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ #endif return GL_UNSIGNED_SHORT; - #if defined(TARGET_OPENGLES) && defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_DEPTH_COMPONENT24: return GL_UNSIGNED_INT; case GL_DEPTH_COMPONENT32F: @@ -399,7 +400,7 @@ int ofGetGLType(const ofFloatPixels & pixels) { ofImageType ofGetImageTypeFromGLType(int glType){ switch(glType){ case GL_LUMINANCE: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) #ifndef TARGET_OPENGLES case GL_LUMINANCE8: case GL_LUMINANCE16: @@ -424,7 +425,7 @@ ofImageType ofGetImageTypeFromGLType(int glType){ return OF_IMAGE_GRAYSCALE; case GL_RGB: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_RGB8: #ifndef TARGET_OPENGLES case GL_RGB16: @@ -439,7 +440,7 @@ ofImageType ofGetImageTypeFromGLType(int glType){ return OF_IMAGE_COLOR; case GL_RGBA: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_RGBA8: #ifndef TARGET_OPENGLES case GL_RGBA16: @@ -593,14 +594,14 @@ int ofGetGLInternalFormatFromPixelFormat(ofPixelFormat pixelFormat){ switch(pixelFormat){ case OF_PIXELS_BGRA: case OF_PIXELS_RGBA: -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) return GL_RGBA8; #else return GL_RGBA; #endif case OF_PIXELS_RGB: case OF_PIXELS_BGR: -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) return GL_RGB8; #else return GL_RGB; @@ -708,7 +709,7 @@ int ofGetGLFormatFromPixelFormat(ofPixelFormat pixelFormat){ #endif default: - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) ofLogError("ofGLUtils") << "ofGetGLFormatFromPixelFormat(): unknown OF pixel format " << pixelFormat << ", returning GL_RED"; return ofIsGLProgrammableRenderer() ? GL_RED : GL_LUMINANCE; #else @@ -732,7 +733,7 @@ int ofGetNumChannelsFromGLFormat(int glFormat){ return 1; case GL_LUMINANCE_ALPHA: return 2; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_RED: return 1; case GL_RG: @@ -744,40 +745,37 @@ int ofGetNumChannelsFromGLFormat(int glFormat){ } int ofGetBytesPerChannelFromGLType(int glType){ - switch(glType) { - case GL_UNSIGNED_BYTE: - return 1; - case GL_UNSIGNED_SHORT: - return 2; - -#if !defined(TARGET_OPENGLES) && defined(GL_RGB565) - case GL_UNSIGNED_SHORT_5_6_5: - return 2; + switch(glType) { + case GL_UNSIGNED_BYTE: + return 1; + case GL_UNSIGNED_SHORT: + return 2; + +#if !defined(TARGET_OPENGLES) || defined(GL_RGB565) + case GL_UNSIGNED_SHORT_5_6_5: + return 2; #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) - case GL_FLOAT: - return 4; -#endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_UNSIGNED_INT_24_8: - return 4; +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) + case GL_FLOAT: + return 4; #endif + case GL_UNSIGNED_INT_24_8: + return 4; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) - case GL_UNSIGNED_INT: - return 4; +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) + case GL_UNSIGNED_INT: + return 4; #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) - case GL_HALF_FLOAT: - return 2; -#endif - default: - ofLogError("ofGetBytesPerChannelFromGLType") << "unknown type returning 1"; - return 1; - } + case GL_HALF_FLOAT: + return 2; + + default: + ofLogError("ofGetBytesPerChannelFromGLType") << "unknown type returning 1"; + return 1; + } } void ofSetPixelStoreiAlignment(GLenum pname, int w, int bpc, int numChannels){ @@ -832,7 +830,7 @@ bool ofGLCheckExtension(string searchName){ } bool ofGLSupportsNPOTTextures(){ -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // Desktop + GLES 3.0+ support NPOT textures natively (core feature) return true; #else diff --git a/libs/openFrameworks/gl/ofGLUtils.h b/libs/openFrameworks/gl/ofGLUtils.h index b0cf93ec178..b6a39e4e890 100644 --- a/libs/openFrameworks/gl/ofGLUtils.h +++ b/libs/openFrameworks/gl/ofGLUtils.h @@ -200,7 +200,7 @@ void ofDisableGLDebugLog(); #endif - #if defined(GL_ES_VERSION_3_0) + #if (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) // === GLES 3.0 / 3.1 additional fallbacks === // High-precision depth (very useful for shadows / FBOs) #ifndef GL_DEPTH_COMPONENT32F diff --git a/libs/openFrameworks/gl/ofMaterial.cpp b/libs/openFrameworks/gl/ofMaterial.cpp index 363c71e12c3..43326c8ef4d 100644 --- a/libs/openFrameworks/gl/ofMaterial.cpp +++ b/libs/openFrameworks/gl/ofMaterial.cpp @@ -110,7 +110,7 @@ std::string ofMaterial::getTextureTypeAsString(const ofMaterialTextureType & aMa //---------------------------------------------------------- bool ofMaterial::isPBRSupported() { - #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + #if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) return false; // pure GLES 2.0 does not support PBR #endif return ofIsGLProgrammableRenderer(); @@ -127,7 +127,7 @@ void ofMaterial::setPBR(bool ab) { return; } - #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + #if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) if (ab) { if (!bPrintedPBRRenderWarning) { bPrintedPBRRenderWarning = true; @@ -1510,7 +1510,7 @@ namespace{ if (ofIsGLProgrammableRenderer()) { // Shadows require programmable renderer + GLES 3.0+ (or desktop) - #if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) + #if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) ofStringReplace(source, "%shader_shadow_include%", shadow_shader_include); #else ofStringReplace(source, "%shader_shadow_include%", ""); diff --git a/libs/openFrameworks/gl/ofShader.cpp b/libs/openFrameworks/gl/ofShader.cpp index 4fa42ec4b95..74a5256c6fa 100644 --- a/libs/openFrameworks/gl/ofShader.cpp +++ b/libs/openFrameworks/gl/ofShader.cpp @@ -83,7 +83,7 @@ static void releaseProgram(GLuint id) { } } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) //-------------------------------------------------------------- ofShader::TransformFeedbackRangeBinding::TransformFeedbackRangeBinding(const ofBufferObject & buffer, GLuint offset, GLuint size) : offset(offset) @@ -213,7 +213,7 @@ bool ofShader::load(const of::filesystem::path & vertName, const of::filesystem: return linkProgram(); } -#if (!defined(TARGET_OPENGLES) && defined(glDispatchCompute)) || defined(GL_ES_VERSION_3_1) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_1) && defined(TARGET_OPENGLES_3) && defined(glDispatchCompute))) //-------------------------------------------------------------- bool ofShader::loadCompute(const of::filesystem::path & shaderName) { return setupShaderFromFile(GL_COMPUTE_SHADER, shaderName) && linkProgram(); @@ -251,7 +251,7 @@ bool ofShader::setup(const ofShaderSettings & settings) { return linkProgram(); } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) //-------------------------------------------------------------- bool ofShader::setup(const TransformFeedbackSettings & settings) { for (auto shader : settings.shaderFiles) { @@ -851,7 +851,7 @@ void ofShader::end() const { ofGetGLRenderer()->unbind(*this); } -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) //-------------------------------------------------------------- void ofShader::beginTransformFeedback(GLenum mode) const { begin(); @@ -923,7 +923,7 @@ void ofShader::endTransformFeedback(const std::vector shaderFiles; std::unordered_map shaderSources; @@ -119,7 +119,7 @@ class ofShader { #endif bool setup(const ofShaderSettings & settings); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) bool setup(const TransformFeedbackSettings & settings); #endif @@ -139,7 +139,7 @@ class ofShader { void end() const; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) void beginTransformFeedback(GLenum mode) const; void beginTransformFeedback(GLenum mode, const TransformFeedbackRangeBinding & binding) const; void beginTransformFeedback(GLenum mode, const std::vector & binding) const; @@ -152,7 +152,7 @@ class ofShader { void endTransformFeedback(const std::vector & binding) const; #endif -#if (!defined(TARGET_OPENGLES) && defined(glDispatchCompute)) || defined(GL_ES_VERSION_3_1) +#if !defined(TARGET_OPENGLES) || (defined(TARGET_OPENGLES_3) && defined(glDispatchCompute)) || defined(GL_ES_VERSION_3_1)) void dispatchCompute(GLuint x, GLuint y, GLuint z) const; #endif @@ -201,7 +201,7 @@ class ofShader { // set attributes that vary per vertex (look up the location before glBegin) GLint getAttributeLocation(const std::string & name) const; -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) #ifdef GLEW_ARB_uniform_buffer_object GLint getUniformBlockIndex(const std::string & name) const; GLint getUniformBlockBinding(const std::string & name) const; diff --git a/libs/openFrameworks/gl/ofShadow.cpp b/libs/openFrameworks/gl/ofShadow.cpp index 6377d4a11fb..54a6aecb526 100644 --- a/libs/openFrameworks/gl/ofShadow.cpp +++ b/libs/openFrameworks/gl/ofShadow.cpp @@ -341,7 +341,7 @@ std::string ofShadow::getShaderDefinesAsString() { //-------------------------------------------------------------- bool ofShadow::areShadowsSupported() { - #if defined(TARGET_OPENGLES) && !defined(GL_ES_VERSION_3_0) + #if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) return false; // GLES 2.0 does not support shadows #endif @@ -984,7 +984,7 @@ void ofShadow::_allocateFbo() { GLenum gl_read_status = GL_FRAMEBUFFER_UNSUPPORTED; GLenum textureTarget = getTextureTarget(data->lightType); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) GLenum depthComponent = GL_DEPTH_COMPONENT32F; GLenum glType = GL_FLOAT; #else diff --git a/libs/openFrameworks/gl/ofTexture.cpp b/libs/openFrameworks/gl/ofTexture.cpp index 826879a0fa0..f878e86e01a 100644 --- a/libs/openFrameworks/gl/ofTexture.cpp +++ b/libs/openFrameworks/gl/ofTexture.cpp @@ -722,7 +722,7 @@ void ofTexture::generateMipmap(){ switch (texData.textureTarget) { /// OpenGL ES only supports mipmap for the following two texture targets: case GL_TEXTURE_2D: -#if defined(GL_ES_VERSION_2_0) || defined(GL_ES_VERSION_3_0) +#if defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_2_0) && defined(TARGET_OPENGLES_2)) case GL_TEXTURE_CUBE_MAP: #endif #ifndef TARGET_OPENGLES @@ -730,7 +730,7 @@ void ofTexture::generateMipmap(){ case GL_TEXTURE_1D: case GL_TEXTURE_1D_ARRAY: #endif -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: #endif diff --git a/libs/openFrameworks/gl/ofTexture.h b/libs/openFrameworks/gl/ofTexture.h index fa150f5dca9..d9f10cd2978 100644 --- a/libs/openFrameworks/gl/ofTexture.h +++ b/libs/openFrameworks/gl/ofTexture.h @@ -569,7 +569,7 @@ class ofTexture : public ofBaseDraws { /// \param glType the OpenGL type of the data. void loadData(const void * data, int w, int h, int glFormat, int glType); -#if !defined(TARGET_OPENGLES) || defined(GL_ES_VERSION_3_0) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) /// \brief Load pixels from an ofBufferObject /// /// This is different to allocate(ofBufferObject,internal). That diff --git a/libs/openFrameworks/utils/ofConstants.h b/libs/openFrameworks/utils/ofConstants.h index 44ae9d6f430..b9745071d2d 100644 --- a/libs/openFrameworks/utils/ofConstants.h +++ b/libs/openFrameworks/utils/ofConstants.h @@ -339,6 +339,28 @@ typedef TESSindex ofIndexType; #include // intrinsics SIMD on https://learn.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170 #endif +#ifdef TARGET_OPENGLES + #if !defined(TARGET_OPENGLES_3) + #if defined(GL_ES_VERSION_3_0) || \ + (defined(TARGET_EMSCRIPTEN) && defined(USE_WEBGL2)) || \ + defined(TARGET_OPENGLES_3_1) || defined(TARGET_OPENGLES_3_2) + #define TARGET_OPENGLES_3 + #if defined(GL_ES_VERSION_3_1) + #define TARGET_OPENGLES_3_1 + #endif + #if defined(GL_ES_VERSION_3_2) + #define TARGET_OPENGLES_3_2 + #endif + #endif + #endif + // User can force-disable GLES3 + #if defined(TARGET_FORCE_GLES_2) || defined(TARGET_FORCE_GLES_1) + #undef TARGET_OPENGLES_3 + #undef TARGET_OPENGLES_3_1 + #undef TARGET_OPENGLES_3_2 + #endif +#endif + //------------------------------------------------ soundplayer //MAC_OS and IOS uncomment to enable AVEnginePlayer #ifdef OF_NO_FMOD From 78c3489cf5b79e307d8b96f3435d79db91896965 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Thu, 9 Apr 2026 14:26:47 +1000 Subject: [PATCH 36/38] ofMesh Mode to Triangles on init --- libs/openFrameworks/3d/ofMesh.inl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/openFrameworks/3d/ofMesh.inl b/libs/openFrameworks/3d/ofMesh.inl index e9e5363b0fc..0990186b27b 100644 --- a/libs/openFrameworks/3d/ofMesh.inl +++ b/libs/openFrameworks/3d/ofMesh.inl @@ -2939,8 +2939,7 @@ template ofMesh_ ofMesh_::axis( float size ) { ofMesh_ mesh; - // mesh only available as wireframe // - mesh.setMode(OF_PRIMITIVE_LINES); + mesh.setMode(OF_PRIMITIVE_TRIANGLES); V vertices[6] = { V(0,0,0), From 05152bad1a4bd34ce39c761c400e952b91c25eb8 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Thu, 9 Apr 2026 14:54:35 +1000 Subject: [PATCH 37/38] ofShader Fix --- libs/openFrameworks/gl/ofShader.cpp | 4 ++-- libs/openFrameworks/gl/ofShader.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/openFrameworks/gl/ofShader.cpp b/libs/openFrameworks/gl/ofShader.cpp index 74a5256c6fa..23bfd406f00 100644 --- a/libs/openFrameworks/gl/ofShader.cpp +++ b/libs/openFrameworks/gl/ofShader.cpp @@ -213,7 +213,7 @@ bool ofShader::load(const of::filesystem::path & vertName, const of::filesystem: return linkProgram(); } -#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_1) && defined(TARGET_OPENGLES_3) && defined(glDispatchCompute))) +#if !defined(TARGET_OPENGLES) || (defined(GL_ES_VERSION_3_1) && defined(TARGET_OPENGLES_3) && defined(glDispatchCompute)) //-------------------------------------------------------------- bool ofShader::loadCompute(const of::filesystem::path & shaderName) { return setupShaderFromFile(GL_COMPUTE_SHADER, shaderName) && linkProgram(); @@ -923,7 +923,7 @@ void ofShader::endTransformFeedback(const std::vector & binding) const; #endif -#if !defined(TARGET_OPENGLES) || (defined(TARGET_OPENGLES_3) && defined(glDispatchCompute)) || defined(GL_ES_VERSION_3_1)) +#if !defined(TARGET_OPENGLES) || (defined(TARGET_OPENGLES_3) && defined(glDispatchCompute) && defined(GL_ES_VERSION_3_1)) void dispatchCompute(GLuint x, GLuint y, GLuint z) const; #endif From 61558137c94f76e0d3a6ed305717fbe270b93da8 Mon Sep 17 00:00:00 2001 From: Dan Rosser Date: Thu, 9 Apr 2026 21:05:14 +1000 Subject: [PATCH 38/38] OpenGL fixes --- libs/openFrameworks/gl/ofFbo.cpp | 2 +- libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp | 2 +- libs/openFrameworks/gl/ofGLUtils.cpp | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libs/openFrameworks/gl/ofFbo.cpp b/libs/openFrameworks/gl/ofFbo.cpp index 2d2b7715dcc..cf0ec24f7cc 100644 --- a/libs/openFrameworks/gl/ofFbo.cpp +++ b/libs/openFrameworks/gl/ofFbo.cpp @@ -34,7 +34,7 @@ using std::vector; */ -#if defined(TARGET_OPENGLES) || !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) +#if defined(TARGET_OPENGLES) && !(defined(GL_ES_VERSION_3_0) && defined(TARGET_OPENGLES_3)) bool ofFbo::bglFunctionsInitialized=false; typedef void (* glGenFramebuffersType) (GLsizei n, GLuint* framebuffers); diff --git a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp index 6e27f86c4a5..8c311d6ad9e 100644 --- a/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp +++ b/libs/openFrameworks/gl/ofGLProgrammableRenderer.cpp @@ -500,7 +500,7 @@ void ofGLProgrammableRenderer::drawElementsInstanced(const ofVbo & vbo, GLuint d // https://www.khronos.org/opengles/sdk/docs/man3/xhtml/glDrawElementsInstanced.xml ofLogWarning("ofVbo") << "drawElementsInstanced(): hardware instancing is not supported on OpenGL ES <= 3.1"; #else - glDrawElementsInstanced(drawMode, amt, indexType, nullptr, primCount); + glDrawElementsInstanced(drawMode, amt, GL_UNSIGNED_INT, nullptr, primCount); #endif vbo.unbind(); } diff --git a/libs/openFrameworks/gl/ofGLUtils.cpp b/libs/openFrameworks/gl/ofGLUtils.cpp index df78e483bc4..885d21049af 100644 --- a/libs/openFrameworks/gl/ofGLUtils.cpp +++ b/libs/openFrameworks/gl/ofGLUtils.cpp @@ -337,7 +337,6 @@ int ofGetGLTypeFromInternal(int glInternalFormat){ #endif #ifndef TARGET_OPENGLES - case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: case GL_R32UI: case GL_RG32UI: