- OBJ file reading
- VBO memory management - Lighting
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
|||||||
CXX=g++
|
CXX=g++
|
||||||
CXXOPTS=-Og -ggdb -Wall -Wextra -pedantic -Wno-unused-function -Wno-unused-parameter -std=c++11
|
CXXOPTS=-Og -ggdb -Wall -Wextra -pedantic -Wno-unused-function -Wno-unused-parameter -std=c++11
|
||||||
LDOPTS=-flto
|
LDOPTS=-flto
|
||||||
LIBS=-lGL -lSDL2 -lSDL2_image -lobj
|
LIBS=-lglbinding -lSDL2 -lSDL2_image -lobj
|
||||||
CXXSRCS=main.cc objectParser.cc
|
CXXSRCS=main.cc objectParser.cc
|
||||||
OBJS=$(addprefix objs/,$(CXXSRCS:.cc=.o))
|
OBJS=$(addprefix objs/,$(CXXSRCS:.cc=.o))
|
||||||
|
|
||||||
|
|||||||
70
Object.hh
Normal file
70
Object.hh
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#ifndef __OPENGLPLAYGROUND_OBJECT_HH__
|
||||||
|
#define __OPENGLPLAYGROUND_OBJECT_HH__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "objectParser.hh"
|
||||||
|
#include "VBOManager.hh"
|
||||||
|
|
||||||
|
class Object {
|
||||||
|
public:
|
||||||
|
Object(VBOManager& vboManager, std::vector<objVertexAttribs> const& vas, std::vector<uint16_t> const& indices,
|
||||||
|
Program& prog)
|
||||||
|
: _vboManager(vboManager), _prog(prog), _indices(indices) {
|
||||||
|
construct(vas);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object(VBOManager& vboManager, std::string const& filename, Program& prog)
|
||||||
|
: _vboManager(vboManager), _prog(prog) {
|
||||||
|
auto tmp = readObject(filename);
|
||||||
|
_indices = std::get<1>(tmp);
|
||||||
|
construct(std::get<0>(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
~Object() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(glm::mat4 const& modelview) const {
|
||||||
|
glBindVertexArray(_vaID);
|
||||||
|
_prog.use();
|
||||||
|
glUniformMatrix4fv(_prog.getUniformLocation("model_matrix"), 1, GL_FALSE,
|
||||||
|
glm::value_ptr(modelview));
|
||||||
|
glDrawElements(GL_TRIANGLES, _indices.size(), GL_UNSIGNED_SHORT, _indices.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void construct(std::vector<objVertexAttribs> const& vas) {
|
||||||
|
_vbo = _vboManager.alloc(sizeof(objVertexAttribs)*vas.size());
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _vbo.getVBOId());
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, _vbo.getOfs(), sizeof(objVertexAttribs)*vas.size(),
|
||||||
|
(void*)vas.data());
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &_vaID);
|
||||||
|
glBindVertexArray(_vaID);
|
||||||
|
|
||||||
|
GLint al;
|
||||||
|
if((al = _prog.getAttribLocation("vertex")) != -1) {
|
||||||
|
glEnableVertexAttribArray(al);
|
||||||
|
glVertexAttribPointer(al, 3, GL_FLOAT, GL_FALSE, sizeof(objVertexAttribs),
|
||||||
|
(void*)(_vbo.getOfs()+offsetof(objVertexAttribs, vertex)));
|
||||||
|
}
|
||||||
|
if((al = _prog.getAttribLocation("vertexTC")) != -1) {
|
||||||
|
glEnableVertexAttribArray(al);
|
||||||
|
glVertexAttribPointer(al, 2, GL_UNSIGNED_SHORT, GL_TRUE, sizeof(objVertexAttribs),
|
||||||
|
(void*)(_vbo.getOfs()+offsetof(objVertexAttribs, texCoords)));
|
||||||
|
}
|
||||||
|
if((al = _prog.getAttribLocation("vertexNorm")) != -1) {
|
||||||
|
glEnableVertexAttribArray(al);
|
||||||
|
glVertexAttribPointer(al, 4, GL_INT_2_10_10_10_REV, GL_TRUE, sizeof(objVertexAttribs),
|
||||||
|
(void*)(_vbo.getOfs()+offsetof(objVertexAttribs, normal)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VBOManager& _vboManager;
|
||||||
|
VBOManager::VBOAlloc _vbo;
|
||||||
|
Program& _prog;
|
||||||
|
std::vector<uint16_t> _indices;
|
||||||
|
GLuint _vaID;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
181
VBOManager.hh
Normal file
181
VBOManager.hh
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
#ifndef __OPENGLPLAYGROUND_VBOMANAGER_HH__
|
||||||
|
#define __OPENGLPLAYGROUND_VBOMANAGER_HH__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include <glbinding/gl/gl.h>
|
||||||
|
|
||||||
|
using namespace gl;
|
||||||
|
|
||||||
|
class VBOManager {
|
||||||
|
public:
|
||||||
|
VBOManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
~VBOManager() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class VBO;
|
||||||
|
|
||||||
|
static const size_t default_size = 1048576;
|
||||||
|
static const size_t alignment = 8;
|
||||||
|
|
||||||
|
class AllocFailed {};
|
||||||
|
|
||||||
|
public:
|
||||||
|
class VBOAlloc {
|
||||||
|
public:
|
||||||
|
~VBOAlloc() {
|
||||||
|
if(_vbo)
|
||||||
|
_vbo->free(*this);
|
||||||
|
_vbo = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VBOAlloc(VBOAlloc&& move) : _vbo(move._vbo), _ofs(move._ofs), _size(move._size) {
|
||||||
|
move._vbo = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
VBOAlloc& operator=(VBOAlloc&& move) {
|
||||||
|
_vbo = move._vbo;
|
||||||
|
_ofs = move._ofs;
|
||||||
|
_size = move._size;
|
||||||
|
move._vbo = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
VBOAlloc() : _vbo(nullptr), _ofs(0), _size(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getOfs() const {
|
||||||
|
assert(_vbo);
|
||||||
|
return _ofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getSize() const {
|
||||||
|
assert(_vbo);
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint getVBOId() const {
|
||||||
|
assert(_vbo);
|
||||||
|
return _vbo->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VBOAlloc(VBO &vbo, size_t ofs, size_t size) : _vbo(&vbo), _ofs(ofs), _size(size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class VBOManager;
|
||||||
|
friend class VBO;
|
||||||
|
|
||||||
|
VBO *_vbo;
|
||||||
|
size_t _ofs, _size;
|
||||||
|
};
|
||||||
|
|
||||||
|
VBOAlloc alloc(size_t size, GLenum type = GL_STATIC_DRAW) {
|
||||||
|
for(auto& vbo : _vbos[type]) {
|
||||||
|
try {
|
||||||
|
return vbo.alloc(size);
|
||||||
|
} catch (AllocFailed &ex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_vbos[type].emplace_back((size>default_size)?size:default_size, type);
|
||||||
|
|
||||||
|
return _vbos[type].back().alloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class VBO {
|
||||||
|
public:
|
||||||
|
VBO(size_t size = default_size, GLenum type = GL_STATIC_DRAW) : _bufID(0) {
|
||||||
|
glGenBuffers(1, &_bufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, _bufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, size, NULL, type);
|
||||||
|
_allocs.emplace_back(_Entry{size, false});
|
||||||
|
}
|
||||||
|
|
||||||
|
VBO(VBO const& copy) = delete;
|
||||||
|
|
||||||
|
VBO(VBO&& move) : _bufID(move._bufID), _allocs(move._allocs) {
|
||||||
|
move._bufID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~VBO() {
|
||||||
|
for (auto ent : _allocs) {
|
||||||
|
assert(!ent.used);
|
||||||
|
}
|
||||||
|
if (_bufID)
|
||||||
|
glDeleteBuffers(1, &_bufID);
|
||||||
|
_bufID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VBOAlloc alloc(size_t size) {
|
||||||
|
if (size%alignment != 0)
|
||||||
|
size += (alignment - (size%alignment));
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
for (auto it = _allocs.begin();it != _allocs.end();++it) {
|
||||||
|
if (!it->used && (it->size >= size)) {
|
||||||
|
size_t leftover = it->size - size;
|
||||||
|
it->used = true;
|
||||||
|
it->size = size;
|
||||||
|
if (leftover > 0)
|
||||||
|
_allocs.insert(++it, _Entry{leftover, false});
|
||||||
|
printf("DEBUG: VBO: Allocated %lu @ %lu in %u\n", size, pos, _bufID);
|
||||||
|
return VBOAlloc(*this, pos, size);
|
||||||
|
}
|
||||||
|
pos += it->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw AllocFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(VBOAlloc& alloc) {
|
||||||
|
size_t pos = 0;
|
||||||
|
for (auto it = _allocs.begin();it != _allocs.end();++it) {
|
||||||
|
if (pos == alloc._ofs) {
|
||||||
|
assert(it->size == alloc._size);
|
||||||
|
printf("DEBUG: VBO: Freed %lu @ %lu in %u\n", alloc._size, pos, _bufID);
|
||||||
|
it->used = false;
|
||||||
|
if ((std::next(it) != _allocs.end()) &&
|
||||||
|
!std::next(it)->used) {
|
||||||
|
it->size += std::next(it)->size;
|
||||||
|
_allocs.erase(std::next(it));
|
||||||
|
}
|
||||||
|
if ((it != _allocs.begin()) &&
|
||||||
|
!std::prev(it)->used) {
|
||||||
|
it->size += std::prev(it)->size;
|
||||||
|
_allocs.erase(std::prev(it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos += it->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint getID() const {
|
||||||
|
return _bufID;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint _bufID;
|
||||||
|
|
||||||
|
struct _Entry {
|
||||||
|
size_t size;
|
||||||
|
bool used;
|
||||||
|
};
|
||||||
|
std::list<_Entry> _allocs;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<GLenum, std::vector<VBO> > _vbos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
14
common.hh
14
common.hh
@@ -6,11 +6,12 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#include <glbinding/gl/gl.h>
|
||||||
#include <GL/gl.h>
|
|
||||||
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
using namespace gl;
|
||||||
|
|
||||||
class Exception {
|
class Exception {
|
||||||
public:
|
public:
|
||||||
Exception() {
|
Exception() {
|
||||||
@@ -68,7 +69,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual std::string toString() const {
|
virtual std::string toString() const {
|
||||||
return "GLException: " + errToString() + "(" + std::to_string(_err) + ")";
|
return "GLException: " + errToString() + "(" + std::to_string(static_cast<int>(_err)) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -118,4 +119,11 @@ static std::string fileToString(std::string const& name) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class VAFormats {
|
||||||
|
Vertex,
|
||||||
|
VertexTexcoord,
|
||||||
|
VertexNormal,
|
||||||
|
VertexNormalTexcoord
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
92
main.cc
92
main.cc
@@ -5,8 +5,9 @@
|
|||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_image.h>
|
#include <SDL2/SDL_image.h>
|
||||||
|
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#include <glbinding/gl/gl.h>
|
||||||
#include <GL/gl.h>
|
#include <glbinding/Binding.h>
|
||||||
|
#include <glbinding/callbacks.h>
|
||||||
|
|
||||||
#define GLM_FORCE_RADIANS
|
#define GLM_FORCE_RADIANS
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
@@ -17,13 +18,28 @@
|
|||||||
#include "common.hh"
|
#include "common.hh"
|
||||||
#include "shaders.hh"
|
#include "shaders.hh"
|
||||||
#include "texture.hh"
|
#include "texture.hh"
|
||||||
|
#include "VBOManager.hh"
|
||||||
#include "objectParser.hh"
|
#include "objectParser.hh"
|
||||||
|
#include "Object.hh"
|
||||||
|
|
||||||
|
using namespace gl;
|
||||||
|
|
||||||
|
void glAfterCallback(glbinding::FunctionCall const& fc)
|
||||||
|
{
|
||||||
|
glbinding::setCallbackMask(glbinding::CallbackMask::None);
|
||||||
|
GLenum error = glGetError();
|
||||||
|
glbinding::setCallbackMask(glbinding::CallbackMask::After);
|
||||||
|
if (error != GL_NO_ERROR)
|
||||||
|
throw GLException(error);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
int retcode = 0;
|
int retcode = 0;
|
||||||
|
|
||||||
|
glbinding::Binding::initialize();
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
std::printf("Could not init SDL: %s\n", SDL_GetError());
|
std::printf("Could not init SDL: %s\n", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
@@ -49,7 +65,7 @@ int main(int argc, char *argv[])
|
|||||||
SDL_WINDOWPOS_UNDEFINED,
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
640,
|
640,
|
||||||
480,
|
480,
|
||||||
SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_OPENGL);
|
/*SDL_WINDOW_FULLSCREEN_DESKTOP |*/ SDL_WINDOW_OPENGL);
|
||||||
|
|
||||||
if (!window) {
|
if (!window) {
|
||||||
std::printf("Could not create window: %s\n", SDL_GetError());
|
std::printf("Could not create window: %s\n", SDL_GetError());
|
||||||
@@ -65,8 +81,12 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear GL errors
|
||||||
|
while(glGetError() != GL_NO_ERROR);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while(glGetError() != GL_NO_ERROR);
|
glbinding::setCallbackMask(glbinding::CallbackMask::After);
|
||||||
|
glbinding::setAfterCallback(glAfterCallback);
|
||||||
|
|
||||||
{
|
{
|
||||||
int depth, stencil, aa, major, minor;
|
int depth, stencil, aa, major, minor;
|
||||||
@@ -84,8 +104,8 @@ int main(int argc, char *argv[])
|
|||||||
SDL_GetWindowSize(window, &width, &height);
|
SDL_GetWindowSize(window, &width, &height);
|
||||||
glm::mat4 proj = glm::perspectiveFov(75.0f, static_cast<float>(width), static_cast<float>(height),
|
glm::mat4 proj = glm::perspectiveFov(75.0f, static_cast<float>(width), static_cast<float>(height),
|
||||||
0.1f, 100.0f);
|
0.1f, 100.0f);
|
||||||
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 10),
|
glm::mat4 view = glm::lookAt(glm::vec3(2.0f, 2.0f, 10),
|
||||||
glm::vec3(0, 0, 0),
|
glm::vec3(0.0f, 0.0f, 0),
|
||||||
glm::vec3(0, 1, 0));
|
glm::vec3(0, 1, 0));
|
||||||
// sf::Font font;
|
// sf::Font font;
|
||||||
// if (!font.loadFromFile("DejaVuSans.ttf")) {
|
// if (!font.loadFromFile("DejaVuSans.ttf")) {
|
||||||
@@ -101,55 +121,33 @@ int main(int argc, char *argv[])
|
|||||||
// sf::Clock clock;
|
// sf::Clock clock;
|
||||||
// sf::Time last = clock.getElapsedTime();
|
// sf::Time last = clock.getElapsedTime();
|
||||||
|
|
||||||
|
VBOManager vboManager;
|
||||||
|
|
||||||
Texture2D cubeTex("textures/Wood_Box_Texture.jpg");
|
Texture2D cubeTex("textures/Wood_Box_Texture.jpg");
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, static_cast<int>(GL_LINEAR_MIPMAP_LINEAR));
|
||||||
if (SDL_GL_ExtensionSupported("GL_EXT_texture_filter_anisotropic"))
|
if (SDL_GL_ExtensionSupported("GL_EXT_texture_filter_anisotropic"))
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0f);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0f);
|
||||||
else
|
else
|
||||||
std::printf("Warning: extension GL_EXT_texture_filter_anisotropic not supported\n");
|
std::printf("Warning: extension GL_EXT_texture_filter_anisotropic not supported\n");
|
||||||
|
Texture2D redTex("textures/red.png");
|
||||||
auto box = readObject("objects/woodbox.obj");
|
Texture2D whiteTex("textures/white.png");
|
||||||
|
|
||||||
VertexShader vs{fileToString("shaders/textured.vs")};
|
VertexShader vs{fileToString("shaders/textured.vs")};
|
||||||
FragmentShader fs{fileToString("shaders/textured.fs")};
|
FragmentShader fs{fileToString("shaders/textured.fs")};
|
||||||
Program prog(vs, fs);
|
Program prog(vs, fs);
|
||||||
checkGlError();
|
|
||||||
|
|
||||||
prog.use();
|
prog.use();
|
||||||
glUniformMatrix4fv(prog.getUniformLocation("projection_matrix"), 1, GL_FALSE,
|
glUniformMatrix4fv(prog.getUniformLocation("projection_matrix"), 1, GL_FALSE,
|
||||||
glm::value_ptr(proj));
|
glm::value_ptr(proj));
|
||||||
|
glUniformMatrix4fv(prog.getUniformLocation("view_matrix"), 1, GL_FALSE,
|
||||||
|
glm::value_ptr(view));
|
||||||
glUniform1i(prog.getUniformLocation("texBase"), 0);
|
glUniform1i(prog.getUniformLocation("texBase"), 0);
|
||||||
|
|
||||||
int vertexAL = prog.getAttribLocation("vertex");
|
Object box(vboManager, "objects/woodbox.obj", prog);
|
||||||
int vertexTCAL = prog.getAttribLocation("vertexTC");
|
Object pyramid(vboManager, "objects/pyramid.obj", prog);
|
||||||
|
Object plane(vboManager, "objects/plane.obj", prog);
|
||||||
checkGlError();
|
|
||||||
|
|
||||||
GLuint buf;
|
|
||||||
glGenBuffers(1, &buf);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buf);
|
|
||||||
checkGlError();
|
|
||||||
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(objVertexAttribs)*std::get<0>(box).size(), NULL, GL_STATIC_DRAW);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(objVertexAttribs)*std::get<0>(box).size(),
|
|
||||||
(void*)std::get<0>(box).data());
|
|
||||||
|
|
||||||
GLuint arr[2];
|
|
||||||
glGenVertexArrays(2, arr);
|
|
||||||
checkGlError();
|
|
||||||
|
|
||||||
glBindVertexArray(arr[0]);
|
|
||||||
glEnableVertexAttribArray(vertexAL);
|
|
||||||
glEnableVertexAttribArray(vertexTCAL);
|
|
||||||
glVertexAttribPointer(vertexAL, 3, GL_FLOAT, GL_FALSE, sizeof(objVertexAttribs),
|
|
||||||
(void*)offsetof(objVertexAttribs, vertex));
|
|
||||||
glVertexAttribPointer(vertexTCAL, 2, GL_UNSIGNED_SHORT, GL_TRUE, sizeof(objVertexAttribs),
|
|
||||||
(void*)offsetof(objVertexAttribs, texCoords));
|
|
||||||
checkGlError();
|
|
||||||
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
checkGlError();
|
|
||||||
|
|
||||||
bool close = false;
|
bool close = false;
|
||||||
|
|
||||||
@@ -169,14 +167,18 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
checkGlError();
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
prog.use();
|
glm::mat4 model = glm::translate(glm::vec3(0.5f, 0.5f, -0.5f)) *
|
||||||
glm::mat4 model = glm::rotate(SDL_GetTicks()*0.001f, glm::vec3(1.0f, 0.0f, 0.0f));
|
glm::rotate(SDL_GetTicks()*0.001f, glm::vec3(1.0f, 0.0f, 0.0f)) *
|
||||||
glUniformMatrix4fv(prog.getUniformLocation("modelview_matrix"), 1, GL_FALSE,
|
glm::translate(glm::vec3(-0.5f, -0.5f, 0.5f));
|
||||||
glm::value_ptr(view*model));
|
cubeTex.bind();
|
||||||
glDrawElements(GL_TRIANGLES, std::get<1>(box).size(), GL_UNSIGNED_SHORT, std::get<1>(box).data());
|
box.draw(model);
|
||||||
checkGlError();
|
whiteTex.bind();
|
||||||
|
plane.draw(glm::translate(glm::vec3(2.0f, -2.5f, 0.0f))*
|
||||||
|
glm::rotate(0.35f, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||||
|
redTex.bind();
|
||||||
|
pyramid.draw(glm::translate(glm::vec3(-2.0f, 0.0f, 0.0f)));
|
||||||
|
|
||||||
// glUseProgram(0);
|
// glUseProgram(0);
|
||||||
// sf::Time now = clock.getElapsedTime();
|
// sf::Time now = clock.getElapsedTime();
|
||||||
|
|||||||
221
objectParser.cc
221
objectParser.cc
@@ -5,6 +5,9 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <tr1/functional>
|
#include <tr1/functional>
|
||||||
#include <obj.hpp>
|
#include <obj.hpp>
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/packing.hpp>
|
||||||
|
|
||||||
#include "objectParser.hh"
|
#include "objectParser.hh"
|
||||||
|
|
||||||
@@ -20,69 +23,135 @@ class ObjectParser {
|
|||||||
private:
|
private:
|
||||||
void texture_vertex_callback(obj::float_type u, obj::float_type v)
|
void texture_vertex_callback(obj::float_type u, obj::float_type v)
|
||||||
{
|
{
|
||||||
|
assert(!_addedGenerated);
|
||||||
if ((u > 1.0f) || (u < 0.0f))
|
if ((u > 1.0f) || (u < 0.0f))
|
||||||
std::cout << "Warning: Clamping texture coordinate U to [0.0, 1.0]" << std::endl;
|
std::cout << "Warning: Clamping texture coordinate U to [0.0, 1.0]" << std::endl;
|
||||||
uint16_t c_u = static_cast<uint16_t>(fminf(1.0f, fmaxf(0.0f, u))*65535.0);
|
uint16_t c_u = glm::packUnorm1x16(u);
|
||||||
if ((v > 1.0f) || (v < 0.0f))
|
if ((v > 1.0f) || (v < 0.0f))
|
||||||
std::cout << "Warning: Clamping texture coordinate V to [0.0, 1.0]" << std::endl;
|
std::cout << "Warning: Clamping texture coordinate V to [0.0, 1.0]" << std::endl;
|
||||||
uint16_t c_v = static_cast<uint16_t>(fminf(1.0f, fmaxf(0.0f, v))*65535.0);
|
uint16_t c_v = glm::packUnorm1x16(v);
|
||||||
_texCoords.emplace_back(c_u, c_v);
|
_texCoords.emplace_back(glm::u16vec2(c_u, c_v));
|
||||||
std::cout << "vt " << c_u << " " << c_v << "\n";
|
std::cout << "vt " << c_u << " " << c_v << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void geometric_vertex_callback(obj::float_type x, obj::float_type y, obj::float_type z)
|
void geometric_vertex_callback(obj::float_type x, obj::float_type y, obj::float_type z)
|
||||||
{
|
{
|
||||||
_vertices.emplace_back(x, y, z);
|
_vertices.emplace_back(glm::vec3(x, y, z));
|
||||||
std::cout << "v " << x << " " << y << " " << z << "\n";
|
std::cout << "v " << x << " " << y << " " << z << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void vertex_normal_callback(obj::float_type x, obj::float_type y, obj::float_type z)
|
void vertex_normal_callback(obj::float_type x, obj::float_type y, obj::float_type z)
|
||||||
{
|
{
|
||||||
|
assert(!_addedGenerated);
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
signed :2;
|
|
||||||
signed z:10;
|
|
||||||
signed y:10;
|
|
||||||
signed x:10;
|
signed x:10;
|
||||||
|
signed y:10;
|
||||||
|
signed z:10;
|
||||||
|
// signed :2;
|
||||||
|
// signed z:10;
|
||||||
|
// signed y:10;
|
||||||
|
// signed x:10;
|
||||||
} bits;
|
} bits;
|
||||||
uint32_t all;
|
uint32_t all;
|
||||||
} pack_10;
|
} pack_10;
|
||||||
if ((x > 1.0f) || (x < -1.0f))
|
if ((x > 1.0f) || (x < -1.0f))
|
||||||
std::cout << "Warning: Clamping normal X to [-1.0, 1.0]" << std::endl;
|
std::cout << "Warning: Clamping normal X to [-1.0, 1.0]" << std::endl;
|
||||||
pack_10.bits.x = static_cast<int>(fminf(1.0f, fmaxf(-1.0f, x))*511.0);
|
|
||||||
if ((y > 1.0f) || (y < -1.0f))
|
if ((y > 1.0f) || (y < -1.0f))
|
||||||
std::cout << "Warning: Clamping normal Y to [-1.0, 1.0]" << std::endl;
|
std::cout << "Warning: Clamping normal Y to [-1.0, 1.0]" << std::endl;
|
||||||
pack_10.bits.y = static_cast<int>(fminf(1.0f, fmaxf(-1.0f, y))*511.0);
|
|
||||||
if ((z > 1.0f) || (z < -1.0f))
|
if ((z > 1.0f) || (z < -1.0f))
|
||||||
std::cout << "Warning: Clamping normal Z to [-1.0, 1.0]" << std::endl;
|
std::cout << "Warning: Clamping normal Z to [-1.0, 1.0]" << std::endl;
|
||||||
pack_10.bits.z = static_cast<int>(fminf(1.0f, fmaxf(-1.0f, z))*511.0);
|
pack_10.all = glm::packSnorm3x10_1x2(glm::vec4(x, y, z, 0.0f));
|
||||||
_normals.push_back(pack_10.all);
|
_normals.push_back(pack_10.all);
|
||||||
std::cout << "vn " << pack_10.bits.x << " " << pack_10.bits.y << " " << pack_10.bits.z << "\n";
|
std::cout << "vn " << pack_10.bits.x << " " << pack_10.bits.y << " " << pack_10.bits.z << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void triangular_face_geometric_vertices_callback(index_type a, index_type b, index_type c)
|
size_t _find_vertex_tc_norm(size_t vert, size_t tc, size_t norm)
|
||||||
{
|
{
|
||||||
}
|
auto pair_it = _vertex_tc_norm_map.find(std::tuple<std::size_t, std::size_t, std::size_t>(vert, tc, norm));
|
||||||
|
|
||||||
size_t _find_vertex_tc_pair(index_2_tuple_type const& a)
|
|
||||||
{
|
|
||||||
auto pair_it = _vertex_tc_pairs_map.find(std::tuple<std::size_t, std::size_t>(std::tr1::get<0>(a), std::tr1::get<1>(a)));
|
|
||||||
size_t pair_pos;
|
size_t pair_pos;
|
||||||
if (pair_it != _vertex_tc_pairs_map.end())
|
if (pair_it != _vertex_tc_norm_map.end())
|
||||||
pair_pos = pair_it->second;
|
pair_pos = pair_it->second;
|
||||||
else {
|
else {
|
||||||
_vertex_tc_pairs.emplace_back(std::get<0>(_vertices[std::tr1::get<0>(a)-1]),
|
_vertex_tc_norm.emplace_back(_vertices[vert],
|
||||||
std::get<1>(_vertices[std::tr1::get<0>(a)-1]),
|
_texCoords[tc],
|
||||||
std::get<2>(_vertices[std::tr1::get<0>(a)-1]),
|
_normals[norm]);
|
||||||
std::get<0>(_texCoords[std::tr1::get<1>(a)-1]),
|
pair_pos = _vertex_tc_norm.size()-1;
|
||||||
std::get<1>(_texCoords[std::tr1::get<1>(a)-1]));
|
_vertex_tc_norm_map.emplace(std::tuple<std::size_t, std::size_t, std::size_t>(vert, tc, norm),
|
||||||
pair_pos = _vertex_tc_pairs.size()-1;
|
|
||||||
_vertex_tc_pairs_map.emplace(std::tuple<std::size_t, std::size_t>(std::tr1::get<0>(a), std::tr1::get<1>(a)),
|
|
||||||
pair_pos);
|
pair_pos);
|
||||||
}
|
}
|
||||||
return pair_pos;
|
return pair_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 _calculateNormal(glm::vec3 const& a, glm::vec3 const& b, glm::vec3 const& c)
|
||||||
|
{
|
||||||
|
return glm::normalize(glm::cross(b-a, c-a));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _generateNormal(glm::vec3 const& a, glm::vec3 const& b, glm::vec3 const& c)
|
||||||
|
{
|
||||||
|
glm::vec3 normal = _calculateNormal(a, b, c);
|
||||||
|
uint32_t norm32 = glm::packSnorm3x10_1x2(glm::vec4(normal, 0.0f));
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
for(auto& ent : _normals) {
|
||||||
|
if (ent == norm32)
|
||||||
|
return pos;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
_addedGenerated = true;
|
||||||
|
_normals.push_back(norm32);
|
||||||
|
return _normals.size()-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t _generateTC()
|
||||||
|
{
|
||||||
|
glm::u16vec2 tc(0, 0);
|
||||||
|
|
||||||
|
size_t pos = 0;
|
||||||
|
for(auto& ent : _texCoords) {
|
||||||
|
if (ent == tc)
|
||||||
|
return pos;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
_addedGenerated = true;
|
||||||
|
_texCoords.push_back(tc);
|
||||||
|
return _texCoords.size()-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void triangular_face_geometric_vertices_callback(index_type a, index_type b, index_type c)
|
||||||
|
{
|
||||||
|
if ((_vertices.size() < a) ||
|
||||||
|
(_vertices.size() < b) ||
|
||||||
|
(_vertices.size() < c))
|
||||||
|
throw ParseException("Vertex Index out of range");
|
||||||
|
|
||||||
|
size_t norm = _generateNormal(_vertices[a-1],
|
||||||
|
_vertices[b-1],
|
||||||
|
_vertices[c-1]);
|
||||||
|
size_t tc = _generateTC();
|
||||||
|
|
||||||
|
std::cout << "f (" << a << ", " << tc << ", " << norm << ")" <<
|
||||||
|
" (" << b << ", " << tc << ", " << norm << ")" <<
|
||||||
|
" (" << c << ", " << tc << ", " << norm << ")\n";
|
||||||
|
|
||||||
|
size_t a_pos = _find_vertex_tc_norm(a-1,
|
||||||
|
tc,
|
||||||
|
norm);
|
||||||
|
size_t b_pos = _find_vertex_tc_norm(b-1,
|
||||||
|
tc,
|
||||||
|
norm);
|
||||||
|
size_t c_pos = _find_vertex_tc_norm(c-1,
|
||||||
|
tc,
|
||||||
|
norm);
|
||||||
|
_faces.emplace_back(a_pos, b_pos, c_pos);
|
||||||
|
|
||||||
|
std::cout << "\t [" << a_pos << ", " << b_pos << ", " << c_pos << "]\n";
|
||||||
|
}
|
||||||
|
|
||||||
void triangular_face_geometric_vertices_texture_vertices_callback(index_2_tuple_type a, index_2_tuple_type b, index_2_tuple_type c)
|
void triangular_face_geometric_vertices_texture_vertices_callback(index_2_tuple_type a, index_2_tuple_type b, index_2_tuple_type c)
|
||||||
{
|
{
|
||||||
if ((_vertices.size() < std::tr1::get<0>(a)) ||
|
if ((_vertices.size() < std::tr1::get<0>(a)) ||
|
||||||
@@ -94,13 +163,23 @@ private:
|
|||||||
(_texCoords.size() < std::tr1::get<1>(c)))
|
(_texCoords.size() < std::tr1::get<1>(c)))
|
||||||
throw ParseException("Texture Coordinate Index out of range");
|
throw ParseException("Texture Coordinate Index out of range");
|
||||||
|
|
||||||
std::cout << "f (" << std::tr1::get<0>(a) << ", " << std::tr1::get<1>(a) << ")" <<
|
size_t norm = _generateNormal(_vertices[std::tr1::get<0>(a)-1],
|
||||||
" (" << std::tr1::get<0>(b) << ", " << std::tr1::get<1>(b) << ")" <<
|
_vertices[std::tr1::get<0>(b)-1],
|
||||||
" (" << std::tr1::get<0>(c) << ", " << std::tr1::get<1>(c) << ")\n";
|
_vertices[std::tr1::get<0>(c)-1]);
|
||||||
|
|
||||||
size_t a_pos = _find_vertex_tc_pair(a);
|
std::cout << "f (" << std::tr1::get<0>(a) << ", " << std::tr1::get<1>(a) << ", " << norm << ")" <<
|
||||||
size_t b_pos = _find_vertex_tc_pair(b);
|
" (" << std::tr1::get<0>(b) << ", " << std::tr1::get<1>(b) << ", " << norm << ")" <<
|
||||||
size_t c_pos = _find_vertex_tc_pair(c);
|
" (" << std::tr1::get<0>(c) << ", " << std::tr1::get<1>(c) << ", " << norm << ")\n";
|
||||||
|
|
||||||
|
size_t a_pos = _find_vertex_tc_norm(std::tr1::get<0>(a)-1,
|
||||||
|
std::tr1::get<1>(a)-1,
|
||||||
|
norm);
|
||||||
|
size_t b_pos = _find_vertex_tc_norm(std::tr1::get<0>(b)-1,
|
||||||
|
std::tr1::get<1>(b)-1,
|
||||||
|
norm);
|
||||||
|
size_t c_pos = _find_vertex_tc_norm(std::tr1::get<0>(c)-1,
|
||||||
|
std::tr1::get<1>(c)-1,
|
||||||
|
norm);
|
||||||
_faces.emplace_back(a_pos, b_pos, c_pos);
|
_faces.emplace_back(a_pos, b_pos, c_pos);
|
||||||
|
|
||||||
std::cout << "\t [" << a_pos << ", " << b_pos << ", " << c_pos << "]\n";
|
std::cout << "\t [" << a_pos << ", " << b_pos << ", " << c_pos << "]\n";
|
||||||
@@ -108,11 +187,67 @@ private:
|
|||||||
|
|
||||||
void triangular_face_geometric_vertices_vertex_normals_callback(index_2_tuple_type a, index_2_tuple_type b, index_2_tuple_type c)
|
void triangular_face_geometric_vertices_vertex_normals_callback(index_2_tuple_type a, index_2_tuple_type b, index_2_tuple_type c)
|
||||||
{
|
{
|
||||||
|
if ((_vertices.size() < std::tr1::get<0>(a)) ||
|
||||||
|
(_vertices.size() < std::tr1::get<0>(b)) ||
|
||||||
|
(_vertices.size() < std::tr1::get<0>(c)))
|
||||||
|
throw ParseException("Vertex Index out of range");
|
||||||
|
if ((_normals.size() < std::tr1::get<1>(a)) ||
|
||||||
|
(_normals.size() < std::tr1::get<1>(b)) ||
|
||||||
|
(_normals.size() < std::tr1::get<1>(c)))
|
||||||
|
throw ParseException("Normal Index out of range");
|
||||||
|
|
||||||
|
size_t tc = _generateTC();
|
||||||
|
|
||||||
|
std::cout << "f (" << std::tr1::get<0>(a) << ", " << tc << ", " << std::tr1::get<1>(a) << ")" <<
|
||||||
|
" (" << std::tr1::get<0>(b) << ", " << tc << "," << std::tr1::get<1>(b) << ")" <<
|
||||||
|
" (" << std::tr1::get<0>(c) << ", " << tc << ", " << std::tr1::get<1>(c) << ")\n";
|
||||||
|
|
||||||
|
size_t a_pos = _find_vertex_tc_norm(std::tr1::get<0>(a)-1,
|
||||||
|
tc,
|
||||||
|
std::tr1::get<1>(a)-1);
|
||||||
|
size_t b_pos = _find_vertex_tc_norm(std::tr1::get<0>(b)-1,
|
||||||
|
tc,
|
||||||
|
std::tr1::get<1>(b)-1);
|
||||||
|
size_t c_pos = _find_vertex_tc_norm(std::tr1::get<0>(c)-1,
|
||||||
|
tc,
|
||||||
|
std::tr1::get<1>(c)-1);
|
||||||
|
_faces.emplace_back(a_pos, b_pos, c_pos);
|
||||||
|
|
||||||
|
std::cout << "\t [" << a_pos << ", " << b_pos << ", " << c_pos << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback(index_3_tuple_type a, index_3_tuple_type b,
|
void triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback(index_3_tuple_type a, index_3_tuple_type b,
|
||||||
index_3_tuple_type c)
|
index_3_tuple_type c)
|
||||||
{
|
{
|
||||||
|
if ((_vertices.size() < std::tr1::get<0>(a)) ||
|
||||||
|
(_vertices.size() < std::tr1::get<0>(b)) ||
|
||||||
|
(_vertices.size() < std::tr1::get<0>(c)))
|
||||||
|
throw ParseException("Vertex Index out of range");
|
||||||
|
if ((_texCoords.size() < std::tr1::get<1>(a)) ||
|
||||||
|
(_texCoords.size() < std::tr1::get<1>(b)) ||
|
||||||
|
(_texCoords.size() < std::tr1::get<1>(c)))
|
||||||
|
throw ParseException("Texture Coordinate Index out of range");
|
||||||
|
if ((_normals.size() < std::tr1::get<2>(a)) ||
|
||||||
|
(_normals.size() < std::tr1::get<2>(b)) ||
|
||||||
|
(_normals.size() < std::tr1::get<2>(c)))
|
||||||
|
throw ParseException("Normal Index out of range");
|
||||||
|
|
||||||
|
std::cout << "f (" << std::tr1::get<0>(a) << ", " << std::tr1::get<1>(a) << ", " << std::tr1::get<2>(a) << ")" <<
|
||||||
|
" (" << std::tr1::get<0>(b) << ", " << std::tr1::get<1>(b) << ", " << std::tr1::get<2>(b) << ")" <<
|
||||||
|
" (" << std::tr1::get<0>(c) << ", " << std::tr1::get<1>(c) << ", " << std::tr1::get<2>(c) << ")\n";
|
||||||
|
|
||||||
|
size_t a_pos = _find_vertex_tc_norm(std::tr1::get<0>(a)-1,
|
||||||
|
std::tr1::get<1>(a)-1,
|
||||||
|
std::tr1::get<2>(a)-1);
|
||||||
|
size_t b_pos = _find_vertex_tc_norm(std::tr1::get<0>(b)-1,
|
||||||
|
std::tr1::get<1>(b)-1,
|
||||||
|
std::tr1::get<2>(b)-1);
|
||||||
|
size_t c_pos = _find_vertex_tc_norm(std::tr1::get<0>(c)-1,
|
||||||
|
std::tr1::get<1>(c)-1,
|
||||||
|
std::tr1::get<2>(c)-1);
|
||||||
|
_faces.emplace_back(a_pos, b_pos, c_pos);
|
||||||
|
|
||||||
|
std::cout << "\t [" << a_pos << ", " << b_pos << ", " << c_pos << "]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void quadrilateral_face_geometric_vertices_callback(index_type a, index_type b, index_type c, index_type d)
|
void quadrilateral_face_geometric_vertices_callback(index_type a, index_type b, index_type c, index_type d)
|
||||||
@@ -201,16 +336,19 @@ private:
|
|||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::tuple<float, float, float> > _vertices;
|
bool _addedGenerated;
|
||||||
std::vector<std::tuple<uint16_t, uint16_t> > _texCoords;
|
|
||||||
|
std::vector<glm::vec3> _vertices;
|
||||||
|
std::vector<glm::u16vec2> _texCoords;
|
||||||
std::vector<uint32_t> _normals;
|
std::vector<uint32_t> _normals;
|
||||||
|
|
||||||
std::map<std::tuple<std::size_t, std::size_t>, std::size_t > _vertex_tc_pairs_map;
|
std::map<std::tuple<std::size_t, std::size_t, std::size_t>, std::size_t > _vertex_tc_norm_map;
|
||||||
std::vector<std::tuple<float, float, float, uint16_t, uint16_t> > _vertex_tc_pairs;
|
std::vector<std::tuple<glm::vec3, glm::u16vec2, glm::uint32_t> > _vertex_tc_norm;
|
||||||
|
|
||||||
std::vector<std::tuple<std::size_t, std::size_t, std::size_t> > _faces;
|
std::vector<std::tuple<std::size_t, std::size_t, std::size_t> > _faces;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectParser() {
|
ObjectParser() : _addedGenerated(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~ObjectParser() {
|
~ObjectParser() {
|
||||||
@@ -249,13 +387,14 @@ public:
|
|||||||
std::vector<objVertexAttribs> buildVA()
|
std::vector<objVertexAttribs> buildVA()
|
||||||
{
|
{
|
||||||
std::vector<objVertexAttribs> ret;
|
std::vector<objVertexAttribs> ret;
|
||||||
for (auto const& ent : _vertex_tc_pairs) {
|
for (auto const& ent : _vertex_tc_norm) {
|
||||||
objVertexAttribs tmp;
|
objVertexAttribs tmp;
|
||||||
tmp.vertex[0] = std::get<0>(ent);
|
tmp.vertex[0] = std::get<0>(ent).x;
|
||||||
tmp.vertex[1] = std::get<1>(ent);
|
tmp.vertex[1] = std::get<0>(ent).y;
|
||||||
tmp.vertex[2] = std::get<2>(ent);
|
tmp.vertex[2] = std::get<0>(ent).z;
|
||||||
tmp.texCoords[0] = std::get<3>(ent);
|
tmp.texCoords[0] = std::get<1>(ent).x;
|
||||||
tmp.texCoords[1] = std::get<4>(ent);
|
tmp.texCoords[1] = std::get<1>(ent).y;
|
||||||
|
tmp.normal = std::get<2>(ent);
|
||||||
ret.push_back(tmp);
|
ret.push_back(tmp);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ private:
|
|||||||
struct objVertexAttribs {
|
struct objVertexAttribs {
|
||||||
float vertex[3];
|
float vertex[3];
|
||||||
uint16_t texCoords[2];
|
uint16_t texCoords[2];
|
||||||
|
uint32_t normal;
|
||||||
} __attribute__((__packed__));
|
} __attribute__((__packed__));
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
11
objects/plane.obj
Normal file
11
objects/plane.obj
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
v 0.0 0.0 0.0
|
||||||
|
v 0.0 5.0 0.0
|
||||||
|
v 0.0 0.0 -50.0
|
||||||
|
v 0.0 5.0 -50.0
|
||||||
|
|
||||||
|
vt 0.0 0.0
|
||||||
|
vt 1.0 0.0
|
||||||
|
vt 0.0 1.0
|
||||||
|
vt 1.0 1.0
|
||||||
|
|
||||||
|
f 1/1 2/3 4/4 3/2
|
||||||
17
objects/pyramid.obj
Normal file
17
objects/pyramid.obj
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
v 0.0 0.0 0.0
|
||||||
|
v 0.5 1.0 0.5
|
||||||
|
v -0.5 1.0 0.5
|
||||||
|
v 0.0 1.0 -0.707
|
||||||
|
|
||||||
|
#vt 0.0 0.0
|
||||||
|
#vt 1.0 0.0
|
||||||
|
#vt 0.0 1.0
|
||||||
|
#vt 1.0 1.0
|
||||||
|
|
||||||
|
#f 1/1 2/2 3/3
|
||||||
|
#f 1/1 3/2 4/3
|
||||||
|
#f 1/1 4/2 2/3
|
||||||
|
|
||||||
|
f 1 2 3
|
||||||
|
f 1 3 4
|
||||||
|
f 1 4 2
|
||||||
@@ -13,21 +13,9 @@ vt 1.0 0.0
|
|||||||
vt 0.0 1.0
|
vt 0.0 1.0
|
||||||
vt 1.0 1.0
|
vt 1.0 1.0
|
||||||
|
|
||||||
vn 0.0 0.0 1.0
|
f 2/1 4/3 3/4 1/2
|
||||||
vn 1.0 0.0 0.0
|
f 1/1 3/3 7/4 5/2
|
||||||
vn 0.0 0.0 -1.0
|
f 5/1 7/3 8/4 6/2
|
||||||
vn -1.0 0.0 0.0
|
f 6/1 8/3 4/4 2/2
|
||||||
vn 0.0 1.0 0.0
|
f 6/1 2/3 1/4 5/2
|
||||||
vn 0.0 -1.0 0.0
|
f 4/1 8/3 7/4 3/2
|
||||||
|
|
||||||
f 1/1 3/3 4/4 2/2
|
|
||||||
|
|
||||||
f 2/1 4/3 8/4 6/2
|
|
||||||
|
|
||||||
f 6/1 8/3 7/4 5/2
|
|
||||||
|
|
||||||
f 5/1 7/3 3/4 1/2
|
|
||||||
|
|
||||||
f 5/1 1/3 2/4 6/2
|
|
||||||
|
|
||||||
f 3/1 7/3 8/4 4/2
|
|
||||||
|
|||||||
23
shaders.hh
23
shaders.hh
@@ -4,11 +4,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#include <glbinding/gl/gl.h>
|
||||||
#include <GL/gl.h>
|
|
||||||
|
|
||||||
#include "common.hh"
|
#include "common.hh"
|
||||||
|
|
||||||
|
using namespace gl;
|
||||||
|
|
||||||
class ShaderException : public GLException {
|
class ShaderException : public GLException {
|
||||||
public:
|
public:
|
||||||
ShaderException(std::string const& msg) : GLException(glGetError()), _msg(msg) {
|
ShaderException(std::string const& msg) : GLException(glGetError()), _msg(msg) {
|
||||||
@@ -169,27 +170,25 @@ public:
|
|||||||
glUseProgram(_progID);
|
glUseProgram(_progID);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getUniformLocation(std::string const& name) const {
|
GLint getUniformLocation(std::string const& name) const {
|
||||||
auto search = _uniformLocCache.find(name);
|
auto search = _uniformLocCache.find(name);
|
||||||
if (search != _uniformLocCache.end())
|
if (search != _uniformLocCache.end())
|
||||||
return search->second;
|
return search->second;
|
||||||
|
|
||||||
int ret = glGetUniformLocation(_progID, name.c_str());
|
GLint ret = glGetUniformLocation(_progID, name.c_str());
|
||||||
if (ret == -1)
|
if (ret != -1)
|
||||||
throw GLException(glGetError());
|
_uniformLocCache.emplace(name, ret);
|
||||||
_uniformLocCache.emplace(name, ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getAttribLocation(std::string const& name) const {
|
GLint getAttribLocation(std::string const& name) const {
|
||||||
auto search = _attribLocCache.find(name);
|
auto search = _attribLocCache.find(name);
|
||||||
if (search != _attribLocCache.end())
|
if (search != _attribLocCache.end())
|
||||||
return search->second;
|
return search->second;
|
||||||
|
|
||||||
int ret = glGetAttribLocation(_progID, name.c_str());
|
GLint ret = glGetAttribLocation(_progID, name.c_str());
|
||||||
if (ret == -1)
|
if (ret != -1)
|
||||||
throw GLException(glGetError());
|
_attribLocCache.emplace(name, ret);
|
||||||
_attribLocCache.emplace(name, ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,14 @@
|
|||||||
uniform sampler2D texBase;
|
uniform sampler2D texBase;
|
||||||
|
|
||||||
in vec2 fragTC;
|
in vec2 fragTC;
|
||||||
|
//in vec3 fragNorm;
|
||||||
|
//in vec3 light0Vect;
|
||||||
|
in vec3 light;
|
||||||
|
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
color = texture(texBase, fragTC);
|
vec4 texColor = texture(texBase, fragTC);
|
||||||
|
|
||||||
|
color = texColor*vec4(light, 1.0)+texColor*0.05;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,39 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
|
||||||
uniform mat4 projection_matrix;
|
uniform mat4 projection_matrix;
|
||||||
uniform mat4 modelview_matrix;
|
uniform mat4 view_matrix;
|
||||||
|
uniform mat4 model_matrix;
|
||||||
|
|
||||||
in vec3 vertex;
|
const uint lights = 2u;
|
||||||
in vec2 vertexTC;
|
|
||||||
|
const vec3 lightPos[lights] = {vec3(2.0, -2.0, 10.0),
|
||||||
|
vec3(2.0, 2.0, 10.0)};
|
||||||
|
const vec3 lightColor[lights] = {vec3(1.0, 0.9, 0.8),
|
||||||
|
vec3(0.0, 1.0, 0.0)};
|
||||||
|
const float lightIntensity[lights] = {75.0, 25.0};
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 vertex;
|
||||||
|
layout(location = 1) in vec2 vertexTC;
|
||||||
|
layout(location = 2) in vec3 vertexNorm;
|
||||||
|
|
||||||
out vec2 fragTC;
|
out vec2 fragTC;
|
||||||
|
out vec3 light;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_Position = projection_matrix * modelview_matrix * vec4(vertex, 1.0);
|
vec4 vertex_Pos = model_matrix * vec4(vertex, 1.0);
|
||||||
|
gl_Position = projection_matrix * view_matrix * vertex_Pos;
|
||||||
|
|
||||||
fragTC = vertexTC;
|
fragTC = vertexTC;
|
||||||
|
|
||||||
|
vec3 vertexNorm_trans = (model_matrix*vec4(vertexNorm, 0.0)).xyz;
|
||||||
|
light = vec3(0.0, 0.0, 0.0);
|
||||||
|
for (uint i = 0u;i < lights;++i) {
|
||||||
|
vec3 lightVec = lightPos[i]-vertex_Pos.xyz;
|
||||||
|
vec3 lightNorm = normalize(lightVec);
|
||||||
|
float lightDist = length(lightVec);
|
||||||
|
light += lightColor[i]*clamp(dot(vertexNorm_trans, lightNorm), 0.0, 1.0)*
|
||||||
|
clamp(lightIntensity[i]/(lightDist*lightDist), 0.0, 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
texture.hh
11
texture.hh
@@ -9,11 +9,12 @@
|
|||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <SDL2/SDL_image.h>
|
#include <SDL2/SDL_image.h>
|
||||||
|
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#include <glbinding/gl/gl.h>
|
||||||
#include <GL/gl.h>
|
|
||||||
|
|
||||||
#include "common.hh"
|
#include "common.hh"
|
||||||
|
|
||||||
|
using namespace gl;
|
||||||
|
|
||||||
static unsigned ilog2(unsigned in)
|
static unsigned ilog2(unsigned in)
|
||||||
{
|
{
|
||||||
unsigned ret = 0u;
|
unsigned ret = 0u;
|
||||||
@@ -40,7 +41,6 @@ public:
|
|||||||
SDL_LockSurface(surf);
|
SDL_LockSurface(surf);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surf->w, surf->h, GL_RGB, GL_UNSIGNED_BYTE, surf->pixels);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
checkGlError();
|
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
glDeleteTextures(1, &_texID);
|
glDeleteTextures(1, &_texID);
|
||||||
throw;
|
throw;
|
||||||
@@ -59,14 +59,12 @@ public:
|
|||||||
|
|
||||||
void bind() {
|
void bind() {
|
||||||
glBindTexture(GL_TEXTURE_2D, _texID);
|
glBindTexture(GL_TEXTURE_2D, _texID);
|
||||||
checkGlError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void _glCreate(unsigned width, unsigned height) {
|
void _glCreate(unsigned width, unsigned height) {
|
||||||
glGenTextures(1, &_texID);
|
glGenTextures(1, &_texID);
|
||||||
checkGlError();
|
|
||||||
try {
|
try {
|
||||||
glBindTexture(GL_TEXTURE_2D, _texID);
|
glBindTexture(GL_TEXTURE_2D, _texID);
|
||||||
unsigned logWidth = ilog2(width), logHeight = ilog2(height);
|
unsigned logWidth = ilog2(width), logHeight = ilog2(height);
|
||||||
@@ -77,12 +75,11 @@ private:
|
|||||||
std::printf("Warning: extension GL_ARB_texture_storage not supported!\n");
|
std::printf("Warning: extension GL_ARB_texture_storage not supported!\n");
|
||||||
for (unsigned i = 0u; i < levels; ++i)
|
for (unsigned i = 0u; i < levels; ++i)
|
||||||
{
|
{
|
||||||
glTexImage2D(GL_TEXTURE_2D, i, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, i, static_cast<const int>(GL_RGB8), width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||||
width = std::max(1u, (width / 2u));
|
width = std::max(1u, (width / 2u));
|
||||||
height = std::max(1u, (height / 2u));
|
height = std::max(1u, (height / 2u));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkGlError();
|
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
glDeleteTextures(1, &_texID);
|
glDeleteTextures(1, &_texID);
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
textures/red.png
Normal file
BIN
textures/red.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 B |
BIN
textures/white.png
Normal file
BIN
textures/white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 B |
Reference in New Issue
Block a user