diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..285bbad --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +core/couch diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0d78d07 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +all: + $(MAKE) -C core diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..ca37990 --- /dev/null +++ b/common.mk @@ -0,0 +1,3 @@ +CXX = g++ +CXXFLAGS = `pkg-config --cflags gl glew glfw3 guile-2.2` -g +LIBS = `pkg-config --libs gl glew glfw3 guile-2.2` diff --git a/core/Ball.cpp b/core/Ball.cpp new file mode 100644 index 0000000..7748d65 --- /dev/null +++ b/core/Ball.cpp @@ -0,0 +1,10 @@ +#include "Ball.h" + +Ball::Ball() { + vertices.push_back(Vertex(0.0f, 0.0f, 0.0f)); + vertices.push_back(Vertex(1.0f, 0.0f, 0.0f)); + vertices.push_back(Vertex(0.5f, 1.0f, 0.0f)); + + indices.push_back(Index(0, 1, 2)); +} + diff --git a/core/Ball.h b/core/Ball.h new file mode 100644 index 0000000..84aa577 --- /dev/null +++ b/core/Ball.h @@ -0,0 +1,11 @@ +#ifndef BALL_H +#define BALL_H + +#include "Mesh.h" + +class Ball : public Mesh { +public: + Ball(); +}; + +#endif /* BALL_H */ diff --git a/core/Index.cpp b/core/Index.cpp new file mode 100644 index 0000000..77d41f9 --- /dev/null +++ b/core/Index.cpp @@ -0,0 +1,7 @@ +#include "Index.h" + +Index::Index(unsigned int v0, unsigned int v1, unsigned int v2) { + this->v0 = v0; + this->v1 = v1; + this->v2 = v2; +} diff --git a/core/Index.h b/core/Index.h new file mode 100644 index 0000000..49d814f --- /dev/null +++ b/core/Index.h @@ -0,0 +1,13 @@ +#ifndef INDEX_H +#define INDEX_H + +#include + +struct Index { + unsigned int v0, v1, v2; + Index(unsigned int v0, unsigned int v1, unsigned int v2); +}; + +typedef std::vector IndexList; + +#endif /* INDEX_H */ diff --git a/core/Makefile b/core/Makefile new file mode 100644 index 0000000..414f981 --- /dev/null +++ b/core/Makefile @@ -0,0 +1,8 @@ +include ../common.mk + +SOURCES = $(wildcard *.cpp) +OBJS = $(SOURCES:.cpp=.o) + +all: couch +couch: $(OBJS) + $(CXX) $(LIBS) -o $@ $^ diff --git a/core/Mesh.cpp b/core/Mesh.cpp new file mode 100644 index 0000000..b498847 --- /dev/null +++ b/core/Mesh.cpp @@ -0,0 +1,36 @@ +#include "Mesh.h" + +Mesh::Mesh() {} + +Mesh::Mesh(VertexList vertices, IndexList indices) { + this->vertices = vertices; + this->indices = indices; +} + +void Mesh::SetupMesh() { + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); + + glBindVertexArray(VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), + &vertices[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(Index), + &indices[0], GL_STATIC_DRAW); + + // Vertex positions + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*) 0); + // TODO normals, uv + + glBindVertexArray(0); +} + +void Mesh::Draw() { + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, indices.size() * 3, GL_UNSIGNED_INT, 0); + glBindVertexArray(0); +} diff --git a/core/Mesh.h b/core/Mesh.h new file mode 100644 index 0000000..2ae9d6a --- /dev/null +++ b/core/Mesh.h @@ -0,0 +1,22 @@ +#ifndef MESH_H +#define MESH_H + +#include "types.h" +#include "Vertex.h" +#include "Index.h" +#include "Transform.h" + +class Mesh { +public: + VertexList vertices; + IndexList indices; + Transform transform; + Mesh(); + Mesh(VertexList vertices, IndexList indices); + void Draw(); + virtual void SetupMesh(); +private: + Id VAO, VBO, EBO; +}; + +#endif /* MESH_H */ diff --git a/core/Shader.cpp b/core/Shader.cpp new file mode 100644 index 0000000..6fb9210 --- /dev/null +++ b/core/Shader.cpp @@ -0,0 +1,73 @@ +#include "Shader.h" + +Shader::Shader(const char* vertexPath, const char* fragmentPath) { + std::string vertexCode; + std::string fragmentCode; + + std::ifstream vShaderFile; + std::ifstream fShaderFile; + + vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); + fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + try { + vShaderFile.open(vertexPath); + fShaderFile.open(fragmentPath); + std::stringstream vShaderStream, fShaderStream; + + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + + vShaderFile.close(); + fShaderFile.close(); + + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + } catch (std::ifstream::failure e) { + std::cerr << "Error reading shader file." << std::endl; + } + + const char * vShaderCode = vertexCode.c_str(); + const char * fShaderCode = fragmentCode.c_str(); + + + Id vertex, fragment; + int success; + char infoLog[512]; + + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vShaderCode, NULL); + glCompileShader(vertex); + glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(vertex, 512, NULL, infoLog); + std::cerr << "Vertex shader failed compilation\n" << infoLog << std::endl; + } + + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fShaderCode, NULL); + glCompileShader(fragment); + glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(fragment, 512, NULL, infoLog); + std::cerr << "Fragment shader failed compilation\n" << infoLog << std::endl; + } + + id = glCreateProgram(); + glAttachShader(id, vertex); + glAttachShader(id, fragment); + glLinkProgram(id); + glGetProgramiv(id, GL_LINK_STATUS, &success); + if(!success) { + glGetProgramInfoLog(id, 512, NULL, infoLog); + std::cerr << "Shader program linking failed\n" << infoLog << std::endl; + } + + glDeleteShader(vertex); + glDeleteShader(fragment); + +} + +void Shader::Use() { + glUseProgram(id); +} diff --git a/core/Shader.h b/core/Shader.h new file mode 100644 index 0000000..8bd981d --- /dev/null +++ b/core/Shader.h @@ -0,0 +1,19 @@ +#ifndef SHADER_H +#define SHADER_H + +#include +#include +#include +#include + +#include "types.h" + +class Shader { +public: + Id id; + + Shader(const char *vertexPath, const char *fragmentPath); + void Use(); +}; + +#endif /* SHADER_H */ diff --git a/core/Transform.cpp b/core/Transform.cpp new file mode 100644 index 0000000..6d9ac4d --- /dev/null +++ b/core/Transform.cpp @@ -0,0 +1,9 @@ +#include "Transform.h" + +Transform::Transform() { + position = Vector3(0.0f); +} + +Transform::Transform(Vector3 position) { + this->position = position; +} diff --git a/core/Transform.h b/core/Transform.h index 608fed3..11cc46b 100644 --- a/core/Transform.h +++ b/core/Transform.h @@ -4,7 +4,9 @@ #include "types.h" struct Transform { - Position position; -} + Transform(); + Transform(Vector3 position); + Vector3 position; +}; #endif /* TRANSFORM_H */ diff --git a/core/Vertex.cpp b/core/Vertex.cpp new file mode 100644 index 0000000..86891bf --- /dev/null +++ b/core/Vertex.cpp @@ -0,0 +1,13 @@ +#include "Vertex.h" + +Vertex::Vertex() { + x = 0.0f; + y = 0.0f; + z = 0.0f; +} + +Vertex::Vertex(cfloat x, cfloat y, cfloat z) { + this->x = x; + this->y = y; + this->z = z; +} diff --git a/core/Vertex.h b/core/Vertex.h index fe109c3..38d3af1 100644 --- a/core/Vertex.h +++ b/core/Vertex.h @@ -1,10 +1,16 @@ #ifndef VERTEX_H #define VERTEX_H +#include + #include "types.h" struct Vertex { + Vertex(); + Vertex(cfloat x, cfloat y, cfloat z); cfloat x, y, z; -} +}; + +typedef std::vector VertexList; #endif /* VERTEX_H */ diff --git a/core/couch.cpp b/core/couch.cpp new file mode 100644 index 0000000..122b01d --- /dev/null +++ b/core/couch.cpp @@ -0,0 +1,58 @@ +#include + +#include +#include + +#include "types.h" + +#include "Shader.h" +#include "Ball.h" + +Window *window; + +const int width = 800; +const int height = 600; + +int main() { + int err; + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + window = glfwCreateWindow(width, height, "Couch", NULL, NULL); + + if (!window) { + std::cerr << "Error creating window" << std::endl; + return 1; + } + + glfwMakeContextCurrent(window); + + err = glewInit(); + if (err != GLEW_OK) { + std::cerr << "Error initializing glew" << std::endl; + } + + glViewport(0, 0, width, height); + + Shader shader("shaders/flat.vert", "shaders/flat.frag"); + shader.Use(); + + Ball ball; + ball.SetupMesh(); + + while(!glfwWindowShouldClose(window)) { + glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + ball.Draw(); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwDestroyWindow(window); + glfwTerminate(); + return 0; +} diff --git a/core/types.h b/core/types.h index 238af88..e9d6418 100644 --- a/core/types.h +++ b/core/types.h @@ -1,10 +1,15 @@ #ifndef TYPES_H #define TYPES_H +#include + #include +#include #include -typedef glm::vec3 Position; +typedef GLFWwindow Window; +typedef glm::vec3 Vector3; typedef GLfloat cfloat; +typedef GLuint Id; #endif /* TYPES_H */ diff --git a/shaders/flat.frag b/shaders/flat.frag new file mode 100644 index 0000000..9b6c80c --- /dev/null +++ b/shaders/flat.frag @@ -0,0 +1,10 @@ +#version 330 core + +// uniform vec3 color; + +out vec4 FragColor; + +void main() { + //FragColor = vec4(color, 1.0); + FragColor = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/shaders/flat.vert b/shaders/flat.vert new file mode 100644 index 0000000..803d897 --- /dev/null +++ b/shaders/flat.vert @@ -0,0 +1,12 @@ +#version 330 core + +layout (location = 0) in vec3 pos; + +// uniform mat4 MODEL; +// uniform mat4 VIEW; +// uniform mat4 PROJECTION; + +void main() { + //gl_Position = MODEL * VIEW * PROJECTION * vec4(pos, 1.0); + gl_Position = vec4(pos, 1.0); +}