|
|
@@ -28,16 +28,15 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|
|
#include <GL/glew.h>
|
|
|
#include <cassert>
|
|
|
#include <algorithm>
|
|
|
+
|
|
|
#include "Types.h"
|
|
|
-#include "GLIndexBuffer.h"
|
|
|
#include "GLOcclusionQuery.h"
|
|
|
#include "GLRenderer.h"
|
|
|
#include "GLUtils.h"
|
|
|
-#include "GLVertexBuffer.h"
|
|
|
#include "Log.h"
|
|
|
#include "Material.h"
|
|
|
-#include "Allocator.h"
|
|
|
#include "TextureResource.h"
|
|
|
+#include "Vec3.h"
|
|
|
|
|
|
#if defined(WINDOWS)
|
|
|
//Define the missing constants in vs' gl.h
|
|
|
@@ -61,8 +60,12 @@ GLRenderer::GLRenderer() :
|
|
|
m_max_vertex_vertices(0),
|
|
|
m_max_anisotropy(0.0f),
|
|
|
|
|
|
- m_texture_count(0),
|
|
|
- m_active_texture_unit(0)
|
|
|
+ m_textures_id_table(m_allocator, MAX_TEXTURES),
|
|
|
+ m_active_texture_unit(0),
|
|
|
+
|
|
|
+ m_vertex_buffers_id_table(m_allocator, MAX_VERTEX_BUFFERS),
|
|
|
+ m_index_buffers_id_table(m_allocator, MAX_INDEX_BUFFERS),
|
|
|
+ m_render_buffers_id_table(m_allocator, MAX_RENDER_BUFFERS)
|
|
|
{
|
|
|
m_min_max_point_size[0] = 0.0f;
|
|
|
m_min_max_point_size[1] = 0.0f;
|
|
|
@@ -185,6 +188,134 @@ GLRenderer::~GLRenderer()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+VertexBufferId GLRenderer::create_vertex_buffer(const void* vertices, size_t count, VertexFormat format)
|
|
|
+{
|
|
|
+ const VertexBufferId id = m_vertex_buffers_id_table.create();
|
|
|
+
|
|
|
+ GLVertexBuffer& buffer = m_vertex_buffers[id.index];
|
|
|
+
|
|
|
+ glGenBuffers(1, &buffer.gl_object);
|
|
|
+
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, buffer.gl_object);
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, count * Vertex::bytes_per_vertex(format), vertices, GL_STATIC_DRAW);
|
|
|
+
|
|
|
+ buffer.count = count;
|
|
|
+ buffer.format = format;
|
|
|
+
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+VertexBufferId GLRenderer::create_dynamic_vertex_buffer(const void* vertices, size_t count, VertexFormat format)
|
|
|
+{
|
|
|
+ const VertexBufferId id = m_vertex_buffers_id_table.create();
|
|
|
+
|
|
|
+ GLVertexBuffer& buffer = m_vertex_buffers[id.index];
|
|
|
+
|
|
|
+ glGenBuffers(1, &buffer.gl_object);
|
|
|
+
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, buffer.gl_object);
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, count * Vertex::bytes_per_vertex(format), vertices, GL_STREAM_DRAW);
|
|
|
+
|
|
|
+ buffer.count = count;
|
|
|
+ buffer.format = format;
|
|
|
+
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void GLRenderer::update_vertex_buffer(VertexBufferId id, const void* vertices, size_t count, size_t offset)
|
|
|
+{
|
|
|
+ assert(m_vertex_buffers_id_table.has(id));
|
|
|
+
|
|
|
+ GLVertexBuffer& buffer = m_vertex_buffers[id.index];
|
|
|
+
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, buffer.gl_object);
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, offset * Vertex::bytes_per_vertex(buffer.format),
|
|
|
+ count * Vertex::bytes_per_vertex(buffer.format), vertices);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void GLRenderer::destroy_vertex_buffer(VertexBufferId id)
|
|
|
+{
|
|
|
+ assert(m_vertex_buffers_id_table.has(id));
|
|
|
+
|
|
|
+ GLVertexBuffer& buffer = m_vertex_buffers[id.index];
|
|
|
+
|
|
|
+ glDeleteBuffers(1, &buffer.gl_object);
|
|
|
+
|
|
|
+ m_vertex_buffers_id_table.destroy(id);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+IndexBufferId GLRenderer::create_index_buffer(const void* indices, size_t count)
|
|
|
+{
|
|
|
+ const IndexBufferId id = m_index_buffers_id_table.create();
|
|
|
+
|
|
|
+ GLIndexBuffer& buffer = m_index_buffers[id.index];
|
|
|
+
|
|
|
+ glGenBuffers(1, &buffer.gl_object);
|
|
|
+
|
|
|
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.gl_object);
|
|
|
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(GLushort), indices, GL_STATIC_DRAW);
|
|
|
+
|
|
|
+ buffer.index_count = count;
|
|
|
+
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void GLRenderer::destroy_index_buffer(IndexBufferId id)
|
|
|
+{
|
|
|
+ assert(m_index_buffers_id_table.has(id));
|
|
|
+
|
|
|
+ GLIndexBuffer& buffer = m_index_buffers[id.index];
|
|
|
+
|
|
|
+ glDeleteBuffers(1, &buffer.gl_object);
|
|
|
+
|
|
|
+ m_index_buffers_id_table.destroy(id);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// RenderBufferId GLRenderer::create_render_buffer(uint32_t width, uint32_t height, PixelFormat format)
|
|
|
+// {
|
|
|
+// const RenderBufferId id = m_render_buffers_id_table.create();
|
|
|
+
|
|
|
+// GLRenderBuffer& buffer = m_render_buffers[id.index];
|
|
|
+
|
|
|
+// if (GLEW_EXT_framebuffer_object)
|
|
|
+// {
|
|
|
+// glGenFramebuffersEXT(1, &buffer.gl_frame_buffer);
|
|
|
+// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer.gl_frame_buffer);
|
|
|
+
|
|
|
+// glGenRenderbuffersEXT(1, &buffer.gl_render_buffer);
|
|
|
+// glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, buffer.gl_render_buffer);
|
|
|
+
|
|
|
+// glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, width, height);
|
|
|
+
|
|
|
+// glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, buffer.gl_render_buffer);
|
|
|
+
|
|
|
+// glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
|
|
+// }
|
|
|
+
|
|
|
+// return id;
|
|
|
+// }
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// void GLRenderer::destroy_render_buffer(RenderBufferId id)
|
|
|
+// {
|
|
|
+// GLRenderBuffer& buffer = m_render_buffers[id.index];
|
|
|
+
|
|
|
+// if (GLEW_EXT_framebuffer_object)
|
|
|
+// {
|
|
|
+// glDeleteFramebuffersEXT(1, &buffer.gl_frame_buffer);
|
|
|
+// glDeleteRenderbuffersEXT(1, &buffer.gl_render_buffer);
|
|
|
+// }
|
|
|
+
|
|
|
+// m_render_buffers_id_table.destroy(id);
|
|
|
+// }
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
void GLRenderer::set_clear_color(const Color4& color)
|
|
|
{
|
|
|
@@ -221,6 +352,23 @@ void GLRenderer::set_lighting(bool lighting)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void GLRenderer::bind_texture(uint32_t unit, TextureId texture)
|
|
|
+{
|
|
|
+ assert(m_textures_id_table.has(texture));
|
|
|
+
|
|
|
+ if (!activate_texture_unit(unit))
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ m_texture_unit_target[unit] = GL_TEXTURE_2D;
|
|
|
+ m_texture_unit[unit] = m_textures[texture.index].gl_object;
|
|
|
+
|
|
|
+ glEnable(m_texture_unit_target[unit]);
|
|
|
+ glBindTexture(m_texture_unit_target[unit], m_texture_unit[unit]);
|
|
|
+}
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
void GLRenderer::set_texturing(uint32_t unit, bool texturing)
|
|
|
{
|
|
|
@@ -237,21 +385,6 @@ void GLRenderer::set_texturing(uint32_t unit, bool texturing)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-void GLRenderer::set_texture(uint32_t unit, TextureId texture)
|
|
|
-{
|
|
|
- if (!activate_texture_unit(unit))
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- m_texture_unit_target[unit] = GL_TEXTURE_2D;
|
|
|
- m_texture_unit[unit] = m_textures[texture.index].texture_object;
|
|
|
-
|
|
|
- glEnable(m_texture_unit_target[unit]);
|
|
|
- glBindTexture(m_texture_unit_target[unit], m_texture_unit[unit]);
|
|
|
-}
|
|
|
-
|
|
|
//-----------------------------------------------------------------------------
|
|
|
void GLRenderer::set_texture_mode(uint32_t unit, TextureMode mode, const Color4& blendColor)
|
|
|
{
|
|
|
@@ -613,44 +746,82 @@ void GLRenderer::set_matrix(MatrixType type, const Mat4& matrix)
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-void GLRenderer::draw_vertex_index_buffer(const VertexBuffer* vertices, const IndexBuffer* indices)
|
|
|
+void GLRenderer::bind_vertex_buffer(VertexBufferId vb) const
|
|
|
{
|
|
|
- assert(vertices != NULL);
|
|
|
- assert(indices != NULL);
|
|
|
+ assert(m_vertex_buffers_id_table.has(vb));
|
|
|
|
|
|
- glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
- glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
- glEnableClientState(GL_COLOR_ARRAY);
|
|
|
+ const GLVertexBuffer& vertex_buffer = m_vertex_buffers[vb.index];
|
|
|
|
|
|
- vertices->Bind();
|
|
|
- indices->Bind();
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer.gl_object);
|
|
|
|
|
|
- glDrawElements(GL_TRIANGLES, indices->GetIndexCount(), GL_UNSIGNED_SHORT, 0);
|
|
|
-
|
|
|
- glDisableClientState(GL_COLOR_ARRAY);
|
|
|
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
- glDisableClientState(GL_NORMAL_ARRAY);
|
|
|
- glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
+ switch (vertex_buffer.format)
|
|
|
+ {
|
|
|
+ case VF_XY_FLOAT_32:
|
|
|
+ {
|
|
|
+ glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
+ glVertexPointer(2, GL_FLOAT, 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case VF_XYZ_FLOAT_32:
|
|
|
+ {
|
|
|
+ glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
+ glVertexPointer(3, GL_FLOAT, 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case VF_UV_FLOAT_32:
|
|
|
+ {
|
|
|
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
+ glTexCoordPointer(2, GL_FLOAT, 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case VF_UVT_FLOAT_32:
|
|
|
+ {
|
|
|
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
+ glTexCoordPointer(3, GL_FLOAT, 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case VF_XYZ_NORMAL_FLOAT_32:
|
|
|
+ {
|
|
|
+ glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
+ glNormalPointer(GL_FLOAT, 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case VF_XYZ_UV_XYZ_NORMAL_FLOAT_32:
|
|
|
+ {
|
|
|
+ glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
+ glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
+ glVertexPointer(3, GL_FLOAT, 0, 0);
|
|
|
+ glTexCoordPointer(2, GL_FLOAT, 0, 0);
|
|
|
+ glNormalPointer(GL_FLOAT, 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ assert(0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-void GLRenderer::draw_point_buffer(const VertexBuffer* buffer)
|
|
|
+void GLRenderer::draw_triangles(IndexBufferId id) const
|
|
|
{
|
|
|
- if (buffer == NULL)
|
|
|
- return;
|
|
|
- glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
- glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
- glEnableClientState(GL_COLOR_ARRAY);
|
|
|
+ assert(m_index_buffers_id_table.has(id));
|
|
|
|
|
|
- buffer->Bind();
|
|
|
- glDrawArrays(GL_POINTS, 0, buffer->GetVertexCount());
|
|
|
+ const GLIndexBuffer& index_buffer = m_index_buffers[id.index];
|
|
|
|
|
|
- glDisableClientState(GL_COLOR_ARRAY);
|
|
|
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
- glDisableClientState(GL_NORMAL_ARRAY);
|
|
|
- glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer.gl_object);
|
|
|
+
|
|
|
+ glDrawElements(GL_TRIANGLES, index_buffer.index_count, GL_UNSIGNED_SHORT, 0);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void GLRenderer::bind_render_buffer(RenderBufferId id) const
|
|
|
+{
|
|
|
+ assert(m_render_buffers_id_table.has(id));
|
|
|
+
|
|
|
+ const GLRenderBuffer& render_buffer = m_render_buffers[id.index];
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
@@ -739,47 +910,22 @@ void GLRenderer::draw_lines(const float* vertices, const float* colors, uint32_t
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-void GLRenderer::draw_triangles(const float* vertices, const float* normals, const float* uvs, const uint16_t* indices, uint32_t count)
|
|
|
+TextureId GLRenderer::load_texture(TextureResource* texture)
|
|
|
{
|
|
|
- glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
|
+ const TextureId id = m_textures_id_table.create();
|
|
|
|
|
|
- glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
- glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
- glVertexPointer(3, GL_FLOAT, 0, vertices);
|
|
|
- glNormalPointer(GL_FLOAT, 0, normals);
|
|
|
- glTexCoordPointer(2, GL_FLOAT, 0, uvs);
|
|
|
-
|
|
|
- glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices);
|
|
|
+ GLTexture& gl_texture = m_textures[id.index];
|
|
|
|
|
|
- glDisableClientState(GL_VERTEX_ARRAY);
|
|
|
- glDisableClientState(GL_NORMAL_ARRAY);
|
|
|
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
-}
|
|
|
+ glGenTextures(1, &gl_texture.gl_object);
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-TextureId GLRenderer::load_texture(TextureResource* texture)
|
|
|
-{
|
|
|
- // If texture not found, create a new one
|
|
|
- GLuint gl_texture_object;
|
|
|
+ glBindTexture(GL_TEXTURE_2D, gl_texture.gl_object);
|
|
|
|
|
|
- glGenTextures(1, &gl_texture_object);
|
|
|
- glBindTexture(GL_TEXTURE_2D, gl_texture_object);
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->width(), texture->height(), 0,
|
|
|
GL::pixel_format(texture->format()), GL_UNSIGNED_BYTE, texture->data());
|
|
|
|
|
|
- TextureId id;
|
|
|
- id.index = m_texture_count;
|
|
|
- id.id = 0;
|
|
|
-
|
|
|
- m_textures[id.index].texture_object = gl_texture_object;
|
|
|
- m_textures[id.index].texture_resource = texture;
|
|
|
- m_textures[id.index].id = id;
|
|
|
-
|
|
|
- m_texture_count++;
|
|
|
+ gl_texture.texture_resource = texture;
|
|
|
|
|
|
return id;
|
|
|
}
|
|
|
@@ -794,19 +940,19 @@ void GLRenderer::unload_texture(TextureResource* texture)
|
|
|
//-----------------------------------------------------------------------------
|
|
|
TextureId GLRenderer::reload_texture(TextureResource* old_texture, TextureResource* new_texture)
|
|
|
{
|
|
|
- for (uint32_t i = 0; i < m_texture_count; i++)
|
|
|
- {
|
|
|
- if (m_textures[i].texture_resource == old_texture)
|
|
|
- {
|
|
|
- // Reload texture
|
|
|
- glBindTexture(GL_TEXTURE_2D, m_textures[i].texture_object);
|
|
|
+ // for (uint32_t i = 0; i < m_texture_count; i++)
|
|
|
+ // {
|
|
|
+ // if (m_textures[i].texture_resource == old_texture)
|
|
|
+ // {
|
|
|
+ // // Reload texture
|
|
|
+ // glBindTexture(GL_TEXTURE_2D, m_textures[i].gl_object);
|
|
|
|
|
|
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, new_texture->width(), new_texture->height(),
|
|
|
- GL::pixel_format(new_texture->format()), GL_UNSIGNED_BYTE, new_texture->data());
|
|
|
+ // glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, new_texture->width(), new_texture->height(),
|
|
|
+ // GL::pixel_format(new_texture->format()), GL_UNSIGNED_BYTE, new_texture->data());
|
|
|
|
|
|
- m_textures[i].texture_resource = new_texture;
|
|
|
- }
|
|
|
- }
|
|
|
+ // m_textures[i].texture_resource = new_texture;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|