void draw() { DMatrix4 view, projection; parg_zcam_dmatrices(&projection, &view); DMatrix4 model = DM4MakeTranslation((DVector3){-0.5, -0.5, -1}); Matrix4 mvp = M4MakeFromDM4(DM4Mul(projection, DM4Mul(view, model))); const Vector4 BLACK = {0, 0, 0, 1}; Vector2 mapsize = {1, 1}; parg_aar rect = parg_zcam_get_rectangle(); parg_tilerange tiles; float slippyfract = parg_aar_to_tilerange(rect, mapsize, &tiles); parg_aar slippyaar = parg_aar_from_tilename(tiles.mintile, mapsize); Vector4* slippybox = (Vector4*) &slippyaar; slippybox->z = 1.0 / (slippybox->z - slippybox->x); slippybox->w = 1.0 / (slippybox->w - slippybox->y); parg_draw_clear(); parg_shader_bind(P_OCEAN); parg_uniform_matrix4f(U_MVP, &mvp); parg_uniform1i(U_SHOWGRID, showgrid); parg_uniform4f(U_SLIPPYBOX, slippybox); parg_uniform1f(U_SLIPPYFRACT, slippyfract); parg_texture_bind(ocean_texture, 0); parg_varray_bind(parg_mesh_index(ocean_mesh)); parg_varray_enable( parg_mesh_coord(ocean_mesh), A_POSITION, 3, PARG_FLOAT, 0, 0); parg_draw_triangles_u16(0, parg_mesh_ntriangles(ocean_mesh)); parg_shader_bind(P_SOLID); parg_uniform_matrix4f(U_MVP, &mvp); parg_uniform4f(U_COLOR, &BLACK); parg_varray_bind(parg_mesh_index(landmass_mesh)); parg_varray_enable( parg_mesh_coord(landmass_mesh), A_POSITION, 3, PARG_FLOAT, 0, 0); parg_draw_wireframe_triangles_u16(0, parg_mesh_ntriangles(landmass_mesh)); if (mode_highp) { float x = parg_aar_width(rect) / fbsize.x; float y = parg_aar_height(rect) / fbsize.y; slippybox->z *= x; slippybox->w *= y; slippybox->x = (slippybox->x - rect.left) / x; slippybox->y = (slippybox->y - rect.bottom) / y; } parg_shader_bind(mode_highp ? P_LANDMASS_FRAGCOORD : P_LANDMASS); parg_uniform_matrix4f(U_MVP, &mvp); parg_uniform1i(U_SHOWGRID, showgrid); parg_uniform4f(U_SLIPPYBOX, slippybox); parg_uniform1f(U_SLIPPYFRACT, slippyfract); parg_texture_bind(paper_texture, 0); parg_draw_triangles_u16(0, parg_mesh_ntriangles(landmass_mesh)); }
void draw() { Matrix4 modelview = view; Matrix4 mvp = M4Mul(projection, view); // Draw the background. parg_draw_clear(); parg_shader_bind(P_TEXTURE); parg_texture_bind(abstract, 0); parg_uniform_matrix4f(U_MVP, &mvp); parg_varray_enable( parg_mesh_coord(backdrop), A_POSITION, 3, PARG_FLOAT, 0, 0); parg_varray_enable(parg_mesh_uv(backdrop), A_TEXCOORD, 2, PARG_FLOAT, 0, 0); parg_varray_bind(parg_mesh_index(backdrop)); parg_draw_triangles_u16(0, parg_mesh_ntriangles(backdrop)); parg_varray_disable(A_TEXCOORD); // Prep for the scene. modelview = M4Mul(view, model); mvp = M4Mul(projection, modelview); parg_texture_bind(kleintex, 0); parg_uniform_matrix4f(U_MVP, &mvp); parg_varray_enable( parg_mesh_coord(kleingeo), A_POSITION, 3, PARG_FLOAT, 0, 0); parg_varray_enable(parg_mesh_uv(kleingeo), A_TEXCOORD, 2, PARG_FLOAT, 0, 0); parg_varray_bind(parg_mesh_index(kleingeo)); // Draw each chart of the Klein bottle, skipping the podium disk. int start = 0; for (int i = 0; i < NCHARTS; i++) { if (i != PODIUM_CHART) { parg_draw_triangles_u16(start, CHARTS[i]); } start += CHARTS[i]; } // Draw it again for the reflection. parg_framebuffer_pushfbo(reflection, 0); parg_draw_clear(); Matrix4 invert = M4MakeScale((Vector3){1, -1, 1}); parg_state_cullfaces(0); Matrix4 flipped = M4Mul(model, invert); mvp = M4Mul(projection, M4Mul(view, flipped)); parg_uniform_matrix4f(U_MVP, &mvp); start = 0; for (int i = 0; i < NCHARTS; i++) { if (i != PODIUM_CHART) { parg_draw_triangles_u16(start, CHARTS[i]); } start += CHARTS[i]; } mvp = M4Mul(projection, modelview); parg_state_cullfaces(1); parg_framebuffer_popfbo(); // Draw the podium. parg_shader_bind(P_PODIUM); parg_texture_bind(rust, 1); parg_framebuffer_bindtex(reflection, 2); parg_uniform1i(U_RUST, 1); parg_uniform1i(U_REFLECTION, 2); parg_uniform2f(U_RESOLUTION, resolution, resolution); parg_uniform_matrix4f(U_MVP, &mvp); start = 0; for (int i = 0; i < NCHARTS; i++) { if (i == PODIUM_CHART) { parg_draw_triangles_u16(start, CHARTS[i]); } start += CHARTS[i]; } parg_varray_disable(A_TEXCOORD); // Draw the walls of the cylinder. #if CYLINDER parg_shader_bind(P_CYLINDER); parg_uniform_matrix4f(U_MVP, &mvp); parg_varray_enable( parg_mesh_coord(cylinder), A_POSITION, 3, PARG_FLOAT, 0, 0); parg_varray_bind(parg_mesh_index(cylinder)); parg_draw_triangles_u16(0, parg_mesh_ntriangles(cylinder)); #endif // Draw the logo billboard. parg_state_blending(1); parg_state_depthtest(0); parg_shader_bind(P_LOGO); parg_uniform_matrix4f(U_MVP, &mvp); parg_texture_bind(logo, 0); parg_varray_enable( parg_mesh_coord(billboard), A_POSITION, 2, PARG_FLOAT, 0, 0); parg_varray_enable( parg_mesh_coord(billboard), A_TEXCOORD, 2, PARG_FLOAT, 0, 0); parg_draw_one_quad(); parg_varray_disable(A_TEXCOORD); parg_state_blending(0); parg_state_depthtest(1); }
void draw() { int mesh = 0, multi = 0, meshcolor = 0; switch (state) { case STATE_GRAY_SOURCE: parg_shader_bind(P_GRAY); parg_texture_bind(graytex, 0); parg_uniform1f(U_ZSCALE, 1); break; case STATE_COLOR_IH: mesh = 1; parg_shader_bind(P_GRAYMESH); parg_uniform1f(U_ZSCALE, 0.3); break; case STATE_COLOR_DHSCSI: mesh = multi = 1; parg_shader_bind(P_GRAYMESH); parg_uniform1f(U_ZSCALE, 0.3); break; case STATE_MULTI_RGBA: case STATE_MULTI_RGB: case STATE_MULTI_DIAGRAM: meshcolor = mesh = multi = 1; parg_shader_bind(P_GRAYMESH); parg_uniform1f(U_ZSCALE, 0.25); break; case STATE_COLOR_DEFAULT: case STATE_GRAY_DEFAULT: case STATE_GRAY_SIMPLIFY: case STATE_GRAY_INVERT: case STATE_GRAY_HEIGHTS: mesh = 1; parg_shader_bind(P_GRAYMESH); parg_uniform1f(U_ZSCALE, 1); break; case STATE_GRAY_MULTI: mesh = multi = 1; parg_shader_bind(P_GRAYMESH); parg_texture_bind(colortex, 0); parg_uniform1f(U_ZSCALE, 0.3); break; case STATE_GRAY_DUAL: mesh = multi = 1; parg_shader_bind(P_GRAYMESH); parg_texture_bind(colortex, 0); parg_uniform1f(U_ZSCALE, 1); break; case STATE_GRAY_DHS: case STATE_GRAY_DHSC: mesh = multi = 1; parg_shader_bind(P_GRAYMESH); parg_texture_bind(colortex, 0); parg_uniform1f(U_ZSCALE, 0.5); break; case STATE_COLOR_SOURCE: parg_texture_bind(colortex, 0); parg_shader_bind(P_COLOR); parg_uniform1f(U_ZSCALE, 1); break; default: break; } if (mesh) { for (int i = 0; i < sizeof(trimesh) / sizeof(trimesh[0]); i++) { parg_mesh_free(trimesh[i]); } memset(trimesh, 0, sizeof(trimesh)); create_mesh(); } Matrix4 model; if (mesh) { model = M4MakeScale(V3MakeFromElems(20, 20, 10)); model = M4Mul(M4MakeTranslation(V3MakeFromElems(-10, -10, 0)), model); } else { model = M4MakeIdentity(); } Matrix4 modelview = M4Mul(view, model); Matrix4 mvp = M4Mul(projection, modelview); parg_uniform_matrix4f(U_MVP, &mvp); parg_draw_clear(); if (mesh) { Vector4 colors[3]; colors[0] = (Vector4){0, 0.6, 0.9, 1}; colors[1] = (Vector4){0, 0.9, 0.6, 1}; colors[2] = (Vector4){0.9, 0.6, 0, 1}; Vector4 black = {0, 0, 0, 1.0}; for (int imesh = 0; imesh < nmeshes; imesh++) { parg_varray_enable(parg_mesh_coord(trimesh[imesh]), A_POSITION, 3, PARG_FLOAT, 0, 0); parg_varray_bind(parg_mesh_index(trimesh[imesh])); if (meshcolor) { unsigned int b = meshcolors[imesh] & 0xff; unsigned int g = (meshcolors[imesh] >> 8) & 0xff; unsigned int r = (meshcolors[imesh] >> 16) & 0xff; unsigned int a = (meshcolors[imesh] >> 24) & 0xff; Vector4 color; color.x = r / 255.0f; color.y = g / 255.0f; color.z = b / 255.0f; color.w = a / 255.0f; parg_uniform4f(U_COLOR, &color); } else { parg_uniform4f(U_COLOR, &colors[imesh]); } parg_draw_triangles_u16(0, parg_mesh_ntriangles(trimesh[imesh])); parg_uniform4f(U_COLOR, &black); parg_draw_wireframe_triangles_u16( 0, parg_mesh_ntriangles(trimesh[imesh])); } } else {