class Renderer: def __init__(self, walls=(), ground=None, sky=None, filename='SOURCE-2.jpg', reducing=1): self.walls = walls self.ground = ground print ground self.sky = sky self.vertexes = VertexData() self.triangles = [] self.count = 0 self.filename = filename self.project = CameraProperties.make_project_name(filename) self.cp = CameraProperties(project=self.project) self.reducing = reducing # self.world_image = self.cp.image2plane(reducing=self.reducing) self.world_image = self.get_world_coordinates_image(self.project) def get_world_coordinates_image(self, project=''): world_image = ExtendedImage.load(project) if not world_image: world_image = self.cp.image2plane(reducing=self.reducing) return world_image def set_vertexes(self, increase=2): # self.set_ground_by_points_in_grid(increase=1) self.set_ground_by_lines(increase=increase) # self.set_ground_by_vertexes() for wall in self.walls: self.set_wall(wall=wall) self.set_sky() def set_ground_by_lines(self, increase=4.0): if not self.ground: return tangents = [line[0][1] / line[0][0] for line in self.ground] idx_min_tg = tangents.index(min(tangents)) points_count = len(self.ground) p1, p2 = self.ground[(idx_min_tg - 1) % points_count][0], \ self.ground[(idx_min_tg + 1) % points_count][0] next_idx = (idx_min_tg - 1) % points_count if p1[0] > p2[0] \ else (idx_min_tg + 1) % points_count oriented_points = [self.ground[idx_min_tg][0], self.ground[next_idx][0]] now_idx, prev_idx = next_idx, idx_min_tg idx = self.find_next_point(now_idx=now_idx, prev_idx=prev_idx) while now_idx != idx_min_tg: print idx oriented_points.append(self.ground[idx][0]) now_idx, prev_idx = idx, now_idx idx = self.find_next_point(now_idx=now_idx, prev_idx=prev_idx, count=points_count) print oriented_points orientations = [self.line_orientation(oriented_points[i], oriented_points[(i + 1) % points_count]) for i in range(points_count)] param = lambda indx: get_parameters((oriented_points[indx], oriented_points[(indx + 1) % points_count])) lines_func = [lambda x, y: y <= get_value(param(i), x) if orientations[i] > 0 else y >= get_value(param(i), x) for i in range(points_count)] increase = float(increase) min_x, min_y, max_x, max_y = 10000, 10000, 0, 0 for line in lines: x, y = line[0] min_x = min(min_x, x) min_y = min(min_y, y) max_x = max(max_x, x) max_y = max(max_y, y) square = 0 x, x_m, y_m = 0, max_x - min_x, max_y - min_y while x < x_m: y = 0 while y < y_m: if all(func(x, y) for func in lines_func): square += 1 from random import random self.vertexes += Vertex(pos=(int(x / increase), int(y / increase), 0), nor=(0, 0, 1), col=(random(), random(), random())) y += 1 / increase x += 1 / increase # for x in [0: 1/increase: max_x - min_x]: # for y in range((max_y - min_y) * int(increase)): # if all(func(x, y) for func in lines_func): # square += 1 # from random import random # self.vertexes += Vertex(pos=(int(x / increase), int(y / increase), 0), # nor=(0, 0, 1), col=(random(), random(), random())) print square if not self.triangles: self.set_triangles() def set_ground_by_points_in_grid(self, normal=(0, 0, 1), increase=2.0): if not self.ground: return increase = float(increase) points_on_plane = get_points_on_plane(self.ground, increase=increase) print points_on_plane pop = points_on_plane square = 0 for i in range(pop.shape[0]): for j in range(pop.shape[1]): if pop[i][j]: square += 1 from random import random self.vertexes += Vertex(pos=(int(i / increase), int(j / increase), 0), nor=normal, col=(random(), random(), random())) print square if not self.triangles: self.set_triangles() def __draw_ground_by_vertexes(self): if not self.ground: return glColor3f(1, 1, 1) glBindTexture(GL_TEXTURE_2D, self.world_texture) glBegin(GL_POLYGON) glNormal3f(0, 0, -1) for line in self.ground: point_x, point_y = line[0] # glTexCoord2f(point_x / self.image_width, point_y / self.image_height) wp = self.cp.img2world(point=(point_x, point_y), reducing=self.reducing) glTexCoord2fv(self.world_image.image_coordinates(wp)) glVertex3f(float(wp[0]), float(wp[1]), 0) glEnd() @staticmethod def find_next_point(now_idx=1, prev_idx=0, count=5): return (now_idx + 1 if prev_idx == (now_idx - 1) % count else now_idx - 1) % count @staticmethod def line_orientation(p1, p2): return 1 if p1[0] > p2[0] else -1 def set_wall(self, wall=None, normal=(1, 0, 0)): pass def set_sky(self, normal=(0, -1, 0)): pass def set_triangles(self): points = [] for ver in self.vertexes: points.append(ver.pos[0:2]) triangles = delaunay(points) for tri in triangles: self.triangles.extend(self.vertexes[tri[i]].pos for i in xrange(3)) def __draw_cube(self, pos=(), size=1): if not pos: pos = self.cen x1, y1, z1 = pos x2, y2, z2 = map(lambda p: p + size, [x1, y1, z1]) glBindTexture(GL_TEXTURE_2D, self.texture) glBegin(GL_POLYGON) # front face glNormal3f(0.0, 0.0, 1.0) glTexCoord2f(0, 0) glVertex3f(x1, y1, z2) glTexCoord2f(1, 0) glVertex3f(x2, y1, z2) glTexCoord2f(1, 1) glVertex3f(x2, y2, z2) glTexCoord2f(0, 1) glVertex3f(x1, y2, z2) glEnd() glBegin(GL_POLYGON) # back face glNormal3f(0.0, 0.0, -1.0) glTexCoord2f(1, 0) glVertex3f(x2, y1, z1) glTexCoord2f(0, 0) glVertex3f(x1, y1, z1) glTexCoord2f(0, 1) glVertex3f(x1, y2, z1) glTexCoord2f(1, 1) glVertex3f(x2, y2, z1) glEnd() glBegin(GL_POLYGON) # left face glNormal3f(-1.0, 0.0, 0.0) glTexCoord2f(0, 0) glVertex3f(x1, y1, z1) glTexCoord2f(0, 1) glVertex3f(x1, y1, z2) glTexCoord2f(1, 1) glVertex3f(x1, y2, z2) glTexCoord2f(1, 0) glVertex3f(x1, y2, z1) glEnd() glBegin(GL_POLYGON) # right face glNormal3f(1.0, 0.0, 0.0) glTexCoord2f(0, 1) glVertex3f(x2, y1, z2) glTexCoord2f(0, 0) glVertex3f(x2, y1, z1) glTexCoord2f(1, 0) glVertex3f(x2, y2, z1) glTexCoord2f(1, 1) glVertex3f(x2, y2, z2) glEnd() glBegin(GL_POLYGON) # top face glNormal3f(0.0, 1.0, 0.0) glTexCoord2f(0, 1) glVertex3f(x1, y2, z2) glTexCoord2f(1, 1) glVertex3f(x2, y2, z2) glTexCoord2f(1, 0) glVertex3f(x2, y2, z1) glTexCoord2f(0, 0) glVertex3f(x1, y2, z1) glEnd() glBegin(GL_POLYGON) # bottom face glNormal3f(0.0, -1.0, 0.0) glTexCoord2f(1, 1) glVertex3f(x2, y1, z2) glTexCoord2f(1, 0) glVertex3f(x1, y1, z2) glTexCoord2f(0, 0) glVertex3f(x1, y1, z1) glTexCoord2f(0, 1) glVertex3f(x2, y1, z1) glEnd() @staticmethod def __draw_coordinates(): glLineWidth(2) glColor3f(1, 0, 0) glBegin(GL_LINES) glVertex3f(0, 0, 0) glVertex3f(10, 0, 0) glEnd() glLineWidth(2) glColor3f(0, 1, 0) glBegin(GL_LINES) glVertex3f(0, 0, 0) glVertex3f(0, 10, 0) glEnd() glLineWidth(2) glColor3f(0, 0, 1) glBegin(GL_LINES) glVertex3f(0, 0, 0) glVertex3f(0, 0, 10) glEnd() def __load_world_texture(self): image = self.world_image.image self.world_image_width = image.size[0] self.world_image_height = image.size[1] image = image.tobytes('raw', 'RGBA', 0, -1) texture = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texture) # 2d texture (x and y size) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) gluBuild2DMipmaps(GL_TEXTURE_2D, 3, self.world_image_width, self.world_image_height, GL_RGBA, GL_UNSIGNED_BYTE, image) self.world_texture = texture def __load_texture(self, filename='SOURCE.jpg', image=None): if not image: image = Image.open(filename) self.image_width = image.size[0] self.image_height = image.size[1] image = image.tobytes('raw', 'RGBA', 0, -1) texture = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, texture) # 2d texture (x and y size) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) gluBuild2DMipmaps(GL_TEXTURE_2D, 3, self.image_width, self.image_height, GL_RGBA, GL_UNSIGNED_BYTE, image) self.texture = texture def __init(self): glClearColor(0, 0, 0, 0) glClearDepth(1.0) glDepthFunc(GL_LEQUAL) glEnable(GL_DEPTH_TEST) glEnable(GL_TEXTURE_2D) glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) # self.eye, self.cen, self.up = [0, 0, 5], [3, 3, 0], [0, 1, 1] self.eye, self.cen, self.up = self.cp.get_eye_center_up_right(reducing=self.reducing) / self.world_image.reducing self.mouse_x, self.mouse_y, self.push = 0, 0, False # self.__load_texture(filename=self.filename) self.__load_world_texture() gluPerspective(60, 1.5, 0.1, 100000) def __reshape(self, width, height): glViewport(0, 0, width, height) glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(60.0, float(width) / float(height), 1.0, 1000.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(self.eye[0], self.eye[1], self.eye[2], self.cen[0], self.cen[1], self.cen[2], self.up[0], self.up[1], self.up[2]) print self.eye, self.cen def __display(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(self.eye[0], self.eye[1], self.eye[2], self.cen[0], self.cen[1], self.cen[2], self.up[0], self.up[1], self.up[2]) # glLoadIdentity() # glTranslatef(1, 0, 3) # glRotatef(0, 1, -1, 0) # d = 3 / sqrt(3) # glTranslatef(d - 1.5, d - 1.5, d - 1.5) # glTranslatef(1.5, 1.5, 1.5) # move cube from the center # glRotatef(0, 1.0, 1.0, 0.0) # glTranslatef(-1.5, -1.5, -1.5) # move cube into the center # self.__draw_objects() self.__draw_ground_by_vertexes() self.__draw_coordinates() # self.__draw_cube() glutSwapBuffers() def __e_pressed(self, speed): temp = map(lambda a, b: (a - b) * speed / 3.0, self.cen, self.eye) self.eye = map(lambda a, t: a + t, self.eye, temp) self.cen = map(lambda a, t: a + t, self.cen, temp) def __q_pressed(self, speed): temp = map(lambda a, b: (a - b) * speed / 3.0, self.cen, self.eye) self.eye = map(lambda a, t: a - t, self.eye, temp) self.cen = map(lambda a, t: a - t, self.cen, temp) def __w_pressed(self, speed): self.eye[2] += 3 * speed self.cen[2] += 3 * speed def __s_pressed(self, speed): self.eye[2] -= 3 * speed self.cen[2] -= 3 * speed def __a_pressed(self, speed): cross_vector = normalize(np.cross(np.array(map(lambda a, b: a - b, self.eye, self.cen)), np.array(self.up))) self.eye = map(lambda a, b: a + b * speed, self.eye, cross_vector) self.cen = map(lambda a, b: a + b * speed, self.cen, cross_vector) def __d_pressed(self, speed): cross_vector = normalize(np.cross(np.array(map(lambda a, b: a - b, self.eye, self.cen)), np.array(self.up))) self.eye = map(lambda a, b: a - b * speed, self.eye, cross_vector) self.cen = map(lambda a, b: a - b * speed, self.cen, cross_vector) def __keyboard(self, key, mx, my): speed = 0.8 print self.cen, self.eye { 'e': self.__e_pressed, 'q': self.__q_pressed, 'w': self.__w_pressed, 'a': self.__a_pressed, 's': self.__s_pressed, 'd': self.__d_pressed, }[key](speed) def __mouse(self, button, mode, pos_x, pos_y): if button == GLUT_LEFT_BUTTON: self.mouse_x = pos_x self.mouse_y = pos_y self.push = True if mode == GLUT_DOWN else False def __mouse_move(self, pos_x, pos_y): if self.push: _x, _y = pos_x - self.mouse_x, pos_y - self.mouse_y temp = map(lambda a, b: a - b, self.cen, self.eye) if _x: fx = _x * pi / 180.0 / 20.0 self.cen[2] = self.eye[2] + sin(fx) * temp[0] + cos(fx) * temp[2] self.cen[0] = self.eye[0] + cos(fx) * temp[0] - sin(fx) * temp[2] print _x, _y if _y: self.cen[1] -= _y / 20.0 self.mouse_x = pos_x self.mouse_y = pos_y def render(self): glutInit(sys.argv) glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH) glutInitWindowSize(500, 500) glutCreateWindow('First Try') glutDisplayFunc(self.__display) glutReshapeFunc(self.__reshape) glutKeyboardFunc(self.__keyboard) glutMouseFunc(self.__mouse) glutMotionFunc(self.__mouse_move) glutIdleFunc(glutPostRedisplay) self.__init() glutMainLoop()