Can draw colored stuff using VertexArrayMeshes

simple_math_single_header
Martin Felis 2018-02-28 12:39:12 +01:00
parent 076f051d48
commit 76985c878f
6 changed files with 264 additions and 35 deletions

View File

@ -2,7 +2,7 @@
uniform vec4 uColor;
in vec3 fragmentColor;
in vec4 fragmentColor;
out vec3 outColor;
@ -13,6 +13,7 @@ void main() {
uColor.b * fragmentColor.b
);
outColor = max(uColor.rgb, fragmentColor);
//outColor = fragmentColor + uColor.rgb - uColor.rgb;
// outColor = max(uColor.rgb, fragmentColor.rgb);
outColor = fragmentColor.rgb + uColor.rgb - uColor.rgb;
}

View File

@ -1,14 +1,16 @@
#version 150 core
#extension GL_ARB_explicit_attrib_location : require
in vec3 inCoord;
in vec3 inColor;
in vec4 inCoord;
in vec3 inNormal;
in vec2 inUV;
in vec4 inColor;
uniform mat4 uModelViewProj;
out vec3 fragmentColor;
out vec4 fragmentColor;
void main() {
gl_Position = uModelViewProj * vec4(inCoord, 1);
gl_Position = uModelViewProj * inCoord;
fragmentColor = inColor;
}

View File

@ -151,6 +151,25 @@ class Matrix {
~Matrix() {};
Matrix (
const val_type &v00, const val_type &v01
) {
assert (nrows == 2);
assert (ncols == 1);
mData[0] = v00;
mData[1] = v01;
}
void set(
const val_type &v00, const val_type &v01
) {
COMPILE_ASSERT (nrows * ncols == 2);
mData[0] = v00;
mData[1] = v01;
}
Matrix (
const val_type &v00, const val_type &v01, const val_type &v02
) {

View File

@ -50,6 +50,9 @@ static const GLfloat g_coordinate_system_vertex_buffer_data[] = {
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
VertexArray gVertexArray;
VertexArrayMesh gVertexArrayMesh;
//
// Module
//
@ -180,7 +183,23 @@ void Camera::DrawGui() {
//
void Renderer::Initialize(int width, int height) {
mDefaultTexture.MakeGrid(128, Vector3f (0.8, 0.8f, 0.8f), Vector3f (0.2f, 0.2f, 0.2f));
gVertexArray.Initialize(1000, GL_STATIC_DRAW);
gVertexArrayMesh.Initialize(gVertexArray, 6);
VertexArray::VertexData vertex_data[] = {
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 255, 0, 0, 255 },
{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 255, 0, 0, 255 },
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 255, 0, 255},
{0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 255, 0, 255},
{0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 255, 255},
{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 255, 255}
};
gVertexArrayMesh.SetData(vertex_data, 6);
// Mesh
glGenVertexArrays(1, &mMesh.mVertexArrayId);
glBindVertexArray(mMesh.mVertexArrayId);
@ -294,12 +313,7 @@ void Renderer::RenderGl() {
);
// glDrawArrays(GL_TRIANGLES, 0, 3); // starting from vertex 0; 3 vertices total
glDisableVertexAttribArray(0);
glBindAttribLocation(mDefaultProgram.mProgramId, 0, "inCoord");
glBindAttribLocation(mDefaultProgram.mProgramId, 1, "inColor");
// Coordinate system
// // Coordinate system
glEnableVertexAttribArray(0);
glBindVertexArray(mCoordinateSystem.mVertexArrayId);
glUniform4fv(muDefaultColor, 1, Vector4f(0.0f, 0.0f, 0.0f, 1.0f).data());
@ -324,6 +338,20 @@ void Renderer::RenderGl() {
);
glDrawArrays(GL_LINES, 0, 6);
// Coordinate System: VertexArrayMesh
model_view_projection =
TranslateMat44(1.25f, 0.0f, 0.0f)
* mCamera.mViewMatrix
* mCamera.mProjectionMatrix;
glUniformMatrix4fv(muDefaultModelViewProjection, 1, GL_FALSE, model_view_projection.data());
glUniform4fv(muDefaultColor, 1, Vector4f(1.0f, 0.0f, 0.0f, 1.0f).data());
glBindAttribLocation(mDefaultProgram.mProgramId, 0, "inCoord");
glBindAttribLocation(mDefaultProgram.mProgramId, 1, "inNormal");
glBindAttribLocation(mDefaultProgram.mProgramId, 2, "inUV");
glBindAttribLocation(mDefaultProgram.mProgramId, 3, "inColor");
gVertexArray.Bind();
gVertexArrayMesh.Draw(GL_LINES);
if (mSettings->DrawDepth) {
mRenderTarget.RenderToLinearizedDepth(true);
glClear(GL_COLOR_BUFFER_BIT);

View File

@ -323,33 +323,172 @@ bool Texture::Load(const char* filename, int num_components) {
assert(false);
}
VertexArray::~VertexArray() {
if (mVertexArrayId != -1) {
Cleanup();
}
}
void VertexArray::Initialize(const int& size, GLenum usage) {
mSize = size;
mUsed = 0;
mNumVertices = size;
mNumUsedVertices = 0;
glGenVertexArrays (1, &mVertexArrayId);
glBindVertexArray(mVertexArrayId);
glGenBuffers(1, &mVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * size, NULL, usage);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * mNumVertices, NULL, usage);
}
void VertexArray::Cleanup() {
glDeleteBuffers(1, &mVertexBuffer);
mVertexBuffer = -1;
glDeleteVertexArrays(1, &mVertexArrayId);
mVertexArrayId = -1;
mNumVertices = -1;
mNumUsedVertices = -1;
}
GLuint VertexArray::AllocateMesh(const int& size) {
GLuint mesh_data_size = size * sizeof(VertexData);
if (mUsed + mesh_data_size > mSize) {
if (mNumUsedVertices + size > mNumVertices) {
gLog("Cannot allocate mesh in VertexArray: not enough vertices available");
assert(false);
return -1;
}
GLuint offset = mUsed;
mUsed += mesh_data_size;
GLuint offset = mNumUsedVertices;
mNumUsedVertices += size;
return offset;
}
void VertexArrayMesh::Initialize(VertexArray &array, const int& size) {
mOffset = array.AllocateMesh(size);
assert(mOffset != -1);
void VertexArray::Bind() {
glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
// Attribute 0: coords
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
4,
GL_FLOAT,
GL_FALSE,
(sizeof(VertexData)),
(void*)0
);
// Attribute 1: color
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
4,
GL_UNSIGNED_BYTE,
GL_FALSE,
(sizeof(VertexData)),
(void*)(sizeof(float) * 9)
);
// Attribute 2: normals
glEnableVertexAttribArray(2);
glVertexAttribPointer(
2,
3,
GL_FLOAT,
GL_FALSE,
(sizeof(VertexData)),
(void*)(sizeof(float) * 4)
);
// Attribute 3: texture coordinates
glEnableVertexAttribArray(3);
glVertexAttribPointer(
3,
2,
GL_FLOAT,
GL_FALSE,
(sizeof(VertexData)),
(void*)(sizeof(float) * 7)
);
}
bool VertexArray::IsBound() {
GLint bound_vertex_buffer = -1;
glGetIntegerv (GL_ARRAY_BUFFER_BINDING, &bound_vertex_buffer);
return bound_vertex_buffer == mVertexBuffer;
}
void VertexArrayMesh::Initialize(VertexArray &array, const int& size) {
mVertexArray = &array;
mIndexOffset = mVertexArray->AllocateMesh(size);
mOffsetPtr = (void*) (sizeof(VertexArray::VertexData) * mIndexOffset);
}
void VertexArrayMesh::SetData(
const VertexArray::VertexData* data,
const int& count
) {
// upload the data
mVertexCount = count;
glBindBuffer(GL_ARRAY_BUFFER, mVertexArray->mVertexBuffer);
glBufferSubData(
GL_ARRAY_BUFFER,
(GLintptr) mOffsetPtr,
sizeof(VertexArray::VertexData) * count,
data
);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void VertexArrayMesh::SetData(
const std::vector<Vector4f> &coords,
const std::vector<Vector3f> &normals,
const std::vector<Vector2f> &uvs,
const std::vector<Vector4f> &colors,
const std::vector<GLuint> &indices
) {
assert(mOffsetPtr != (void*) -1);
int vertex_count = coords.size();
assert(vertex_count > 0);
bool have_normals = normals.size() > 0;
bool have_uvs = uvs.size() > 0;
bool have_colors = colors.size() > 0;
assert(!have_normals || (normals.size() == vertex_count));
assert(!have_uvs || (uvs.size() == vertex_count));
assert(!have_colors || (colors.size() == vertex_count));
std::vector<VertexArray::VertexData> vertex_data(vertex_count, VertexArray::VertexData());
for (int i = 0, n = vertex_count; i < n; ++i) {
memcpy (vertex_data[i].mCoords, coords[i].data(), sizeof(float) * 4);
if (have_normals) {
memcpy (vertex_data[i].mNormals, normals[i].data(), sizeof(float) * 3);
} else {
memset (vertex_data[i].mNormals, 0, sizeof(float) * 3);
}
if (have_uvs) {
memcpy (vertex_data[i].mTexCoords, uvs[i].data(), sizeof(float) * 2);
} else {
memset (vertex_data[i].mTexCoords, 0, sizeof(float) * 2);
}
if (have_colors) {
memcpy (vertex_data[i].mColor, colors[i].data(), sizeof(float) * 4);
} else {
memset (vertex_data[i].mColor, 0, sizeof(float) * 4);
}
}
SetData(
vertex_data.data(),
vertex_count
);
}
void VertexArrayMesh::Draw(GLenum mode) {
assert(mVertexArray->IsBound());
glDrawArrays(mode, mIndexOffset, mVertexCount);
}

View File

@ -5,6 +5,8 @@
#include <GL/gl3w.h> // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you.
#include <vector>
struct Transform {
Quaternion rotation = Quaternion (0.0f, 0.0f, 0.0f, 1.0f);
Vector3f translation = Vector3f (0.0f, 0.0f, 0.0f);
@ -199,31 +201,69 @@ struct Mesh {
struct VertexArray {
GLuint mVertexBuffer = -1;
GLuint mVertexArrayId = -1;
GLuint mSize = -1;
GLuint mUsed = -1;
GLuint mNumVertices = -1;
GLuint mNumUsedVertices = -1;
struct VertexData {
float mCoords[4];
float mNormals[4];
float mTexCoords[2];
GLubyte mColor[4];
union {
struct {
float x;
float y;
float z;
float w;
float nx;
float ny;
float nz;
float u;
float v;
GLubyte r;
GLubyte g;
GLubyte b;
GLubyte a;
};
struct {
float mCoords[4];
float mNormals[3];
float mTexCoords[2];
GLubyte mColor[4];
};
};
};
~VertexArray();
void Initialize(const int& size, GLenum usage);
void Cleanup();
GLuint AllocateMesh(const int& size);
void Bind();
bool IsBound();
};
struct VertexArrayMesh {
GLuint mOffset;
VertexArray* mVertexArray = (VertexArray*) -1;
void* mOffsetPtr = (void*) -1;
GLuint mVertexCount = -1;
GLuint mIndexOffset = -1;
GLuint mIndexBuffer = -1;
GLuint mIndexCount = -1;
void Initialize(VertexArray &array, const int& size);
void SetData(
const VertexArray::VertexData* data,
const int& count
);
void SetData(
const std::vector<Vector4f> &coords,
const std::vector<Vector4f> &normals,
const std::vector<Vector3f> &normals,
const std::vector<Vector2f> &uvs,
const std::vector<Vector4f> &colors
const std::vector<Vector4f> &colors,
const std::vector<GLuint> &indices
);
void Draw(GLenum mode);
};
#endif