Created
January 7, 2018 09:44
-
-
Save k0nze/e97d9d2230a11e2f61e1844ccbed9a3e to your computer and use it in GitHub Desktop.
OpenGL ES 2.0 RPi 3 texture attempt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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