168 lines
4.6 KiB
C
168 lines
4.6 KiB
C
|
/************************************************************************************
|
||
|
|
||
|
Authors : Bradley Austin Davis <bdavis@saintandreas.org>
|
||
|
Copyright : Copyright Brad Davis. All Rights reserved.
|
||
|
|
||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
you may not use this file except in compliance with the License.
|
||
|
You may obtain a copy of the License at
|
||
|
|
||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
||
|
Unless required by applicable law or agreed to in writing, software
|
||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
See the License for the specific language governing permissions and
|
||
|
limitations under the License.
|
||
|
|
||
|
************************************************************************************/
|
||
|
#pragma once
|
||
|
|
||
|
#ifndef GL_ZERO
|
||
|
#error "You must include the gl headers before including this file"
|
||
|
#endif
|
||
|
|
||
|
#include "GlBuffers.h"
|
||
|
#include "GlVertexArrays.h"
|
||
|
|
||
|
namespace gl {
|
||
|
|
||
|
class Geometry;
|
||
|
|
||
|
typedef std::shared_ptr<Geometry> GeometryPtr;
|
||
|
|
||
|
class Geometry {
|
||
|
public:
|
||
|
static const int VERTEX_ATTRIBUTE_SIZE = 4;
|
||
|
static const int BYTES_PER_ATTRIBUTE = (sizeof(float)
|
||
|
* VERTEX_ATTRIBUTE_SIZE);
|
||
|
enum Flag {
|
||
|
HAS_NORMAL = 0x01,
|
||
|
HAS_COLOR = 0x02,
|
||
|
HAS_TEXTURE = 0x04,
|
||
|
};
|
||
|
|
||
|
VertexBufferPtr vertices;
|
||
|
IndexBufferPtr indices;
|
||
|
VertexArrayPtr vertexArray;
|
||
|
|
||
|
unsigned int elements;
|
||
|
GLenum elementType;
|
||
|
unsigned int verticesPerElement;
|
||
|
unsigned int flags;
|
||
|
|
||
|
void bindVertexArray() {
|
||
|
vertexArray->bind();
|
||
|
}
|
||
|
|
||
|
static void unbindVertexArray() {
|
||
|
gl::VertexArray::unbind();
|
||
|
}
|
||
|
|
||
|
static unsigned int getStride(unsigned int flags) {
|
||
|
int result = VERTEX_ATTRIBUTE_SIZE;
|
||
|
if (flags & Geometry::Flag::HAS_NORMAL) {
|
||
|
result += VERTEX_ATTRIBUTE_SIZE;
|
||
|
}
|
||
|
if (flags & Geometry::Flag::HAS_COLOR) {
|
||
|
result += VERTEX_ATTRIBUTE_SIZE;
|
||
|
}
|
||
|
if (flags & Geometry::Flag::HAS_TEXTURE) {
|
||
|
result += VERTEX_ATTRIBUTE_SIZE;
|
||
|
}
|
||
|
return result * sizeof(float);
|
||
|
}
|
||
|
|
||
|
unsigned int getStride() {
|
||
|
return getStride(flags);
|
||
|
}
|
||
|
|
||
|
void draw() {
|
||
|
glDrawElements(elementType, elements * verticesPerElement,
|
||
|
GL_UNSIGNED_INT, (void*) 0);
|
||
|
}
|
||
|
|
||
|
Geometry(
|
||
|
const std::vector<glm::vec4> & in_vertices,
|
||
|
const std::vector<GLuint> & in_indices,
|
||
|
unsigned int elements = 0,
|
||
|
unsigned int flags = 0,
|
||
|
GLenum elementType = GL_TRIANGLES,
|
||
|
unsigned int verticesPerElement = 3)
|
||
|
: elements(elements),
|
||
|
elementType(elementType),
|
||
|
flags(flags),
|
||
|
vertexArray(new gl::VertexArray()),
|
||
|
verticesPerElement(verticesPerElement) {
|
||
|
vertices = VertexBufferPtr(new VertexBuffer());
|
||
|
*vertices << VectorLoader<glm::vec4>(in_vertices);
|
||
|
indices = IndexBufferPtr(new IndexBuffer());
|
||
|
*indices << VectorLoader<GLuint>(in_indices);
|
||
|
buildVertexArray();
|
||
|
}
|
||
|
|
||
|
Geometry(
|
||
|
const gl::VertexBufferPtr in_vertices,
|
||
|
const gl::IndexBufferPtr in_indices,
|
||
|
unsigned int elements = 0,
|
||
|
unsigned int flags = 0,
|
||
|
GLenum elementType = GL_TRIANGLES,
|
||
|
unsigned int verticesPerElement = 3)
|
||
|
: vertices(in_vertices),
|
||
|
indices(in_indices),
|
||
|
elements(elements),
|
||
|
flags(flags),
|
||
|
vertexArray(new gl::VertexArray()),
|
||
|
elementType(elementType),
|
||
|
verticesPerElement(verticesPerElement) {
|
||
|
buildVertexArray();
|
||
|
}
|
||
|
|
||
|
void buildVertexArray() {
|
||
|
vertexArray->bind();
|
||
|
{
|
||
|
indices->bind();
|
||
|
vertices->bind();
|
||
|
GL_CHECK_ERROR;
|
||
|
unsigned int stride = getStride(flags);
|
||
|
GLfloat * offset = 0;
|
||
|
glEnableVertexAttribArray(gl::Attribute::Position);
|
||
|
glVertexAttribPointer(gl::Attribute::Position, 3, GL_FLOAT, GL_FALSE,
|
||
|
stride, offset);
|
||
|
GL_CHECK_ERROR;
|
||
|
|
||
|
if (flags & HAS_NORMAL) {
|
||
|
offset += VERTEX_ATTRIBUTE_SIZE;
|
||
|
glEnableVertexAttribArray(gl::Attribute::Normal);
|
||
|
glVertexAttribPointer(gl::Attribute::Normal, 3, GL_FLOAT, GL_FALSE,
|
||
|
stride, offset);
|
||
|
GL_CHECK_ERROR;
|
||
|
}
|
||
|
|
||
|
if (flags & HAS_COLOR) {
|
||
|
offset += VERTEX_ATTRIBUTE_SIZE;
|
||
|
glEnableVertexAttribArray(gl::Attribute::Color);
|
||
|
glVertexAttribPointer(gl::Attribute::Color, 3, GL_FLOAT, GL_FALSE,
|
||
|
stride, offset);
|
||
|
GL_CHECK_ERROR;
|
||
|
}
|
||
|
|
||
|
if (flags & HAS_TEXTURE) {
|
||
|
offset += VERTEX_ATTRIBUTE_SIZE;
|
||
|
glEnableVertexAttribArray(gl::Attribute::TexCoord0);
|
||
|
glVertexAttribPointer(gl::Attribute::TexCoord0, 2, GL_FLOAT,
|
||
|
GL_FALSE, stride, offset);
|
||
|
GL_CHECK_ERROR;
|
||
|
}
|
||
|
}
|
||
|
VertexArray::unbind();
|
||
|
IndexBuffer::unbind();
|
||
|
VertexBuffer::unbind();
|
||
|
GL_CHECK_ERROR;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
} // gl
|
||
|
|