123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- #include <assert.h>
- #include "test-util-3d.h"
- #define STB_IMAGE_IMPLEMENTATION
- #include "stb_image.h"
- static EGLint const config_attribute_list[] = {
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_DEPTH_SIZE, 8,
- EGL_NONE
- };
- static const EGLint context_attribute_list[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
- static EGLDisplay display;
- static EGLConfig config;
- static EGLint num_config;
- static EGLContext context;
- static GLuint program;
- const char *vertex_shader_source =
- "attribute vec4 aPosition; \n"
- "attribute vec4 aColor; \n"
- "uniform sampler2D depthMap; \n"
- "uniform float angle;\n"
- " \n"
- "varying vec4 vColor; \n"
- " \n"
- "void main() \n"
- "{ \n"
- " vColor = aColor * vec4(8.02, 1.18, 1, 1); \n"
- " float x = aPosition.x;\n"
- " float y = aPosition.y;\n"
- " float z = texture2D(depthMap, vColor.xy).r;"
- " gl_Position = vec4(x, cos(angle)*y - sin(angle)*z, 1.0, 1.0); \n"
- "} \n";
- const char *fragment_shader_source =
- "precision mediump float; \n"
- " \n"
- "varying vec4 vColor; \n"
- "uniform sampler2D uTexture; \n"
- "uniform sampler2D depthMap; \n"
- " \n"
- "void main() \n"
- "{ \n"
- " gl_FragColor = texture2D(uTexture, vColor.xy); \n"
- "} \n";
- struct forward_grid {
- int width, height;
- GLfloat *vVertices;
- GLfloat *vColors;
- unsigned short *indices;
- };
- static struct forward_grid
- generate_grid(int N)
- {
- struct forward_grid grid = {
- .width = N,
- .height = N
- };
-
- grid.vVertices = calloc(N * N * 3, sizeof(GLfloat));
- grid.vColors = calloc(N * N * 4, sizeof(GLfloat));
- grid.indices = calloc(N * N * 6, sizeof(*grid.indices));
-
- assert(N < 128);
-
- float step_size = (2.0) / ((float) (N - 1));
- for (int step_y = 0; step_y < N; ++step_y) {
- float y = step_y * step_size - 0.7f;
- for (int step_x = 0; step_x < N; ++step_x) {
- float x = step_x * step_size - 0.7f;
-
- int vertex_number = step_y*N + step_x;
- grid.vVertices[vertex_number*3 + 0] = x;
- grid.vVertices[vertex_number*3 + 1] = y;
-
- grid.vColors[vertex_number*4 + 0] = ((float) step_x) / (N - 1);
- grid.vColors[vertex_number*4 + 1] = ((float) step_y) / (N - 1);
- }
- }
-
- int index_start = 0;
- for (int y = 0; y < (N - 1); ++y) {
- for (int x = 0; x < (N - 1); ++x) {
-
- grid.indices[index_start + 0] = (y + 0)*N + (x + 0);
- grid.indices[index_start + 1] = (y + 0)*N + (x + 1);
- grid.indices[index_start + 2] = (y + 1)*N + (x + 0);
-
- grid.indices[index_start + 3] = (y + 1)*N + (x + 1);
- grid.indices[index_start + 4] = (y + 0)*N + (x + 1);
- grid.indices[index_start + 5] = (y + 1)*N + (x + 0);
-
- index_start += 6;
- }
- }
-
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, grid.vVertices);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, grid.vColors);
- glEnableVertexAttribArray(1);
- return grid;
- }
- static void
- draw_grid(struct forward_grid *grid)
- {
-
- glDrawElements(GL_TRIANGLES, 3 * 2 * grid->width * grid->height, GL_UNSIGNED_SHORT, grid->indices);
- }
- struct image {
- uint8_t *data;
- int width;
- int height;
- int n;
- };
- static void
- init_texture(struct image *img, int number)
- {
- GLuint textures[2], texture_handle;
- glGenTextures(1, &textures);
- glActiveTexture(GL_TEXTURE0 + number);
- glBindTexture(GL_TEXTURE_2D, textures[0]);
- int mode = (img->n == 4) ? GL_RGBA : GL_LUMINANCE;
- glTexImage2D(
- GL_TEXTURE_2D, 0, mode,
- img->width, img->height, 0,
- mode, GL_UNSIGNED_BYTE, img->data);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- texture_handle = glGetUniformLocation(program, number ? "depthMap" : "uTexture");
- glUniform1i(texture_handle, number);
- }
- static int
- count_pixels(struct image *img, int start_x, int start_y)
- {
- int distance = 0;
- uint32_t *data32 = (uint32_t *) img->data;
-
- for (int x = start_x; x < img->width; ++x) {
- uint32_t color = data32[start_y * img->width + x];
- uint8_t alpha = color >> 24;
-
- if (alpha == 0) break;
- ++distance;
- }
- return distance;
- }
- #define MIN(a,b) ((a>b)?(b):(a))
- static struct image
- generate_depth_map(struct image *src, int start_x, int start_y)
- {
-
- struct image dst = {
- .data = calloc(src->width * src->height, 4),
- .width = src->width,
- .height = src->height,
- .n = 4,
- };
- int *lengths = malloc(sizeof(int) * src->height);
-
- for (int y = 0; y < src->height; ++y) {
- lengths[y] = count_pixels(src, start_x, y);
- }
-
- uint32_t *data32 = (uint32_t *) dst.data;
- for (int y = 0; y < dst.height; ++y) {
- for (int x = 0; x < dst.width; ++x) {
- float length = lengths[y];
- float coord = x - start_x;
- float depth_det = length*length - coord*coord;
-
- uint8_t udepth = 0;
-
- if (depth_det >= 0) {
- float depth = sqrtf(depth_det);
- int d = depth * 4;
- data32[(y * dst.width) + x] = MIN(d, 255);
- }
- }
- }
- return dst;
- }
- int main()
- {
- GLint width, height;
- EGLSurface surface;
- display = get_display();
-
- eglChooseConfig(display, config_attribute_list, &config, 1, &num_config);
-
- context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list);
- surface = make_window(display, config, 2048, 1280);
- eglQuerySurface(display, surface, EGL_WIDTH, &width);
- eglQuerySurface(display, surface, EGL_HEIGHT, &height);
-
- eglMakeCurrent(display, surface, surface, context);
- program = get_program(vertex_shader_source, fragment_shader_source);
- glBindAttribLocation(program, 0, "aPosition");
- glBindAttribLocation(program, 1, "aColor");
- link_program(program);
- glViewport(0, 0, width, height);
-
- struct image img;
- img.data = stbi_load("pencil.png", &img.width, &img.height, &img.n, 0);
- assert(img.data != NULL);
- assert(img.n == 4);
-
- int start_x = img.width >> 1;
- int start_y = 0;
- struct image depth_map = generate_depth_map(&img, start_x, start_y);
- init_texture(&img, 0);
- init_texture(&depth_map, 1);
-
- stbi_image_free(img.data);
-
- struct forward_grid grid = generate_grid(127);
-
- int u_angle = glGetUniformLocation(program, "angle");
- float angle = 0.0f;
- for (;;) {
- glClearColor(0.5, 0.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
- glUniform1f(u_angle, angle);
- draw_grid(&grid);
- eglSwapBuffers(display, surface);
- glFlush();
- angle += (3.14159f/180.0f);
- }
- eglDestroySurface(display, surface);
- eglTerminate(display);
- return 0;
- }
|