ParticleObject::ParticleObject(GraphicContext &gc, Scene &scene_owner, SceneObject *parent_object) : SceneObject(scene_owner, parent_object) { std::vector<Vec3f> object_positions; std::vector<Vec4f> object_colours; object_positions.resize(num_points); object_colours.resize(num_points); const float scale_x = 0.0015f; const float scale_y = 0.0015f; const float scale_z = 0.0015f; for (int cnt=0; cnt < num_points; cnt++) { object_positions[cnt] = Vec3f( ((rand() & 0xFFFFF) - (0xFFFFF/128.0f)) * scale_x, ((rand() & 0xFFFFF) - (0xFFFFF/128.0f)) * scale_y, ((rand() & 0xFFFFF) - (0xFFFFF/128.0f)) * scale_z ); Vec3f pos = object_positions[cnt]; pos = pos * pos; pos.normalize(); object_colours[cnt] = Vec4f( pos.x, pos.y, pos.z, 1.0f); } object_positions_vbo = VertexArrayBuffer(gc, &object_positions[0], sizeof(Vec3f) * object_positions.size()); object_colours_vbo = VertexArrayBuffer(gc, &object_colours[0], sizeof(Vec4f) * object_colours.size()); }
RenderBatchBuffer::RenderBatchBuffer(GraphicContext &gc) : current_vertex_buffer(0) { for (int index=0; index < num_vertex_buffers; index++) { vertex_buffers[index] = VertexArrayBuffer(gc, vertex_buffer_size, usage_stream_draw); } }
RenderBatchBuffer::RenderBatchBuffer(GraphicContext &gc) { for (auto & elem : vertex_buffers) { elem = VertexArrayBuffer(gc, vertex_buffer_size, usage_stream_draw); } }
GameTerrain::GameTerrain( GraphicContext &gc, const std::string &heightmap_png, const std::string &texture_png, const std::string &areas_png, const std::string &borders_png, int area_count, float vertical_scale) : num_vertices(0) { color_areas = PNGProvider::load(areas_png).to_format(tf_r8); PixelBuffer pb = PNGProvider::load(heightmap_png).to_format(tf_rgba8); int width = pb.get_width()-1; int height = pb.get_height()-1; num_vertices = width*height*3*4 /*+ width*6*2 + height*6*2 + 6*/; vertex_buffer = VertexArrayBuffer(gc, num_vertices*sizeof(Vertex)); vertex_buffer.lock(cl_access_write_only); Vertex *vertex_data = reinterpret_cast<Vertex *>(vertex_buffer.get_data()); int pitch = pb.get_pitch(); unsigned char *data = reinterpret_cast<unsigned char *>(pb.get_data()); for (int y = 0; y < height; y++) { unsigned int *line1 = reinterpret_cast<unsigned int *>(data + y*pitch); unsigned int *line2 = reinterpret_cast<unsigned int *>(data + (y+1)*pitch); Vertex *vertex_line = vertex_data + 3*4*width*y; for (int x = 0; x < width; x++) { float height1 = (line1[x] >> 24) * vertical_scale; float height2 = (line1[x+1] >> 24) * vertical_scale; float height3 = (line2[x] >> 24) * vertical_scale; float height4 = (line2[x+1] >> 24) * vertical_scale; float height5 = (height1 + height2 + height3 + height4) / 4.0f; Vertex *vertex_quad = vertex_line + x*3*4; Vec3f positions[12] = { Vec3f(x+0.0f, height1, y+0.0f), Vec3f(x+1.0f, height2, y+0.0f), Vec3f(x+0.5f, height5, y+0.5f), Vec3f(x+1.0f, height2, y+0.0f), Vec3f(x+1.0f, height4, y+1.0f), Vec3f(x+0.5f, height5, y+0.5f), Vec3f(x+1.0f, height4, y+1.0f), Vec3f(x+0.0f, height3, y+1.0f), Vec3f(x+0.5f, height5, y+0.5f), Vec3f(x+0.0f, height3, y+1.0f), Vec3f(x+0.0f, height1, y+0.0f), Vec3f(x+0.5f, height5, y+0.5f) }; for (int i = 0; i < 12; i++) vertex_quad[i].position = positions[i]; Vec3f normal1 = calc_normal(x, y, data, width, height, pitch); Vec3f normal2 = calc_normal(x+1, y, data, width, height, pitch); Vec3f normal3 = calc_normal(x, y+1, data, width, height, pitch); Vec3f normal4 = calc_normal(x+1, y+1, data, width, height, pitch); Vec3f normal5 = (normal1+normal2+normal3+normal4)/4.0f; vertex_quad[0].normal = normal1; vertex_quad[1].normal = normal2; vertex_quad[2].normal = normal5; vertex_quad[3].normal = normal2; vertex_quad[4].normal = normal4; vertex_quad[5].normal = normal5; vertex_quad[6].normal = normal4; vertex_quad[7].normal = normal3; vertex_quad[8].normal = normal5; vertex_quad[9].normal = normal3; vertex_quad[10].normal = normal1; vertex_quad[11].normal = normal5; } } vertex_data += width*height*3*4; /* for (int y = 0; y < height; y++) { unsigned int *line1 = reinterpret_cast<unsigned int *>(data + y*pitch); unsigned int *line2 = reinterpret_cast<unsigned int *>(data + (y+1)*pitch); float scale = 0.4f; float height1 = (line1[0] >> 24)*scale; float height2 = (line2[0] >> 24)*scale; float height3 = (line1[width] >> 24)*scale; float height4 = (line2[width] >> 24)*scale; vertex_data[y*6*2+0].position = Vec3f(0, -0.1f, (float)y); vertex_data[y*6*2+1].position = Vec3f(0, (float)height1, (float)y); vertex_data[y*6*2+2].position = Vec3f(0, (float)height2, (float)y+1); vertex_data[y*6*2+3].position = Vec3f(0, (float)height2, (float)y+1); vertex_data[y*6*2+4].position = Vec3f(0, -0.1f, (float)y+1); vertex_data[y*6*2+5].position = Vec3f(0, -0.1f, (float)y); vertex_data[y*6*2+11].position = Vec3f((float)width+1, -0.1f, (float)y); vertex_data[y*6*2+10].position = Vec3f((float)width+1, (float)height3, (float)y); vertex_data[y*6*2+9].position = Vec3f((float)width+1, (float)height4, (float)y+1); vertex_data[y*6*2+8].position = Vec3f((float)width+1, (float)height4, (float)y+1); vertex_data[y*6*2+7].position = Vec3f((float)width+1, -0.1f, (float)y+1); vertex_data[y*6*2+6].position = Vec3f((float)width+1, -0.1f, (float)y); for (int i = 0; i < 6; i++) vertex_data[y*6*2+i].normal = Vec3f(-1, 0, 0); for (int i = 0; i < 6; i++) vertex_data[y*6*2+6+i].normal = Vec3f(1, 0, 0); } vertex_data += height*6*2; unsigned int *line1 = reinterpret_cast<unsigned int *>(data); unsigned int *line2 = reinterpret_cast<unsigned int *>(data + height*pitch); for (int x = 0; x < width; x++) { float scale = 0.4f; float height1 = (line1[x] >> 24)*scale; float height2 = (line1[x+1] >> 24)*scale; float height3 = (line2[x] >> 24)*scale; float height4 = (line2[x+1] >> 24)*scale; vertex_data[x*6*2+5].position = Vec3f((float)x, -0.1f, 0); vertex_data[x*6*2+4].position = Vec3f((float)x, (float)height1, 0); vertex_data[x*6*2+3].position = Vec3f((float)x+1, (float)height2, 0); vertex_data[x*6*2+2].position = Vec3f((float)x+1, (float)height2, 0); vertex_data[x*6*2+1].position = Vec3f((float)x+1, -0.1f, 0); vertex_data[x*6*2+0].position = Vec3f((float)x, -0.1f, 0); vertex_data[x*6*2+6].position = Vec3f((float)x, -0.1f, (float)height+1); vertex_data[x*6*2+7].position = Vec3f((float)x, (float)height3, (float)height+1); vertex_data[x*6*2+8].position = Vec3f((float)x+1, (float)height4, (float)height+1); vertex_data[x*6*2+9].position = Vec3f((float)x+1, (float)height4, (float)height+1); vertex_data[x*6*2+10].position = Vec3f((float)x+1, -0.1f, (float)height+1); vertex_data[x*6*2+11].position = Vec3f((float)x, -0.1f, (float)height+1); for (int i = 0; i < 6; i++) vertex_data[x*6*2+i].normal = Vec3f(0, 0, -1); for (int i = 0; i < 6; i++) vertex_data[x*6*2+6+i].normal = Vec3f(0, 0, 1); } vertex_data += width*6*2; vertex_data[0].position = Vec3f(0, -0.1f, 0); vertex_data[1].position = Vec3f((float)width, -0.1f, 0); vertex_data[2].position = Vec3f((float)width, -0.1f, (float)height); vertex_data[3].position = Vec3f((float)width, -0.1f, (float)height); vertex_data[4].position = Vec3f(0, -0.1f, (float)height); vertex_data[5].position = Vec3f(0, -0.1f, 0); for (int i = 0; i < 6; i++) vertex_data[i].normal = Vec3f(0, -1, 0); */ vertex_buffer.unlock(); size = Size(width+1, height+1); this->area_count = area_count; VirtualDirectory vdir; shader_program = ProgramObject::load(gc, "Resources/map_vertex.glsl", "Resources/map_fragment.glsl", vdir); shader_program.bind_attribute_location(0, "in_position"); shader_program.bind_attribute_location(1, "in_normal"); if (!shader_program.link()) throw Exception("Map shader program failed to link: " + shader_program.get_info_log()); texture_base = Texture2D(gc, texture_png); texture_base.set_min_filter(filter_linear); texture_base.set_mag_filter(filter_linear); // Change the values between area colors to avoid GPUs merging them together PixelBuffer image = ImageProviderFactory::load(areas_png).to_format(tf_rgba8); unsigned int* image_data = reinterpret_cast<unsigned int*>(image.get_data()); int image_total_pixels = image.get_width()*image.get_height(); for (int i = 0; i < image_total_pixels; i++) { unsigned int area_color = (image_data[i]>>24)*255/area_count; image_data[i] = (area_color<<24)+(area_color<<16)+(area_color<<8)+area_color; } texture_areas = Texture2D(gc, image.get_size()); texture_areas.set_image(image); texture_areas.set_min_filter(filter_nearest); texture_areas.set_mag_filter(filter_nearest); texture_borders = Texture2D(gc, borders_png); texture_borders.set_min_filter(filter_linear); texture_borders.set_mag_filter(filter_linear); }