diff --git a/CMakeLists.txt b/CMakeLists.txt index ffb030d..8f2888d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,10 +24,12 @@ SET(srcs main.cpp gl/Shader.cpp gl/Shader.h gl/VertexArray.cpp gl/VertexArray.h gl/Renderer.cpp gl/Renderer.h blocks/BaseBlock.cpp blocks/BaseBlock.h - blocks/GrasBlock.cpp blocks/GrasBlock.h + blocks/DirtBlock.cpp blocks/DirtBlock.h blocks/BlockRenderer.cpp blocks/BlockRenderer.h blocks/RenderBase.cpp blocks/RenderBase.h - gl/Camera.cpp gl/Camera.h) + gl/Camera.cpp gl/Camera.h + bmploader.cpp bmploader.h + gl/Texture.cpp gl/Texture.h blocks/TextureLoader.cpp blocks/TextureLoader.h blocks/Stoneblock.cpp blocks/Stoneblock.h crosshair/CrossHair.cpp crosshair/CrossHair.h blocks/AirBlock.h) add_executable(opengltest ${srcs}) diff --git a/assets/blocks/dirt.bmp b/assets/blocks/dirt.bmp new file mode 100644 index 0000000..c37bd80 Binary files /dev/null and b/assets/blocks/dirt.bmp differ diff --git a/assets/blocks/stone.bmp b/assets/blocks/stone.bmp new file mode 100644 index 0000000..fc8b73d Binary files /dev/null and b/assets/blocks/stone.bmp differ diff --git a/blocks/AirBlock.h b/blocks/AirBlock.h new file mode 100644 index 0000000..2754b9e --- /dev/null +++ b/blocks/AirBlock.h @@ -0,0 +1,18 @@ +// +// Created by lukas on 08.02.22. +// + +#ifndef OPENGLTEST_AIRBLOCK_H +#define OPENGLTEST_AIRBLOCK_H + +#include "BaseBlock.h" + +class AirBlock : public BaseBlock{ +public: + AirBlock(uint xpos, uint ypos, uint zpos) : BaseBlock(xpos, ypos, zpos, nullptr) {} + + void render() override { + } +}; + +#endif //OPENGLTEST_AIRBLOCK_H diff --git a/blocks/BaseBlock.cpp b/blocks/BaseBlock.cpp index a96953a..ff26004 100644 --- a/blocks/BaseBlock.cpp +++ b/blocks/BaseBlock.cpp @@ -2,9 +2,6 @@ // Created by lukas on 04.02.22. // -#define GL_GLEXT_PROTOTYPES - -#include #include #include #include @@ -12,16 +9,16 @@ #include "BlockRenderer.h" void BaseBlock::render() { - glUniform3f(BlockRenderer::getInstance()->getUniformhandle("u_color"), r, g, b); + BlockRenderer::getInstance()->s.Bind(); glm::mat4 position = glm::translate(glm::mat4(1.0f), glm::vec3((float) xpos * 2, (float) ypos * 2, (float) zpos * 2)); glUniformMatrix4fv(BlockRenderer::getInstance()->getUniformhandle("translation"), 1, GL_FALSE, &position[0][0]); + texture->Bind(); + BlockRenderer::getInstance()->render(); } -BaseBlock::BaseBlock(float r, float g, float b, uint xpos, uint ypos, uint zpos) : r(r), g(g), b(b), xpos(xpos), ypos(ypos), zpos(zpos) { - // BlockRenderer::init(); - // this->getrenderer().init(); +BaseBlock::BaseBlock(uint xpos, uint ypos, uint zpos, Texture *texture): xpos(xpos), ypos(ypos), zpos(zpos), texture(texture) { } \ No newline at end of file diff --git a/blocks/BaseBlock.h b/blocks/BaseBlock.h index 4fb8d8b..d9c40d4 100644 --- a/blocks/BaseBlock.h +++ b/blocks/BaseBlock.h @@ -7,16 +7,19 @@ #include "BlockRenderer.h" +#include "../gl/Texture.h" +#include +#include class BaseBlock { private: - float r,g,b; - uint xpos,ypos,zpos; + Texture *texture; + uint xpos, ypos, zpos; public: - BaseBlock(float r, float g, float b, uint xpos, uint ypos, uint zpos); + BaseBlock(uint xpos, uint ypos, uint zpos, Texture *texture); - void render(); + virtual void render(); }; diff --git a/blocks/BlockRenderer.cpp b/blocks/BlockRenderer.cpp index 576a808..5aeb7f3 100644 --- a/blocks/BlockRenderer.cpp +++ b/blocks/BlockRenderer.cpp @@ -3,68 +3,87 @@ // #include "BlockRenderer.h" +#include "../gl/Texture.h" #define GL_GLEXT_PROTOTYPES #include VertexArray *BlockRenderer::setVertexArray() { - float cube_vertices[] = { - // front - -1.0, -1.0, 1.0, - 1.0, -1.0, 1.0, - 1.0, 1.0, 1.0, - -1.0, 1.0, 1.0, - // back - -1.0, -1.0, -1.0, - 1.0, -1.0, -1.0, - 1.0, 1.0, -1.0, - -1.0, 1.0, -1.0 - }; + float cubee[] = { + // face #1 + 1, 1, 1, 1, 0, + -1, 1, 1, 1, 1, + -1, -1, 1, 0, 1, + 1, -1, 1, 0, 0, - GLfloat cube_colors[] = { - // front colors - 1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0, - 1.0, 1.0, 1.0, - // back colors - 1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0, - 1.0, 1.0, 1.0 - }; + // face #2 + 1, 1, 1, 1, 0, + 1, -1, 1, 1, 1, + 1, -1, -1, 0, 1, + 1, 1, -1, 0, 0, + + // face #3 + 1, 1, 1, 1, 0, + 1, 1, -1, 1, 1, + -1, 1, -1, 0, 1, + -1, 1, 1, 0, 0, + + // face #4 + -1, -1, -1, 1, 0, + -1, 1, -1, 1, 1, + 1, 1, -1, 0, 1, + 1, -1, -1, 0, 0, + + // face #5 + -1, -1, -1, 1, 0, + -1, -1, 1, 1, 1, + -1, 1, 1, 0, 1, + -1, 1, -1, 0, 0, + + // face #6 + -1, -1, -1, 1, 0, + 1, -1, -1, 1, 1, + 1, -1, 1, 0, 1, + -1, -1, 1, 0, 0,}; // Generate a vertex buffer - auto *vb = new VertexBuffer(cube_vertices, sizeof(cube_vertices)); + auto *vb = new VertexBuffer(cubee, sizeof(cubee)); + auto *va = new VertexArray(*vb); + va->add(0,3,5,0); + va->add(1,2,5,12); - // - return new VertexArray(*vb); + return va; } IndexBuffer *BlockRenderer::setIndexBuffer() { - unsigned cube_elements[] = { - // front + unsigned indexx[] = { 0, 1, 2, 2, 3, 0, - // right - 1, 5, 6, - 6, 2, 1, - // back - 7, 6, 5, - 5, 4, 7, - // left - 4, 0, 3, - 3, 7, 4, - // bottom - 4, 5, 1, - 1, 0, 4, - // top - 3, 2, 6, - 6, 7, 3 + + 4, 5, 6, + 6, 7, 4, + + 8, 9, 10, + 10, 11, 8, + + 12, 13, 14, + 14, 15, 12, + + 16, 17, 18, + 18, 19, 16, + + 20, 21, 22, + 22, 23, 20, + + 24, 25, 26, + 26, 27, 24, + + 28, 29, 30, + 30, 31, 28 }; - return new IndexBuffer(cube_elements, 36);; + return new IndexBuffer(indexx, 48); } Shader BlockRenderer::setShader() { @@ -83,6 +102,7 @@ Shader BlockRenderer::setShader() { Shader s; s.loadShader(vertsrc, geosrc, fragsrc); s.Bind(); + return s; } diff --git a/blocks/DirtBlock.cpp b/blocks/DirtBlock.cpp new file mode 100644 index 0000000..60eb78f --- /dev/null +++ b/blocks/DirtBlock.cpp @@ -0,0 +1,9 @@ +// +// Created by lukas on 04.02.22. +// + +#include "DirtBlock.h" +#include "TextureLoader.h" + +DirtBlock::DirtBlock(const uint &xpos, const uint &ypos, const uint &zpos) : BaseBlock(xpos, ypos, zpos, TextureLoader::loadTexture("../assets/blocks/dirt.bmp")) { +} diff --git a/blocks/DirtBlock.h b/blocks/DirtBlock.h new file mode 100644 index 0000000..c5aa2d0 --- /dev/null +++ b/blocks/DirtBlock.h @@ -0,0 +1,18 @@ +// +// Created by lukas on 04.02.22. +// + +#ifndef OPENGLTEST_DIRTBLOCK_H +#define OPENGLTEST_DIRTBLOCK_H + + +#include +#include "BaseBlock.h" + +class DirtBlock : public BaseBlock { +public: + DirtBlock(const uint &xpos, const uint &ypos, const uint &zpos); +}; + + +#endif //OPENGLTEST_DIRTBLOCK_H diff --git a/blocks/GrasBlock.cpp b/blocks/GrasBlock.cpp deleted file mode 100644 index 4d39f76..0000000 --- a/blocks/GrasBlock.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// -// Created by lukas on 04.02.22. -// - -#include "GrasBlock.h" - -GrasBlock::GrasBlock(const uint &xpos, const uint &ypos, const uint &zpos) : BaseBlock(0.0f, 1.0f, 0.0f, xpos, ypos, zpos) { -} diff --git a/blocks/GrasBlock.h b/blocks/GrasBlock.h deleted file mode 100644 index b668e5d..0000000 --- a/blocks/GrasBlock.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Created by lukas on 04.02.22. -// - -#ifndef OPENGLTEST_GRASBLOCK_H -#define OPENGLTEST_GRASBLOCK_H - - -#include -#include "BaseBlock.h" - -class GrasBlock : public BaseBlock { -public: - GrasBlock(const uint &xpos, const uint &ypos, const uint &zpos); -}; - - -#endif //OPENGLTEST_GRASBLOCK_H diff --git a/blocks/RenderBase.h b/blocks/RenderBase.h index 4d108d7..7ebd55f 100644 --- a/blocks/RenderBase.h +++ b/blocks/RenderBase.h @@ -6,51 +6,63 @@ #define OPENGLTEST_RENDERBASE_H +#include #include "../gl/Renderer.h" #include "../gl/Shader.h" -template +template class RenderBase { -public: - virtual VertexArray* setVertexArray() = 0; - virtual Shader setShader() = 0; - virtual IndexBuffer* setIndexBuffer() = 0; +private: + static RenderBase *instance; +protected: + RenderBase() { + if (instance) throw std::logic_error("Instance already exists"); + instance = this; + } - static RenderBase* getInstance() { +public: + virtual VertexArray *setVertexArray() = 0; + + virtual Shader setShader() = 0; + + virtual IndexBuffer *setIndexBuffer() = 0; + + static RenderBase *getInstance() { if (instance == nullptr) { - instance = new T(); + new T(); instance->init(); } return instance; - } -private: - static RenderBase* instance; - - -private: +public: Renderer r; - VertexArray* va; - IndexBuffer* ib; + VertexArray *va; + IndexBuffer *ib; Shader s; public: - RenderBase(){}; - void render(){ + + + virtual void render() { r.render(*va, *ib, s); } + void init() { s = setShader(); va = setVertexArray(); ib = setIndexBuffer(); } - void deinit(){} - unsigned getMVPhandle(){ + void deinit() { + glDeleteProgram(s.getHandle()); + } + + unsigned getMVPhandle() { return s.getUniformHandle("MVP"); } - unsigned getUniformhandle(std::string name){ + + unsigned getUniformhandle(std::string name) { return s.getUniformHandle(std::move(name)); } }; diff --git a/blocks/Stoneblock.cpp b/blocks/Stoneblock.cpp new file mode 100644 index 0000000..a74d0a4 --- /dev/null +++ b/blocks/Stoneblock.cpp @@ -0,0 +1,8 @@ +// +// Created by lukas on 06.02.22. +// + +#include "Stoneblock.h" +#include "TextureLoader.h" + +Stoneblock::Stoneblock(uint xpos, uint ypos, uint zpos) : BaseBlock(xpos, ypos, zpos, TextureLoader::loadTexture("../assets/blocks/stone.bmp")) {} diff --git a/blocks/Stoneblock.h b/blocks/Stoneblock.h new file mode 100644 index 0000000..04340c9 --- /dev/null +++ b/blocks/Stoneblock.h @@ -0,0 +1,17 @@ +// +// Created by lukas on 06.02.22. +// + +#ifndef OPENGLTEST_STONEBLOCK_H +#define OPENGLTEST_STONEBLOCK_H + + +#include "BaseBlock.h" + +class Stoneblock: public BaseBlock { +public: + Stoneblock(uint xpos, uint ypos, uint zpos); +}; + + +#endif //OPENGLTEST_STONEBLOCK_H diff --git a/blocks/TextureLoader.cpp b/blocks/TextureLoader.cpp new file mode 100644 index 0000000..a379df6 --- /dev/null +++ b/blocks/TextureLoader.cpp @@ -0,0 +1,22 @@ +// +// Created by lukas on 06.02.22. +// + +#include +#include "TextureLoader.h" + +std::unordered_map TextureLoader::texts; + +Texture *TextureLoader::loadTexture(std::string path) { + if (texts.find(path) != texts.end()) { + return &texts[path]; + } else { + std::cout << "Loading texture: " << path << std::endl; + auto *t = new Texture; + t->load(path); + t->Bind(); + + texts[path] = *t; + return t; + } +} diff --git a/blocks/TextureLoader.h b/blocks/TextureLoader.h new file mode 100644 index 0000000..35d149d --- /dev/null +++ b/blocks/TextureLoader.h @@ -0,0 +1,23 @@ +// +// Created by lukas on 06.02.22. +// + +#ifndef OPENGLTEST_TEXTURELOADER_H +#define OPENGLTEST_TEXTURELOADER_H + + +#include +#include "../gl/Texture.h" + +class TextureLoader { +private: + static std::unordered_map texts; +public: + static Texture* loadTexture(std::string path); + +private: + +}; + + +#endif //OPENGLTEST_TEXTURELOADER_H diff --git a/blocks/fragment.shader b/blocks/fragment.shader index 273ce43..e52c309 100644 --- a/blocks/fragment.shader +++ b/blocks/fragment.shader @@ -1,9 +1,11 @@ R"(#version 330 core out vec4 color; uniform vec3 u_color; +uniform sampler2D u_texture; in vec3 normal; in vec4 pos; +in vec2 texcoords; void main() { @@ -15,6 +17,9 @@ void main() // set light color vec3 diffuse = diff * vec3(1.0,1.0,1.0); - vec3 result = (diffuse) * u_color; + vec4 c = texture(u_texture, texcoords); + + vec3 result = (diffuse) * c.xyz; color = vec4(result,0.0); +// color = c; })"; \ No newline at end of file diff --git a/blocks/geometry.shader b/blocks/geometry.shader index e3eab01..afcfba4 100644 --- a/blocks/geometry.shader +++ b/blocks/geometry.shader @@ -4,9 +4,11 @@ layout(triangles) in; layout(triangle_strip, max_vertices=3) out; out vec3 normal; - out vec4 pos; +in vec2 v_texcoords[]; +out vec2 texcoords; + void main( void ) { vec3 a = ( gl_in[1].gl_Position - gl_in[0].gl_Position ).xyz; @@ -18,6 +20,7 @@ void main( void ) gl_Position = gl_in[i].gl_Position; normal = N; pos = gl_in[i].gl_Position; + texcoords = v_texcoords[i]; EmitVertex( ); } diff --git a/blocks/vertex.shader b/blocks/vertex.shader index 63cd45b..f4c2d43 100644 --- a/blocks/vertex.shader +++ b/blocks/vertex.shader @@ -1,16 +1,17 @@ R"(#version 330 core // Input vertex data, different for all executions of this shader. layout(location = 0) in vec3 vertexPosition_modelspace; +layout(location = 1) in vec2 texCoords; //// Values that stay constant for the whole mesh. uniform mat4 MVP; uniform mat4 translation; -out vec3 FragPos; +out vec2 v_texcoords; void main(){ // Output position of the vertex, in clip space : MVP * position vec4 pos = MVP * translation * vec4(vertexPosition_modelspace,1); gl_Position = pos; - FragPos = pos.xyz; + v_texcoords = texCoords; })"; \ No newline at end of file diff --git a/bmploader.cpp b/bmploader.cpp new file mode 100644 index 0000000..ff89f16 --- /dev/null +++ b/bmploader.cpp @@ -0,0 +1,76 @@ +// +// Created by lukas on 05.02.22. +// +#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#include "bmploader.h" + +unsigned bmploader::loadBMP(const char *imagepath) { + // Data read from the header of the BMP file + unsigned char header[54]; // Each BMP file begins by a 54-bytes header + unsigned int dataPos; // Position in the file where the actual data begins + int width, height; + unsigned int imageSize; // = width*height*3 + // Actual RGB data + unsigned char * data; + + + // Open the file + FILE * file = fopen(imagepath,"rb"); + if (!file){printf("Image could not be opened\n"); return 0;} + + if ( fread(header, 1, 54, file)!=54 ){ // If not 54 bytes read : problem + printf("Not a correct BMP file\n"); + return false; + } + + if ( header[0]!='B' || header[1]!='M' ){ + printf("Not a correct BMP file\n"); + return 0; + } + + // Read ints from the byte array + dataPos = *(int*)&(header[0x0A]); + imageSize = *(int*)&(header[0x22]); + width = *(int*)&(header[0x12]); + height = *(int*)&(header[0x16]); + + // Some BMP files are misformatted, guess missing information + if (imageSize==0) imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component + if (dataPos==0) dataPos=54; // The BMP header is done that way + + // Create a buffer + data = new unsigned char [imageSize]; + + // Read the actual data from the file into the buffer + fread(data,1,imageSize,file); + + //Everything is in memory now, the file can be closed + fclose(file); + + glEnable(GL_TEXTURE_2D); + + // Create one OpenGL texture + unsigned textureID; + glGenTextures(1, &textureID); + glActiveTexture(GL_TEXTURE0); + // "Bind" the newly created texture : all future texture functions will modify this texture + glBindTexture(GL_TEXTURE_2D, textureID); + + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // Give the image to OpenGL + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data); + // Generate mipmaps, by the way. + glGenerateMipmap(GL_TEXTURE_2D); + + + + return textureID; +} diff --git a/bmploader.h b/bmploader.h new file mode 100644 index 0000000..0976301 --- /dev/null +++ b/bmploader.h @@ -0,0 +1,15 @@ +// +// Created by lukas on 05.02.22. +// + +#ifndef OPENGLTEST_BMPLOADER_H +#define OPENGLTEST_BMPLOADER_H + + +class bmploader { +public: + unsigned loadBMP(const char * imagepath); +}; + + +#endif //OPENGLTEST_BMPLOADER_H diff --git a/crosshair/CrossHair.cpp b/crosshair/CrossHair.cpp new file mode 100644 index 0000000..5c9d703 --- /dev/null +++ b/crosshair/CrossHair.cpp @@ -0,0 +1,50 @@ +// +// Created by lukas on 06.02.22. +// +#define GL_GLEXT_PROTOTYPES +#include +#include "CrossHair.h" + +VertexArray *CrossHair::setVertexArray() { + float fade[] = { + // face #1 + -0.02, -0.05, + 0.02, 0.02, + -0.05, 0.05, + }; + + // Generate a vertex buffer + auto *vb = new VertexBuffer(fade, sizeof(fade)); + auto *va = new VertexArray(*vb); + va->add(0,2,3,0); + + return va; +} + +Shader CrossHair::setShader() { + const std::string vertsrc = +#include "vertex.shader" + + const std::string fragsrc = +#include "fragment.shader" + + Shader s; + s.loadShader(vertsrc, "", fragsrc); + s.Bind(); + + return s; +} + +IndexBuffer *CrossHair::setIndexBuffer() { + unsigned indexx[] = { + 0,2,1 + }; + + return new IndexBuffer(indexx, 3); +} + +void CrossHair::render() { + s.Bind(); + glUniform3f(getUniformhandle("u_color"), 1.0f, 1.0f, 1.0f); + RenderBase::render(); +} diff --git a/crosshair/CrossHair.h b/crosshair/CrossHair.h new file mode 100644 index 0000000..f5dbf3b --- /dev/null +++ b/crosshair/CrossHair.h @@ -0,0 +1,23 @@ +// +// Created by lukas on 06.02.22. +// + +#ifndef OPENGLTEST_CROSSHAIR_H +#define OPENGLTEST_CROSSHAIR_H + + +#include "../blocks/RenderBase.h" + +class CrossHair : public RenderBase { +public: + VertexArray *setVertexArray() override; + + Shader setShader() override; + + IndexBuffer *setIndexBuffer() override; + + void render() override; +}; + + +#endif //OPENGLTEST_CROSSHAIR_H diff --git a/crosshair/fragment.shader b/crosshair/fragment.shader new file mode 100644 index 0000000..b002f00 --- /dev/null +++ b/crosshair/fragment.shader @@ -0,0 +1,8 @@ +R"(#version 330 core +out vec4 color; +uniform vec3 u_color; + +void main() +{ + color = vec4(u_color, 0.5); +})"; \ No newline at end of file diff --git a/crosshair/vertex.shader b/crosshair/vertex.shader new file mode 100644 index 0000000..c3c4751 --- /dev/null +++ b/crosshair/vertex.shader @@ -0,0 +1,9 @@ +R"(#version 330 core +// Input vertex data, different for all executions of this shader. +layout(location = 0) in vec2 vertexPosition_modelspace; + +void main(){ + // Output position of the vertex, in clip space : MVP * position + vec4 pos = vec4(vertexPosition_modelspace,0.0,1.0); + gl_Position = pos; +})"; \ No newline at end of file diff --git a/gl/Camera.cpp b/gl/Camera.cpp index 9eb66dd..26fb4a2 100644 --- a/gl/Camera.cpp +++ b/gl/Camera.cpp @@ -2,6 +2,7 @@ // Created by lukas on 05.02.22. // #define GL_GLEXT_PROTOTYPES + #include #include #include @@ -68,13 +69,16 @@ void Camera::setWindowSize(double width, double height) { void Camera::addRotaion(double rotx, double roty) { rx -= rotx / 300; - ry -= roty / 300; + ry += roty / 300; // limit to 2pi rx = std::fmod(rx, (2 * M_PI)); ry = std::fmod(ry, (2 * M_PI)); + ry = fmin(ry, M_PI / 2.0f); + ry = fmax(ry, -M_PI / 2.0f); + updateCameraPos(); } @@ -93,3 +97,15 @@ double Camera::getxangle() const { double Camera::getyangle() const { return ry; } + +double Camera::getXpos() { + return x; +} + +double Camera::getYpos() { + return y; +} + +double Camera::getZpos() { + return z; +} diff --git a/gl/Camera.h b/gl/Camera.h index 50f08c8..f10fc78 100644 --- a/gl/Camera.h +++ b/gl/Camera.h @@ -19,6 +19,10 @@ public: void setPos(double x, double y, double z); void addPos(double x, double y, double z); + double getXpos(); + double getYpos(); + double getZpos(); + void setRotation(double rotx, double roty); void addRotaion(double rotx, double roty); diff --git a/gl/Shader.cpp b/gl/Shader.cpp index 95e7014..0ced4fe 100644 --- a/gl/Shader.cpp +++ b/gl/Shader.cpp @@ -12,6 +12,7 @@ #include #include #include +#include unsigned int Shader::compileShader(const char *source, unsigned int type) const { unsigned int shaderid = glCreateShader(type); @@ -46,9 +47,9 @@ unsigned Shader::getHandle() const { } unsigned Shader::getUniformHandle(std::string name) { - if(uniformhandles.find(name) != uniformhandles.end()){ + if (uniformhandles.find(name) != uniformhandles.end()) { return uniformhandles[name]; - }else{ + } else { const unsigned id = glGetUniformLocation(mProgHandle, name.c_str()); uniformhandles[name] = id; return id; @@ -82,37 +83,56 @@ unsigned int Shader::loadShaderFromFile(const std::string vertex_file_path, cons } unsigned int Shader::loadShader(const std::string vertex_src, const std::string geometry_src, const std::string fragment_src) { - // Compile Vertex Shader - printf("Compiling vertex shader\n"); - uint VertexShaderID = compileShader(vertex_src.c_str(), GL_VERTEX_SHADER); - if (VertexShaderID == 0) { - printf("Error Compiling shader\n"); - return 0; + uint VertexShaderID; + uint GeometryShaderID; + uint FragmentShaderID; + + if (!vertex_src.empty()) { + // Compile Vertex Shader + printf("Compiling vertex shader\n"); + VertexShaderID = compileShader(vertex_src.c_str(), GL_VERTEX_SHADER); + if (VertexShaderID == 0) { + printf("Error Compiling vertex shader\n"); + return 0; + } } - printf("Compiling geometry shader\n"); - uint GeometryShaderID = compileShader(geometry_src.c_str(), GL_GEOMETRY_SHADER); - if (GeometryShaderID == 0) { - printf("Error Compiling shader\n"); - return 0; + + if (!geometry_src.empty()) { + printf("Compiling geometry shader\n"); + GeometryShaderID = compileShader(geometry_src.c_str(), GL_GEOMETRY_SHADER); + if (GeometryShaderID == 0) { + printf("Error Compiling shader\n"); + return 0; + } } - printf("Compiling fragment shader\n"); - uint FragmentShaderID = compileShader(fragment_src.c_str(), GL_FRAGMENT_SHADER); - if (FragmentShaderID == 0) { - printf("Error Compiling shader\n"); - return 0; + if (!fragment_src.empty()) { + printf("Compiling fragment shader\n"); + FragmentShaderID = compileShader(fragment_src.c_str(), GL_FRAGMENT_SHADER); + if (FragmentShaderID == 0) { + printf("Error Compiling shader\n"); + return 0; + } } + // Link the program GLint Result = GL_FALSE; int InfoLogLength; printf("Linking shader program\n"); GLuint ProgramID = glCreateProgram(); - glAttachShader(ProgramID, VertexShaderID); - glAttachShader(ProgramID, GeometryShaderID); - glAttachShader(ProgramID, FragmentShaderID); + if (!vertex_src.empty()) { + glAttachShader(ProgramID, VertexShaderID); + } + if (!geometry_src.empty()) { + glAttachShader(ProgramID, GeometryShaderID); + } + if (!fragment_src.empty()) { + glAttachShader(ProgramID, FragmentShaderID); + } + glLinkProgram(ProgramID); // Check the program @@ -125,11 +145,20 @@ unsigned int Shader::loadShader(const std::string vertex_src, const std::string } // cleanup shaders - glDetachShader(ProgramID, VertexShaderID); - glDetachShader(ProgramID, FragmentShaderID); + if (!vertex_src.empty()){ + glDetachShader(ProgramID, VertexShaderID); + glDeleteShader(VertexShaderID); + } - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); + if (!geometry_src.empty()){ + glDetachShader(ProgramID, GeometryShaderID); + glDeleteShader(GeometryShaderID); + } + + if (!fragment_src.empty()){ + glDetachShader(ProgramID, FragmentShaderID); + glDeleteShader(FragmentShaderID); + } mProgHandle = ProgramID; return ProgramID; diff --git a/gl/Shader.h b/gl/Shader.h index 1bc93e1..c5f75c7 100644 --- a/gl/Shader.h +++ b/gl/Shader.h @@ -7,6 +7,12 @@ #include #include +#include +#include +#include +#define GL_GLEXT_PROTOTYPES + +#include class Shader { private: @@ -24,22 +30,24 @@ public: unsigned int loadShader(const std::string vertex_src, const std::string geometry_src, const std::string fragment_src); - /** - * comile a specific shader source - * @param source source string - * @param type shader tpye - * @return id of copiled shader - */ - unsigned int compileShader(const char *source, unsigned int type) const; + std::string readFile(std::string path); void Bind() const; unsigned getHandle() const; - unsigned getUniformHandle(std::string name); +private: + /** + * comile a specific shader source + * @param source source string + * @param type shader tpye + * @return id of copiled shader + */ + unsigned int compileShader(const char *source, unsigned int type) const; + }; #endif //OPENGLTEST_SHADER_H diff --git a/gl/Texture.cpp b/gl/Texture.cpp new file mode 100644 index 0000000..bd93de8 --- /dev/null +++ b/gl/Texture.cpp @@ -0,0 +1,26 @@ +// +// Created by lukas on 06.02.22. +// + +#include "Texture.h" +#include "../bmploader.h" + +#define GL_GLEXT_PROTOTYPES + +#include + +Texture::Texture() { +} + +void Texture::Bind() { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexturehandle); +} + +void Texture::UnBind() { + glBindTexture(GL_TEXTURE_2D, 0); +} + +void Texture::load(std::string path) { + mTexturehandle = bmploader().loadBMP(path.c_str()); +} diff --git a/gl/Texture.h b/gl/Texture.h new file mode 100644 index 0000000..dba49d5 --- /dev/null +++ b/gl/Texture.h @@ -0,0 +1,22 @@ +// +// Created by lukas on 06.02.22. +// + +#ifndef OPENGLTEST_TEXTURE_H +#define OPENGLTEST_TEXTURE_H + + +#include + +class Texture { +private: + unsigned mTexturehandle; +public: + Texture(); + void load(std::string path); + void Bind(); + void UnBind(); +}; + + +#endif //OPENGLTEST_TEXTURE_H diff --git a/gl/VertexArray.cpp b/gl/VertexArray.cpp index 48df8e4..64fd8d9 100644 --- a/gl/VertexArray.cpp +++ b/gl/VertexArray.cpp @@ -14,13 +14,22 @@ VertexArray::VertexArray(const VertexBuffer& buff) { // generate new vertex array object glGenVertexArrays(1, &handle); + Bind(); - // specify syntax of my data - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) nullptr); - glEnableVertexAttribArray(0); +// // specify syntax of my data +// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *) nullptr); +// glEnableVertexAttribArray(0); +// +// glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void *) 12); +// glEnableVertexAttribArray(1); } unsigned VertexArray::getHandle() const { return handle; } + +void VertexArray::add(int index, int size, int stride, int pos) { + glVertexAttribPointer(index, size, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void *) pos); + glEnableVertexAttribArray(index); +} diff --git a/gl/VertexArray.h b/gl/VertexArray.h index a4806bb..3f38b91 100644 --- a/gl/VertexArray.h +++ b/gl/VertexArray.h @@ -17,6 +17,8 @@ public: void Bind() const; + void add(int index, int size, int stride, int pos); + unsigned getHandle() const; }; diff --git a/main.cpp b/main.cpp index cfeda65..aa54cc0 100644 --- a/main.cpp +++ b/main.cpp @@ -3,19 +3,19 @@ #define GL_GLEXT_PROTOTYPES #include -#include #include #include "gl/Shader.h" #include "gl/IndexBuffer.h" #include "gl/VertexArray.h" #include "gl/Renderer.h" -#include "blocks/GrasBlock.h" +#include "blocks/DirtBlock.h" #include "blocks/BlockRenderer.h" #include "gl/Camera.h" +#include "blocks/Stoneblock.h" +#include "crosshair/CrossHair.h" +#include "blocks/AirBlock.h" #include -#include - //#define WIREFRAME void framebuffer_size_callback(GLFWwindow *window, int width, int height); @@ -31,6 +31,7 @@ double oldx = 0; double oldy = 0; bool menuopen = false; +std::vector blocks; void cursor_position_callback(GLFWwindow *window, double xpos, double ypos) { if (menuopen)return; @@ -44,6 +45,21 @@ void cursor_position_callback(GLFWwindow *window, double xpos, double ypos) { cam.addRotaion(xdiff, ydiff); } +void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) + { + double xpos, ypos; + cam.getXpos(); + + blocks.erase(blocks.begin()+1); + + //getting cursor position + glfwGetCursorPos(window, &xpos, &ypos); + std::cout << "Cursor Position at (" << xpos << " : " << ypos << std::endl; + } +} + GLFWwindow *initWindow() { glfwInit(); @@ -74,6 +90,7 @@ GLFWwindow *initWindow() { glfwSetCursorPosCallback(window, cursor_position_callback); + glfwSetMouseButtonCallback(window, mouse_button_callback); if (glfwRawMouseMotionSupported()) glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); @@ -94,24 +111,20 @@ int main() { #endif glEnable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GrasBlock gb(0, 0, 0); - BaseBlock bb(0.0f, (float) rand() / RAND_MAX, 1.0f, 1, 0, 0); - - // BlockRenderer::getInstance()->init(); - - std::vector blocks; - - blocks.push_back(gb); - blocks.push_back(bb); - blocks.emplace_back(1.0f, .0f, 1.0f, 0, 0, 1); - - for (int i = 0; i < 5; i++) { - blocks.push_back(GrasBlock(i, i, 0)); + for (int x = 0; x < 35; x++) { + for (int y = 0; y < 35; ++y) { + blocks.push_back(new AirBlock(x,y,2)); + blocks.push_back(new DirtBlock(x, y, (int)(sin(x / 3.0)*3)+ (int)(cos(y / 2.0)*2)) ); + blocks.push_back(new Stoneblock(x, y, 0)); + } } - cam.setPos(0, 0, 0); - cam.setRotation(0,0); + cam.setPos(0, 0, 3); + cam.setRotation(0, 0); + + CrossHair::getInstance()->s.Bind(); while (!glfwWindowShouldClose(window)) { // process user input events @@ -120,17 +133,29 @@ int main() { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + +// glUniform3f(CrossHair::getInstance()->getUniformhandle("u_color"), 0.0f, 0.0f, 0.0f); + CrossHair::getInstance()->render(); + +// CrossHair::getInstance()->s.Bind(); +// glBindTexture(GL_TEXTURE_2D, 0); + for (auto b: blocks) { - b.render(); + b->render(); } + // swap buffer to calc and show glfwSwapBuffers(window); // poll for and execute events glfwPollEvents(); } - // glDeleteProgram(shaderProgram); + for(auto b : blocks){ + delete b; + } + BlockRenderer::getInstance()->deinit(); glfwTerminate(); return 0; @@ -165,11 +190,11 @@ void processInput(GLFWwindow *window) { } if (glfwGetKey(window, GLFW_KEY_SPACE)) { - cam.addPos(0.0,0.0,0.1); + cam.addPos(0.0, 0.0, 0.1); } if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT)) { - cam.addPos(0.0,0.0,-0.1); + cam.addPos(0.0, 0.0, -0.1); } }