Skip to content

Instantly share code, notes, and snippets.

@jvcleave
Created January 29, 2013 07:40
Show Gist options
  • Select an option

  • Save jvcleave/4662519 to your computer and use it in GitHub Desktop.

Select an option

Save jvcleave/4662519 to your computer and use it in GitHub Desktop.
simple GLES 2 window for RPI
OBJS=simpleWindow.o
BIN=simpleWindow.bin
CFLAGS+=-DSTANDALONE -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -DTARGET_POSIX -D_LINUX -fPIC -DPIC -D_REENTRANT -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -U_FORTIFY_SOURCE -Wall -g -DHAVE_LIBOPENMAX=2 -DOMX -DOMX_SKIP64BIT -ftree-vectorize -pipe -DUSE_EXTERNAL_OMX -DHAVE_LIBBCM_HOST -DUSE_EXTERNAL_LIBBCM_HOST -DUSE_VCHIQ_ARM -Wno-psabi
LDFLAGS+=-L/opt/vc/lib/ -lGLESv2 -lEGL -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt -L/opt/vc/hello_pi/libs/ilclient -L/opt/vc/hello_pi/libs/vgfont
INCLUDES+=-I/opt/vc/include/ -I/opt/vc/include/interface/vcos/pthreads -I./ -I/opt/vc/hello_pi/libs/ilclient -I/opt/vc/hello_pi/libs/vgfont
all: $(BIN) $(LIB)
%.o: %.c
@rm -f $@
$(CC) $(CFLAGS) $(INCLUDES) -g -c $< -o $@ -Wno-deprecated-declarations
%.o: %.cpp
@rm -f $@
$(CXX) $(CFLAGS) $(INCLUDES) -g -c $< -o $@ -Wno-deprecated-declarations
%.bin: $(OBJS)
$(CC) -o $@ -Wl,--whole-archive $(OBJS) $(LDFLAGS) -Wl,--no-whole-archive -rdynamic
%.a: $(OBJS)
$(AR) r $@ $^
clean:
for i in $(OBJS); do (if test -e "$$i"; then ( rm $$i ); fi ); done
@rm -f $(BIN) $(LIB)
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include "bcm_host.h"
#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"
#define check() assert(glGetError() == 0)
int main ()
{
bcm_host_init();
uint32_t screen_width;
uint32_t screen_height;
EGLDisplay display;
EGLSurface surface;
EGLContext context;
GLuint vertShader;
GLuint fragmentShader;
GLuint program;
GLuint tex_fb;
GLuint tex;
GLuint buf;
int terminate = 0;
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
};
static const EGLint context_attributes[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLConfig config;
// get an EGL display connection
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(display!=EGL_NO_DISPLAY);
// initialize the EGL display connection
result = eglInitialize(display, NULL, NULL);
assert(EGL_FALSE != result);
// get an appropriate EGL frame buffer configuration
result = eglChooseConfig(display, attribute_list, &config, 1, &num_config);
assert(EGL_FALSE != result);
// get an appropriate EGL frame buffer configuration
result = eglBindAPI(EGL_OPENGL_ES_API);
assert(EGL_FALSE != result);
// create an EGL rendering context
context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes);
assert(context!=EGL_NO_CONTEXT);
// create an EGL window surface
success = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
assert( success >= 0 );
dst_rect.x = 0;
dst_rect.y = 0;
dst_rect.width = screen_width;
dst_rect.height = screen_height;
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = screen_width << 16;
src_rect.height = 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 = screen_width;
nativewindow.height = screen_height;
vc_dispmanx_update_submit_sync( dispman_update );
surface = eglCreateWindowSurface( display, config, &nativewindow, NULL );
assert(surface != EGL_NO_SURFACE);
// connect the context to the surface
result = eglMakeCurrent(display, surface, surface, context);
assert(EGL_FALSE != result);
// Set background color and clear buffers
glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
glClear( GL_COLOR_BUFFER_BIT );
static const GLfloat vertex_data[] = {
-1.0,-1.0,1.0,1.0,
1.0,-1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
-1.0,1.0,1.0,1.0
};
const GLchar* vertShader_source = STRINGIFY(
attribute vec4 vertex;
void main (void)
{
gl_Position = vertex;
}
);
vertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource( vertShader, 1, &vertShader_source, 0);
glCompileShader( vertShader);
const GLchar* fragmentShader_source = STRINGIFY(
uniform vec4 color;
uniform sampler2D tex;
void main (void){
gl_FragColor = color;
}
);
GLuint unif_color, attr_vertex;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource( fragmentShader, 1, &fragmentShader_source, 0);
glCompileShader( fragmentShader);
program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
// Prepare a texture image
glGenTextures(1, &tex);
glGenBuffers(1, &buf);
// Prepare a framebuffer for rendering
glGenFramebuffers(1, &tex_fb);
attr_vertex = glGetAttribLocation(program, "vertex");
unif_color = glGetUniformLocation(program, "color");
while (!terminate)
{
//glClearColor ( 0.0, 1.0, 1.0, 1.0 );
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width, screen_height, 0, GL_RGB,GL_UNSIGNED_SHORT_5_6_5, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, tex_fb);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, tex, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Prepare viewport
glViewport ( 0, 0, screen_width, screen_height );
// Upload vertex data to a buffer
glBindBuffer(GL_ARRAY_BUFFER, buf);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glVertexAttribPointer(attr_vertex, 4, GL_FLOAT, 0, 16, 0);
glEnableVertexAttribArray(attr_vertex);
// Now render to the main frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Clear the background (not really necessary I suppose)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, buf);
glUseProgram ( program );
glBindTexture(GL_TEXTURE_2D, tex);
glUniform4f(unif_color, 1.0, 1.0, 1.0, 1.0);
glDrawArrays (GL_TRIANGLE_FAN, 0, 4 );
glBindBuffer(GL_ARRAY_BUFFER, 0);
glFlush();
glFinish();
eglSwapBuffers(display, surface);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment