namespace {
const Block::Face face_map[Block::FACE_COUNT * Block::TURN_COUNT][Block::FACE_COUNT] = {
- { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_FRONT, Block::FACE_BACK, }, // face: up, turn: none x
+ { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_FRONT, Block::FACE_BACK, }, // face: up, turn: none
{ Block::FACE_UP, Block::FACE_DOWN, Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_LEFT, Block::FACE_RIGHT, }, // face: up, turn: left
{ Block::FACE_UP, Block::FACE_DOWN, Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_BACK, Block::FACE_FRONT, }, // face: up, turn: around
{ Block::FACE_UP, Block::FACE_DOWN, Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_RIGHT, Block::FACE_LEFT, }, // face: up, turn: right
const glm::mat4 &transform,
BlockModel::Index idx_offset
) const {
- shape->Vertices(buf.vertices, buf.normals, buf.indices, transform, idx_offset);
+ shape->Vertices(buf.vertices, buf.indices, transform, idx_offset);
buf.colors.insert(buf.colors.end(), shape->VertexCount(), color);
}
return light[index];
}
-float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const BlockModel::Normal &norm) const {
+float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Model::Normal &norm) const {
float light = GetLight(index);
Chunk::Pos pos(ToPos(index));
vtx_counter += type.shape->VertexCount();
for (size_t vtx = vtx_begin; vtx < vtx_counter; ++vtx) {
- buf.lights.emplace_back(GetVertexLight(i, buf.vertices[vtx], buf.normals[vtx]));
+ buf.lights.emplace_back(GetVertexLight(
+ i,
+ buf.vertices[vtx],
+ type.shape->VertexNormal(vtx - vtx_begin, blocks[i].Transform())
+ ));
}
}
int GetLight(const Pos &pos) const { return GetLight(ToIndex(pos)); }
int GetLight(const Block::Pos &pos) const { return GetLight(ToIndex(pos)); }
- float GetVertexLight(int index, const BlockModel::Position &, const BlockModel::Normal &) const;
+ float GetVertexLight(int index, const BlockModel::Position &, const Model::Normal &) const;
bool Intersection(
const Ray &ray,
nullptr // offset
);
-#ifndef NDEBUG
- if (buf.normals.size() < buf.vertices.size()) {
- std::cerr << "BlockModel: not enough normals!" << std::endl;
- }
-#endif
- glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
- glBufferData(GL_ARRAY_BUFFER, buf.normals.size() * sizeof(glm::vec3), buf.normals.data(), GL_STATIC_DRAW);
- glEnableVertexAttribArray(ATTRIB_NORMAL);
- glVertexAttribPointer(
- ATTRIB_NORMAL, // location (for shader)
- 3, // size
- GL_FLOAT, // type
- GL_FALSE, // normalized
- 0, // stride
- nullptr // offset
- );
-
#ifndef NDEBUG
if (buf.lights.size() < buf.vertices.size()) {
std::cerr << "BlockModel: not enough lights!" << std::endl;
public:
using Position = glm::vec3;
using Color = glm::vec3;
- using Normal = glm::vec3;
using Light = float;
using Index = unsigned int;
using Positions = std::vector<Position>;
using Colors = std::vector<Color>;
- using Normals = std::vector<Normal>;
using Lights = std::vector<Light>;
using Indices = std::vector<Index>;
Positions vertices;
Colors colors;
- Normals normals;
Lights lights;
Indices indices;
void Clear() {
vertices.clear();
colors.clear();
- normals.clear();
lights.clear();
indices.clear();
}
void Reserve(size_t p, size_t i) {
vertices.reserve(p);
colors.reserve(p);
- normals.reserve(p);
lights.reserve(p);
indices.reserve(i);
}
enum Attribute {
ATTRIB_VERTEX,
ATTRIB_COLOR,
- ATTRIB_NORMAL,
ATTRIB_LIGHT,
ATTRIB_INDEX,
ATTRIB_COUNT,
}
+GLint Program::AttributeLocation(const GLchar *name) const {
+ return glGetAttribLocation(handle, name);
+}
+
GLint Program::UniformLocation(const GLchar *name) const {
return glGetUniformLocation(handle, name);
}
BlockLighting::BlockLighting()
: program()
, vp(1.0f)
-, m_handle(0)
, mv_handle(0)
, mvp_handle(0)
, fog_density_handle(0) {
"#version 330 core\n"
"layout(location = 0) in vec3 vtx_position;\n"
"layout(location = 1) in vec3 vtx_color;\n"
- "layout(location = 2) in vec3 vtx_normal;\n"
- "layout(location = 3) in float vtx_light;\n"
- "uniform mat4 M;\n"
+ "layout(location = 2) in float vtx_light;\n"
"uniform mat4 MV;\n"
"uniform mat4 MVP;\n"
"out vec3 frag_color;\n"
"out vec3 vtx_viewspace;\n"
- "out vec3 normal;\n"
"out float frag_light;\n"
"void main() {\n"
"gl_Position = MVP * vec4(vtx_position, 1);\n"
"frag_color = vtx_color;\n"
"vtx_viewspace = (MV * vec4(vtx_position, 1)).xyz;\n"
- "normal = (M * vec4(vtx_normal, 0)).xyz;\n"
"frag_light = vtx_light;\n"
"}\n"
);
"void main() {\n"
"vec3 ambient = vec3(0.1, 0.1, 0.1) * frag_color;\n"
"float light_power = clamp(pow(0.8, 15 - frag_light), 0, 1);\n"
- //"float light_power = clamp(frag_light / 15, 0, 1);\n"
- // this should be the same as the clear color, otherwise looks really weird
"vec3 fog_color = vec3(0, 0, 0);\n"
"float e = 2.718281828;\n"
//"vec3 reflect_color = ambient + frag_color * light_power;\n"
throw std::runtime_error("link program");
}
- m_handle = program.UniformLocation("M");
mv_handle = program.UniformLocation("MV");
mvp_handle = program.UniformLocation("MVP");
fog_density_handle = program.UniformLocation("fog_density");
void BlockLighting::SetM(const glm::mat4 &m) {
glm::mat4 mv(view * m);
glm::mat4 mvp(vp * m);
- glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]);
glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]);
glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]);
}
bool Linked() const;
void Log(std::ostream &) const;
+ GLint AttributeLocation(const GLchar *name) const;
GLint UniformLocation(const GLchar *name) const;
void Use() const { glUseProgram(handle); }
glm::mat4 view;
glm::mat4 vp;
- GLuint m_handle;
GLuint mv_handle;
GLuint mvp_handle;
GLuint light_direction_handle;
void Shape::Vertices(
Model::Positions &vertex,
Model::Normals &normal,
- Model::Indices &index,
- const Model::Position &elem_offset,
- Model::Index idx_offset
+ Model::Indices &index
) const {
for (const auto &pos : vtx_pos) {
- vertex.emplace_back(elem_offset + pos);
+ vertex.emplace_back(pos);
+ }
+ for (const auto &nrm : vtx_nrm) {
+ normal.emplace_back(nrm);
}
- normal.insert(normal.end(), vtx_nrm.begin(), vtx_nrm.end());
for (auto idx : vtx_idx) {
- index.emplace_back(idx_offset + idx);
+ index.emplace_back(idx);
}
}
}
}
+void Shape::Vertices(
+ BlockModel::Positions &vertex,
+ BlockModel::Indices &index,
+ const glm::mat4 &transform,
+ BlockModel::Index idx_offset
+) const {
+ for (const auto &pos : vtx_pos) {
+ vertex.emplace_back(transform * glm::vec4(pos, 1.0f));
+ }
+ for (auto idx : vtx_idx) {
+ index.emplace_back(idx_offset + idx);
+ }
+}
+
void Shape::Outline(
OutlineModel::Positions &vertex,
OutlineModel::Indices &index,
/// the number of vertex indices this shape has
size_t VertexIndexCount() const { return vtx_idx.size(); }
+ const Model::Normal &VertexNormal(size_t idx) const { return vtx_nrm[idx]; }
+ Model::Normal VertexNormal(
+ size_t idx, const glm::mat4 &transform
+ ) const {
+ return Model::Normal(transform * glm::vec4(vtx_nrm[idx], 0.0f));
+ }
+
/// fill given buffers with this shape's elements with an
- /// optional offset
+ /// optional transform and offset
void Vertices(
Model::Positions &vertex,
Model::Normals &normal,
- Model::Indices &index,
- const Model::Position &elem_offset = { 0.0f, 0.0f, 0.0f },
- Model::Index idx_offset = 0
+ Model::Indices &index
) const;
void Vertices(
Model::Positions &vertex,
const glm::mat4 &transform,
Model::Index idx_offset = 0
) const;
+ void Vertices(
+ BlockModel::Positions &vertex,
+ BlockModel::Indices &index,
+ const glm::mat4 &transform,
+ BlockModel::Index idx_offset = 0
+ ) const;
/// the number of vertices this shape's outline has
size_t OutlineCount() const { return out_pos.size(); }