void make_single_cube( GLuint *position_buffer, GLuint *normal_buffer, GLuint *uv_buffer, int w) { int faces = 6; glDeleteBuffers(1, position_buffer); glDeleteBuffers(1, normal_buffer); glDeleteBuffers(1, uv_buffer); GLfloat *position_data = malloc(sizeof(GLfloat) * faces * 18); GLfloat *normal_data = malloc(sizeof(GLfloat) * faces * 18); GLfloat *uv_data = malloc(sizeof(GLfloat) * faces * 12); make_cube( position_data, normal_data, uv_data, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0.5, w); *position_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 18, position_data ); *normal_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 18, normal_data ); *uv_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 12, uv_data ); free(position_data); free(normal_data); free(uv_data); }
void metaball_geometry::update_uniforms(GLuint program) { glUseProgram(program); GLint isoLevel_loc = glGetUniformLocation(program, "isoLevel"); glUniform1f(isoLevel_loc, isolevel_); GLint metaballCnt_loc = glGetUniformLocation(program, "metaballCnt"); glUniform1i(metaballCnt_loc, metaballs_.size()); vec4 metaballs_info[MAX_METABALL_CNT]; for (size_t i = 0; i < metaballs_.size(); ++i) { metaballs_info[i] = vec4(metaballs_[i]->position, metaballs_[i]->potential); } GLint metaballs_loc = glGetUniformLocation(program, "metaballs"); glUniform4fv(metaballs_loc, metaballs_.size(), reinterpret_cast<float*>(metaballs_info)); // vertex decals to form a cube from center point vec3 decals[8]; float width = (upper_bound_.x - lower_bound_.x) / resolution_; float half_width = width / 2; vec3 dv(half_width, half_width, half_width); make_cube(-dv, dv, decals); GLint vertDecalLoc = glGetUniformLocation(program, "vertDecal"); glUniform3fv(vertDecalLoc, 8, reinterpret_cast<float*>(decals)); }
void make_rotated_cube( float *vertex, float *normal, float *texture, float x, float y, float z, float n, int w, float rx, float ry) { make_cube(vertex, normal, texture, 1, 1, 1, 1, 1, 1, 0, 0, 0, n, w); float a[16]; float b[16]; float vec[4] = {0}; vec[3] = 1; mat_identity(a); mat_rotate(b, 0, 1, 0, rx); mat_multiply(a, b, a); mat_rotate(b, cosf(rx), 0, sinf(rx), -ry); mat_multiply(a, b, a); mat_translate(b, x, y, z); mat_multiply(a, b, a); for (int i = 0; i < 36; i++) { // vertex float *v = vertex + i * 3; vec[0] = *(v++); vec[1] = *(v++); vec[2] = *(v++); mat_vec_multiply(vec, a, vec); v = vertex + i * 3; *(v++) = vec[0]; *(v++) = vec[1]; *(v++) = vec[2]; // normal float *d = normal + i * 3; vec[0] = *(d++); vec[1] = *(d++); vec[2] = *(d++); mat_vec_multiply(vec, a, vec); d = normal + i * 3; *(d++) = vec[0]; *(d++) = vec[1]; *(d++) = vec[2]; } }
ExperimentalApp() : GLFWApp(1280, 800, "Glass Material App") { igm.reset(new gui::ImGuiManager(window)); gui::make_dark_theme(); //cubeTex = load_cubemap(); int width, height; glfwGetWindowSize(window, &width, &height); glViewport(0, 0, width, height); // Debugging views for offscreen surfaces uiSurface.bounds = {0, 0, (float) width, (float) height}; uiSurface.add_child( {{0.0000f, +10},{0, +10},{0.1667f, -10},{0.133f, +10}}); uiSurface.add_child( {{0.1667f, +10},{0, +10},{0.3334f, -10},{0.133f, +10}}); uiSurface.layout(); grid = RenderableGrid(1, 100, 100); cameraController.set_camera(&camera); camera.look_at({0, 2.5, -2.5}, {0, 2.0, 0}); lights[0] = {{0, 10, -10}, {0, 0, 1}}; lights[1] = {{0, 10, 10}, {0, 1, 0}}; Renderable reflectiveSphere = Renderable(make_sphere(2.f)); reflectiveSphere.pose = Pose(float4(0, 0, 0, 1), float3(0, 2, 0)); glassModels.push_back(std::move(reflectiveSphere)); Renderable debugAxis = Renderable(make_axis(), false, GL_LINES); debugAxis.pose = Pose(float4(0, 0, 0, 1), float3(0, 1, 0)); regularModels.push_back(std::move(debugAxis)); Renderable cubeA = Renderable(make_cube()); cubeA.pose = Pose(make_rotation_quat_axis_angle({1, 0, 1}, ANVIL_PI / 3), float3(5, 0, 0)); regularModels.push_back(std::move(cubeA)); Renderable cubeB = Renderable(make_cube()); cubeB.pose = Pose(make_rotation_quat_axis_angle({1, 0, 1}, ANVIL_PI / 4), float3(-5, 0, 0)); regularModels.push_back(std::move(cubeB)); glassMaterialShader = make_watched_shader(shaderMonitor, "assets/shaders/glass_vert.glsl", "assets/shaders/glass_frag.glsl"); simpleShader = make_watched_shader(shaderMonitor, "assets/shaders/simple_vert.glsl", "assets/shaders/simple_frag.glsl"); cubeCamera.reset(new CubemapCamera({1024, 1024})); gl_check_error(__FILE__, __LINE__); }
ExperimentalApp() : GLFWApp(940, 720, "GlCamera Sandbox App") { int width, height; glfwGetWindowSize(window, &width, &height); glViewport(0, 0, width, height); cameraController.set_camera(&camera); camera.look_at({0, 8, 24}, {0, 0, 0}); cameraZ = camera.pose.position.z; simpleShader.reset(new GlShader(read_file_text("assets/shaders/simple_vert.glsl"), read_file_text("assets/shaders/simple_frag.glsl"))); { lights.resize(2); lights[0].color = float3(249.f / 255.f, 228.f / 255.f, 157.f / 255.f); lights[0].pose.position = float3(25, 15, 0); lights[1].color = float3(255.f / 255.f, 242.f / 255.f, 254.f / 255.f); lights[1].pose.position = float3(-25, 15, 0); } { cameraPositions.resize(2); cameraPositions[0] = Renderable(make_frustum()); cameraPositions[0].pose.position = float3(0, 8, +24); cameraPositions[0].mesh.set_non_indexed(GL_LINES); cameraPositions[1] = Renderable(make_frustum()); cameraPositions[1].pose.position = float3(0, 8, -24); cameraPositions[1].mesh.set_non_indexed(GL_LINES); } { proceduralModels.resize(4); proceduralModels[0] = Renderable(make_sphere(1.0)); proceduralModels[0].pose.position = float3(0, 2, +8); proceduralModels[1] = Renderable(make_cube()); proceduralModels[1].pose.position = float3(0, 2, -8); proceduralModels[2] = Renderable(make_icosahedron()); proceduralModels[2].pose.position = float3(8, 2, 0); proceduralModels[3] = Renderable(make_octohedron()); proceduralModels[3].pose.position = float3(-8, 2, 0); } start = look_at_pose(float3(0, 8, +24), float3(-8, 2, 0)); end = look_at_pose(float3(0, 8, -24), float3(-8, 2, 0)); grid = RenderableGrid(1, 64, 64); gl_check_error(__FILE__, __LINE__); }
/* explicit */ cube::cube() : base() { TRACE("hugh::scene::object::geometry::cube::cube"); attribute_list_.clear(); index_list_ .clear(); make_cube(attribute_list_, index_list_); compute_bounds(); compute_tangents(); }
void gen_cube_buffers( GLuint *position_buffer, GLuint *normal_buffer, GLuint *uv_buffer, float x, float y, float z, float n, int w) { GLfloat *position_data, *normal_data, *uv_data; malloc_buffers(3, 6, &position_data, &normal_data, &uv_data); make_cube( position_data, normal_data, uv_data, 1, 1, 1, 1, 1, 1, x, y, z, n, w); gen_buffers( 3, 6, position_data, normal_data, uv_data, position_buffer, normal_buffer, uv_buffer); }
GLuint BufferUtils::genCubeBuffer(float x, float y, float z, float n, int w) { GLfloat *data = malloc_faces(10, 6); float ao[6][4] = {0}; float light[6][4] = { {0.5, 0.5, 0.5, 0.5}, {0.5, 0.5, 0.5, 0.5}, {0.5, 0.5, 0.5, 0.5}, {0.5, 0.5, 0.5, 0.5}, {0.5, 0.5, 0.5, 0.5}, {0.5, 0.5, 0.5, 0.5} }; make_cube(data, ao, light, 1, 1, 1, 1, 1, 1, x, y, z, 0, 0, 0, n, w); return gen_faces(10, 6, data); }
void TemplateGame::init() { // Load texture m_simpleTex = LoadImagePNG( gameDataFile("", "simpletex.png" ).c_str() ); // Load font m_fontImg = LoadImagePNG( gameDataFile("", "nesfont.png" ).c_str() ); m_nesFont = makeFont_nesfont_8( m_fontImg.textureId ); m_cube = make_cube(); // setColorConstant( m_cube, vec4f( 1.0, 1.0, 1.0 ) ); m_basicShader = loadShader( "template.Plastic" ); m_rotate = 0.0; glEnable( GL_DEPTH_TEST ); }
void update_chunk(Chunk *chunk) { Map *map = &chunk->map; if (chunk->faces) { glDeleteBuffers(1, &chunk->position_buffer); glDeleteBuffers(1, &chunk->normal_buffer); glDeleteBuffers(1, &chunk->uv_buffer); } int faces = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } faces += total; } END_MAP_FOR_EACH; GLfloat *position_data = malloc(sizeof(GLfloat) * faces * 18); GLfloat *normal_data = malloc(sizeof(GLfloat) * faces * 18); GLfloat *uv_data = malloc(sizeof(GLfloat) * faces * 12); int position_offset = 0; int uv_offset = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } if (total == 0) { continue; } if (is_plant(e->w)) { float rotation = simplex3(e->x, e->y, e->z, 4, 0.5, 2) * 360; make_plant( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, e->x, e->y, e->z, 0.5, e->w, rotation); } else { make_cube( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, f1, f2, f3, f4, f5, f6, e->x, e->y, e->z, 0.5, e->w); } position_offset += total * 18; uv_offset += total * 12; } END_MAP_FOR_EACH; GLuint position_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 18, position_data ); GLuint normal_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 18, normal_data ); GLuint uv_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 12, uv_data ); free(position_data); free(normal_data); free(uv_data); chunk->faces = faces; chunk->position_buffer = position_buffer; chunk->normal_buffer = normal_buffer; chunk->uv_buffer = uv_buffer; }
void maininit(int argc, char **argv) { GLfloat specular [] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat shininess [] = { 100.0 }; GLfloat position [] = { 1.0, 1.0, 1.0, 0.0 }; printf("Press T or Esc\n"); fflush(stdout); glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_ALPHA | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(50, 50); glutCreateWindow("Light"); glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE); // Set the clear color to black glClearColor(0.5, 0.4, 0.3, 0.2); // Set the shading model glShadeModel(GL_SMOOTH); // Set the polygon mode to fill // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT, GL_FILL); // Enable depth testing for hidden line removal glEnable(GL_DEPTH_TEST); // Define material properties of specular color and degree of // shininess. Since this is only done once in this particular // example, it applies to all objects. Material properties can // be set for individual objects, individual faces of the objects, // individual vertices of the faces, etc... // glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glMaterialfv(GL_FRONT, GL_SPECULAR, specular); // glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess); glMaterialfv(GL_FRONT, GL_SHININESS, shininess); // Set the GL_AMBIENT_AND_DIFFUSE color state variable to be the // one referred to by all following calls to glColor // glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); // Create a Directional Light Source glLightfv(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Create the display lists make_sphere(); make_cube(); // Assign reshape() to be the function called whenever // an expose event occurs // tkExposeFunc(reshape); glutReshapeFunc (reshape); // Assign reshape() to be the function called whenever // a reshape event occurs //?? tkReshapeFunc(reshape); // Assign key_down() to be the function called whenever // a key is pressed glutKeyboardFunc (keyboard); // Assign draw() to be the function called whenever a display // event occurs, generally after a resize or expose event // tkDisplayFunc(draw); glutDisplayFunc (draw); // Pass program control to tk's event handling code // In other words, loop forever // tkExec(); glutMainLoop(); }
void app_initialize(App *app) { // Make sure the required extensions are present. const GLubyte* extensions = glGetString(GL_EXTENSIONS); char * found_multiview2_extension = strstr ((const char*)extensions, "GL_OVR_multiview2"); char * found_multisample_multiview_extension = strstr ((const char*)extensions, "GL_OVR_multiview_multisampled_render_to_texture"); char * found_border_clamp_extension = strstr ((const char*)extensions, "GL_EXT_texture_border_clamp"); if (found_multiview2_extension == NULL) { LOGI("OpenGL ES 3.0 implementation does not support GL_OVR_multiview2 extension.\n"); exit(EXIT_FAILURE); } if (found_multisample_multiview_extension == NULL) { // If multisampled multiview is not supported, multisampling will not be used, so no need to exit here. LOGI("OpenGL ES 3.0 implementation does not support GL_OVR_multiview_multisampled_render_to_texture extension.\n"); } if (found_border_clamp_extension == NULL) { LOGI("OpenGL ES 3.0 implementation does not support GL_EXT_texture_border_clamp extension.\n"); exit(EXIT_FAILURE); } GL_CHECK(glGenVertexArrays(1, &app->vao)); GL_CHECK(glBindVertexArray(app->vao)); GL_CHECK(glViewport(0, 0, app->window_width, app->window_height)); app->vbo_cube = make_cube(); app->fb = make_eye_framebuffer(Eye_Fb_Resolution_X, Eye_Fb_Resolution_Y, Num_Views); // The coefficients below may be calibrated by photographing an // image containing straight lines, both vertical and horizontal, // through the lenses of the HMD, at the position where the viewer // would be looking through them. // Ideally, the user would be allowed to calibrate them for their // own eyes, through some calibration utility. The application should // then load a stored user-profile on runtime. For now, we hardcode // some values based on our calibration of the SM-R320 Gear VR // lenses. // Left lens app->hmd.left.coefficients_red.k1 = 0.19f; app->hmd.left.coefficients_red.k2 = 0.21f; app->hmd.left.coefficients_red.k3 = 0.0f; app->hmd.left.coefficients_red.p1 = 0.0f; app->hmd.left.coefficients_red.p2 = 0.0f; app->hmd.left.coefficients_green.k1 = 0.22f; app->hmd.left.coefficients_green.k2 = 0.24f; app->hmd.left.coefficients_green.k3 = 0.0f; app->hmd.left.coefficients_green.p1 = 0.0f; app->hmd.left.coefficients_green.p2 = 0.0f; app->hmd.left.coefficients_blue.k1 = 0.24f; app->hmd.left.coefficients_blue.k2 = 0.26f; app->hmd.left.coefficients_blue.k3 = 0.0f; app->hmd.left.coefficients_blue.p1 = 0.0f; app->hmd.left.coefficients_blue.p2 = 0.0f; // Right lens app->hmd.right.coefficients_red.k1 = 0.19f; app->hmd.right.coefficients_red.k2 = 0.21f; app->hmd.right.coefficients_red.k3 = 0.0f; app->hmd.right.coefficients_red.p1 = 0.0f; app->hmd.right.coefficients_red.p2 = 0.0f; app->hmd.right.coefficients_green.k1 = 0.22f; app->hmd.right.coefficients_green.k2 = 0.24f; app->hmd.right.coefficients_green.k3 = 0.0f; app->hmd.right.coefficients_green.p1 = 0.0f; app->hmd.right.coefficients_green.p2 = 0.0f; app->hmd.right.coefficients_blue.k1 = 0.24f; app->hmd.right.coefficients_blue.k2 = 0.26f; app->hmd.right.coefficients_blue.k3 = 0.0f; app->hmd.right.coefficients_blue.p1 = 0.0f; app->hmd.right.coefficients_blue.p2 = 0.0f; // These may be computed by measuring the distance between the top // of the unscaled distorted image and the top of the screen. Denote // this distance by Delta. The normalized view coordinate of the // distorted image top is // Y = 1 - 2 Delta / Screen_Size_Y // We want to scale this coordinate such that it maps to the top of // the view. That is, // Y * fill_scale = 1 // Solving for fill_scale gives the equations below. float delta = Centimeter(0.7f); app->hmd.left.fill_scale = 1.0f / (1.0f - 2.0f * delta / Screen_Size_Y); app->hmd.right.fill_scale = 1.0f / (1.0f - 2.0f * delta / Screen_Size_Y); // These are computed such that the centers of the displayed framebuffers // on the device are seperated by the viewer's IPD. app->hmd.left.image_centre = vec2(+1.0f - Eye_IPD / (Screen_Size_X / 2.0f), 0.0f); app->hmd.right.image_centre = vec2(-1.0f + Eye_IPD / (Screen_Size_X / 2.0f), 0.0f); // These are computed such that the distortion takes place around // an offset determined by the difference between lens seperation // and the viewer's eye IPD. If the difference is zero, the distortion // takes place around the image centre. app->hmd.left.distort_centre = vec2((Lens_IPD - Eye_IPD) / (Screen_Size_X / 2.0f), 0.0f); app->hmd.right.distort_centre = vec2((Eye_IPD - Lens_IPD) / (Screen_Size_X / 2.0f), 0.0f); app->warp_mesh[0] = make_warp_mesh(app->hmd.left); app->warp_mesh[1] = make_warp_mesh(app->hmd.right); get_attrib_location( distort, position); get_attrib_location( distort, uv_red_low_res); get_attrib_location( distort, uv_green_low_res); get_attrib_location( distort, uv_blue_low_res); get_attrib_location( distort, uv_red_high_res); get_attrib_location( distort, uv_green_high_res); get_attrib_location( distort, uv_blue_high_res); get_uniform_location(distort, layer_index); get_uniform_location(distort, framebuffer); get_attrib_location (cube, position); get_attrib_location (cube, normal); get_uniform_location(cube, projection); get_uniform_location(cube, view); get_uniform_location(cube, model); }
ExperimentalApp() : GLFWApp(1280, 800, "Geometric Algorithm Development App") { glfwSwapInterval(0); igm.reset(new gui::ImGuiManager(window)); gui::make_dark_theme(); fixedTimer.start(); lights[0] = {{0, 10, -10}, {0, 0, 1}}; lights[1] = {{0, 10, 10}, {0, 1, 0}}; int width, height; glfwGetWindowSize(window, &width, &height); glViewport(0, 0, width, height); grid = RenderableGrid(1, 100, 100); cameraController.set_camera(&camera); camera.look_at({0, 2.5, -2.5}, {0, 2.0, 0}); simpleShader = make_watched_shader(shaderMonitor, "../assets/shaders/simple_vert.glsl", "assets/shaders/simple_frag.glsl"); normalDebugShader = make_watched_shader(shaderMonitor, "../assets/shaders/normal_debug_vert.glsl", "assets/shaders/normal_debug_frag.glsl"); Renderable debugAxis = Renderable(make_axis(), false, GL_LINES); debugAxis.pose = Pose(float4(0, 0, 0, 1), float3(0, 1, 0)); debugModels.push_back(std::move(debugAxis)); // Initial supershape settings supershape = Renderable(make_supershape_3d(16, 5, 7, 4, 12)); supershape.pose.position = {0, 2, -2}; // Initialize PTF stuff { std::array<float3, 4> controlPoints = {float3(0.0f, 0.0f, 0.0f), float3(0.667f, 0.25f, 0.0f), float3(1.33f, 0.25f, 0.0f), float3(2.0f, 0.0f, 0.0f)}; ptf = make_parallel_transport_frame_bezier(controlPoints, 32); for (int i = 0; i < ptf.size(); ++i) { Renderable p = Renderable(make_cube()); ptfBoxes.push_back(std::move(p)); } } // Initialize Parabolic pointer stuff { // Set up the ground plane used as a nav mesh for the parabolic pointer worldSurface = make_plane(48, 48, 96, 96); for (auto & p : worldSurface.vertices) { float4x4 model = make_rotation_matrix({1, 0, 0}, -ANVIL_PI / 2); p = transform_coord(model, p); } worldSurfaceRenderable = Renderable(worldSurface); parabolicPointer = make_parabolic_pointer(worldSurface, params); } // Initialize objects for ballistic trajectory tests { turret.source = Renderable(make_tetrahedron()); turret.source.pose = Pose({-5, 2, 5}); turret.target = Renderable(make_cube()); turret.target.pose = Pose({0, 0, 40}); turret.bullet = Renderable(make_sphere(1.0f)); } float4x4 tMat = mul(make_translation_matrix({3, 4, 5}), make_rotation_matrix({0, 0, 1}, ANVIL_PI / 2)); auto p = make_pose_from_transform_matrix(tMat); std::cout << tMat << std::endl; std::cout << p << std::endl; gl_check_error(__FILE__, __LINE__); }
void gen_chunk_buffers(Chunk *chunk) { Map *map = &chunk->map; int faces = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } faces += total; } END_MAP_FOR_EACH; GLfloat *position_data, *normal_data, *uv_data; malloc_buffers(3, faces, &position_data, &normal_data, &uv_data); int position_offset = 0; int uv_offset = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } if (total == 0) { continue; } if (is_plant(e->w)) { float rotation = simplex3(e->x, e->y, e->z, 4, 0.5, 2) * 360; make_plant( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, e->x, e->y, e->z, 0.5, e->w, rotation); } else { make_cube( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, f1, f2, f3, f4, f5, f6, e->x, e->y, e->z, 0.5, e->w); } position_offset += total * 18; uv_offset += total * 12; } END_MAP_FOR_EACH; gen_buffers( 3, faces, position_data, normal_data, uv_data, &chunk->position_buffer, &chunk->normal_buffer, &chunk->uv_buffer); chunk->faces = faces; chunk->dirty = 0; }