Sorry I just assumed all the models would have loads of quads and stuff in them. It’s not a big issue anyway as model conversion can be done in code quite easily on the fly. I may be getting a bit out of my depth here but does Oolite have its own shader pipeline or does it just use the default Open GL one? If it does just use the Open GL one then it could be possible to port it to Open GL ES 1.2 as this has a
similar to that of Open GL. Open GL ES 2 though has the programmable pipeline that I believe you do need to implement yourself.
Below is a really simple Raspberry Pi Open GL ES 1.2 program that just displays a spinning icosahedron so you can see how the vertices / colours etc are submitted to ogl. No textures involved here. Not sure if this is helpful? See the
method.
And about memory foot print... I’m getting ready to dodge rotten tomatoes but, what if we went without any textures to start with? Would that reduce the memory footprint a lot or no?
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include "bcm_host.h"
#include "GLES/gl.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include "OpenGLCommon.h"
#define PATH "./"
#define IMAGE_SIZE 128
#ifndef M_PI
#define M_PI 3.141592654
#endif
typedef struct
{
uint32_t screen_width;
uint32_t screen_height;
// OpenGL|ES objects
EGLDisplay display;
EGLSurface surface;
EGLContext context;
} STATE_T;
static float DegreesToRadians(float degrees);
static void setupView(STATE_T *state);
static void drawView(STATE_T *state);
static void exit_func(void);
static volatile int terminate;
static STATE_T _state, *state=&_state;
static const Vertex3D vertices[]= {
{0, -0.525731, 0.850651}, // vertices[0]
{0.850651, 0, 0.525731}, // vertices[1]
{0.850651, 0, -0.525731}, // vertices[2]
{-0.850651, 0, -0.525731}, // vertices[3]
{-0.850651, 0, 0.525731}, // vertices[4]
{-0.525731, 0.850651, 0}, // vertices[5]
{0.525731, 0.850651, 0}, // vertices[6]
{0.525731, -0.850651, 0}, // vertices[7]
{-0.525731, -0.850651, 0}, // vertices[8]
{0, -0.525731, -0.850651}, // vertices[9]
{0, 0.525731, -0.850651}, // vertices[10]
{0, 0.525731, 0.850651} // vertices[11]
};
static const Color3D colors[] = {
{1.0, 0.0, 0.0, 1.0},
{1.0, 0.5, 0.0, 1.0},
{1.0, 1.0, 0.0, 1.0},
{0.5, 1.0, 0.0, 1.0},
{0.0, 1.0, 0.0, 1.0},
{0.0, 1.0, 0.5, 1.0},
{0.0, 1.0, 1.0, 1.0},
{0.0, 0.5, 1.0, 1.0},
{0.0, 0.0, 1.0, 1.0},
{0.5, 0.0, 1.0, 1.0},
{1.0, 0.0, 1.0, 1.0},
{1.0, 0.0, 0.5, 1.0}
};
static const GLubyte icosahedronFaces[] = {
1, 2, 6,
1, 7, 2,
3, 4, 5,
4, 3, 8,
6, 5, 11,
5, 6, 10,
9, 10, 2,
10, 9, 3,
7, 8, 9,
8, 7, 0,
11, 0, 1,
0, 11, 4,
6, 2, 10,
1, 6, 11,
3, 5, 10,
5, 4, 11,
2, 7, 9,
7, 1, 0,
3, 9, 8,
4, 8, 0,
};
//==============================================================================
static void init_ogl(STATE_T *state)
{
int32_t success = 0;
EGLBoolean result;
EGLint num_config;
static EGL_DISPMANX_WINDOW_T nativewindow;
DISPMANX_ELEMENT_HANDLE_T dispman_element;
DISPMANX_DISPLAY_HANDLE_T dispman_display;
DISPMANX_UPDATE_HANDLE_T dispman_update;
VC_RECT_T dst_rect;
VC_RECT_T src_rect;
static const EGLint attribute_list[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
EGLConfig config;
// get an EGL display connection
state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(state->display!=EGL_NO_DISPLAY);
// initialize the EGL display connection
result = eglInitialize(state->display, NULL, NULL);
assert(EGL_FALSE != result);
// get an appropriate EGL frame buffer configuration
result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
assert(EGL_FALSE != result);
// create an EGL rendering context
state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
assert(state->context!=EGL_NO_CONTEXT);
// create an EGL window surface
success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
assert( success >= 0 );
dst_rect.x = 0;
dst_rect.y = 0;
dst_rect.width = state->screen_width;
dst_rect.height = state->screen_height;
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = state->screen_width << 16;
src_rect.height = state->screen_height << 16;
dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
dispman_update = vc_dispmanx_update_start( 0 );
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
0/*layer*/, &dst_rect, 0/*src*/,
&src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
nativewindow.element = dispman_element;
nativewindow.width = state->screen_width;
nativewindow.height = state->screen_height;
vc_dispmanx_update_submit_sync( dispman_update );
state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
assert(state->surface != EGL_NO_SURFACE);
// connect the context to the surface
result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
assert(EGL_FALSE != result);
}
//==============================================================================
static float DegreesToRadians(float degrees)
{
return degrees * M_PI / 180;
}
//==============================================================================
const float zNear = 0.01f, zFar = 1000.0f, fieldOfView = 45.0f;
static void setupView(STATE_T *state)
{
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
float aspectRatio = (float)state->screen_width / (float)state->screen_height;
/*
glOrthof(-1.0f, // Left
1.0f, // Right
-1.0f / aspectRatio, // Bottom
1.0f / aspectRatio, // Top
zNear, // Near
zFar); // Far
*/
float size = zNear * tanf(DegreesToRadians(fieldOfView) / 2.0);
/*
//Use size for left and right but make the top and bottom smaller by dividing by the aspect ratio
glFrustumf(-size, // Left
size, // Right
-size / aspectRatio, // Bottom
size / aspectRatio, // Top
zNear, // Near
zFar); // Far
*/
//Use size for top and bottom but make the left and right larger by multiplying by the aspect ratio - I like this more, gives a bigger frustum
glFrustumf(-size * aspectRatio, // Left
size * aspectRatio, // Right
-size, // Bottom
size, // Top
zNear, // Near
zFar); // Far
glViewport(0, 0, (GLsizei)state->screen_width, (GLsizei)state->screen_height);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_CULL_FACE);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
}
//==============================================================================
static GLfloat rot = 0.5;
static void drawView(STATE_T *state)
{
glRotatef(rot,1.0f,1.0f,1.0f);
glClearColor(0.7, 0.7, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glDrawElements(GL_TRIANGLES, 60, GL_UNSIGNED_BYTE, icosahedronFaces);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
eglSwapBuffers(state->display, state->surface);
}
//==============================================================================
static void exit_func(void)
{
// clear screen
glClear( GL_COLOR_BUFFER_BIT );
eglSwapBuffers(state->display, state->surface);
// Release OpenGL resources
eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
eglDestroySurface( state->display, state->surface );
eglDestroyContext( state->display, state->context );
eglTerminate( state->display );
printf("closed\n");
}
//==============================================================================
int main ()
{
bcm_host_init();
// Clear application state
memset( state, 0, sizeof( *state ) );
// Start OGLES
init_ogl(state);
setupView(state);
while (!terminate)
{
//usleep(5*1000);
drawView(state);
}
exit_func();
return 0;
}