Improved Batch Functionality

Now batches are actually batches.

Also added the MeshFactory class.

Drawing modes are now specified with DrawMode instead of the
GLenum. Renderables must be specified with a draw mode.
This commit is contained in:
elipzer 2018-09-06 23:22:40 -04:00
parent 2b8db77667
commit 3485bcb2a0
21 changed files with 394 additions and 147 deletions

View File

@ -8,9 +8,7 @@ Application::Application()
}
Application::~Application()
{
}
Application::~Application() {}
int Application::run()
{

View File

@ -2,23 +2,116 @@
#include "stdafx.h"
#include <cstddef>
#include <vector>
#include "ShaderProgram.h"
#include "Exception.h"
template <typename RenderableType>
namespace
{
struct EmptyElement {};
}
template <typename VertexType, typename IndexType, typename ElementType = EmptyElement, typename RenderableType = Renderable<VertexType, IndexType> >
class Batch
{
public:
void init()
typedef GLsizei SizeType;
Batch(
const RenderableType* renderable,
const SizeType& element_count,
const SizeType& element_render_count
)
: m_p_renderable(renderable), m_elements(element_count), m_element_render_count(element_render_count)
{
populate_vbos();
setup_vao();
if (std::is_same<unsigned int, IndexType>::value)
{
m_gl_index_type = GL_UNSIGNED_INT;
}
else if (std::is_same<unsigned short, IndexType>::value)
{
m_gl_index_type = GL_UNSIGNED_SHORT;
}
else if (std::is_same<unsigned char, IndexType>::value)
{
m_gl_index_type = GL_UNSIGNED_BYTE;
}
else
{
throw EXCEPTION("Invalid Batch IndexType");
}
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vertex_vbo);
glGenBuffers(1, &m_index_vbo);
}
virtual void render() const = 0;
virtual ~Batch()
{
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vertex_vbo);
glDeleteBuffers(1, &m_index_vbo);
}
void init()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
glBufferData(GL_ARRAY_BUFFER, m_p_renderable->get_mesh()->vertex_count * sizeof(VertexType), m_p_renderable->get_mesh()->vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, NULL);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_p_renderable->get_mesh()->index_count * sizeof(IndexType), m_p_renderable->get_mesh()->indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL);
setup_element_buffer();
glBindVertexArray(m_vao); // Possibly want to move these three lines into the init function
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_vbo);
setup_vao();
glBindVertexArray(NULL);
}
void render() const
{
glBindVertexArray(m_vao);
glDrawElementsInstanced(
m_p_renderable->get_draw_mode(),
m_p_renderable->get_mesh()->index_count,
m_gl_index_type,
0,
(GLsizei)m_element_render_count
);
glBindVertexArray(NULL);
}
void set_element_render_count(const SizeType& element_render_count)
{
m_element_render_count = element_render_count;
}
ElementType& get_element() { return m_elements[0]; }
ElementType& get_element(const SizeType& index) { return m_elements[index]; }
const ElementType& get_element() const { return m_elements[0]; }
const ElementType& get_element(const SizeType& index) const { return m_elements[index]; }
protected:
virtual void populate_vbos() = 0;
virtual void setup_element_buffer() {}
virtual void setup_vao() = 0;
const RenderableType* m_p_renderable;
std::vector<ElementType> m_elements;
SizeType m_element_render_count;
private:
GLuint m_vao;
GLuint m_vertex_vbo;
GLuint m_index_vbo;
GLenum m_gl_index_type;
};

19
OpenGLEngine/DrawMode.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include "stdafx.h"
enum DrawMode : GLenum
{
DRAW_POINTS = GL_POINTS,
DRAW_LINE_STRIP = GL_LINE_STRIP,
DRAW_LINE_LOOP = GL_LINE_LOOP,
DRAW_LINES = GL_LINES,
DRAW_LINE_STRIP_ADJACENCY = GL_LINE_STRIP_ADJACENCY,
DRAW_LINES_ADJACENCY = GL_LINES_ADJACENCY,
DRAW_TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
DRAW_TRIANGLE_FAN = GL_TRIANGLE_FAN,
DRAW_TRIANGLES = GL_TRIANGLES,
DRAW_TRIANGLE_STRIP_ADJACENCY = GL_TRIANGLE_STRIP_ADJACENCY,
DRAW_TRIANGLES_ADJACENCY = GL_TRIANGLES_ADJACENCY,
DRAW_PATCHES = GL_PATCHES,
};

View File

@ -1,9 +1,7 @@
#include "Exception.h"
Exception::Exception(const std::string& message, const std::string& class_name)
: m_message(message), m_class_name(class_name)
{
}
: m_message(message), m_class_name(class_name) {}
const std::string& Exception::get_message()
{

View File

@ -9,7 +9,7 @@
//Max number for frames = 255
//Lower frames = jumpy, instant updates
//Higher frames = smoother, flowing updates
class FPS
class FPS final
{
public:
FPS(unsigned short frames = 2);

View File

@ -1,13 +1,9 @@
#include "InputManager.h"
InputManager::InputManager()
{
}
InputManager::InputManager() {}
InputManager::~InputManager()
{
}
InputManager::~InputManager() {}
void InputManager::mark()
{

View File

@ -3,6 +3,9 @@
template <typename VertexType, typename IndexType>
struct Mesh
{
typedef VertexType VertexType;
typedef IndexType IndexType;
VertexType* vertices = nullptr;
unsigned int vertex_count = 0;
IndexType* indices = nullptr;

205
OpenGLEngine/MeshFactory.h Normal file
View File

@ -0,0 +1,205 @@
#pragma once
#include <vector>
#include "DrawMode.h"
#include "Exception.h"
template <typename VertexType, typename IndexType>
class MeshFactory
{
public:
typedef Mesh<VertexType, IndexType> MeshType;
protected:
MeshFactory() {} // Prevent Instantiation
public:
typedef unsigned int SizeType;
virtual ~MeshFactory()
{
for (SizeType i = 0; i < m_meshes.size(); ++i)
{
delete[] m_meshes[i]->vertices;
delete[] m_meshes[i]->indices;
delete m_meshes[i];
}
}
static MeshType* gen(const DrawMode& draw_mode, const VertexType& a)
{
MeshType* mesh;
switch (draw_mode)
{
case DrawMode::DRAW_POINTS:
mesh = create_mesh(1, 1);
mesh->vertices[0] = a;
mesh->indices[0] = 0;
return mesh;
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
case DrawMode::DRAW_TRIANGLES:
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw Exception("Unable to gen for current draw mode: " + std::to_string(draw_mode), "class MeshFactory");
}
}
static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b)
{
MeshType* mesh;
switch (draw_mode)
{
case DrawMode::DRAW_POINTS:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_LINES:
mesh = create_mesh(2, 2);
mesh->vertices[0] = a;
mesh->vertices[1] = b;
mesh->indices[0] = 0;
mesh->indices[1] = 1;
return mesh;
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
case DrawMode::DRAW_TRIANGLES:
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw Exception("Unable to gen for current draw mode: " + std::to_string(draw_mode), "class MeshFactory");
}
}
static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b, const VertexType& c)
{
MeshType* mesh;
switch (draw_mode)
{
case DrawMode::DRAW_POINTS:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
case DrawMode::DRAW_TRIANGLES:
mesh = create_mesh(3, 3);
mesh->vertices[0] = a;
mesh->vertices[1] = b;
mesh->vertices[2] = c;
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 2;
return mesh;
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw Exception("Unable to gen for current draw mode: " + std::to_string(draw_mode), "class MeshFactory");
}
}
static MeshType* gen(const DrawMode& draw_mode, const VertexType& a, const VertexType& b, const VertexType& c, const VertexType& d)
{
MeshType* mesh;
switch (draw_mode)
{
case DrawMode::DRAW_POINTS:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
mesh = create_mesh(4, 4);
mesh->vertices[0] = a;
mesh->vertices[1] = b;
mesh->vertices[2] = c;
mesh->vertices[3] = d;
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 2;
mesh->indices[3] = 3;
return mesh;
case DrawMode::DRAW_TRIANGLES:
mesh = create_mesh(4, 6);
mesh->vertices[0] = a;
mesh->vertices[1] = b;
mesh->vertices[2] = c;
mesh->vertices[3] = d;
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 2;
mesh->indices[3] = 2;
mesh->indices[4] = 1;
mesh->indices[5] = 3;
return mesh;
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw Exception("Unable to gen for current draw mode: " + std::to_string(draw_mode), "class MeshFactory");
}
}
static MeshType* gen(const DrawMode& draw_mode, const std::vector<VertexType>& vertices, const std::vector<IndexType>& indices)
{
MeshType* mesh;
switch (draw_mode)
{
case DrawMode::DRAW_POINTS:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
case DrawMode::DRAW_TRIANGLES:
int n = vertices.size();
mesh = create_mesh(n, n);
for (SizeType i = 0; i < vertices.size(); ++i)
{
mesh->vertices[i] = vertices[i];
mesh->indices[i] = i;
}
return mesh;
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw Exception("Unable to gen for current draw mode: " + std::to_string(draw_mode), "class MeshFactory");
}
}
protected:
static MeshType* create_mesh(unsigned int vertex_count, unsigned int index_count)
{
MeshType* mesh = new MeshType();
mesh->vertices = new VertexType[vertex_count];
mesh->vertex_count = vertex_count;
mesh->indices = new IndexType[vertex_count];
mesh->index_count = index_count;
m_meshes.push_back(mesh);
return mesh;
}
private:
static std::vector<MeshType*> m_meshes;
};
template <typename VertexType, typename IndexType>
std::vector<Mesh<VertexType, IndexType>*> MeshFactory<VertexType, IndexType>::m_meshes = std::vector<Mesh<VertexType, IndexType>*>();

View File

@ -1,31 +1,8 @@
#include "MyBatch.h"
MyBatch::MyBatch(const MyTriangle& triangle)
: m_triangle(&triangle)
{
}
void MyBatch::render() const
{
glBindVertexArray(m_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void MyBatch::populate_vbos()
{
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
m_triangle->populate_vbo();
}
void MyBatch::setup_vao()
{
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBindVertexArray(0);
}

View File

@ -2,23 +2,16 @@
#include "Batch.h"
#include "Renderable.h"
#include "MyShaderProgram.h"
#include "MyTriangle.h"
class MyBatch : public Batch<MyTriangle>
class MyBatch : public Batch<MyShaderProgram::VertexType, MyShaderProgram::IndexType>
{
public:
MyBatch(const MyTriangle& triangle);
void render() const override;
MyBatch(
const MyShaderProgram::RenderableType* renderable,
const SizeType& element_count,
const SizeType& element_render_count
) : Batch(renderable, element_count, element_render_count) {}
protected:
void populate_vbos() override;
void setup_vao() override;
private:
const MyTriangle* m_triangle;
GLuint m_vbo;
GLuint m_vao;
};

View File

@ -1,7 +1,16 @@
#include "MyObjectOrientedScene.h"
#include "DrawMode.h"
#include "MeshFactory.h"
MyObjectOrientedScene::MyObjectOrientedScene()
: m_batch(m_triangle)
: m_shape(MeshFactory<MyShaderProgram::VertexType, MyShaderProgram::IndexType>::gen(
DrawMode::DRAW_TRIANGLES,
MyShaderProgram::VertexType(-0.5f, 0.4f, 0.0f),
MyShaderProgram::VertexType(0.5f, 0.4f, 0.0f),
MyShaderProgram::VertexType(-0.8f, -0.4f, 0.0f),
MyShaderProgram::VertexType(0.8f, -0.4f, 0.0f)
), DrawMode::DRAW_TRIANGLES), m_batch(&m_shape, 1, 1)
{
}

View File

@ -5,8 +5,6 @@
#include "MyBatch.h"
#include "MyShaderProgram.h"
#include "MyTriangle.h"
class MyObjectOrientedScene : public Scene
{
public:
@ -24,6 +22,6 @@ public:
void render() override;
private:
MyBatch m_batch;
MyTriangle m_triangle;
MyShaderProgram::RenderableType m_shape;
MyShaderProgram m_shader_program;
};

View File

@ -2,6 +2,7 @@
#include "ShaderProgram.h"
#include "Shader.h"
#include "Mesh.h"
#include "Renderable.h"
class MyShaderProgram : public ShaderProgram
@ -9,6 +10,7 @@ class MyShaderProgram : public ShaderProgram
public:
struct VertexType
{
VertexType() {}
VertexType(float x, float y, float z)
: x(x), y(y), z(z)
{
@ -17,8 +19,16 @@ public:
float y;
float z;
};
struct ColorType // Try changing to normalized unsigned chars (0-255) for the example
{
float r;
float g;
float b;
float a;
};
typedef unsigned int IndexType;
typedef Renderable<VertexType, IndexType> RenderableType;
typedef Mesh<VertexType, IndexType> MeshType;
MyShaderProgram();

View File

@ -5,8 +5,6 @@
#include "MyBatch.h"
#include "MyShaderProgram.h"
#include "MyTriangle.h"
class MySimpleScene :
public Scene
{

View File

@ -1,40 +0,0 @@
#include "MyTriangle.h"
#include "Mesh.h"
MyTriangle::MyTriangle()
{
MeshType* mesh = new MeshType();
mesh->vertices = new VertexType[3]
{
{ 0.0f, 0.75f, 0.0f },
{ 0.75f, -0.75f, 0.0f },
{ -0.75f, -0.75f, 0.0f },
};
mesh->vertex_count = 3;
mesh->indices = new unsigned int[3] { 0, 1, 2, };
mesh->index_count = 3;
m_p_mesh = mesh;
}
MyTriangle::~MyTriangle()
{
if (m_p_mesh != nullptr)
{
if (m_p_mesh->vertices != nullptr)
{
delete[] m_p_mesh->vertices;
}
if (m_p_mesh->indices != nullptr)
{
delete[] m_p_mesh->indices;
}
delete m_p_mesh;
m_p_mesh = nullptr;
}
}
void MyTriangle::populate_vbo() const
{
glBufferData(GL_ARRAY_BUFFER, m_p_mesh->vertex_count * sizeof(VertexType), m_p_mesh->vertices, GL_STATIC_DRAW);
}

View File

@ -1,15 +0,0 @@
#pragma once
#include "Renderable.h"
#include "MyShaderProgram.h"
class MyTriangle : public Renderable<MyShaderProgram::VertexType, MyShaderProgram::IndexType>
{
public:
MyTriangle();
~MyTriangle();
void populate_vbo() const override;
};

View File

@ -160,7 +160,6 @@
<ClCompile Include="MyObjectOrientedScene.cpp" />
<ClCompile Include="MyShaderProgram.cpp" />
<ClCompile Include="MySimpleScene.cpp" />
<ClCompile Include="MyTriangle.cpp" />
<ClCompile Include="Shader.cpp" />
<ClCompile Include="ShaderProgram.cpp" />
<ClCompile Include="stdafx.cpp">
@ -172,18 +171,19 @@
<ItemGroup>
<ClInclude Include="Application.h" />
<ClInclude Include="Batch.h" />
<ClInclude Include="DrawMode.h" />
<ClInclude Include="Exception.h" />
<ClInclude Include="FPS.h" />
<ClInclude Include="GLFWInputManager.h" />
<ClInclude Include="InputManager.h" />
<ClInclude Include="mat4x4.h" />
<ClInclude Include="Mesh.h" />
<ClInclude Include="MeshFactory.h" />
<ClInclude Include="MyApplication.h" />
<ClInclude Include="MyBatch.h" />
<ClInclude Include="MyObjectOrientedScene.h" />
<ClInclude Include="MyShaderProgram.h" />
<ClInclude Include="MySimpleScene.h" />
<ClInclude Include="MyTriangle.h" />
<ClInclude Include="Renderable.h" />
<ClInclude Include="Scene.h" />
<ClInclude Include="Shader.h" />

View File

@ -25,6 +25,12 @@
<Filter Include="Source Files\Example\Shader Code">
<UniqueIdentifier>{0c68fb1a-eaef-450c-ab9e-56bcfd75fdff}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Example\Scenes">
<UniqueIdentifier>{922d67ef-ebba-4810-b4c4-fab05be62c9a}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Example\Scenes">
<UniqueIdentifier>{9b6de612-281e-42cd-99a8-1917e2ba77bf}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="InputManager.cpp">
@ -39,15 +45,9 @@
<ClCompile Include="MyApplication.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
<ClCompile Include="MySimpleScene.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
<ClCompile Include="MyTriangle.cpp">
<Filter>Source Files\Example</Filter>
</ClCompile>
<ClCompile Include="Shader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -73,7 +73,10 @@
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MyObjectOrientedScene.cpp">
<Filter>Source Files\Example</Filter>
<Filter>Source Files\Example\Scenes</Filter>
</ClCompile>
<ClCompile Include="MySimpleScene.cpp">
<Filter>Source Files\Example\Scenes</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
@ -104,15 +107,9 @@
<ClInclude Include="FPS.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MySimpleScene.h">
<Filter>Header Files\Example</Filter>
</ClInclude>
<ClInclude Include="Renderable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MyTriangle.h">
<Filter>Header Files\Example</Filter>
</ClInclude>
<ClInclude Include="Shader.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -144,7 +141,16 @@
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MyObjectOrientedScene.h">
<Filter>Header Files\Example</Filter>
<Filter>Header Files\Example\Scenes</Filter>
</ClInclude>
<ClInclude Include="MySimpleScene.h">
<Filter>Header Files\Example\Scenes</Filter>
</ClInclude>
<ClInclude Include="MeshFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DrawMode.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

View File

@ -5,24 +5,25 @@
#include <type_traits>
#include "Mesh.h"
#include "DrawMode.h"
#include "Batch.h"
template <typename VertexType, typename IndexType>
class Renderable
class Renderable final
{
public:
typedef VertexType VertexType;
typedef IndexType IndexType;
typedef Mesh<VertexType, IndexType> MeshType;
virtual ~Renderable() { };
Renderable(const MeshType* mesh, const DrawMode& draw_mode)
: m_p_mesh(mesh), m_draw_mode(draw_mode) {}
const MeshType* get_mesh() const
{
return m_p_mesh;
}
const MeshType* get_mesh() const { return m_p_mesh; }
virtual void populate_vbo() const = 0;
const DrawMode& get_draw_mode() const { return m_draw_mode; }
protected:
private:
const MeshType* m_p_mesh = nullptr;
};
DrawMode m_draw_mode;
};

View File

@ -43,9 +43,7 @@ Shader::Shader(const std::string& source, ShaderType type)
}
}
Shader::~Shader()
{
}
Shader::~Shader() {}
GLuint Shader::get_shader() const
{

View File

@ -19,7 +19,7 @@ std::string Util::load_file(const std::string& path)
if (input_stream.is_open())
{
input_stream.seekg(0, std::ios::end);
size_t size = input_stream.tellg();
std::size_t size = input_stream.tellg();
std::string buffer(size, ' ');
input_stream.seekg(std::ios::beg);
input_stream.read(&buffer[0], size);