Initial OpenGL Core port
This commit is contained in:
parent
b00ece6f2a
commit
205919e1a9
5
core/renderer/renderer.cpp
Normal file
5
core/renderer/renderer.cpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include "renderer.hpp"
|
||||||
|
|
||||||
|
namespace hibis {
|
||||||
|
Renderer::Renderer(LoggerCallback logger) : mLogger(logger) {}
|
||||||
|
}
|
|
@ -5,19 +5,23 @@
|
||||||
#include "../math/types.hpp"
|
#include "../math/types.hpp"
|
||||||
#include "../resources/resource.hpp"
|
#include "../resources/resource.hpp"
|
||||||
#include "../resources/texture.hpp"
|
#include "../resources/texture.hpp"
|
||||||
|
#include "../resources/shader.hpp"
|
||||||
#include "../callback.hpp"
|
#include "../callback.hpp"
|
||||||
|
|
||||||
namespace hibis {
|
namespace hibis {
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
Renderer(LoggerCallback logger) : mLogger(logger) {}
|
Renderer(LoggerCallback logger);
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
virtual void clearScreen(Color col) = 0;
|
virtual void clearScreen(Color col) = 0;
|
||||||
virtual void renderCurrent() = 0;
|
virtual void renderCurrent() = 0;
|
||||||
|
|
||||||
virtual void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) = 0;
|
virtual void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) = 0;
|
||||||
virtual void drawTexture(Texture* resource, float scale, IntVec2 pos) = 0;
|
virtual void drawTexture(Texture* resource, IntRect size) = 0;
|
||||||
|
|
||||||
|
virtual void useShader(Shader* shader, Point2D points[3]) = 0;
|
||||||
|
virtual void stopUsingShaders() = 0;
|
||||||
|
|
||||||
// Pre and Post draw
|
// Pre and Post draw
|
||||||
virtual void preDraw() = 0;
|
virtual void preDraw() = 0;
|
||||||
|
@ -27,10 +31,13 @@ namespace hibis {
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
|
|
||||||
// Util
|
// Util
|
||||||
|
virtual void compileShader(Shader* shader) = 0;
|
||||||
|
virtual void toggleWireframe() = 0;
|
||||||
virtual void setWindowTitle(std::string title) = 0;
|
virtual void setWindowTitle(std::string title) = 0;
|
||||||
|
|
||||||
bool mKeepOpen = true;
|
bool mKeepOpen = true;
|
||||||
protected:
|
protected:
|
||||||
LoggerCallback mLogger;
|
LoggerCallback mLogger;
|
||||||
|
bool mIsWireframeMode = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
10
core/resources/shader.cpp
Normal file
10
core/resources/shader.cpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "shader.hpp"
|
||||||
|
|
||||||
|
namespace hibis {
|
||||||
|
Shader::Shader(std::string vertexShaderPath, std::string fragShaderPath) {
|
||||||
|
mShaderPaths[0] = vertexShaderPath;
|
||||||
|
mShaderPaths[1] = fragShaderPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::~Shader() {}
|
||||||
|
}
|
20
core/resources/shader.hpp
Normal file
20
core/resources/shader.hpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "resource.hpp"
|
||||||
|
|
||||||
|
namespace hibis {
|
||||||
|
class Shader : public Resource {
|
||||||
|
public:
|
||||||
|
Shader(std::string vertexShaderPath, std::string fragShaderPath);
|
||||||
|
~Shader();
|
||||||
|
// Vertex then Frag shader
|
||||||
|
unsigned int mShaderIDs[2] = {0, 0};
|
||||||
|
unsigned int mShaderProgram = 0;
|
||||||
|
unsigned int mShaderVAO = 0;
|
||||||
|
unsigned int mShaderVBO = 0;
|
||||||
|
|
||||||
|
std::string mShaderPaths[2];
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,20 +1,14 @@
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <stb_image/stb_image.h>
|
||||||
|
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
|
|
||||||
namespace hibis {
|
namespace hibis {
|
||||||
Texture::Texture(char* path) : mData(), mImageWidth(0), mImageHeight(0), mBuffer() {
|
Texture::Texture(const char* path) : mData(), mImageWidth(0), mImageHeight(0), mImageChannels(0) {
|
||||||
unsigned int error = lodepng::load_file(mBuffer, path);
|
mData = stbi_load(path, &mImageWidth, &mImageHeight, &mImageChannels, 0);
|
||||||
if (error) {
|
|
||||||
TODO("error message")
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error = lodepng::decode(mData, mImageWidth, mImageHeight, mBuffer);
|
Texture::~Texture() {
|
||||||
|
stbi_image_free(mData);
|
||||||
if (error) {
|
|
||||||
TODO("error message")
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture() {}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <lodepng/lodepng.h>
|
|
||||||
|
|
||||||
#include "resource.hpp"
|
#include "resource.hpp"
|
||||||
#include "../pragmautil.hpp"
|
#include "../pragmautil.hpp"
|
||||||
|
|
||||||
|
@ -11,11 +9,9 @@ namespace hibis {
|
||||||
TODO("Make this function")
|
TODO("Make this function")
|
||||||
class Texture : Resource {
|
class Texture : Resource {
|
||||||
public:
|
public:
|
||||||
Texture(char* path);
|
Texture(const char* path);
|
||||||
~Texture();
|
~Texture();
|
||||||
std::vector<unsigned char> mData;
|
unsigned char* mData;
|
||||||
unsigned int mImageWidth, mImageHeight;
|
int mImageWidth, mImageHeight, mImageChannels;
|
||||||
private:
|
|
||||||
std::vector<unsigned char> mBuffer;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
6991
external/lodepng/lodepng.cpp
vendored
6991
external/lodepng/lodepng.cpp
vendored
File diff suppressed because it is too large
Load diff
2089
external/lodepng/lodepng.h
vendored
2089
external/lodepng/lodepng.h
vendored
File diff suppressed because it is too large
Load diff
7987
external/stb_image/stb_image.h
vendored
Normal file
7987
external/stb_image/stb_image.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
@ -12,8 +12,9 @@ include_dirs = include_directories('./external')
|
||||||
|
|
||||||
# Files
|
# Files
|
||||||
libhibis_src_core = files('core/engine/engine.cpp')
|
libhibis_src_core = files('core/engine/engine.cpp')
|
||||||
libhibis_src_resources = files('core/resources/texture.cpp', 'core/resources/font.cpp')
|
libhibis_src_renderer = files('core/renderer/renderer.cpp')
|
||||||
libhibis_src = [libhibis_src_core, libhibis_src_resources]
|
libhibis_src_resources = files('core/resources/texture.cpp', 'core/resources/font.cpp', 'core/resources/shader.cpp')
|
||||||
|
libhibis_src = [libhibis_src_core, libhibis_src_renderer, libhibis_src_resources]
|
||||||
|
|
||||||
libhibis_rglcore_src = files('renderer/rglcore/rglcore.cpp')
|
libhibis_rglcore_src = files('renderer/rglcore/rglcore.cpp')
|
||||||
libhibis_test_src = files('test/app.cpp')
|
libhibis_test_src = files('test/app.cpp')
|
||||||
|
@ -24,9 +25,8 @@ libglfw = dependency('glfw3')
|
||||||
libglew = dependency('GLEW')
|
libglew = dependency('GLEW')
|
||||||
libfmt = dependency('fmt')
|
libfmt = dependency('fmt')
|
||||||
libfreetype2 = dependency('freetype2')
|
libfreetype2 = dependency('freetype2')
|
||||||
liblodepng = static_library('lodepng', 'external/lodepng/lodepng.cpp')
|
|
||||||
|
|
||||||
# Compile
|
# Compile
|
||||||
libhibis = library('hibis', libhibis_src, include_directories: include_dirs, link_with: liblodepng, dependencies: [libfreetype2])
|
libhibis = library('hibis', libhibis_src, include_directories: include_dirs, dependencies: [libfreetype2])
|
||||||
libhibis_rglcore = library('hibis_rglcore', libhibis_rglcore_src, include_directories: [include_dirs, './core'], link_with: libhibis, dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])
|
libhibis_rglcore = library('hibis_rglcore', libhibis_rglcore_src, include_directories: [include_dirs, './core'], link_with: libhibis, dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])
|
||||||
hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rglcore'], link_with: [libhibis, libhibis_rglcore], dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])
|
hibistest = executable('hibistest.exec', libhibis_test_src, include_directories: [include_dirs, './core', './renderer/rglcore'], link_with: [libhibis, libhibis_rglcore], dependencies: [libfreetype2, libgl, libglfw, libglew, libfmt])
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "rglcore.hpp"
|
#include "rglcore.hpp"
|
||||||
|
|
||||||
namespace hibis::rglcore {
|
namespace hibis::rglcore {
|
||||||
RGLCore::RGLCore(std::string title, IntVec2 size, LoggerCallback callback) : Renderer(callback) {
|
RGLCore::RGLCore(std::string title, IntVec2 size, LoggerCallback callback) : Renderer(callback), mTextures() {
|
||||||
mLogger(Information, "Preparing GLFW3...");
|
mLogger(Information, "Preparing GLFW3...");
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
mLogger(Fatal, "GLFW couldn't be initialised!");
|
mLogger(Fatal, "GLFW couldn't be initialised!");
|
||||||
|
@ -54,7 +55,49 @@ namespace hibis::rglcore {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RGLCore::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {}
|
void RGLCore::drawText(Resource* resource, std::string text, IntVec2 pos, Color color) {}
|
||||||
void RGLCore::drawTexture(Texture* resource, float scale, IntVec2 pos) {}
|
void RGLCore::drawTexture(Texture* resource, IntRect size) {
|
||||||
|
TODO("finish this")
|
||||||
|
return;
|
||||||
|
unsigned int glTextureID;
|
||||||
|
if (mTextures.find(resource) != mTextures.end()) {
|
||||||
|
glTextureID = mTextures[resource];
|
||||||
|
} else {
|
||||||
|
glGenTextures(1, &glTextureID);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, glTextureID);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resource->mImageWidth, resource->mImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, resource->mData);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RGLCore::useShader(Shader* shader, Point2D points[3]) {
|
||||||
|
float vertices[] = {
|
||||||
|
points[0].x, points[0].y, 0.0f,
|
||||||
|
points[1].x, points[1].y, 0.0f,
|
||||||
|
points[2].x, points[2].y, 0.0f
|
||||||
|
};
|
||||||
|
if (shader->mShaderVAO == 0) {
|
||||||
|
glGenVertexArrays(1, &shader->mShaderVAO);
|
||||||
|
glBindVertexArray(shader->mShaderVAO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, shader->mShaderVBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glUseProgram(shader->mShaderProgram);
|
||||||
|
glBindVertexArray(shader->mShaderVAO);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RGLCore::stopUsingShaders() {
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Pre and Post draw
|
// Pre and Post draw
|
||||||
void RGLCore::preDraw() {}
|
void RGLCore::preDraw() {}
|
||||||
|
@ -65,7 +108,63 @@ namespace hibis::rglcore {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RGLCore::compileShader(Shader* shader) {
|
||||||
|
if (shader->mShaderProgram != 0) return;
|
||||||
|
mLogger(Information, fmt::format("Compiling shader {}", shader->mShaderPaths[0]));
|
||||||
|
glGenBuffers(1, &shader->mShaderVBO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, shader->mShaderVBO);
|
||||||
|
shader->mShaderIDs[0] = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
const char* vertShader = loadFile(shader->mShaderPaths[0]);
|
||||||
|
glShaderSource(shader->mShaderIDs[0], 1, &vertShader, NULL);
|
||||||
|
glCompileShader(shader->mShaderIDs[0]);
|
||||||
|
|
||||||
|
mLogger(Information, fmt::format("Compiling shader {}", shader->mShaderPaths[1]));
|
||||||
|
|
||||||
|
shader->mShaderIDs[1] = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
const char* fragShader = loadFile(shader->mShaderPaths[1]);
|
||||||
|
glShaderSource(shader->mShaderIDs[1], 1, &fragShader, NULL);
|
||||||
|
glCompileShader(shader->mShaderIDs[1]);
|
||||||
|
|
||||||
|
shader->mShaderProgram = glCreateProgram();
|
||||||
|
|
||||||
|
glAttachShader(shader->mShaderProgram, shader->mShaderIDs[0]);
|
||||||
|
glAttachShader(shader->mShaderProgram, shader->mShaderIDs[1]);
|
||||||
|
|
||||||
|
glLinkProgram(shader->mShaderProgram);
|
||||||
|
|
||||||
|
mLogger(Information, "Linked shader.");
|
||||||
|
|
||||||
|
glDeleteShader(shader->mShaderIDs[0]);
|
||||||
|
glDeleteShader(shader->mShaderIDs[1]);
|
||||||
|
|
||||||
|
mLogger(Information, "Cleaned up leftover shader objects.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RGLCore::toggleWireframe() {
|
||||||
|
if (mIsWireframeMode) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
else glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
mIsWireframeMode = !mIsWireframeMode;
|
||||||
|
}
|
||||||
|
|
||||||
void RGLCore::setWindowTitle(std::string title) {
|
void RGLCore::setWindowTitle(std::string title) {
|
||||||
glfwSetWindowTitle(mWindow, title.c_str());
|
glfwSetWindowTitle(mWindow, title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* RGLCore::loadFile(std::string path) {
|
||||||
|
std::string text, line;
|
||||||
|
std::ifstream textFile(path);
|
||||||
|
if (textFile.is_open()) {
|
||||||
|
while (getline(textFile, line)) {
|
||||||
|
text += line + '\n';
|
||||||
|
}
|
||||||
|
textFile.close();
|
||||||
|
} else {
|
||||||
|
text = "";
|
||||||
|
mLogger(Error, fmt::format("Couldn't load file '{}'", path));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* textChar = text.c_str();
|
||||||
|
|
||||||
|
return textChar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
@ -16,11 +17,14 @@ namespace hibis::rglcore {
|
||||||
~RGLCore();
|
~RGLCore();
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
void clearScreen(Color col) override;
|
void clearScreen(Color col = Color {0, 0, 0, 255}) override;
|
||||||
void renderCurrent() override;
|
void renderCurrent() override;
|
||||||
|
|
||||||
void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) override;
|
void drawText(Resource* resource, std::string text, IntVec2 pos, Color color) override;
|
||||||
void drawTexture(Texture* resource, float scale, IntVec2 pos) override;
|
void drawTexture(Texture* resource, IntRect size) override;
|
||||||
|
|
||||||
|
void useShader(Shader* shader, Point2D points[3]) override;
|
||||||
|
void stopUsingShaders() override;
|
||||||
|
|
||||||
// Pre and Post draw
|
// Pre and Post draw
|
||||||
void preDraw() override;
|
void preDraw() override;
|
||||||
|
@ -30,8 +34,13 @@ namespace hibis::rglcore {
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
// Util
|
// Util
|
||||||
|
void compileShader(Shader* shader) override;
|
||||||
|
void toggleWireframe() override;
|
||||||
void setWindowTitle(std::string title) override;
|
void setWindowTitle(std::string title) override;
|
||||||
private:
|
private:
|
||||||
GLFWwindow* mWindow;
|
GLFWwindow* mWindow;
|
||||||
|
std::unordered_map<Texture*, unsigned int> mTextures;
|
||||||
|
|
||||||
|
const char* loadFile(std::string path);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
12
test/app.cpp
12
test/app.cpp
|
@ -44,16 +44,19 @@ void logger(LoggingSeverity severity, std::string message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
logger(Information, fmt::format("PWD: {}", std::getenv("PWD")));
|
||||||
RGLCore renderer = RGLCore("test", IntVec2 {800, 600}, &logger);
|
RGLCore renderer = RGLCore("test", IntVec2 {800, 600}, &logger);
|
||||||
Engine engine = Engine(&renderer, &logger);
|
Engine engine = Engine(&renderer, &logger);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Font font = Font("C:\\Windows\\Fonts\\Arial.ttf", 16);
|
Font font = Font(engine.mFreeTypeLibrary, "C:\\Windows\\Fonts\\Arial.ttf", 16);
|
||||||
#else
|
#else
|
||||||
Font font = Font(engine.mFreeTypeLibrary, "/usr/share/fonts/noto/NotoSans-Light.ttf", 16);
|
Font font = Font(engine.mFreeTypeLibrary, "/usr/share/fonts/noto/NotoSans-Light.ttf", 16);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Texture image = Texture((char*)"test.png");
|
Texture image = Texture((char*)"test.png");
|
||||||
|
Shader shader = Shader("../test/test.vert", "../test/test.frag");
|
||||||
|
renderer.compileShader(&shader);
|
||||||
|
|
||||||
uint8_t red = 0;
|
uint8_t red = 0;
|
||||||
bool increaseRed = true;
|
bool increaseRed = true;
|
||||||
|
@ -61,6 +64,8 @@ int main() {
|
||||||
uint size = 16;
|
uint size = 16;
|
||||||
uint f = 0;
|
uint f = 0;
|
||||||
|
|
||||||
|
Point2D points[3] = {{-0.5f, -0.5f}, {0.5f, -0.5f}, {0.0f, 0.5f}};
|
||||||
|
|
||||||
logger(Information, "Started Hibis test app! BEHOLD: Colours.");
|
logger(Information, "Started Hibis test app! BEHOLD: Colours.");
|
||||||
while (renderer.mKeepOpen) {
|
while (renderer.mKeepOpen) {
|
||||||
engine.runNodeProcesses();
|
engine.runNodeProcesses();
|
||||||
|
@ -85,8 +90,9 @@ int main() {
|
||||||
|
|
||||||
// Clear screen then sleep for ~16ms
|
// Clear screen then sleep for ~16ms
|
||||||
renderer.clearScreen(Color {red, 0, 0, 255});
|
renderer.clearScreen(Color {red, 0, 0, 255});
|
||||||
renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255});
|
renderer.useShader(&shader, points);
|
||||||
renderer.drawTexture(&image, 1.0f, IntVec2 {10, 10});
|
//renderer.drawText(&font, "Testing Text", IntVec2 {0, 0}, Color {255, 255, 255, 255});
|
||||||
|
//renderer.drawTexture(&image, 1.0f, IntVec2 {10, 10});
|
||||||
|
|
||||||
engine.drawNodes();
|
engine.drawNodes();
|
||||||
renderer.renderCurrent();
|
renderer.renderCurrent();
|
||||||
|
|
6
test/test.frag
Normal file
6
test/test.frag
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#version 330 core
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
|
||||||
|
}
|
6
test/test.vert
Normal file
6
test/test.vert
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#version 330 core
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||||
|
}
|
Loading…
Reference in a new issue