# 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 <EGL/egl.h>
#include <GLES/gl.h>
- #define GL_GLEXT_PROTOTYPES 1
- #include <GLES/glext.h>
- #include <errno.h>
-
- #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;
EGLConfig mnit_config;
int32_t mnit_width;
int32_t mnit_height;
- float mnit_zoom;
struct mnit_opengles_Texture {
GLuint texture;
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" `{
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] =
{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;
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;
init do extern_init
fun midway_init( format: Int ) do end
- fun extern_init: Bool is extern import midway_init `{
+ fun extern_init: Bool import midway_init `{
/* initialize OpenGL ES and EGL */
const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_NONE
};
- EGLint w, h, dummy, format;
+ EGLint w, h, format;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
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;
}
/* Used by Android to set buffer geometry */
- Opengles1Display_midway_init(recv, format);
+ Opengles1Display_midway_init(self, format);
surface = eglCreateWindowSurface(display, config, mnit_window, NULL);
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;
}
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);
return 0;
`}
- fun close is extern `{
+ fun close `{
if ( mnit_display != EGL_NO_DISPLAY) {
eglMakeCurrent( mnit_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if ( mnit_context != EGL_NO_CONTEXT) {
mnit_surface = EGL_NO_SURFACE;
`}
- redef fun begin is extern `{
+ redef fun begin `{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
`}
- redef fun width: Int is extern `{
+ redef fun width: Int `{
return mnit_width;
`}
- redef fun height: Int is extern `{
+ redef fun height: Int `{
return mnit_height;
`}
- redef fun finish is extern `{
+ redef fun finish `{
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 `{
+ redef fun set_viewport( x, y, w, h ) `{
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}
};
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);
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}
};
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);
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},
};
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);
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 clear( r, g, b: Float ) is extern `{
+ redef fun clear( r, g, b: Float ) `{
glClearColor( r, g, b, 1.0 );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
`}
- fun clear_alpha( r, g, b, a: Float ) is extern `{
+ fun clear_alpha( r, g, b, a: Float ) `{
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 ); `}
+ redef fun destroy `{ free( self ); `}
- redef fun width: Int is extern `{ return recv->width; `}
- redef fun height: Int is extern `{ return recv->height; `}
+ redef fun width: Int `{ return self->width; `}
+ redef fun height: Int `{ return self->height; `}
- fun center_x: Int `{ return recv->center_x; `}
- fun center_y: Int `{ return recv->center_y; `}
+ fun center_x: Int `{ return self->center_x; `}
+ fun center_y: Int `{ return self->center_y; `}
- redef fun scale=( v: Float ) is extern `{
- recv->scale = v;
- recv->center_x = v*recv->width/2;
- recv->center_y = v*recv->height/2;
+ redef fun scale=( v: Float ) `{
+ self->scale = v;
+ self->center_x = v*self->width/2;
+ self->center_y = v*self->height/2;
`}
- redef fun scale: Float is extern `{ return recv->scale; `}
+ redef fun scale: Float `{ return self->scale; `}
- redef fun blended=( v: Bool ) is extern `{ recv->blended = v; `}
- redef fun blended: Bool is extern `{ return recv->blended; `}
+ redef fun blended=( v: Bool ) `{ self->blended = v; `}
+ redef fun blended: Bool `{ return self->blended; `}
# inherits scale and blend from source
- redef fun subimage( x, y, w, h: Int ): Image is extern import Opengles1Image as ( Image ) `{
+ redef fun subimage( x, y, w, h: Int ): Image import Opengles1Image.as( Image ) `{
struct mnit_opengles_Texture* image =
malloc( sizeof( struct mnit_opengles_Texture ) );
- image->texture = recv->texture;
+ image->texture = self->texture;
image->width = w;
image->height = h;
- image->center_x = recv->scale*w/2;
- image->center_y = recv->scale*h/2;
- 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;
+ image->center_x = self->scale*w/2;
+ image->center_y = self->scale*h/2;
+ image->scale = self->scale;
+ image->blended = self->blended;
+
+ float r_dx = self->src_xi - self->src_xo;
+ float r_dy = self->src_yi - self->src_yo;
+ image->src_xo = self->src_xo + ((float)x)/self->width*r_dx;
+ image->src_yo = self->src_yo + ((float)y)/self->height*r_dy;
+ image->src_xi = self->src_xo + ((float)x+w)/self->width*r_dx;
+ image->src_yi = self->src_yo + ((float)y+h)/self->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
-