diff --git a/project/ugine3d.vcxproj b/project/ugine3d.vcxproj
index e873992..d358ad2 100644
--- a/project/ugine3d.vcxproj
+++ b/project/ugine3d.vcxproj
@@ -79,6 +79,7 @@
       true
       ../lib/glew
       GLEW_STATIC;_MBCS;%(PreprocessorDefinitions)
+      stdcpp20
     
     
       ../lib/glfw
@@ -93,6 +94,7 @@
       true
       ../lib/glew
       GLEW_STATIC;_MBCS;%(PreprocessorDefinitions)
+      stdcpp20
     
     
       ../lib/glfw
@@ -109,6 +111,7 @@
       true
       ../lib/glew
       GLEW_STATIC;_MBCS;%(PreprocessorDefinitions)
+      stdcpp20
     
     
       true
@@ -127,6 +130,7 @@
       true
       ../lib/glew
       GLEW_STATIC;_MBCS;%(PreprocessorDefinitions)
+      stdcpp20
     
     
       true
diff --git a/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog
index 6abd271..651e310 100644
Binary files a/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog and b/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog differ
diff --git a/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog
index c5c3a4c..a5383a8 100644
Binary files a/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog and b/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog differ
diff --git a/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog
index f7ed733..ea26fe3 100644
Binary files a/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog and b/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog differ
diff --git a/project/x64/Debug/Practica3D.tlog/Cl.items.tlog b/project/x64/Debug/Practica3D.tlog/Cl.items.tlog
index 692c598..a17c04f 100644
--- a/project/x64/Debug/Practica3D.tlog/Cl.items.tlog
+++ b/project/x64/Debug/Practica3D.tlog/Cl.items.tlog
@@ -1,2 +1,5 @@
 C:\Users\rabil\git\utad-programacion3d\lib\glew\glew.c;C:\Users\rabil\git\utad-programacion3d\project\x64\Debug\glew.obj
+C:\Users\rabil\git\utad-programacion3d\src\buffer.cpp;C:\Users\rabil\git\utad-programacion3d\project\x64\Debug\buffer.obj
 C:\Users\rabil\git\utad-programacion3d\src\main.cpp;C:\Users\rabil\git\utad-programacion3d\project\x64\Debug\main.obj
+C:\Users\rabil\git\utad-programacion3d\src\shader.cpp;C:\Users\rabil\git\utad-programacion3d\project\x64\Debug\shader.obj
+C:\Users\rabil\git\utad-programacion3d\src\vertex.cpp;C:\Users\rabil\git\utad-programacion3d\project\x64\Debug\vertex.obj
diff --git a/project/x64/Debug/Practica3D.tlog/link.command.1.tlog b/project/x64/Debug/Practica3D.tlog/link.command.1.tlog
index 11e8aaf..9665717 100644
Binary files a/project/x64/Debug/Practica3D.tlog/link.command.1.tlog and b/project/x64/Debug/Practica3D.tlog/link.command.1.tlog differ
diff --git a/project/x64/Debug/Practica3D.tlog/link.read.1.tlog b/project/x64/Debug/Practica3D.tlog/link.read.1.tlog
index 7354563..c6fb7b3 100644
Binary files a/project/x64/Debug/Practica3D.tlog/link.read.1.tlog and b/project/x64/Debug/Practica3D.tlog/link.read.1.tlog differ
diff --git a/project/x64/Debug/Practica3D.tlog/link.write.1.tlog b/project/x64/Debug/Practica3D.tlog/link.write.1.tlog
index d686ba1..7164f6e 100644
Binary files a/project/x64/Debug/Practica3D.tlog/link.write.1.tlog and b/project/x64/Debug/Practica3D.tlog/link.write.1.tlog differ
diff --git a/project/x64/Debug/Practica3D.tlog/unsuccessfulbuild b/project/x64/Debug/Practica3D.tlog/unsuccessfulbuild
new file mode 100644
index 0000000..e69de29
diff --git a/project/x64/Debug/ugine3d.log b/project/x64/Debug/ugine3d.log
index 950e898..7de5d45 100644
--- a/project/x64/Debug/ugine3d.log
+++ b/project/x64/Debug/ugine3d.log
@@ -1,4 +1,9 @@
-  glew.c
+  buffer.cpp
   main.cpp
-LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
-  ugine3d.vcxproj -> C:\Users\rabil\git\utad-programacion3d\project\x64\Debug\Practica3D.exe
+  Generating Code...
+C:\Users\rabil\git\utad-programacion3d\src\main.cpp(84,9): error C2660: 'Buffer::Draw': function does not take 0 arguments
+  C:\Users\rabil\git\utad-programacion3d\src\buffer.h(15,7):
+  see declaration of 'Buffer::Draw'
+  C:\Users\rabil\git\utad-programacion3d\src\main.cpp(84,9):
+  while trying to match the argument list '()'
+  
diff --git a/src/buffer.cpp b/src/buffer.cpp
index ddd683c..7c47d8b 100644
--- a/src/buffer.cpp
+++ b/src/buffer.cpp
@@ -1 +1,31 @@
-#include "buffer.h"
\ No newline at end of file
+#include "buffer.h"
+
+#include 
+
+#include "../lib/glew/GL/glew.h"
+#include "../lib/glfw/glfw3.h"
+
+#include "vertex.h"
+
+Buffer::Buffer(const std::vector& vertices, const std::vector& indices)
+{
+	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.data(), GL_STATIC_DRAW);
+
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
+	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW);
+
+	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
+	glEnableVertexAttribArray(0);
+}
+
+void Buffer::Draw(const Shader& shader) const
+{
+	glBindVertexArray(VAO);
+	glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
+}
\ No newline at end of file
diff --git a/src/buffer.h b/src/buffer.h
index 3a43b3a..09af19d 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1,10 +1,21 @@
 #ifndef BUFFER_H_
 #define BUFFER_H_
 
+#include 
+
 #include "../lib/glm/glm.hpp"
 
-struct Buffer {
-	glm::vec3 position{ 0.0f, 0.0f, 0.0f };
+#include "vertex.h"
+#include "shader.h"
+
+class Buffer {
+public:
+	Buffer(const std::vector& vertices, const std::vector& indices);
+
+	void Draw(const Shader& shader) const;
+
+private:
+	uint32_t VAO, VBO, EBO;
 };
 
 #endif // BUFFER_H_
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 524181f..ab954a4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3,52 +3,96 @@
 #endif
 
 
-#include "../lib/glfw/glfw3.h"
 #include 
 #include 
 
+#include "../lib/glew/GL/glew.h"
+#include "../lib/glfw/glfw3.h"
+#include "../lib/glm/glm.hpp"
+#include "../lib/glm/gtc/matrix_transform.hpp"
+
+#include "vertex.h"
+#include "shader.h"
+#include "buffer.h"
+
 #define SCREEN_WIDTH 800
 #define SCREEN_HEIGHT 600
 
 int main() {
 	// init glfw
-	if ( !glfwInit() ) {
-		std::cout << "could not initialize glfw" << std::endl;
-		return -1;
+	if (!glfwInit()) {
+		std::cerr << "Failed to initialize glfw\n";
+		return 1;
 	}
 
 	// create window
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 	//glfwWindowHint(GLFW_RESIZABLE, false);
 	glfwWindowHint(GLFW_SAMPLES, 8);
-	GLFWwindow* win = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "", nullptr, nullptr);
+
+	GLFWwindow* win = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Daniel Poveda", nullptr, nullptr);
 	if (!win) {
-		std::cout << "could not create opengl window" << std::endl;
+		std::cerr << "Failed to create opengl window\n";
 		glfwTerminate();
-		return -1;
+		return 1;
 	}
 	glfwMakeContextCurrent(win);
 
-	
+	glewExperimental = GL_TRUE;
+	if (glewInit() != GLEW_OK) {
+		std::cerr << "Failed to initialize GLEW\n";
+		glfwTerminate();
+		return 1;
+	}
+
+	glEnable(GL_DEPTH_TEST);
+	Shader shader("data/vertex.glsl", "data/fragment.glsl");
+
+	std::vector vertices = {
+		{{-0.5f, -0.5f, 0.0f}},
+		{{0.5f, -0.5f, 0.0f}}, 
+		{{0.0f, 0.5f, 0.0f}}
+	};
+	std::vector indices = { 0, 1, 2 };
+	Buffer buffer(vertices, indices);
+
+	glm::mat4 projection = glm::perspective(glm::radians(45.0f), static_cast(SCREEN_WIDTH) / SCREEN_HEIGHT, 0.1f, 100.0f);
+	glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 6));
 
 	// main loop
 	float angle = 0;
 	double lastTime = glfwGetTime();
 	while ( !glfwWindowShouldClose(win) && !glfwGetKey(win, GLFW_KEY_ESCAPE) ) {
 		// get delta time
-		float deltaTime = static_cast(glfwGetTime() - lastTime);
-		lastTime = glfwGetTime();
+		float delta = static_cast(glfwGetTime() - lastTime);
 
 		// get window size
-		int screenWidth, screenHeight;
-		glfwGetWindowSize(win, &screenWidth, &screenHeight);
+		//int screenWidth, screenHeight;
+		//glfwGetWindowSize(win, &screenWidth, &screenHeight);
 
-		
+		// Logic
+		glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(delta * 32.0f), glm::vec3(0, 1, 0));
+		glm::mat4 mvp = projection * view * model;
+
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		//glClearColor(0, 255, 0, 255);
+		shader.use();
+		uint32_t mvpLoc = glGetUniformLocation(shader.getId(), "MVP");
+		glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, &mvp[0][0]);
+		buffer.Draw(shader);
 
 		// refresh screen
 		glfwSwapBuffers(win);
 		glfwPollEvents();
+
+		// Set last time
+		lastTime = glfwGetTime();
 	}
 
 	// shutdown
 	glfwTerminate();
+
+	return 0;
 }
\ No newline at end of file
diff --git a/src/shader.cpp b/src/shader.cpp
index fda6ca3..4e49246 100644
--- a/src/shader.cpp
+++ b/src/shader.cpp
@@ -1 +1,43 @@
-#include "shader.h"
\ No newline at end of file
+#include "shader.h"
+
+#include 
+#include 
+#include 
+
+#include "../lib/glew/GL/glew.h"
+#include "../lib/glfw/glfw3.h"
+
+namespace {
+	std::string readShaderFile(const std::string& filename) {
+		std::ifstream file(filename);
+		if (!file)
+			throw std::runtime_error("Failed to open shader file: " + filename);
+		std::stringstream buffer;
+		buffer << file.rdbuf();
+		return buffer.str();
+	}
+} // namespace
+
+Shader::Shader(const std::string& vertexPath, const std::string& fragmentPath)
+{
+	std::string vertexCode = readShaderFile(vertexPath);
+	std::string fragmentCode = readShaderFile(fragmentPath);
+	const char* vShaderCode = vertexCode.c_str();
+	const char* fShaderCode = fragmentCode.c_str();
+
+	const uint32_t vertex = glCreateShader(GL_VERTEX_SHADER);
+	glShaderSource(vertex, 1, &vShaderCode, NULL);
+	glCompileShader(vertex);
+
+	const uint32_t fragment = glCreateShader(GL_FRAGMENT_SHADER);
+	glShaderSource(fragment, 1, &fShaderCode, NULL);
+	glCompileShader(fragment);
+
+	program = glCreateProgram();
+	glAttachShader(program, vertex);
+	glAttachShader(program, fragment);
+	glLinkProgram(program);
+
+	glDeleteShader(vertex);
+	glDeleteShader(fragment);
+}
\ No newline at end of file
diff --git a/src/shader.h b/src/shader.h
index 1479df6..eb304f4 100644
--- a/src/shader.h
+++ b/src/shader.h
@@ -1,10 +1,22 @@
 #ifndef SHADER_H_
 #define SHADER_H_
 
+#include 
+
+#include "../lib/glew/GL/glew.h"
+#include "../lib/glfw/glfw3.h"
 #include "../lib/glm/glm.hpp"
 
-struct Shader {
-	glm::vec3 position{ 0.0f, 0.0f, 0.0f };
+class Shader {
+public:
+	Shader(const std::string& vertexPath, const std::string& fragmentPath);
+
+	void use() const { glUseProgram(program); }
+	uint32_t getId() const { return program; }
+
+private:
+	uint32_t program;
 };
+	
 
 #endif // SHADER_H_
\ No newline at end of file