Browse Source

breaking changes to implement textures in renderer

master
cinnaboot 8 years ago
parent
commit
d318a4ed90
  1. 2
      Makefile
  2. 12
      data/default.fs
  3. 7
      data/default.vs
  4. 34
      data/test.level.dae
  5. 78
      src/mesh.cpp
  6. 2
      src/mesh.h
  7. 90
      src/render_group.cpp
  8. 23
      src/render_group.h

2
Makefile

@ -1,7 +1,7 @@
CXX = g++
CXXFLAGS = -std=c++11 -g -ggdb -Wall -I/usr/include/SDL2 -Iext/aixlog/include -Iext/stb_libs
CXXFLAGS = -std=c++11 -g -ggdb3 -Wall -I/usr/include/SDL2 -Iext/aixlog/include -Iext/stb_libs
SRC_DIR = src
OBJ_DIR = build

12
data/default.fs

@ -1,8 +1,11 @@
#version 330 core
in vec3 fragmentColor;
in vec3 fragColor;
in vec3 fragNormal;
in vec3 fragVertex;
in vec2 fragUV;
out vec4 color;
uniform mat4 model;
uniform mat3 normal_matrix;
@ -17,7 +20,8 @@ struct point_light {
uniform point_light lights[MAX_LIGHTS];
uniform uint num_lights = 0u;
out vec3 color;
uniform sampler2D sampler;
void main()
{
@ -32,6 +36,8 @@ void main()
totalBrightness += brightness;
}
color = clamp(totalBrightness, 0, 1) * fragmentColor;
vec4 sampled_color = texture(sampler, fragUV.st);
color = clamp(totalBrightness, 0, 1) * sampled_color;
//color = clamp(totalBrightness, 0, 1) * fragColor;
}

7
data/default.vs

@ -3,10 +3,12 @@
layout (location = 0) in vec3 vertexPosition_modelspace;
layout (location = 1) in vec3 vertexColor;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec3 texCoord;
out vec3 fragmentColor;
out vec3 fragColor;
out vec3 fragNormal;
out vec3 fragVertex;
out vec2 fragUV;
uniform mat4 model;
uniform mat4 view;
@ -14,9 +16,10 @@ uniform mat4 projection;
void main()
{
fragmentColor = vertexColor;
fragColor = vertexColor;
fragNormal = normal;
fragVertex = vertexPosition_modelspace;
fragUV = texCoord.st;
gl_Position = projection * view * model * vec4(vertexPosition_modelspace, 1);
}

34
data/test.level.dae

@ -5,8 +5,8 @@
<author>Blender User</author>
<authoring_tool>Blender 2.79.0 commit date:2018-05-26, commit time:21:51, hash:32432d91bbe</authoring_tool>
</contributor>
<created>2018-12-24T11:48:15</created>
<modified>2018-12-24T11:48:15</modified>
<created>2018-12-24T10:36:57</created>
<modified>2018-12-24T10:36:57</modified>
<unit name="meter" meter="1"/>
<up_axis>Z_UP</up_axis>
</asset>
@ -16,7 +16,7 @@
</image>
</library_images>
<library_effects>
<effect id="test_texture_png-effect">
<effect id="ground_material-effect">
<profile_COMMON>
<newparam sid="test_texture_png-surface">
<surface type="2D">
@ -29,21 +29,27 @@
</sampler2D>
</newparam>
<technique sid="common">
<phong>
<lambert>
<emission>
<color sid="emission">0 0 0 1</color>
</emission>
<ambient>
<color sid="ambient">0 0 0 1</color>
</ambient>
<diffuse>
<texture texture="test_texture_png-sampler" texcoord="test_texture_png"/>
<texture texture="test_texture_png-sampler" texcoord="UVMap"/>
</diffuse>
<specular>
<color sid="specular">0 0 0 1</color>
</specular>
</phong>
<index_of_refraction>
<float sid="index_of_refraction">1</float>
</index_of_refraction>
</lambert>
</technique>
</profile_COMMON>
</effect>
</library_effects>
<library_materials>
<material id="test_texture_png-material" name="test_texture_png">
<instance_effect url="#test_texture_png-effect"/>
<material id="ground_material-material" name="ground_material">
<instance_effect url="#ground_material-effect"/>
</material>
</library_materials>
<library_geometries>
@ -81,7 +87,7 @@
<vertices id="Plane-mesh-vertices">
<input semantic="POSITION" source="#Plane-mesh-positions"/>
</vertices>
<triangles material="test_texture_png-material" count="242">
<triangles material="ground_material-material" count="242">
<input semantic="VERTEX" source="#Plane-mesh-vertices" offset="0"/>
<input semantic="NORMAL" source="#Plane-mesh-normals" offset="1"/>
<input semantic="TEXCOORD" source="#Plane-mesh-map-0" offset="2" set="0"/>
@ -98,9 +104,7 @@
<instance_geometry url="#Plane-mesh" name="Plane">
<bind_material>
<technique_common>
<instance_material symbol="test_texture_png-material" target="#test_texture_png-material">
<bind_vertex_input semantic="UVMap" input_semantic="TEXCOORD" input_set="0"/>
</instance_material>
<instance_material symbol="ground_material-material" target="#ground_material-material"/>
</technique_common>
</bind_material>
</instance_geometry>

78
src/mesh.cpp

@ -14,9 +14,14 @@
#include "mesh.h"
// forward declarations
meMeshInfo* allocateMeshInfo(uint num_vertices, uint num_indices, bool has_normals, bool has_texture);
void freeMesh(meMeshInfo* mesh);
inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out);
meMeshInfo* copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh);
void freeMesh(meMeshInfo* mesh);
// interface
bool
meInitAssimp()
@ -75,6 +80,37 @@ meShutdownAssimp()
aiDetachAllLogStreams();
}
// internal
meMeshInfo*
allocateMeshInfo(uint num_vertices, uint num_indices, bool has_normals, bool has_texture)
{
meMeshInfo* mi = UTIL_ALLOC(1, meMeshInfo);
mi->model_transform = glm::mat4(1);
// allocate buffers for vertex and index data from mesh
mi->num_vertices = num_vertices;
mi->vertices = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->num_indices = num_indices;
mi->indices = UTIL_ALLOC(num_indices, uint);
if (has_normals) mi->normals = UTIL_ALLOC(mi->num_vertices, glm::vec3);
if (has_texture) mi->texture_coords = UTIL_ALLOC(mi->num_vertices, glm::vec3);
return mi;
}
void
freeMesh(meMeshInfo* mesh)
{
utilFreeImage(mesh->diffuse_texture);
utilSafeFree(mesh->vertices);
utilSafeFree(mesh->normals);
utilSafeFree(mesh->texture_coords);
utilSafeFree(mesh->indices);
utilSafeFree(mesh);
}
inline glm::vec3
copyVector(aiVector3D v_in, glm::vec3& v_out)
{
@ -87,22 +123,21 @@ copyVector(aiVector3D v_in, glm::vec3& v_out)
meMeshInfo*
copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh)
{
meMeshInfo* mi = UTIL_ALLOC(1, meMeshInfo);
mi->model_transform = glm::mat4(1);
bool has_tex = mesh->HasTextureCoords(0);
bool has_normals = mesh->HasNormals();
meMeshInfo* mi = allocateMeshInfo(mesh->mNumVertices, mesh->mNumFaces * 3, has_normals, has_tex);
// allocate buffers for vertex and index data from mesh
mi->num_vertices = mesh->mNumVertices;
mi->vertices = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->normals = UTIL_ALLOC(mi->num_vertices, glm::vec3);
mi->num_indices = mesh->mNumFaces * 3; // NOTE: assume 3 vertices per face
mi->indices = UTIL_ALLOC(mi->num_indices, uint);
// copy vertices and normals
// copy vertices, normals, and texture coords
for (uint i = 0; i < mi->num_vertices; i++) {
copyVector(mesh->mVertices[i], mi->vertices[i]);
if (mesh->HasNormals())
if (has_normals)
copyVector(mesh->mNormals[i], mi->normals[i]);
if (has_tex) {
mi->texture_coords[i].x = mesh->mTextureCoords[0][i].x;
mi->texture_coords[i].y = mesh->mTextureCoords[0][i].y;
}
}
// copy indices
@ -113,9 +148,8 @@ copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh)
// material
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
aiColor3D color(0.f, 0.f, 0.f);
if (AI_SUCCESS != mat->Get(AI_MATKEY_COLOR_DIFFUSE, color)) {
LOG(ERROR) << "Some Assimp-type-error\n";
} else {
if (AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE, color)) {
mi->diffuse_color.r = color.r;
mi->diffuse_color.g = color.g;
mi->diffuse_color.b = color.b;
@ -130,21 +164,9 @@ copyMeshInfo(const char* data_dir, const aiScene* scene, aiMesh* mesh)
file_path.append(data_dir).append("/").append(file_name.C_Str());
LOG(INFO) << "Loading texture file: " << file_name.C_Str() << "\n";
mi->diffuse_texture = utilLoadImage(file_path.c_str());
mi->use_texture = true;
}
}
return mi;
}
void
freeMesh(meMeshInfo* mesh)
{
if (mesh->diffuse_texture.pixels != 0)
utilFreeImage(mesh->diffuse_texture);
utilSafeFree(mesh->vertices);
utilSafeFree(mesh->normals);
utilSafeFree(mesh->indices);
utilSafeFree(mesh);
}

2
src/mesh.h

@ -15,10 +15,12 @@ struct meMeshInfo
uint num_vertices = 0;
glm::vec3* vertices = nullptr;
glm::vec3* normals = nullptr;
glm::vec3* texture_coords = nullptr; // NOTE: using vec3 to stay aligned with other props
uint num_indices = 0;
uint* indices = nullptr;
glm::vec3 diffuse_color;
bool use_texture = false;
util_image diffuse_texture;
};

90
src/render_group.cpp

@ -20,7 +20,8 @@
render_object * allocateRenderObject(uint buffer_len, uint index_len = 0);
void freeRenderObject(render_object* ro);
bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals);
bool initGLTexture(render_object* ro, util_image image);
bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals, bool use_texture);
void sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target);
@ -72,6 +73,7 @@ rgInitShaderProgram(rg_shader_program& sp, const char * vertex_code, const char
sp.projection_matrix_id = glGetUniformLocation(sp.program_id, "projection");
sp.normal_matrix_id = glGetUniformLocation(sp.program_id, "normal_matrix");
sp.num_lights_id = glGetUniformLocation(sp.program_id, "num_lights");
sp.sampler_id = glGetUniformLocation(sp.program_id, "sampler");
glDetachShader(sp.program_id, vertex_shader_id);
glDetachShader(sp.program_id, fragment_shader_id);
@ -121,17 +123,27 @@ rgInitEntity(Entity* e)
for (uint i = 0; i < num_meshes; i++)
{
uint buffer_len = e->mesh_group.meshes[i]->num_vertices * 3;
uint index_len = e->mesh_group.meshes[i]->num_indices;
meMeshInfo* mesh = e->mesh_group.meshes[i];
uint buffer_len = mesh->num_vertices * 3;
uint index_len = mesh->num_indices;
rg->render_objects[i] = allocateRenderObject(buffer_len, index_len);
render_object* ro = rg->render_objects[i];
if (rg->render_objects[i] == nullptr)
if (ro == nullptr)
return false;
if (!convertMeshInfo(e->mesh_group.meshes[i], rg->render_objects[i], rg->use_normals)) {
if (!convertMeshInfo(mesh, ro, rg->use_normals, mesh->use_texture)) {
rgFree(rg);
return false;
}
if (mesh->use_texture) {
ro->use_texture = true;
if (!initGLTexture(ro, mesh->diffuse_texture)) {
LOG(ERROR) << "Error initializing GL texture\n";
return false;
}
}
}
return true;
@ -210,6 +222,14 @@ rgDraw(render_group* rg, glm::mat4 model_matrix,
}
}
if (ro->use_texture) {
glEnableVertexAttribArray(3);
glBindBuffer(GL_ARRAY_BUFFER, ro->uv_buffer.buffer_id);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindTexture(GL_TEXTURE_2D, ro->tex_id);
glUniform1i(rg->shader.sampler_id, 0);
}
// draw
if (rg->draw_indexed) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ro->index_buffer.buffer_id);
@ -224,6 +244,8 @@ rgDraw(render_group* rg, glm::mat4 model_matrix,
glDisableVertexAttribArray(1);
if (rg->use_normals)
glDisableVertexAttribArray(2);
if (ro->use_texture)
glDisableVertexAttribArray(3);
glUseProgram(0);
}
@ -261,6 +283,8 @@ allocateRenderObject(uint buffer_len, uint index_len)
ro->normal_buffer.buffer_len = buffer_len;
ro->color_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat);
ro->color_buffer.buffer_len = buffer_len;
ro->uv_buffer.buffer = UTIL_ALLOC(buffer_len, GLfloat);
ro->uv_buffer.buffer_len = buffer_len;
if (index_len > 0) {
ro->index_buffer.buffer = UTIL_ALLOC(index_len, uint);
@ -282,40 +306,38 @@ allocateRenderObject(uint buffer_len, uint index_len)
void
freeRenderObject(render_object* ro)
{
if (ro == nullptr) {
LOG(ERROR) << "Tried to free nullptr\n";
return;
}
utilSafeFree(ro->vertex_buffer.buffer);
utilSafeFree(ro->normal_buffer.buffer);
utilSafeFree(ro->color_buffer.buffer);
utilSafeFree(ro->uv_buffer.buffer);
utilSafeFree(ro->index_buffer.buffer);
utilSafeFree(ro);
}
void
sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target)
{
glGenBuffers(1, &index_buffer->buffer_id);
glBindBuffer(target, index_buffer->buffer_id);
glBufferData(target, index_buffer->buffer_len * sizeof(uint), index_buffer->buffer, usage);
}
bool
convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals)
convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals, bool use_texture)
{
uint vertex_buf_len = mesh->num_vertices * 3;
GLfloat* vertex_buf = ro->vertex_buffer.buffer;
GLfloat* color_buf = ro->color_buffer.buffer;
GLfloat* normal_buf = ro->normal_buffer.buffer;
GLfloat* uv_buf = ro->uv_buffer.buffer;
uint* index_buf = ro->index_buffer.buffer;
if (!vertex_buf || !color_buf || !normal_buf || !index_buf)
return false;
// dump vertices, colors, and normals into render_group buffers
// dump vertices, colors, normals, and texture coords into render_group buffers
uint vertex_index = 0;
uint vertex_prop_index = 0;
for (uint i = 0; i < vertex_buf_len; i++) {
const glm::vec3& vertex = mesh->vertices[vertex_index];
const glm::vec3& normal = mesh->normals[vertex_index];
switch (vertex_prop_index) {
case 0: vertex_buf[i] = vertex.x; break;
@ -324,6 +346,7 @@ convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals)
}
if (use_normals) {
const glm::vec3& normal = mesh->normals[vertex_index];
switch (vertex_prop_index) {
case 0: normal_buf[i] = normal.x; break;
case 1: normal_buf[i] = normal.y; break;
@ -331,6 +354,15 @@ convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals)
}
}
if (use_texture) {
const glm::vec3& uv = mesh->texture_coords[vertex_index];
switch (vertex_prop_index) {
case 0: uv_buf[i] = uv.x; break;
case 1: uv_buf[i] = uv.y; break;
case 2: uv_buf[i] = uv.z; break;
}
}
color_buf[i] = mesh->diffuse_color[vertex_prop_index];
vertex_prop_index++;
@ -348,8 +380,34 @@ convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals)
rgBufferData(&ro->color_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
if (use_normals)
rgBufferData(&ro->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
if (use_texture)
rgBufferData(&ro->uv_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
sendIndexBufferToGL(&ro->index_buffer, GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
return true;
}
bool
initGLTexture(render_object* ro, util_image image)
{
glGenTextures(1, &ro->tex_id);
glBindTexture(GL_TEXTURE_2D, ro->tex_id);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
GLenum pixel_format = (image.num_channels == 3) ? GL_RGB : GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0, pixel_format, image.w, image.h, 0,
pixel_format, GL_UNSIGNED_BYTE, image.pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
return (glGetError() == GL_NO_ERROR);
}
void
sendIndexBufferToGL(gl_index_buffer* index_buffer, GLenum usage, GLenum target)
{
glGenBuffers(1, &index_buffer->buffer_id);
glBindBuffer(target, index_buffer->buffer_id);
glBufferData(target, index_buffer->buffer_len * sizeof(uint), index_buffer->buffer, usage);
}

23
src/render_group.h

@ -24,25 +24,32 @@ struct gl_index_buffer
uint* buffer = nullptr;
};
struct render_object
{
gl_buffer vertex_buffer;
gl_buffer normal_buffer;
gl_buffer color_buffer;
gl_index_buffer index_buffer;
};
struct rg_shader_program
{
GLuint program_id = 0;
GLuint model_matrix_id = 0;
GLuint view_matrix_id = 0;
GLuint projection_matrix_id = 0;
GLuint normal_matrix_id = 0;
GLuint vertex_array_id = 0;
GLuint sampler_id = 0;
GLuint num_lights_id = 0;
};
struct render_object
{
bool use_texture = false;
GLuint tex_id = 0;
gl_buffer vertex_buffer;
gl_buffer normal_buffer;
gl_buffer color_buffer;
gl_buffer uv_buffer;
gl_index_buffer index_buffer;
};
struct render_group
{
uint num_objects = 0;

Loading…
Cancel
Save