Skip to content

Instantly share code, notes, and snippets.

@k0nze
Created January 7, 2018 09:44
Show Gist options
  • Save k0nze/e97d9d2230a11e2f61e1844ccbed9a3e to your computer and use it in GitHub Desktop.
Save k0nze/e97d9d2230a11e2f61e1844ccbed9a3e to your computer and use it in GitHub Desktop.
OpenGL ES 2.0 RPi 3 texture attempt
// compile with:
// gcc texture.c -o texture -lEGL -lX11 -lGLESv2
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define GL_CHECK(x) \
x; \
{ \
GLenum glError = glGetError(); \
if(glError != GL_NO_ERROR) { \
printf("glGetError() = %i (0x%.8x) at %s:%i\n", glError, glError, __FILE__, __LINE__); \
exit(1); \
} \
}
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
static const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
static const EGLint config_attribs[] = {
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_NONE
};
static const EGLint pbufferAttribs[] = {
EGL_WIDTH, 9, EGL_HEIGHT, 9, EGL_NONE,
};
int main(int argc, char **argv) {
printf("start texture\n");
int i;
int texSize = 2;
EGLint major, minor;
EGLDisplay eglDisplay;
EGLContext eglContext;
EGLSurface eglSurface;
EGLConfig eglConfig;
EGLint eglConfigCount;
Display *dpy = NULL;
char *dpyName = NULL;
Window window;
// open display
dpy = XOpenDisplay (dpyName);
if(!dpy) {
fprintf (stderr, "\nERROR: could not open display\n");
exit (1);
}
// create window
window = XCreateSimpleWindow(dpy, RootWindow (dpy, DefaultScreen (dpy)), 1, 1, WINDOW_WIDTH, WINDOW_HEIGHT, 0, BlackPixel (dpy,DefaultScreen(dpy)), BlackPixel (dpy, DefaultScreen (dpy)));
XStoreName(dpy, window, "texture");
XMapWindow(dpy, window);
// move window to upper left corner
XMoveWindow(dpy, window, 0, 0);
XSync(dpy, 0);
// setup egl
eglDisplay = eglGetDisplay(dpy);
if(!eglInitialize(eglDisplay, &major, &minor)) {
fprintf(stderr, "\nError: failed to initialize EGL\n");
exit(1);
}
printf("Display used %p & EGL versions are %d.%d\n", eglDisplay, major, minor);
printf("EGL version: %s\n", eglQueryString(eglDisplay, EGL_VERSION));
printf("EGL vendor: %s\n", eglQueryString(eglDisplay, EGL_VENDOR));
if(!eglChooseConfig(eglDisplay, config_attribs, &eglConfig, 1, &eglConfigCount)) {
fprintf(stderr, "\nError: could not get an EGL visual config\n");
exit(1);
}
assert(eglConfig);
assert(eglConfigCount > 0);
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
if(!eglBindAPI(EGL_OPENGL_ES_API)) {
fprintf (stderr, "\nError: failed to bind api EGL_OPENGL_ES_API\n");
exit(1);
}
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, NULL);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
// check OpenGL vendor
printf("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
// check OpenGL vendor
printf("OpenGL vendor: %s\n", glGetString(GL_RENDERER));
// check of OpenGL version
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
// check for OpenGL extensions
//printf("OpenGL extensions: %s\n", glGetString(GL_EXTENSIONS));
uint8_t* data = (uint8_t*) malloc(4*texSize*texSize*sizeof(uint8_t));
uint8_t* result = (uint8_t*) malloc(4*texSize*texSize*sizeof(uint8_t));
// fill data
for(i = 0; i < texSize*texSize*4; i++) {
data[i] = i;
result[i] = 0;
}
// create framebuffer and bind it (that is used as offscreen render target)
GLuint fb;
GL_CHECK(glGenFramebuffers(1, &fb));
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, fb));
// create texture
GLuint tex;
GL_CHECK(glGenTextures(1, &tex));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, tex));
// set texture parameters
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
// define texture with RGBA format with 8Bit (GL_UNSIGNED_BYTE)
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
// attach texture
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0));
// transfer data to texture
GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texSize, texSize, GL_RGBA, GL_UNSIGNED_BYTE, data));
// check if framebuffer is complete
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
fprintf (stderr, "\nError: framebuffer not complete\n");
exit(1);
}
// read back texture into result
GL_CHECK(glReadPixels(0, 0, texSize, texSize, GL_RGBA, GL_UNSIGNED_BYTE, result));
// print data and result
printf("data, result:\n");
for(i = 0; i < texSize*texSize*4; i++) {
printf("%d, %d\n", data[i], result[i]);
}
// clean up
free(data);
free(result);
GL_CHECK(glDeleteFramebuffers(1, &fb));
eglBindAPI(EGL_OPENGL_ES_API);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext);
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(eglDisplay, eglContext);
eglDestroySurface(eglDisplay, eglSurface);
eglTerminate(dpy);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment