Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <png.h>
- #include <gbm.h>
- #include <epoxy/gl.h>
- #include <epoxy/egl.h>
- GLuint program;
- EGLDisplay display;
- EGLSurface surface;
- EGLContext context;
- struct gbm_device *gbm;
- struct gbm_surface *gs;
- #define TARGET_SIZE 256
- void eglCheckError(const char *stmt, const char *fname, int line) {
- EGLint err = eglGetError();
- if (err != EGL_SUCCESS)
- printf("EGL ERROR (0x%08x): %s failed at %s:%i\n", err, stmt, fname, line);
- }
- #define EGL_CHECK(stmt) do { \
- stmt; \
- eglCheckError(#stmt, __FILE__, __LINE__); \
- } while (0)
- EGLConfig get_config(void)
- {
- EGLint egl_config_attribs[] = {
- EGL_BUFFER_SIZE, 32,
- EGL_DEPTH_SIZE, EGL_DONT_CARE,
- EGL_STENCIL_SIZE, EGL_DONT_CARE,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE,
- };
- EGLint num_configs;
- assert(eglGetConfigs(display, NULL, 0, &num_configs) == EGL_TRUE);
- EGLConfig *configs = malloc(num_configs * sizeof(EGLConfig));
- assert(eglChooseConfig(display, egl_config_attribs,
- configs, num_configs, &num_configs) == EGL_TRUE);
- assert(num_configs);
- printf("num config %d\n", num_configs);
- // Find a config whose native visual ID is the desired GBM format.
- for (int i = 0; i < num_configs; ++i) {
- EGLint gbm_format;
- assert(eglGetConfigAttrib(display, configs[i],
- EGL_NATIVE_VISUAL_ID, &gbm_format) == EGL_TRUE);
- printf("gbm format %x\n", gbm_format);
- if (gbm_format == GBM_FORMAT_XRGB8888) {
- printf("GBM_FORMAT_XRGB8888 match!\n");
- EGLConfig ret = configs[i];
- free(configs);
- return ret;
- }
- }
- // Failed to find a config with matching GBM format.
- printf("no matching GBM config found!\n");
- abort();
- }
- void RenderTargetInit(void)
- {
- assert(epoxy_has_egl());
- assert(epoxy_has_egl_extension(EGL_NO_DISPLAY, "EGL_KHR_platform_gbm"));
- int fd = open("/dev/dri/card0", O_RDWR);
- assert(fd >= 0);
- gbm = gbm_create_device(fd);
- assert(gbm != NULL);
- assert((display = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, gbm, NULL)) != EGL_NO_DISPLAY);
- EGLint majorVersion;
- EGLint minorVersion;
- assert(eglInitialize(display, &majorVersion, &minorVersion) == EGL_TRUE);
- printf("EGL Version: %s\n", eglQueryString(display, EGL_VERSION));
- printf("EGL Vendor: %s\n", eglQueryString(display, EGL_VENDOR));
- printf("EGL Extensions: %s\n", eglQueryString(display, EGL_EXTENSIONS));
- printf("EGL APIs: %s\n", eglQueryString(display, EGL_CLIENT_APIS));
- assert(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
- EGLConfig config = get_config();
- gs = gbm_surface_create(
- gbm, TARGET_SIZE, TARGET_SIZE, GBM_FORMAT_XRGB8888,
- GBM_BO_USE_SCANOUT|GBM_BO_USE_RENDERING);
- assert(gs);
- EGL_CHECK((surface = eglCreatePlatformWindowSurfaceEXT(display, config, gs, NULL)) != EGL_NO_SURFACE);
- // assert((surface = eglCreatePlatformWindowSurfaceEXT(display, config, gs, NULL)) != EGL_NO_SURFACE);
- const EGLint contextAttribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
- EGL_CHECK((context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)) != EGL_NO_CONTEXT);
- // assert((context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)) != EGL_NO_CONTEXT);
- assert(eglMakeCurrent(display, surface, surface, context) == EGL_TRUE);
- }
- GLuint LoadShader(const char *name, GLenum type)
- {
- FILE *f;
- int size;
- char *buff;
- GLuint shader;
- GLint compiled;
- const GLchar *source[1];
- assert((f = fopen(name, "r")) != NULL);
- // get file size
- fseek(f, 0, SEEK_END);
- size = ftell(f);
- fseek(f, 0, SEEK_SET);
- assert((buff = malloc(size)) != NULL);
- assert(fread(buff, 1, size, f) == size);
- source[0] = buff;
- fclose(f);
- shader = glCreateShader(type);
- glShaderSource(shader, 1, source, &size);
- glCompileShader(shader);
- free(buff);
- glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
- if (!compiled) {
- GLint infoLen = 0;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
- if (infoLen > 1) {
- char *infoLog = malloc(infoLen);
- glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
- fprintf(stderr, "Error compiling shader %s:\n%s\n", name, infoLog);
- free(infoLog);
- }
- glDeleteShader(shader);
- return 0;
- }
- return shader;
- }
- void InitGLES(void)
- {
- GLint linked;
- GLuint vertexShader;
- GLuint fragmentShader;
- assert((vertexShader = LoadShader("vert.glsl", GL_VERTEX_SHADER)) != 0);
- assert((fragmentShader = LoadShader("frag.glsl", GL_FRAGMENT_SHADER)) != 0);
- assert((program = glCreateProgram()) != 0);
- glAttachShader(program, vertexShader);
- glAttachShader(program, fragmentShader);
- glLinkProgram(program);
- glGetProgramiv(program, GL_LINK_STATUS, &linked);
- if (!linked) {
- GLint infoLen = 0;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
- if (infoLen > 1) {
- char *infoLog = malloc(infoLen);
- glGetProgramInfoLog(program, infoLen, NULL, infoLog);
- fprintf(stderr, "Error linking program:\n%s\n", infoLog);
- free(infoLog);
- }
- glDeleteProgram(program);
- exit(1);
- }
- glClearColor(0, 0, 0, 0);
- glViewport(0, 0, TARGET_SIZE, TARGET_SIZE);
- //glEnable(GL_DEPTH_TEST);
- glUseProgram(program);
- }
- void *readImage(char *filename, int *width, int *height)
- {
- char header[8]; // 8 is the maximum size that can be checked
- /* open file and test for it being a png */
- FILE *fp = fopen(filename, "rb");
- assert(fp);
- fread(header, 1, 8, fp);
- assert(!png_sig_cmp(header, 0, 8));
- /* initialize stuff */
- png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- assert(png_ptr);
- png_infop info_ptr = png_create_info_struct(png_ptr);
- assert(info_ptr);
- assert(!setjmp(png_jmpbuf(png_ptr)));
- png_init_io(png_ptr, fp);
- png_set_sig_bytes(png_ptr, 8);
- png_read_info(png_ptr, info_ptr);
- *width = png_get_image_width(png_ptr, info_ptr);
- *height = png_get_image_height(png_ptr, info_ptr);
- int color_type = png_get_color_type(png_ptr, info_ptr);
- assert(color_type == PNG_COLOR_TYPE_RGB);
- int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
- assert(bit_depth == 8);
- int pitch = png_get_rowbytes(png_ptr, info_ptr);
- int number_of_passes = png_set_interlace_handling(png_ptr);
- png_read_update_info(png_ptr, info_ptr);
- /* read file */
- assert(!setjmp(png_jmpbuf(png_ptr)));
- png_bytep buffer = malloc(*height * pitch);
- void *ret = buffer;
- assert(buffer);
- png_bytep *row_pointers = malloc(sizeof(png_bytep) * *height);
- assert(row_pointers);
- for (int i = 0; i < *height; i++) {
- row_pointers[i] = buffer;
- buffer += pitch;
- }
- png_read_image(png_ptr, row_pointers);
- fclose(fp);
- free(row_pointers);
- return ret;
- }
- int writeImage(char* filename, int width, int height, void *buffer, char* title)
- {
- int code = 0;
- FILE *fp = NULL;
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
- // Open file for writing (binary mode)
- fp = fopen(filename, "wb");
- if (fp == NULL) {
- fprintf(stderr, "Could not open file %s for writing\n", filename);
- code = 1;
- goto finalise;
- }
- // Initialize write structure
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (png_ptr == NULL) {
- fprintf(stderr, "Could not allocate write struct\n");
- code = 1;
- goto finalise;
- }
- // Initialize info structure
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- fprintf(stderr, "Could not allocate info struct\n");
- code = 1;
- goto finalise;
- }
- // Setup Exception handling
- if (setjmp(png_jmpbuf(png_ptr))) {
- fprintf(stderr, "Error during png creation\n");
- code = 1;
- goto finalise;
- }
- png_init_io(png_ptr, fp);
- // Write header (8 bit colour depth)
- png_set_IHDR(png_ptr, info_ptr, width, height,
- 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
- // Set title
- if (title != NULL) {
- png_text title_text;
- title_text.compression = PNG_TEXT_COMPRESSION_NONE;
- title_text.key = "Title";
- title_text.text = title;
- png_set_text(png_ptr, info_ptr, &title_text, 1);
- }
- png_write_info(png_ptr, info_ptr);
- // Write image data
- int i;
- for (i = 0; i < height; i++)
- png_write_row(png_ptr, (png_bytep)buffer + i * width * 4);
- // End write
- png_write_end(png_ptr, NULL);
- finalise:
- if (fp != NULL) fclose(fp);
- if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
- if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- return code;
- }
- void Render(void)
- {
- int w, h;
- void *data = readImage("crate-base-2048x2048.png", &w, &h);
- glActiveTexture(GL_TEXTURE0);
- GLuint texid = 0;
- glGenTextures(1, &texid);
- glBindTexture(GL_TEXTURE_2D, texid);
- 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_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
- GLenum err = glGetError();
- printf("err: %.4x\n", err);
- assert(err == GL_NO_ERROR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
- //for (int i = 0; i < 6; i++) {
- // glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
- //}
- glGenerateMipmap(GL_TEXTURE_2D);
- GLfloat vertex[] = {
- -1, -1, 0,
- -1, 1, 0,
- 1, 1, 0,
- 1, -1, 0
- };
- GLfloat tex[] = {
- 1, 1, // 0,
- 1, 0, // 0,
- 0, 0, // 0,
- 0, 1, // 0,
- };
- GLint position = glGetAttribLocation(program, "positionIn");
- glEnableVertexAttribArray(position);
- glVertexAttribPointer(position, 3, GL_FLOAT, 0, 0, vertex);
- GLint texIn = glGetAttribLocation(program, "texIn");
- glEnableVertexAttribArray(texIn);
- glVertexAttribPointer(texIn, 2, GL_FLOAT, 0, 0, tex);
- GLint sample = glGetUniformLocation(program, "tex");
- glUniform1i(sample, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- err = glGetError();
- printf("err: %.4x\n", err);
- assert(err == GL_NO_ERROR);
- eglSwapBuffers(display, surface);
- #if 1
- GLubyte result[TARGET_SIZE * TARGET_SIZE * 4] = {0};
- glReadPixels(0, 0, TARGET_SIZE, TARGET_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, result);
- err = glGetError();
- printf("err: %.4x\n", err);
- //assert(err == GL_NO_ERROR);
- #else
- struct gbm_bo *bo = gbm_surface_lock_front_buffer(gs);
- assert(bo);
- uint32_t stride;
- void *map_data;
- GLubyte *result = gbm_bo_map(bo, 0, 0, TARGET_SIZE, TARGET_SIZE,
- GBM_BO_TRANSFER_READ, &stride, &map_data);
- assert(result);
- assert(stride == TARGET_SIZE * 4);
- #endif
- assert(!writeImage("screenshot.png", TARGET_SIZE, TARGET_SIZE, result, "hello"));
- }
- int main(void)
- {
- RenderTargetInit();
- InitGLES();
- Render();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement