/* don't set windows active in here, is used by renderwin too */ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) { if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */ if (v3d->camera) { BKE_object_where_is_calc(scene, v3d->camera); obmat_to_viewmat(v3d, rv3d, v3d->camera, 0); } else { quat_to_mat4(rv3d->viewmat, rv3d->viewquat); rv3d->viewmat[3][2] -= rv3d->dist; } } else { /* should be moved to better initialize later on XXX */ if (rv3d->viewlock) ED_view3d_lock(rv3d); quat_to_mat4(rv3d->viewmat, rv3d->viewquat); if (rv3d->persp == RV3D_PERSP) rv3d->viewmat[3][2] -= rv3d->dist; if (v3d->ob_centre) { Object *ob = v3d->ob_centre; float vec[3]; copy_v3_v3(vec, ob->obmat[3]); if (ob->type == OB_ARMATURE && v3d->ob_centre_bone[0]) { bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, v3d->ob_centre_bone); if (pchan) { copy_v3_v3(vec, pchan->pose_mat[3]); mul_m4_v3(ob->obmat, vec); } } translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); } else if (v3d->ob_centre_cursor) { float vec[3]; copy_v3_v3(vec, give_cursor(scene, v3d)); translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); } else { translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); } } }
/* draw a 3D stroke in "volumetric" style */ static void gp_draw_stroke_volumetric_3d(bGPDspoint *points, int totpoints, short thickness, short UNUSED(dflag), short UNUSED(sflag)) { GLUquadricObj *qobj = gluNewQuadric(); float base_modelview[4][4], modelview[4][4]; float base_loc[3]; bGPDspoint *pt; int i; /* Get the basic modelview matrix we use for performing calculations */ glGetFloatv(GL_MODELVIEW_MATRIX, (float *)base_modelview); copy_v3_v3(base_loc, base_modelview[3]); /* Create the basic view-aligned billboard matrix we're going to actually draw qobj with: * - We need to knock out the rotation so that we are * simply left with a camera-facing billboard * - The scale factors here are chosen so that the thickness * is relatively reasonable. Otherwise, it gets far too * large! */ scale_m4_fl(modelview, 0.1f); /* draw each point as a disk... */ glPushMatrix(); for (i = 0, pt = points; i < totpoints && pt; i++, pt++) { /* apply translation to base_modelview, so that the translated point is put in the right place */ translate_m4(base_modelview, pt->x, pt->y, pt->z); /* copy the translation component to the billboard matrix we're going to use, * then reset the base matrix to the original values so that we can do the same * for the next point without accumulation/pollution effects */ copy_v3_v3(modelview[3], base_modelview[3]); /* copy offset value */ copy_v3_v3(base_modelview[3], base_loc); /* restore */ /* apply our billboard matrix for drawing... */ glLoadMatrixf((float *)modelview); /* draw the disk using the current state... */ gluDisk(qobj, 0.0, pt->pressure * thickness, 32, 1); } glPopMatrix(); gluDeleteQuadric(qobj); }
/* draw a 2D strokes in "volumetric" style */ static void gp_draw_stroke_volumetric_2d(bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, int offsx, int offsy, int winx, int winy) { GLUquadricObj *qobj = gluNewQuadric(); float modelview[4][4]; float baseloc[3]; float scalefac = 1.0f; bGPDspoint *pt; int i; /* HACK: We need a scale factor for the drawing in the image editor, * which seems to use 1 unit as it's maximum size, whereas everything * else assumes 1 unit = 1 pixel. Otherwise, we only get a massive blob. */ if ((dflag & GP_DRAWDATA_IEDITHACK) && (dflag & GP_DRAWDATA_ONLYV2D)) { scalefac = 0.001f; } /* get basic matrix */ glGetFloatv(GL_MODELVIEW_MATRIX, (float *)modelview); copy_v3_v3(baseloc, modelview[3]); /* draw points */ glPushMatrix(); for (i = 0, pt = points; i < totpoints; i++, pt++) { /* set the transformed position */ float co[2]; gp_calc_2d_stroke_xy(pt, sflag, offsx, offsy, winx, winy, co); translate_m4(modelview, co[0], co[1], 0.0f); glLoadMatrixf((float *)modelview); /* draw the disk using the current state... */ gluDisk(qobj, 0.0, pt->pressure * thickness * scalefac, 32, 1); /* restore matrix */ copy_v3_v3(modelview[3], baseloc); } glPopMatrix(); gluDeleteQuadric(qobj); }
void renderChunk(Chunk *chunk) { // free the previously used buffers. Memory leaks are bad, mmkay. if (chunk->mesh) freeMesh(chunk->mesh); // 6 faces per cube * 2 triangles per face * 3 vertices per triangle * 3 coordinates per vertex unsigned int max_points = countChunkSize(chunk);//6 * 6 * 3 * CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE; // don't render an empty chunk :p if (max_points == 0) { *chunk->mesh = EMPTY_MESH; return; } GLfloat *points = malloc(max_points * sizeof(GLfloat)); GLfloat *normals = malloc(max_points * sizeof(GLfloat)); GLfloat *colors = malloc(max_points * sizeof(GLfloat)); int size; if (useMeshing) size = renderChunkWithMeshing(chunk, points, normals, colors, (vec3){0, 0, 0}, 1.0); else size = renderChunkToArrays(chunk, points, normals, colors, (vec3){0, 0, 0}, 1.0); buildMesh(chunk->mesh, points, normals, colors, NULL, NULL, size * sizeof(GLfloat), size * sizeof(GLfloat), size * sizeof(GLfloat), 0, 0, size / 3); translate_m4(chunk->mesh->modelMatrix, chunk->x * CHUNK_WIDTH, chunk->y * CHUNK_WIDTH, chunk->z * CHUNK_WIDTH); free(points); free(normals); free(colors); }
/* don't set windows active in here, is used by renderwin too */ void view3d_viewmatrix_set(Scene *scene, View3D *v3d, RegionView3D *rv3d) { if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */ if (v3d->camera) { BKE_object_where_is_calc(scene, v3d->camera); obmat_to_viewmat(rv3d, v3d->camera); } else { quat_to_mat4(rv3d->viewmat, rv3d->viewquat); rv3d->viewmat[3][2] -= rv3d->dist; } } else { bool use_lock_ofs = false; /* should be moved to better initialize later on XXX */ if (rv3d->viewlock & RV3D_LOCKED) ED_view3d_lock(rv3d); quat_to_mat4(rv3d->viewmat, rv3d->viewquat); if (rv3d->persp == RV3D_PERSP) rv3d->viewmat[3][2] -= rv3d->dist; if (v3d->ob_centre) { Object *ob = v3d->ob_centre; float vec[3]; copy_v3_v3(vec, ob->obmat[3]); if (ob->type == OB_ARMATURE && v3d->ob_centre_bone[0]) { bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, v3d->ob_centre_bone); if (pchan) { copy_v3_v3(vec, pchan->pose_mat[3]); mul_m4_v3(ob->obmat, vec); } } translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); use_lock_ofs = true; } else if (v3d->ob_centre_cursor) { float vec[3]; copy_v3_v3(vec, ED_view3d_cursor3d_get(scene, v3d)); translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); use_lock_ofs = true; } else { translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); } /* lock offset */ if (use_lock_ofs) { float persmat[4][4], persinv[4][4]; float vec[3]; /* we could calculate the real persmat/persinv here * but it would be unreliable so better to later */ mul_m4_m4m4(persmat, rv3d->winmat, rv3d->viewmat); invert_m4_m4(persinv, persmat); mul_v2_v2fl(vec, rv3d->ofs_lock, rv3d->is_persp ? rv3d->dist : 1.0f); vec[2] = 0.0f; mul_mat3_m4_v3(persinv, vec); translate_m4(rv3d->viewmat, vec[0], vec[1], vec[2]); } /* end lock offset */ } }
int main(void) { if(!glfwInit()) { printf("Could not init GLFW"); getchar(); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); //Opengl 2.1 //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); //Opengl 3.3 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // MacOS fix glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); if(window_init(&window, 640, 480, "Test")) { fprintf( stderr, "Failed to open window.\n" ); getchar(); glfwTerminate(); }; window_set_size_callback(&window, window_size_callback); glewExperimental = GL_TRUE; // Needed for core profile if (glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); getchar(); glfwTerminate(); return -1; } //#clear errors GLEW may trigger printError(); glClearColor(0.0f, 0.0f, 0.4f, 0.0f); GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); //Load model //---------- Model cube; model_init(&cube); model_set_data_length(&cube, sizeof(cube_vertex_data)); model_set_vertices(&cube, cube_vertex_data); model_set_colors(&cube, cube_color_data); model_set_uv_map(&cube, cube_uv_data); model_set_texture(&cube, "./textures/bricks.dds"); model_bind(&cube); //Create shaders //-------------- GLuint vertexShader, fragmentShader; loadShader(&vertexShader, GL_VERTEX_SHADER, mvpVertexShaderSource); loadShader(&fragmentShader, GL_FRAGMENT_SHADER, fragmentShaderSource); //Create program //-------------- GLuint program; createProgram(&program, vertexShader, fragmentShader); // Enable z-buffer // --------------- glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); // Enable culling // -------------- glEnable(GL_CULL_FACE); // Get MVP uniform // --------------- GLuint mvp_ul = glGetUniformLocation(program, "MVP"); // Model Matrix // ------------ Mat4 s; scale_m4(&s, 0.1f, 0.1f, 0.1f); printf("Scale:\n"); print_m4(&s); Mat4 r; rotate_m4(&r, 0.0f, 1.0f, 0.0f, 0.0f); printf("Rotate:\n"); print_m4(&r); Mat4 t; translate_m4(&t, 0.0f, 0.0f, 0.0f); printf("Translate:\n"); print_m4(&t); Mat4 rs; printf("Rotated*Scaled:\n"); mul_m4(&rs, &r, &s); print_m4(&rs); Mat4 model; printf("Model:\n"); mul_m4(&model, &t, &rs); print_m4(&model); // Camera // ------ Vec3 pos; Vec3 center; Vec3 up; Vec3 direction; Vec3 right; camera_init(&camera); camera_set_fov(&camera, 1.0f); camera_set_aspect(&camera, (float)window.width/(float)window.height); Input input; input_init(&input, &window, 0.5f, 0.5f, 0.8f, -5.7f, -2.7f); do { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glUseProgram(program); input_get_data(&input, &pos, &direction, &right); add_v3(¢er, &pos, &direction); cross_v3(&up, &direction, &right); camera_set_position(&camera, &pos); camera_set_center(&camera, ¢er); camera_set_up(&camera, &up); // Mvp Matrix // ---------- Mat4 vp; camera_get_matrix(&camera, &vp); Mat4 mvp; mul_m4(&mvp, &vp, &model); printf("Perspective:\n"); print_m4(&mvp); // Set MVP transform glUniformMatrix4fv(mvp_ul, 1, GL_TRUE, &mvp[0][0]); model_render(&cube); window_swap_buffers(&window); glfwPollEvents(); } while( glfwGetKey(window.handle, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window.handle) == 0 ); // Dispose // ------- model_dispose(&cube); glDeleteVertexArrays(1, &VertexArrayID); glDetachShader(program, fragmentShader); glDetachShader(program, vertexShader); glDeleteShader(fragmentShader); glDeleteShader(vertexShader); glDeleteProgram(program); glfwTerminate(); return 0; }
static void camera_stereo3d_model_matrix(Object *camera, const bool is_left, float r_modelmat[4][4]) { Camera *data = (Camera *)camera->data; float interocular_distance, convergence_distance; short convergence_mode, pivot; float sizemat[4][4]; float fac = 1.0f; float fac_signed; interocular_distance = data->stereo.interocular_distance; convergence_distance = data->stereo.convergence_distance; convergence_mode = data->stereo.convergence_mode; pivot = data->stereo.pivot; if (((pivot == CAM_S3D_PIVOT_LEFT) && is_left) || ((pivot == CAM_S3D_PIVOT_RIGHT) && !is_left)) { camera_model_matrix(camera, r_modelmat); return; } else { float size[3]; mat4_to_size(size, camera->obmat); size_to_mat4(sizemat, size); } if (pivot == CAM_S3D_PIVOT_CENTER) fac = 0.5f; fac_signed = is_left ? fac : -fac; /* rotation */ if (convergence_mode == CAM_S3D_TOE) { float angle; float angle_sin, angle_cos; float toeinmat[4][4]; float rotmat[4][4]; unit_m4(rotmat); if (pivot == CAM_S3D_PIVOT_CENTER) { fac = -fac; fac_signed = -fac_signed; } angle = atanf((interocular_distance * 0.5f) / convergence_distance) / fac; angle_cos = cosf(angle * fac_signed); angle_sin = sinf(angle * fac_signed); rotmat[0][0] = angle_cos; rotmat[2][0] = -angle_sin; rotmat[0][2] = angle_sin; rotmat[2][2] = angle_cos; if (pivot == CAM_S3D_PIVOT_CENTER) { /* set the rotation */ copy_m4_m4(toeinmat, rotmat); /* set the translation */ toeinmat[3][0] = interocular_distance * fac_signed; /* transform */ normalize_m4_m4(r_modelmat, camera->obmat); mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat); /* scale back to the original size */ mul_m4_m4m4(r_modelmat, r_modelmat, sizemat); } else { /* CAM_S3D_PIVOT_LEFT, CAM_S3D_PIVOT_RIGHT */ /* rotate perpendicular to the interocular line */ normalize_m4_m4(r_modelmat, camera->obmat); mul_m4_m4m4(r_modelmat, r_modelmat, rotmat); /* translate along the interocular line */ unit_m4(toeinmat); toeinmat[3][0] = -interocular_distance * fac_signed; mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat); /* rotate to toe-in angle */ mul_m4_m4m4(r_modelmat, r_modelmat, rotmat); /* scale back to the original size */ mul_m4_m4m4(r_modelmat, r_modelmat, sizemat); } } else { normalize_m4_m4(r_modelmat, camera->obmat); /* translate - no rotation in CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL */ translate_m4(r_modelmat, -interocular_distance * fac_signed, 0.0f, 0.0f); /* scale back to the original size */ mul_m4_m4m4(r_modelmat, r_modelmat, sizemat); } }