void OGLRenderLayout::UnbindVertexStreams(ShaderObjectPtr const & so, GLuint vao) const { OGLShaderObjectPtr const & ogl_so = checked_pointer_cast<OGLShaderObject>(so); for (uint32_t i = 0; i < this->NumVertexStreams(); ++ i) { auto const & vertex_stream_fmt = this->VertexStreamFormat(i); for (auto const & vs_elem : vertex_stream_fmt) { GLint attr = ogl_so->GetAttribLocation(vs_elem.usage, vs_elem.usage_index); if (attr != -1) { if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glDisableVertexArrayAttrib(vao, attr); } else if (glloader_GL_EXT_direct_state_access()) { glDisableVertexArrayAttribEXT(vao, attr); } else { glDisableVertexAttribArray(attr); } } } } if (this->InstanceStream()) { if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glVertexArrayBindingDivisor(vao, this->NumVertexStreams(), 0); } size_t const inst_format_size = this->InstanceStreamFormat().size(); for (size_t i = 0; i < inst_format_size; ++ i) { VertexElement const & vs_elem = this->InstanceStreamFormat()[i]; GLint attr = ogl_so->GetAttribLocation(vs_elem.usage, vs_elem.usage_index); if (attr != -1) { if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glDisableVertexArrayAttrib(vao, attr); } else if (glloader_GL_EXT_direct_state_access()) { glDisableVertexArrayAttribEXT(vao, attr); glVertexAttribDivisor(attr, 0); } else { glDisableVertexAttribArray(attr); glVertexAttribDivisor(attr, 0); } } } } }
void* OGLGraphicsBuffer::Map(BufferAccess ba) { GLenum flag = 0; switch (ba) { case BA_Read_Only: flag = GL_READ_ONLY; break; case BA_Write_Only: flag = GL_WRITE_ONLY; break; case BA_Read_Write: flag = GL_READ_WRITE; break; } void* p; if (glloader_GL_EXT_direct_state_access()) { p = glMapNamedBufferEXT(vb_, flag); } else { OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindBuffer(target_, vb_); p = glMapBuffer(target_, flag); } return p; }
OGLGraphicsBuffer::OGLGraphicsBuffer(BufferUsage usage, uint32_t access_hint, GLenum target, ElementInitData const * init_data) : GraphicsBuffer(usage, access_hint), target_(target) { BOOST_ASSERT((GL_ARRAY_BUFFER == target) || (GL_ELEMENT_ARRAY_BUFFER == target)); glGenBuffers(1, &vb_); if (init_data != nullptr) { size_in_byte_ = init_data->row_pitch; if (glloader_GL_EXT_direct_state_access()) { glNamedBufferDataEXT(vb_, static_cast<GLsizeiptr>(size_in_byte_), init_data->data, (BU_Static == usage_) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); } else { OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindBuffer(target_, vb_); glBufferData(target_, static_cast<GLsizeiptr>(size_in_byte_), init_data->data, (BU_Static == usage_) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); } } }
void OGLGraphicsBuffer::Unmap() { if (glloader_GL_EXT_direct_state_access()) { glUnmapNamedBufferEXT(vb_); } else { OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindBuffer(target_, vb_); glUnmapBuffer(target_); } }
void OGLGraphicsBuffer::DoResize() { BOOST_ASSERT(size_in_byte_ != 0); if (glloader_GL_EXT_direct_state_access()) { glNamedBufferDataEXT(vb_, static_cast<GLsizeiptr>(size_in_byte_), nullptr, (BU_Static == usage_) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); } else { OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindBuffer(target_, vb_); glBufferData(target_, static_cast<GLsizeiptr>(size_in_byte_), nullptr, (BU_Static == usage_) ? GL_STATIC_DRAW : GL_DYNAMIC_DRAW); } }
void OGLTexture::TexParameterf(GLenum pname, GLfloat param) { KLAYGE_AUTO(iter, tex_param_f_.find(pname)); if ((iter == tex_param_f_.end()) || (iter->second != param)) { if (glloader_GL_EXT_direct_state_access()) { glTextureParameterfEXT(texture_, target_type_, pname, param); } else { glBindTexture(target_type_, texture_); glTexParameterf(target_type_, pname, param); } tex_param_f_[pname] = param; } }
void OGLTexture::TexParameterf(GLenum pname, GLfloat param) { auto iter = tex_param_f_.find(pname); if ((iter == tex_param_f_.end()) || (iter->second != param)) { if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glTextureParameterf(texture_, pname, param); } else if (glloader_GL_EXT_direct_state_access()) { glTextureParameterfEXT(texture_, target_type_, pname, param); } else { OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); re.BindTexture(0, target_type_, texture_); glTexParameterf(target_type_, pname, param); } tex_param_f_[pname] = param; } }
void OGLRenderLayout::BindVertexStreams(ShaderObjectPtr const & so, GLuint vao) const { OGLShaderObjectPtr const & ogl_so = checked_pointer_cast<OGLShaderObject>(so); RenderEngine& re = Context::Instance().RenderFactoryInstance().RenderEngineInstance(); uint32_t max_vertex_streams = re.DeviceCaps().max_vertex_streams; std::vector<char> used_streams(max_vertex_streams, 0); for (uint32_t i = 0; i < this->NumVertexStreams(); ++ i) { OGLGraphicsBuffer& stream(*checked_pointer_cast<OGLGraphicsBuffer>(this->GetVertexStream(i))); uint32_t const size = this->VertexSize(i); auto const & vertex_stream_fmt = this->VertexStreamFormat(i); if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glVertexArrayVertexBuffer(vao, i, stream.GLvbo(), this->StartVertexLocation() * size, size); } uint32_t elem_offset = 0; for (auto const & vs_elem : vertex_stream_fmt) { GLint attr = ogl_so->GetAttribLocation(vs_elem.usage, vs_elem.usage_index); if (attr != -1) { GLintptr offset = elem_offset + this->StartVertexLocation() * size; GLint const num_components = static_cast<GLint>(NumComponents(vs_elem.format)); GLenum type; GLboolean normalized; OGLMapping::MappingVertexFormat(type, normalized, vs_elem.format); normalized = (((VEU_Diffuse == vs_elem.usage) || (VEU_Specular == vs_elem.usage)) && !IsFloatFormat(vs_elem.format)) ? GL_TRUE : normalized; BOOST_ASSERT(GL_ARRAY_BUFFER == stream.GLType()); stream.Active(true); if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glVertexArrayAttribFormat(vao, attr, num_components, type, normalized, elem_offset); glVertexArrayAttribBinding(vao, attr, i); glEnableVertexArrayAttrib(vao, attr); } else if (glloader_GL_EXT_direct_state_access()) { glVertexArrayVertexAttribOffsetEXT(vao, stream.GLvbo(), attr, num_components, type, normalized, size, offset); glEnableVertexArrayAttribEXT(vao, attr); } else { glVertexAttribPointer(attr, num_components, type, normalized, size, reinterpret_cast<GLvoid*>(offset)); glEnableVertexAttribArray(attr); } used_streams[attr] = 1; } elem_offset += vs_elem.element_size(); } } if (this->InstanceStream()) { OGLGraphicsBuffer& stream(*checked_pointer_cast<OGLGraphicsBuffer>(this->InstanceStream())); uint32_t const instance_size = this->InstanceSize(); BOOST_ASSERT(this->NumInstances() * instance_size <= stream.Size()); if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glVertexArrayVertexBuffer(vao, this->NumVertexStreams(), stream.GLvbo(), this->StartInstanceLocation() * instance_size, instance_size); glVertexArrayBindingDivisor(vao, this->NumVertexStreams(), 1); } size_t const inst_format_size = this->InstanceStreamFormat().size(); uint32_t elem_offset = 0; for (size_t i = 0; i < inst_format_size; ++ i) { VertexElement const & vs_elem = this->InstanceStreamFormat()[i]; GLint attr = ogl_so->GetAttribLocation(vs_elem.usage, vs_elem.usage_index); if (attr != -1) { GLint const num_components = static_cast<GLint>(NumComponents(vs_elem.format)); GLenum type; GLboolean normalized; OGLMapping::MappingVertexFormat(type, normalized, vs_elem.format); normalized = (((VEU_Diffuse == vs_elem.usage) || (VEU_Specular == vs_elem.usage)) && !IsFloatFormat(vs_elem.format)) ? GL_TRUE : normalized; GLintptr offset = elem_offset + this->StartInstanceLocation() * instance_size; BOOST_ASSERT(GL_ARRAY_BUFFER == stream.GLType()); stream.Active(true); if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glVertexArrayAttribFormat(vao, attr, num_components, type, normalized, elem_offset); glVertexArrayAttribBinding(vao, attr, this->NumVertexStreams()); glEnableVertexArrayAttrib(vao, attr); } else if (glloader_GL_EXT_direct_state_access()) { glVertexArrayVertexAttribOffsetEXT(vao, stream.GLvbo(), attr, num_components, type, normalized, instance_size, offset); glEnableVertexArrayAttribEXT(vao, attr); glVertexAttribDivisor(attr, 1); } else { glVertexAttribPointer(attr, num_components, type, normalized, instance_size, reinterpret_cast<GLvoid*>(offset)); glEnableVertexAttribArray(attr); glVertexAttribDivisor(attr, 1); } used_streams[attr] = 1; } elem_offset += vs_elem.element_size(); } } for (GLuint i = 0; i < max_vertex_streams; ++ i) { if (!used_streams[i]) { if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access()) { glDisableVertexArrayAttrib(vao, i); } else if (glloader_GL_EXT_direct_state_access()) { glDisableVertexArrayAttribEXT(vao, i); } else { glDisableVertexAttribArray(i); } } } }