X-Git-Url: http://nitlanguage.org diff --git a/lib/mnit/opengles1.nit b/lib/mnit/opengles1.nit index e45cac9..b11d8dd 100644 --- a/lib/mnit/opengles1.nit +++ b/lib/mnit/opengles1.nit @@ -15,23 +15,13 @@ # limitations under the License. # OpenGL ES1 general support (most of it) -module opengles1 +module opengles1 is pkgconfig("glesv1_cm", "egl") -import display +import mnit_display in "C header" `{ #include #include - #define GL_GLEXT_PROTOTYPES 1 - #include - #include - - #define LOGW(...) ((void)fprintf(stderr, "# warn: %s", __VA_ARGS__)) - #ifdef DEBUG - #define LOGI(...) ((void)fprintf(stderr, "# info: %s", __VA_ARGS__)) - #else - #define LOGI(...) (void)0 - #endif EGLDisplay mnit_display; EGLSurface mnit_surface; @@ -39,7 +29,6 @@ in "C header" `{ EGLConfig mnit_config; int32_t mnit_width; int32_t mnit_height; - float mnit_zoom; struct mnit_opengles_Texture { GLuint texture; @@ -62,15 +51,13 @@ in "C header" `{ GLuint fbo; GLuint depth; GLuint color; - /* - EGLSurface surface; - int width, height; - */ }; GLenum mnit_opengles_error_code; - struct mnit_opengles_Texture *mnit_opengles_load_image( const uint_least32_t *pixels, int width, int height, int has_alpha ); + struct mnit_opengles_Texture *mnit_opengles_load_image( + const uint_least32_t *pixels, int width, int height, + int width_pow2, int height_pow2, int has_alpha); `} in "C" `{ @@ -79,11 +66,9 @@ in "C" `{ GLfloat mnit_opengles_vertices[6][3] = { - {0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, - {1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, }; GLfloat mnit_opengles_texture[6][2] = @@ -96,7 +81,9 @@ in "C" `{ {1.0f, 0.0f} }; - struct mnit_opengles_Texture *mnit_opengles_load_image( const uint_least32_t *pixels, int width, int height, int has_alpha ) + struct mnit_opengles_Texture *mnit_opengles_load_image( + const uint_least32_t *pixels, int width, int height, + int width_pow2, int height_pow2, int has_alpha) { struct mnit_opengles_Texture *image = malloc(sizeof(struct mnit_opengles_Texture)); int format = has_alpha? GL_RGBA: GL_RGB; @@ -110,38 +97,37 @@ in "C" `{ image->src_xo = 0; image->src_yo = 0; - image->src_xi = 1.0; - image->src_yi = 1.0; - + image->src_xi = ((float)width)/width_pow2; + image->src_yi = ((float)height)/height_pow2; if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("a error loading image: %i\n", mnit_opengles_error_code); - printf( "%i\n", mnit_opengles_error_code ); + PRINT_ERROR("error loading image after malloc: %i", mnit_opengles_error_code); } + glGenTextures(1, &image->texture); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("b error loading image: %i\n", mnit_opengles_error_code); - printf( "%i\n", mnit_opengles_error_code ); + PRINT_ERROR("error loading image after glGenTextures: %i", mnit_opengles_error_code); } + glBindTexture(GL_TEXTURE_2D, image->texture); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("c error loading image: %i\n", mnit_opengles_error_code); - printf( "%i\n", mnit_opengles_error_code ); + PRINT_ERROR("error loading image glBindTexture: %i", mnit_opengles_error_code); } - glTexImage2D( GL_TEXTURE_2D, 0, format, width, height, + + glTexImage2D( GL_TEXTURE_2D, 0, format, width_pow2, height_pow2, 0, format, GL_UNSIGNED_BYTE, (GLvoid*)pixels); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("d error loading image: %i\n", mnit_opengles_error_code); - printf( "%i\n", mnit_opengles_error_code ); + PRINT_ERROR("error loading image after glTexImage2D: %i", mnit_opengles_error_code); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("e error loading image: %i\n", mnit_opengles_error_code); - printf( "%i\n", mnit_opengles_error_code ); + PRINT_ERROR("error loading image after gtTexParameter: %i", mnit_opengles_error_code); } return image; @@ -174,27 +160,27 @@ class Opengles1Display EGLDisplay display = eglGetDisplay(mnit_native_display); if ( display == EGL_NO_DISPLAY) { - LOGW("Unable to eglGetDisplay"); + PRINT_ERROR("Unable to eglGetDisplay"); return -1; } if ( eglInitialize(display, 0, 0) == EGL_FALSE) { - LOGW("Unable to eglInitialize"); + PRINT_ERROR("Unable to eglInitialize"); return -1; } if ( eglChooseConfig(display, attribs, &config, 1, &numConfigs) == EGL_FALSE) { - LOGW("Unable to eglChooseConfig"); + PRINT_ERROR("Unable to eglChooseConfig"); return -1; } if ( numConfigs == 0 ) { - LOGW("No configs available for egl"); + PRINT_ERROR("No configs available for egl"); return -1; } if ( eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format) == EGL_FALSE) { - LOGW("Unable to eglGetConfigAttrib"); + PRINT_ERROR("Unable to eglGetConfigAttrib"); return -1; } @@ -205,7 +191,7 @@ class Opengles1Display context = eglCreateContext(display, config, NULL, NULL); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { - LOGW("Unable to eglMakeCurrent"); + PRINT_ERROR("Unable to eglMakeCurrent"); return -1; } @@ -218,9 +204,6 @@ class Opengles1Display mnit_config = config; mnit_width = w; mnit_height = h; - mnit_zoom = 1.0f; - - LOGI( "surface: %i, display: %i, w %i, h %i", (int)surface, (int)display, w, h ); glViewport(0, 0, mnit_width, mnit_height); glMatrixMode(GL_PROJECTION); @@ -265,30 +248,24 @@ class Opengles1Display eglSwapBuffers( mnit_display, mnit_surface ); `} - fun set_as_target is extern `{ - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); - `} - redef fun set_viewport( x, y, w, h ) is extern `{ glLoadIdentity(); glViewport(0,0, mnit_width, mnit_height ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(x, x+w, y+h, y, 0.0f, 1.0f); - /*glOrthof(0.0f, w, h, 0.0f, 0.0f, 1.0f);*/ - mnit_zoom = ((float)w)/mnit_width; glMatrixMode(GL_MODELVIEW); glFrontFace( GL_CW ); `} - redef fun blit( image, x, y ) is extern `{ - GLfloat texture_coord[6][2] = + redef fun blit(image, x, y) do native_blit(image, x.to_f, y.to_f) + + private fun native_blit(image: Opengles1Image, x, y: Float) `{ + GLfloat texture_coord[4][2] = { - {image->src_xo, image->src_yo}, {image->src_xo, image->src_yi}, {image->src_xi, image->src_yi}, {image->src_xo, image->src_yo}, - {image->src_xi, image->src_yi}, {image->src_xi, image->src_yo} }; @@ -310,9 +287,9 @@ class Opengles1Display glDisable(GL_DEPTH_TEST); glVertexPointer(3, GL_FLOAT, 0, mnit_opengles_vertices); - glTexCoordPointer(2, GL_FLOAT, 0, texture_coord ); /* mnit_opengles_texture); */ + glTexCoordPointer(2, GL_FLOAT, 0, texture_coord ); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 6); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -320,25 +297,25 @@ class Opengles1Display glDisable(GL_TEXTURE_2D); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("error drawing: %i", mnit_opengles_error_code); + PRINT_ERROR("error drawing: %i", mnit_opengles_error_code); } `} - redef fun blit_centered( img, x, y ) + redef fun blit_centered(img, x, y) do - x = x - img.center_x - y = y - img.center_y - blit( img, x, y ) + x = x.sub(img.center_x) + y = y.sub(img.center_y) + blit(img, x, y) end - redef fun blit_rotated( image, x, y, angle ) is extern `{ - GLfloat texture_coord[6][2] = + redef fun blit_rotated(image, x, y, angle) do native_blit_rotated(image, x.to_f, y.to_f, angle) + + private fun native_blit_rotated(image: Opengles1Image, x, y, angle: Float) `{ + GLfloat texture_coord[4][2] = { - {image->src_xo, image->src_yo}, {image->src_xo, image->src_yi}, {image->src_xi, image->src_yi}, {image->src_xo, image->src_yo}, - {image->src_xi, image->src_yi}, {image->src_xi, image->src_yo} }; @@ -362,7 +339,7 @@ class Opengles1Display glVertexPointer(3, GL_FLOAT, 0, mnit_opengles_vertices); glTexCoordPointer(2, GL_FLOAT, 0, texture_coord ); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 6); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -370,32 +347,32 @@ class Opengles1Display glDisable(GL_TEXTURE_2D); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("error drawing: %i", mnit_opengles_error_code); + PRINT_ERROR("error drawing: %i", mnit_opengles_error_code); } `} -# fun clear( r, g, b: Int ) is extern `{ -# glClear(GL_COLOR_BUFFER_BIT); -# `} # a = top left, b = bottom left, c = bottom right, d = top right - redef fun blit_stretched( image, ax, ay, bx, by, cx, cy, dx, dy ) is extern `{ - GLfloat texture_coord[6][2] = + redef fun blit_stretched(image, ax, ay, bx, by, cx, cy, dx, dy) + do + native_blit_stretched(image, + ax.to_f, ay.to_f, bx.to_f, by.to_f, + cx.to_f, cy.to_f, dx.to_f, dy.to_f) + end + + private fun native_blit_stretched(image: I, ax, ay, bx, by, cx, cy, dx, dy: Float) `{ + GLfloat texture_coord[4][2] = { - {image->src_xo, image->src_yo}, {image->src_xo, image->src_yi}, {image->src_xi, image->src_yi}, {image->src_xo, image->src_yo}, - {image->src_xi, image->src_yi}, {image->src_xi, image->src_yo} }; GLfloat mnit_opengles_vertices_stretched[6][3] = { - {ax, ay, 0.0f}, {bx, by, 0.0f}, {cx, cy, 0.0f}, {ax, ay, 0.0f}, - {cx, cy, 0.0f}, {dx, dy, 0.0f}, }; @@ -417,7 +394,7 @@ class Opengles1Display glVertexPointer(3, GL_FLOAT, 0, mnit_opengles_vertices_stretched); glTexCoordPointer(2, GL_FLOAT, 0, texture_coord ); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 6); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -425,7 +402,7 @@ class Opengles1Display glDisable(GL_TEXTURE_2D); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { - LOGW ("error drawing: %i", mnit_opengles_error_code); + PRINT_ERROR("error drawing: %i", mnit_opengles_error_code); } `} @@ -438,9 +415,17 @@ class Opengles1Display glClearColor( r, g, b, a ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); `} + + # Set the current color applied to all drawing + # + # require: r, g, b, a in [0.0 .. 1.0] + fun color(r, g, b, a: Float) `{ glColor4f(r, g, b, a); `} + + # Reset the current color to opaque white + fun reset_color `{ glColor4f(1.0f, 1.0f, 1.0f, 1.0f); `} end -extern Opengles1Image in "C" `{struct mnit_opengles_Texture *`} +extern class Opengles1Image in "C" `{struct mnit_opengles_Texture *`} super Image redef fun destroy is extern `{ free( recv ); `} @@ -474,146 +459,13 @@ extern Opengles1Image in "C" `{struct mnit_opengles_Texture *`} image->scale = recv->scale; image->blended = recv->blended; - image->src_xo = ((float)x)/recv->width; - image->src_yo = ((float)y)/recv->height; - image->src_xi = ((float)w+w)/recv->width; - image->src_yi = ((float)x+h)/recv->height; + float r_dx = recv->src_xi - recv->src_xo; + float r_dy = recv->src_yi - recv->src_yo; + image->src_xo = recv->src_xo + ((float)x)/recv->width*r_dx; + image->src_yo = recv->src_yo + ((float)y)/recv->height*r_dy; + image->src_xi = recv->src_xo + ((float)x+w)/recv->width*r_dx; + image->src_yi = recv->src_yo + ((float)y+h)/recv->height*r_dy; return Opengles1Image_as_Image( image ); `} end - - -extern Opengles1DrawableImage in "C" `{struct mnit_opengles_DrawableTexture*`} - super DrawableImage - new ( w, h: Int ) is extern `{ - struct mnit_opengles_DrawableTexture *image = - malloc( sizeof(struct mnit_opengles_DrawableTexture) ); - - #ifdef a - const EGLint attribs[] = { - EGL_WIDTH, w, - EGL_HEIGHT, h, - EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, - EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, - EGL_NONE - }; - - image->surface = eglCreatePbufferSurface( andronit.display, - andronit.config, - attribs ); - if ( eglGetError() ) - LOGW( "eglCreatePbuffer error" ); - - image->width = w; - image->height = h; - image->center_x = w/2; - image->center_y = h/2; - eglMakeCurrent( andronit.display, - surface, - surface, - andronit.context ); - - #else - /* texture */ - glGenTextures(1, &image->super.texture); - glBindTexture(GL_TEXTURE_2D, image->super.texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - /* glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap generation included in OpenGL v1.4c */ - glBindTexture(GL_TEXTURE_2D, 0); - - /* fbo */ - glGenFramebuffersOES( 1, &image->fbo ); - glBindFramebufferOES( GL_FRAMEBUFFER_OES, image->fbo ); - glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, - GL_COLOR_ATTACHMENT0_OES, - GL_TEXTURE_2D, - image->super.texture, - 0 ); - - /* depth */ - glGenRenderbuffersOES(1, &image->depth); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, image->depth); - glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, - w, h); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0); - glFramebufferRenderbufferOES( GL_FRAMEBUFFER_OES, - GL_DEPTH_ATTACHMENT_OES, - GL_RENDERBUFFER_OES, - image->depth ); - - /* tex framebuffer */ - glGenRenderbuffersOES(1, &image->color); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, image->color); - glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, w, h); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, image->color ); - - if ( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) != GL_FRAMEBUFFER_COMPLETE_OES ) - { - LOGW( "framebuffer not set" ); - if ( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES ) - LOGW( "framebuffer not set a" ); - else if ( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES ) - LOGW( "framebuffer not set b" ); - else if ( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES ) - LOGW( "framebuffer not set c" ); - else if ( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES ) - LOGW( "framebuffer not set d" ); - } - - image->super.width = w; - image->super.height = h; - image->super.center_x = w/2; - image->super.center_y = h/2; - image->super.scale = 1.0f; - image->super.blended = 0; - - #endif - - if (glGetError() != GL_NO_ERROR) LOGW( "gl error"); - - return image; - `} - -# fun image: I is extern `{ -# struct mnit_opengles_Texture *image; -# const uint_least32_t *pixels; -# pixels = malloc( sizeof(uint_least32_t)*recv->width*recv->height ); -# glReadPixels( 0, 0, recv->width, recv->height, -# GL_RGBA, GL_UNSIGNED_BYTE, pixels ); -# image = mnit_opengles_load_image( pixels, recv->width, recv->height ); -# return image; - - fun set_as_target is extern `{ - LOGI( "sat %i", recv->fbo ); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, recv->fbo); - /*glBindRenderbufferOES(GL_FRAMEBUFFER_OES, recv->color);*/ - if (glGetError() != GL_NO_ERROR) LOGW( "gl error 0"); - /*glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES,&recv->fbo); - //if (glGetError() != GL_NO_ERROR) LOGW( "gl error a");*/ - glViewport(0, 0, recv->super.width, recv->super.height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof(0.0f, recv->super.width, recv->super.height, 0.0f, 0.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - glFrontFace( GL_CW ); - - glClearColor( 0.0f, 1.0f, 1.0f, 1.0f ); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - `} - - fun unset_as_target is extern `{ - glFlush(); - /*glBindTexture(GL_TEXTURE_2D, recv->super.texture); - glGenerateMipmapOES(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0);*/ - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); - if (glGetError() != GL_NO_ERROR) LOGW( "gl error"); - `} -end -