Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.06 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4.  
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7.  
  8. #include <png.h>
  9. #include <gbm.h>
  10.  
  11. #include <epoxy/gl.h>
  12. #include <epoxy/egl.h>
  13.  
  14. GLuint program;
  15. EGLDisplay display;
  16. EGLSurface surface;
  17. EGLContext context;
  18. struct gbm_device *gbm;
  19. struct gbm_surface *gs;
  20.  
  21. #define TARGET_SIZE 256
  22.  
  23. void eglCheckError(const char *stmt, const char *fname, int line) {
  24.     EGLint err = eglGetError();
  25.     if (err != EGL_SUCCESS)
  26.         printf("EGL ERROR (0x%08x): %s failed at %s:%i\n", err, stmt, fname, line);
  27. }
  28.  
  29. #define EGL_CHECK(stmt) do { \
  30.     stmt; \
  31.     eglCheckError(#stmt, __FILE__, __LINE__); \
  32.     } while (0)
  33.  
  34. EGLConfig get_config(void)
  35. {
  36.     EGLint egl_config_attribs[] = {
  37.         EGL_BUFFER_SIZE,    32,
  38.         EGL_DEPTH_SIZE,     EGL_DONT_CARE,
  39.         EGL_STENCIL_SIZE,   EGL_DONT_CARE,
  40.         EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
  41.         EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
  42.         EGL_NONE,
  43.     };
  44.  
  45.     EGLint num_configs;
  46.     assert(eglGetConfigs(display, NULL, 0, &num_configs) == EGL_TRUE);
  47.  
  48.     EGLConfig *configs = malloc(num_configs * sizeof(EGLConfig));
  49.     assert(eglChooseConfig(display, egl_config_attribs,
  50.                    configs, num_configs, &num_configs) == EGL_TRUE);
  51.     assert(num_configs);
  52.     printf("num config %d\n", num_configs);
  53.  
  54.     // Find a config whose native visual ID is the desired GBM format.
  55.     for (int i = 0; i < num_configs; ++i) {
  56.         EGLint gbm_format;
  57.  
  58.         assert(eglGetConfigAttrib(display, configs[i],
  59.                       EGL_NATIVE_VISUAL_ID, &gbm_format) == EGL_TRUE);
  60.         printf("gbm format %x\n", gbm_format);
  61.  
  62.         if (gbm_format == GBM_FORMAT_XRGB8888) {
  63.             printf("GBM_FORMAT_XRGB8888 match!\n");
  64.             EGLConfig ret = configs[i];
  65.             free(configs);
  66.             return ret;
  67.         }
  68.     }
  69.  
  70.     // Failed to find a config with matching GBM format.
  71.     printf("no matching GBM config found!\n");
  72.     abort();
  73. }
  74.  
  75. void RenderTargetInit(void)
  76. {
  77.     assert(epoxy_has_egl());
  78.     assert(epoxy_has_egl_extension(EGL_NO_DISPLAY, "EGL_KHR_platform_gbm"));
  79.  
  80.     int fd = open("/dev/dri/card0", O_RDWR);
  81.     assert(fd >= 0);
  82.  
  83.     gbm = gbm_create_device(fd);
  84.     assert(gbm != NULL);
  85.  
  86.     assert((display = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, gbm, NULL)) != EGL_NO_DISPLAY);
  87.  
  88.     EGLint majorVersion;
  89.     EGLint minorVersion;
  90.     assert(eglInitialize(display, &majorVersion, &minorVersion) == EGL_TRUE);
  91.  
  92.     printf("EGL Version: %s\n", eglQueryString(display, EGL_VERSION));
  93.     printf("EGL Vendor: %s\n", eglQueryString(display, EGL_VENDOR));
  94.     printf("EGL Extensions: %s\n", eglQueryString(display, EGL_EXTENSIONS));
  95.     printf("EGL APIs: %s\n", eglQueryString(display, EGL_CLIENT_APIS));
  96.  
  97.     assert(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
  98.  
  99.     EGLConfig config = get_config();
  100.  
  101.     gs = gbm_surface_create(
  102.         gbm, TARGET_SIZE, TARGET_SIZE, GBM_FORMAT_XRGB8888,
  103.         GBM_BO_USE_SCANOUT|GBM_BO_USE_RENDERING);
  104.     assert(gs);
  105.  
  106.     EGL_CHECK((surface = eglCreatePlatformWindowSurfaceEXT(display, config, gs, NULL)) != EGL_NO_SURFACE);
  107. //  assert((surface = eglCreatePlatformWindowSurfaceEXT(display, config, gs, NULL)) != EGL_NO_SURFACE);
  108.  
  109.     const EGLint contextAttribs[] = {
  110.         EGL_CONTEXT_CLIENT_VERSION, 2,
  111.         EGL_NONE
  112.     };
  113.     EGL_CHECK((context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)) != EGL_NO_CONTEXT);
  114. //  assert((context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)) != EGL_NO_CONTEXT);
  115.  
  116.     assert(eglMakeCurrent(display, surface, surface, context) == EGL_TRUE);
  117. }
  118.  
  119. GLuint LoadShader(const char *name, GLenum type)
  120. {
  121.     FILE *f;
  122.     int size;
  123.     char *buff;
  124.     GLuint shader;
  125.     GLint compiled;
  126.     const GLchar *source[1];
  127.  
  128.     assert((f = fopen(name, "r")) != NULL);
  129.  
  130.     // get file size
  131.     fseek(f, 0, SEEK_END);
  132.     size = ftell(f);
  133.     fseek(f, 0, SEEK_SET);
  134.  
  135.     assert((buff = malloc(size)) != NULL);
  136.     assert(fread(buff, 1, size, f) == size);
  137.     source[0] = buff;
  138.     fclose(f);
  139.     shader = glCreateShader(type);
  140.     glShaderSource(shader, 1, source, &size);
  141.     glCompileShader(shader);
  142.     free(buff);
  143.     glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  144.     if (!compiled) {
  145.         GLint infoLen = 0;
  146.         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
  147.         if (infoLen > 1) {
  148.             char *infoLog = malloc(infoLen);
  149.             glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
  150.             fprintf(stderr, "Error compiling shader %s:\n%s\n", name, infoLog);
  151.             free(infoLog);
  152.         }
  153.         glDeleteShader(shader);
  154.         return 0;
  155.     }
  156.  
  157.     return shader;
  158. }
  159.  
  160. void InitGLES(void)
  161. {
  162.     GLint linked;
  163.     GLuint vertexShader;
  164.     GLuint fragmentShader;
  165.     assert((vertexShader = LoadShader("vert.glsl", GL_VERTEX_SHADER)) != 0);
  166.     assert((fragmentShader = LoadShader("frag.glsl", GL_FRAGMENT_SHADER)) != 0);
  167.     assert((program = glCreateProgram()) != 0);
  168.     glAttachShader(program, vertexShader);
  169.     glAttachShader(program, fragmentShader);
  170.     glLinkProgram(program);
  171.     glGetProgramiv(program, GL_LINK_STATUS, &linked);
  172.     if (!linked) {
  173.         GLint infoLen = 0;
  174.         glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
  175.         if (infoLen > 1) {
  176.             char *infoLog = malloc(infoLen);
  177.             glGetProgramInfoLog(program, infoLen, NULL, infoLog);
  178.             fprintf(stderr, "Error linking program:\n%s\n", infoLog);
  179.             free(infoLog);
  180.         }
  181.         glDeleteProgram(program);
  182.         exit(1);
  183.     }
  184.  
  185.     glClearColor(0, 0, 0, 0);
  186.     glViewport(0, 0, TARGET_SIZE, TARGET_SIZE);
  187.     //glEnable(GL_DEPTH_TEST);
  188.  
  189.     glUseProgram(program);
  190. }
  191.  
  192. void *readImage(char *filename, int *width, int *height)
  193. {
  194.     char header[8];    // 8 is the maximum size that can be checked
  195.  
  196.         /* open file and test for it being a png */
  197.         FILE *fp = fopen(filename, "rb");
  198.     assert(fp);
  199.         fread(header, 1, 8, fp);
  200.         assert(!png_sig_cmp(header, 0, 8));
  201.  
  202.         /* initialize stuff */
  203.         png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  204.     assert(png_ptr);
  205.  
  206.         png_infop info_ptr = png_create_info_struct(png_ptr);
  207.     assert(info_ptr);
  208.  
  209.         assert(!setjmp(png_jmpbuf(png_ptr)));
  210.  
  211.         png_init_io(png_ptr, fp);
  212.         png_set_sig_bytes(png_ptr, 8);
  213.  
  214.         png_read_info(png_ptr, info_ptr);
  215.  
  216.         *width = png_get_image_width(png_ptr, info_ptr);
  217.         *height = png_get_image_height(png_ptr, info_ptr);
  218.         int color_type = png_get_color_type(png_ptr, info_ptr);
  219.     assert(color_type == PNG_COLOR_TYPE_RGB);
  220.         int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  221.     assert(bit_depth == 8);
  222.     int pitch = png_get_rowbytes(png_ptr, info_ptr);
  223.  
  224.         int number_of_passes = png_set_interlace_handling(png_ptr);
  225.         png_read_update_info(png_ptr, info_ptr);
  226.  
  227.         /* read file */
  228.         assert(!setjmp(png_jmpbuf(png_ptr)));
  229.  
  230.     png_bytep buffer = malloc(*height * pitch);
  231.     void *ret = buffer;
  232.     assert(buffer);
  233.         png_bytep *row_pointers = malloc(sizeof(png_bytep) * *height);
  234.     assert(row_pointers);
  235.         for (int i = 0; i < *height; i++) {
  236.                 row_pointers[i] = buffer;
  237.         buffer += pitch;
  238.     }
  239.  
  240.         png_read_image(png_ptr, row_pointers);
  241.  
  242.         fclose(fp);
  243.     free(row_pointers);
  244.     return ret;
  245. }
  246.  
  247. int writeImage(char* filename, int width, int height, void *buffer, char* title)
  248. {
  249.     int code = 0;
  250.     FILE *fp = NULL;
  251.     png_structp png_ptr = NULL;
  252.     png_infop info_ptr = NULL;
  253.  
  254.     // Open file for writing (binary mode)
  255.     fp = fopen(filename, "wb");
  256.     if (fp == NULL) {
  257.         fprintf(stderr, "Could not open file %s for writing\n", filename);
  258.         code = 1;
  259.         goto finalise;
  260.     }
  261.  
  262.     // Initialize write structure
  263.     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  264.     if (png_ptr == NULL) {
  265.         fprintf(stderr, "Could not allocate write struct\n");
  266.         code = 1;
  267.         goto finalise;
  268.     }
  269.  
  270.     // Initialize info structure
  271.     info_ptr = png_create_info_struct(png_ptr);
  272.     if (info_ptr == NULL) {
  273.         fprintf(stderr, "Could not allocate info struct\n");
  274.         code = 1;
  275.         goto finalise;
  276.     }
  277.  
  278.     // Setup Exception handling
  279.     if (setjmp(png_jmpbuf(png_ptr))) {
  280.         fprintf(stderr, "Error during png creation\n");
  281.         code = 1;
  282.         goto finalise;
  283.     }
  284.  
  285.     png_init_io(png_ptr, fp);
  286.  
  287.     // Write header (8 bit colour depth)
  288.     png_set_IHDR(png_ptr, info_ptr, width, height,
  289.              8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
  290.              PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
  291.  
  292.     // Set title
  293.     if (title != NULL) {
  294.         png_text title_text;
  295.         title_text.compression = PNG_TEXT_COMPRESSION_NONE;
  296.         title_text.key = "Title";
  297.         title_text.text = title;
  298.         png_set_text(png_ptr, info_ptr, &title_text, 1);
  299.     }
  300.  
  301.     png_write_info(png_ptr, info_ptr);
  302.  
  303.     // Write image data
  304.     int i;
  305.     for (i = 0; i < height; i++)
  306.         png_write_row(png_ptr, (png_bytep)buffer + i * width * 4);
  307.  
  308.     // End write
  309.     png_write_end(png_ptr, NULL);
  310.  
  311. finalise:
  312.     if (fp != NULL) fclose(fp);
  313.     if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
  314.     if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
  315.  
  316.     return code;
  317. }
  318.  
  319. void Render(void)
  320. {
  321.     int w, h;
  322.     void *data = readImage("crate-base-2048x2048.png", &w, &h);
  323.  
  324.     glActiveTexture(GL_TEXTURE0);
  325.  
  326.     GLuint texid = 0;
  327.         glGenTextures(1, &texid);
  328.     glBindTexture(GL_TEXTURE_2D, texid);
  329.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  330.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  331.     //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  332.     GLenum err = glGetError();
  333.     printf("err: %.4x\n", err);
  334.     assert(err == GL_NO_ERROR);
  335.  
  336.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  337.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  338.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  339.         //for (int i = 0; i < 6; i++) {
  340.         //    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
  341.         //}
  342.     glGenerateMipmap(GL_TEXTURE_2D);
  343.  
  344.     GLfloat vertex[] = {
  345.         -1, -1, 0,
  346.         -1, 1, 0,
  347.         1, 1, 0,
  348.         1, -1, 0
  349.     };
  350.         GLfloat tex[] = {
  351.         1, 1, // 0,
  352.         1, 0, // 0,
  353.         0, 0, // 0,
  354.         0, 1, // 0,
  355.     };
  356.  
  357.     GLint position = glGetAttribLocation(program, "positionIn");
  358.     glEnableVertexAttribArray(position);
  359.     glVertexAttribPointer(position, 3, GL_FLOAT, 0, 0, vertex);
  360.  
  361.     GLint texIn = glGetAttribLocation(program, "texIn");
  362.     glEnableVertexAttribArray(texIn);
  363.     glVertexAttribPointer(texIn, 2, GL_FLOAT, 0, 0, tex);
  364.  
  365.     GLint sample = glGetUniformLocation(program, "tex");
  366.     glUniform1i(sample, 0);
  367.  
  368.     glClear(GL_COLOR_BUFFER_BIT);
  369.  
  370.     glDrawArrays(GL_TRIANGLES, 0, 3);
  371.  
  372.     err = glGetError();
  373.     printf("err: %.4x\n", err);
  374.     assert(err == GL_NO_ERROR);
  375.  
  376.     eglSwapBuffers(display, surface);
  377.  
  378. #if 1
  379.     GLubyte result[TARGET_SIZE * TARGET_SIZE * 4] = {0};
  380.     glReadPixels(0, 0, TARGET_SIZE, TARGET_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, result);
  381.     err = glGetError();
  382.     printf("err: %.4x\n", err);
  383.     //assert(err == GL_NO_ERROR);
  384. #else
  385.     struct gbm_bo *bo = gbm_surface_lock_front_buffer(gs);
  386.     assert(bo);
  387.  
  388.     uint32_t stride;
  389.     void *map_data;
  390.     GLubyte *result = gbm_bo_map(bo, 0, 0, TARGET_SIZE, TARGET_SIZE,
  391.                      GBM_BO_TRANSFER_READ, &stride, &map_data);
  392.     assert(result);
  393.     assert(stride == TARGET_SIZE * 4);
  394. #endif
  395.  
  396.     assert(!writeImage("screenshot.png", TARGET_SIZE, TARGET_SIZE, result, "hello"));
  397. }
  398.  
  399. int main(void)
  400. {
  401.     RenderTargetInit();
  402.     InitGLES();
  403.     Render();
  404.     return 0;
  405. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement