void render_handler_nui::draw_mesh_strip(const void* coords, int vertex_count) { // Set up current style. m_current_styles[LEFT_STYLE].apply(); std::list<nuiShape::CacheElement*> mElements; nuiShape::CacheElement element(GL_TRIANGLE_STRIP, vertex_count); element.CacheElement()) mElements.push_back(&element); nuiShape shp; shp.GetFillCache().push_back() mpContext->DrawCachedShape(&mElements, eFillShape); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the tris to OpenGL glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); if (m_current_styles[LEFT_STYLE].needs_second_pass()) { m_current_styles[LEFT_STYLE].apply_second_pass(); glDrawArrays(GL_TRIANGLE_STRIP, 0, vertex_count); m_current_styles[LEFT_STYLE].cleanup_second_pass(); } glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); }
/* translate shape from 3d world space to 2d screen space */ void translate_shape() { int d; MATRIX matrix; VTX *outpoint = current_points; QUAD *outface = current_faces; /* build a transformation matrix */ get_transformation_matrix(&matrix, itofix(1), shape.rx, shape.ry, shape.rz, shape.x, shape.y, shape.z); /* output the vertices */ for (d=0; d<NUM_VERTICES; d++) { apply_matrix(&matrix, points[d].x, points[d].y, points[d].z, &outpoint[d].x, &outpoint[d].y, &outpoint[d].z); persp_project(outpoint[d].x, outpoint[d].y, outpoint[d].z, &outpoint[d].x, &outpoint[d].y); } /* output the faces */ for (d=0; d<NUM_FACES; d++) { outface[d] = faces[d]; outface[d].vtxlist = outpoint; } outpoint += NUM_VERTICES; outface += NUM_FACES; }
static int map_output_xrandr(Display *dpy, int deviceid, const char *output_name) { int rc = EXIT_FAILURE; XRRScreenResources *res; XRROutputInfo *output_info; res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy)); output_info = find_output_xrandr(dpy, output_name); /* crtc holds our screen info, need to compare to actual screen size */ if (output_info) { XRRCrtcInfo *crtc_info; Matrix m; matrix_set_unity(&m); crtc_info = XRRGetCrtcInfo (dpy, res, output_info->crtc); set_transformation_matrix(dpy, &m, crtc_info->x, crtc_info->y, crtc_info->width, crtc_info->height); rc = apply_matrix(dpy, deviceid, &m); XRRFreeCrtcInfo(crtc_info); XRRFreeOutputInfo(output_info); } else printf("Unable to find output '%s'. " "Output may not be connected.\n", output_name); XRRFreeScreenResources(res); return rc; }
void apply_rot_norm(double *m, t_coord *move) { double *tmp; tmp = (double *)j_malloc(sizeof(double) * 16); transpose_matrix(tmp, m); apply_matrix(tmp, move); free(tmp); }
void draw_line_strip(const void* coords, int vertex_count) // Draw the line strip formed by the sequence of points. { // Set up current style. m_current_styles[LINE_STYLE].apply(); // apply line width float scale = fabsf(m_current_matrix.get_x_scale()) + fabsf(m_current_matrix.get_y_scale()); float w = m_current_styles[LINE_STYLE].m_width * scale / 2.0f; w = TWIPS_TO_PIXELS(w); // GLfloat width_info[2]; // glGetFloatv(GL_LINE_WIDTH_RANGE, width_info); // if (w > width_info[1]) // { // printf("Your OpenGL implementation does not support the line width" // " requested. Lines will be drawn with reduced width."); // } glLineWidth(w <= 1.0f ? 1.0f : w); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the line-strip to OpenGL glEnableClientState(GL_VERTEX_ARRAY); #if TU_USES_FLOAT_AS_COORDINATE_COMPONENT glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, coords); #else glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); #endif glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glDrawArrays(GL_LINE_STRIP, 0, vertex_count); glDisable(GL_LINE_SMOOTH); // Draw a round dot on the beginning and end coordinates to lines. glPointSize(w); glEnable(GL_POINT_SMOOTH); glDrawArrays(GL_POINTS, 0, vertex_count); glDisable(GL_POINT_SMOOTH); glPointSize(1); glDisableClientState(GL_VERTEX_ARRAY); // restore defaults glPointSize(1); glLineWidth(1); glPopMatrix(); }
void clear() // Clear the drawing surface and initialize viewing parameters. { glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set up the projection and view matrices. // Projection matrix. glMatrixMode(GL_PROJECTION); setup_projection_matrix(window_width, window_height, horizontal_fov_degrees); // View matrix. glMatrixMode(GL_MODELVIEW); glLoadIdentity(); view.m_matrix.View(viewer_dir, viewer_up, viewer_pos); apply_matrix(view.m_matrix); // Transform the frustum planes from view coords into world coords. int i; for (i = 0; i < 6; i++) { // Rotate the plane from view coords into world coords. I'm pretty sure this is not a slick // way to do this :) plane_info& tp = view.m_frustum[i]; plane_info& p = frustum_plane[i]; view.m_matrix.ApplyInverseRotation(&tp.normal, p.normal); vec3 v; view.m_matrix.ApplyInverse(&v, p.normal * p.d); tp.d = v * tp.normal; } // Enable z-buffer. glDepthFunc(GL_LEQUAL); // smaller z gets priority // Turn on back-face culling. glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); // Set the wireframe state. if (wireframe_mode) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } }
static int map_output_xinerama(Display *dpy, int deviceid, const char *output_name) { const char *prefix = "HEAD-"; XineramaScreenInfo *screens = NULL; int rc = EXIT_FAILURE; int event, error; int nscreens; int head; Matrix m; if (!XineramaQueryExtension(dpy, &event, &error)) { fprintf(stderr, "Unable to set screen mapping. Xinerama extension not found\n"); goto out; } if (strlen(output_name) < strlen(prefix) + 1 || strncmp(output_name, prefix, strlen(prefix)) != 0) { fprintf(stderr, "Please specify the output name as HEAD-X," "where X is the screen number\n"); goto out; } head = output_name[strlen(prefix)] - '0'; screens = XineramaQueryScreens(dpy, &nscreens); if (nscreens == 0) { fprintf(stderr, "Xinerama failed to query screens.\n"); goto out; } else if (nscreens <= head) { fprintf(stderr, "Found %d screens, but you requested %s.\n", nscreens, output_name); goto out; } matrix_set_unity(&m); set_transformation_matrix(dpy, &m, screens[head].x_org, screens[head].y_org, screens[head].width, screens[head].height); rc = apply_matrix(dpy, deviceid, &m); out: XFree(screens); return rc; }
void render_handler_nui::draw_line_strip(const void* coords, int vertex_count) // Draw the line strip formed by the sequence of points. { // Set up current style. m_current_styles[LINE_STYLE].apply(); nuiShape shp; nuiContour* pContour = new nuiContour(); std::list<nuiPoint> lines; for (uint i = 0; i < vertex_count; i++) lines.push_back(nuiPoint(coords[i*2], coords[i*2+1])); pContour->AddLines(lines); shp.AddContour(pContour); mpContext->PushMatrix(); apply_matrix(m_current_matrix); if (mMasking) { mpContext->AddClipShape(shp); } else { mpContext->DrawShape(&shp, nuiShapeMode::eStrokeShape); } mpContext->PopMatrix(); /* glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the line-strip to OpenGL glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); glDrawArrays(GL_LINE_STRIP, 0, vertex_count); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); */ }
void setup_view(float nearz, float farz) { // Set up the projection and view matrices. // Projection matrix. glMatrixMode(GL_PROJECTION); setup_projection_matrix(window_width, window_height, horizontal_fov_degrees, nearz, farz); // View matrix. glMatrixMode(GL_MODELVIEW); glLoadIdentity(); s_view.m_matrix.set_view(viewer_dir, viewer_up, viewer_pos); apply_matrix(s_view.m_matrix); // Transform the frustum planes from view coords into world coords. int i; for (i = 0; i < 6; i++) { // Rotate the plane from view coords into world coords. I'm pretty sure this is not a slick // way to do this :) plane_info& tp = s_view.m_frustum[i]; plane_info& p = frustum_plane[i]; s_view.m_matrix.apply_inverse_rotation(&tp.normal, p.normal); vec3 v; s_view.m_matrix.apply_inverse(&v, p.normal * p.d); tp.d = v * tp.normal; } // Enable z-buffer. glDepthFunc(GL_LEQUAL); // smaller z gets priority // Turn on back-face culling. glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); // Set the wireframe state. if (wireframe_mode) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } }
void draw_mesh_primitive(int primitive_type, const void* coords, int vertex_count) // Helper for draw_mesh_strip and draw_triangle_list. { // Set up current style. m_current_styles[LEFT_STYLE].apply(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the tris to OpenGL glEnableClientState(GL_VERTEX_ARRAY); #if TU_USES_FLOAT_AS_COORDINATE_COMPONENT glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, coords); #else glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); #endif glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glDrawArrays(primitive_type, 0, vertex_count); if (m_current_styles[LEFT_STYLE].needs_second_pass()) { m_current_styles[LEFT_STYLE].apply_second_pass(); glDrawArrays(primitive_type, 0, vertex_count); m_current_styles[LEFT_STYLE].cleanup_second_pass(); } glDisable(GL_LINE_SMOOTH); m_current_styles[LEFT_STYLE].applyTexture(primitive_type, coords, vertex_count); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); }
void apply_rot(double *m, t_coord *move) { apply_matrix(m, move); }
void draw_mesh_primitive(int primitive_type, const void* coords, int vertex_count) // Helper for draw_mesh_strip and draw_triangle_list. { #define NORMAL_RENDERING //#define MULTIPASS_ANTIALIASING #ifdef NORMAL_RENDERING // Set up current style. m_current_styles[LEFT_STYLE].apply(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the tris to OpenGL glEnableClientState(GL_VERTEX_ARRAY); #if TU_USES_FLOAT_AS_COORDINATE_COMPONENT glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, coords); #else glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); #endif glDrawArrays(primitive_type, 0, vertex_count); if (m_current_styles[LEFT_STYLE].needs_second_pass()) { m_current_styles[LEFT_STYLE].apply_second_pass(); glDrawArrays(primitive_type, 0, vertex_count); m_current_styles[LEFT_STYLE].cleanup_second_pass(); } // the antialiasing of polygon edges if (m_enable_antialias) { glEnable(GL_POLYGON_SMOOTH); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // GL_NICEST, GL_FASTEST, GL_DONT_CARE glDrawArrays(primitive_type, 0, vertex_count); glDisable(GL_POLYGON_SMOOTH); } glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); #endif // NORMAL_RENDERING #ifdef MULTIPASS_ANTIALIASING // So this approach basically works. This // implementation is not totally finished; two pass // materials (i.e. w/ additive color) aren't correct, // and there are some texture etc issues because I'm // just hosing state uncarefully here. It needs the // optimization of only filling the bounding box of // the shape. You must have destination alpha. // // It doesn't look quite perfect on my GF4. For one // thing, you kinda want to crank down the max curve // subdivision error, because suddenly you can see // sub-pixel shape much better. For another thing, // the antialiasing isn't quite perfect, to my eye. // It could be limited alpha precision, imperfections // GL_POLYGON_SMOOTH, and/or my imagination. glDisable(GL_TEXTURE_2D); glEnable(GL_POLYGON_SMOOTH); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // GL_NICEST, GL_FASTEST, GL_DONT_CARE // Clear destination alpha. // // @@ TODO Instead of drawing this huge screen-filling // quad, we should take a bounding-box param from the // caller, and draw the box (after apply_matrix; // i.e. the box is in object space). The point being, // to only fill the part of the screen that the shape // is in. glBlendFunc(GL_ZERO, GL_SRC_COLOR); glColor4f(1, 1, 1, 0); glBegin(GL_QUADS); glVertex2f(0, 0); glVertex2f(100000, 0); glVertex2f(100000, 100000); glVertex2f(0, 100000); glEnd(); // Set mode for drawing alpha mask. glBlendFunc(GL_ONE, GL_ONE); // additive blending glColor4f(0, 0, 0, m_current_styles[LEFT_STYLE].m_color.m_a / 255.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); apply_matrix(m_current_matrix); // Send the tris to OpenGL. This produces an // antialiased alpha mask of the mesh shape, in the // destination alpha channel. glEnableClientState(GL_VERTEX_ARRAY); #if TU_USES_FLOAT_AS_COORDINATE_COMPONENT glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, coords); #else glVertexPointer(2, GL_SHORT, sizeof(Sint16) * 2, coords); #endif glDrawArrays(primitive_type, 0, vertex_count); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); // Set up desired fill style. m_current_styles[LEFT_STYLE].apply(); // Apply fill, modulated with alpha mask. // // @@ TODO see note above about filling bounding box only. glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA); glBegin(GL_QUADS); glVertex2f(0, 0); glVertex2f(100000, 0); glVertex2f(100000, 100000); glVertex2f(0, 100000); glEnd(); // xxxxx ??? Hm, is our mask still intact, or did we just erase it? // if (m_current_styles[LEFT_STYLE].needs_second_pass()) // { // m_current_styles[LEFT_STYLE].apply_second_pass(); // glDrawArrays(primitive_type, 0, vertex_count); // m_current_styles[LEFT_STYLE].cleanup_second_pass(); // } // @@ hm, there is perhaps more state that needs // fixing here, or setting elsewhere. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #endif // MULTIPASS_ANTIALIASING }
int main(int argc, char *argv[]) { // Initialize randomness srand(time(NULL)); // 7 parameters are required. if (argc != 13) { fprintf(stderr, "Usage: %s obj-file sx sy sz tx ty tz rx ry rz focal-dist hiding\n", argv[0]); return 0; } unsigned int i, j; double sx = atof( argv[2] ); double sy = atof( argv[3] ); double sz = atof( argv[4] ); double tx = atof( argv[5] ); double ty = atof( argv[6] ); double tz = atof( argv[7] ); double rx = atof( argv[8] ); double ry = atof( argv[9] ); double rz = atof( argv[10] ); double fd = atof( argv[11] ); int hiding = atoi( argv[12] ); matrix_double scale = scale_by(sx, sy, sz); matrix_double tras = traslate(tx, ty, tz); matrix_double rot = rotate(rx, ry, rz); matrix_double proj = projection(fd); file_data vnf = readobj(argv[1]); // int p; // for (p = 0; p < vnf.vertices.num_elems; p++) { // point3d t = (vnf.vertices.data)[p]; // fprintf(stderr, "(%f,%f,%f)\n", t.x, t.y, t.z); // } // Join all the transformations in a single matrix // Operation order: Scaling, rotation, traslation and projection matrix_double t1 = product(proj, tras); matrix_double t2 = product(t1, rot); matrix_double t3 = product(t2, scale); apply_matrix(t3, vnf.vertices); dispose_matrix(&t3); dispose_matrix(&t2); dispose_matrix(&t1); dispose_matrix(&scale); dispose_matrix(&tras); dispose_matrix(&rot); dispose_matrix(&proj); // Projection sets w = z, so divide everything by w. for (i = 0; i < vnf.vertices.num_elems; i++) { point3d tmp = (vnf.vertices.data)[i]; tmp.x /= tmp.w; tmp.y /= tmp.w; tmp.z /= tmp.w; (vnf.vertices.data)[i] = tmp; } // The camera normal (taking advantage of perspective projection) vector camera_normal = new_vector( new_point3d(0.0, 0.0, 0.0, 1.0), new_point3d(0.0, 0.0, 1.0, 1.0) ); // The z-buffer double **zbuf = calloc(HEIGHT, sizeof *zbuf); for (i = 0; i < HEIGHT; i++) { zbuf[i] = calloc(WIDTH, sizeof **zbuf); for (j = 0; j < WIDTH; j++) zbuf[i][j] = DBL_MAX; } color c = new_color( 255, 255, 255 ); point center = { WIDTH >> 1, HEIGHT >> 1 }; int invertX = 0, invertY = 1; raster tmp = new_raster(WIDTH, HEIGHT, 3); for (i = 0; i < vnf.faces.num_elems; i++) { point3d v1 = (vnf.vertices.data)[((vnf.faces.data)[i].v1) - 1]; point3d v2 = (vnf.vertices.data)[((vnf.faces.data)[i].v2) - 1]; point3d v3 = (vnf.vertices.data)[((vnf.faces.data)[i].v3) - 1]; point pt[3] = { new_point(v1.x, v1.y), new_point(v2.x, v2.y), new_point(v3.x, v3.y) }; for (j = 0; j < 3; j++) pt[j] = raster_translate(pt[j], center, invertX, invertY); // Hiding faces using face normals if (hiding == 1) { vector va = new_vector( v1, v2 ); vector vb = new_vector( v1, v3 ); vector vn = vector_crossproduct( va, vb ); if ( abs(vector_angle(vn, camera_normal)) < 90.0 ) continue; } // Drawing the face for (j = 0; j < 3; j++) { int curr = j; int next = (j+1) % 3; point ps = pt[curr]; point pe = pt[next]; // Use z-buffering if allowed // if (hiding == 2) // put_line_z(tmp, new_line( ps, pe ), c, bresenham, zbuf, vertices[3][curr], vertices[3][next]); // else put_line(tmp, new_line( ps, pe ), c, bresenham); } // Filling the face using a random, eye-pleasing colour color cr = { ((rand() % 255) + 255) >> 1, ((rand() % 255) + 255) >> 1, ((rand() % 255) + 255) >> 1 }; // if (hiding == 2) // fill_face_z(tmp, pt[0], pt[1], pt[2], cr, zbuf, vertices[3][j], vertices[3][(j+1) % 3]); // elseelse fill_face(tmp, pt[0], pt[1], pt[2], cr); } raster_out(tmp); dispose_raster(tmp); for (i = 0; i < HEIGHT; i++) free(zbuf[i]); free(zbuf); free(vnf.vertices.data); free(vnf.faces.data); return 0; }