From 4645e40b62a801ab507f844a5990d0050016f565 Mon Sep 17 00:00:00 2001 From: Bart van Blokland Date: Mon, 18 Feb 2019 17:52:50 +0100 Subject: [PATCH] Updated code handout for assignment 2 --- .gitmodules | 3 + CMakeLists.txt | 4 +- res/textures/.gitignore | 2 + res/textures/.pastetextureshere | 0 src/gamelogic.cpp | 4 +- src/utilities/glfont.cpp | 38 +++++++++ src/utilities/glfont.h | 6 ++ src/utilities/imageLoader.cpp | 41 ++++++++++ src/utilities/imageLoader.hpp | 12 +++ src/utilities/shapes.cpp | 140 ++++++++++++++++++++++---------- 10 files changed, 206 insertions(+), 44 deletions(-) create mode 100644 res/textures/.gitignore create mode 100644 res/textures/.pastetextureshere create mode 100644 src/utilities/glfont.cpp create mode 100644 src/utilities/glfont.h create mode 100644 src/utilities/imageLoader.cpp create mode 100644 src/utilities/imageLoader.hpp diff --git a/.gitmodules b/.gitmodules index 1038314..8233d4f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "arrrgh"] path = arrrgh url = https://github.com/ElectricToy/arrrgh.git +[submodule "lib/lodepng"] + path = lib/lodepng + url = https://github.com/lvandeve/lodepng diff --git a/CMakeLists.txt b/CMakeLists.txt index 948f619..b8014ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ add_subdirectory(lib/SFML) include_directories (src/ lib/glad/include/ lib/glfw/include/ + lib/lodepng/ lib/glm/ lib/stb/ lib/arrrgh/ @@ -51,7 +52,8 @@ include_directories (src/ # # Add files # -file (GLOB VENDORS_SOURCES lib/glad/src/glad.c) +file (GLOB VENDORS_SOURCES lib/glad/src/glad.c + lib/lodepng/lodepng.cpp) file (GLOB_RECURSE PROJECT_HEADERS src/*.hpp src/*.h) file (GLOB_RECURSE PROJECT_SOURCES src/*.cpp diff --git a/res/textures/.gitignore b/res/textures/.gitignore new file mode 100644 index 0000000..cbb145f --- /dev/null +++ b/res/textures/.gitignore @@ -0,0 +1,2 @@ +./*.png + diff --git a/res/textures/.pastetextureshere b/res/textures/.pastetextureshere new file mode 100644 index 0000000..e69de29 diff --git a/src/gamelogic.cpp b/src/gamelogic.cpp index 1681440..bef19ac 100644 --- a/src/gamelogic.cpp +++ b/src/gamelogic.cpp @@ -99,8 +99,8 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { shader->makeBasicShader("../res/shaders/simple.vert", "../res/shaders/simple.frag"); shader->activate(); - Mesh box = generateBox(boxDimensions.x, boxDimensions.y, boxDimensions.z, false); - Mesh pad = generateBox(padDimensions.x, padDimensions.y, padDimensions.z, true); + Mesh box = generateBox(boxDimensions.x, boxDimensions.y, boxDimensions.z, true); + Mesh pad = generateBox(padDimensions.x, padDimensions.y, padDimensions.z, false); Mesh sphere = generateSphere(1.0, 40, 40); unsigned int ballVAO = generateBuffer(sphere); diff --git a/src/utilities/glfont.cpp b/src/utilities/glfont.cpp new file mode 100644 index 0000000..79397f0 --- /dev/null +++ b/src/utilities/glfont.cpp @@ -0,0 +1,38 @@ +#include +#include "glfont.h" + +Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth, float totalTextWidth) { + float characterWidth = totalTextWidth / float(text.length()); + float characterHeight = characterHeightOverWidth * characterWidth; + + unsigned int vertexCount = 4 * text.length(); + unsigned int indexCount = 6 * text.length(); + + Mesh mesh; + + mesh.vertices.resize(vertexCount); + mesh.indices.resize(indexCount); + + for(unsigned int i = 0; i < text.length(); i++) + { + float baseXCoordinate = float(i) * characterWidth; + + mesh.vertices.at(4 * i + 0) = {baseXCoordinate, 0, 0}; + mesh.vertices.at(4 * i + 1) = {baseXCoordinate + characterWidth, 0, 0}; + mesh.vertices.at(4 * i + 2) = {baseXCoordinate + characterWidth, characterHeight, 0}; + + mesh.vertices.at(4 * i + 0) = {baseXCoordinate, 0, 0}; + mesh.vertices.at(4 * i + 2) = {baseXCoordinate + characterWidth, characterHeight, 0}; + mesh.vertices.at(4 * i + 3) = {baseXCoordinate, characterHeight, 0}; + + + mesh.indices.at(6 * i + 0) = 4 * i + 0; + mesh.indices.at(6 * i + 1) = 4 * i + 1; + mesh.indices.at(6 * i + 2) = 4 * i + 2; + mesh.indices.at(6 * i + 3) = 4 * i + 0; + mesh.indices.at(6 * i + 4) = 4 * i + 2; + mesh.indices.at(6 * i + 5) = 4 * i + 3; + } + + return mesh; +} \ No newline at end of file diff --git a/src/utilities/glfont.h b/src/utilities/glfont.h new file mode 100644 index 0000000..844c322 --- /dev/null +++ b/src/utilities/glfont.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include "mesh.h" + +Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth, float totalTextWidth); \ No newline at end of file diff --git a/src/utilities/imageLoader.cpp b/src/utilities/imageLoader.cpp new file mode 100644 index 0000000..88a708a --- /dev/null +++ b/src/utilities/imageLoader.cpp @@ -0,0 +1,41 @@ +#include "imageLoader.hpp" +#include + +// Original source: https://raw.githubusercontent.com/lvandeve/lodepng/master/examples/example_decode.cpp +PNGImage loadPNGFile(std::string fileName) +{ + std::vector png; + std::vector pixels; //the raw pixels + unsigned int width, height; + + //load and decode + unsigned error = lodepng::load_file(png, fileName); + if(!error) error = lodepng::decode(pixels, width, height, png); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... + + // Unfortunately, images usually have their origin at the top left. + // OpenGL instead defines the origin to be on the _bottom_ left instead, so + // here's the world's most inefficient way to flip the image vertically. + + // You're welcome :) + + unsigned int widthBytes = 4 * width; + + for(unsigned int row = 0; row < (height / 2); row++) { + for(unsigned int col = 0; col < widthBytes; col++) { + std::swap(pixels[row * widthBytes + col], pixels[(height - 1 - row) * widthBytes + col]); + } + } + + PNGImage image; + image.width = width; + image.height = height; + image.pixels = pixels; + + return image; + +} \ No newline at end of file diff --git a/src/utilities/imageLoader.hpp b/src/utilities/imageLoader.hpp new file mode 100644 index 0000000..5f3099f --- /dev/null +++ b/src/utilities/imageLoader.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "lodepng.h" +#include +#include + +typedef struct PNGImage { + unsigned int width, height; + std::vector pixels; +} PNGImage; + +PNGImage loadPNGFile(std::string fileName); \ No newline at end of file diff --git a/src/utilities/shapes.cpp b/src/utilities/shapes.cpp index 079ae2b..c0cf322 100644 --- a/src/utilities/shapes.cpp +++ b/src/utilities/shapes.cpp @@ -7,53 +7,54 @@ Mesh generateBox(float width, float height, float depth, bool flipFaces) { // Edit: well, that backfired.. std::vector vertices = { - {0, 0, 0}, - {0, height, depth}, - {0, 0, depth}, + {0, 0, 0}, + {0, 0, depth}, + {0, height, depth}, - {0, 0, 0}, - {0, height, 0}, - {0, height, depth}, + {0, 0, 0}, + {0, height, depth}, + {0, height, 0}, - {width, 0, 0}, + {width, 0, 0}, {width, height, depth}, - {width, height, 0}, - - {width, 0, 0}, - {width, 0, depth}, - {width, height, depth}, - - {0, 0, 0}, - {width, 0, 0}, - {width, height, 0}, - - {0, 0, 0}, - {width, height, 0}, - {0, height, 0}, - - {0, 0, depth}, - {width, height, depth}, - {width, 0, depth}, - - {0, 0, depth}, - {0, height, depth}, - {width, height, depth}, - - {0, 0, 0}, - {width, 0, depth}, - {width, 0, 0}, - - {0, 0, 0}, - {0, 0, depth}, - {width, 0, depth}, - - {width, height, 0}, - {0, height, depth}, - {0, height, 0}, + {width, 0, depth}, + {width, 0, 0}, {width, height, 0}, {width, height, depth}, - {0, height, depth}}; + + {0, 0, 0}, + {width, height, 0}, + {width, 0, 0}, + + {0, 0, 0}, + {0, height, 0}, + {width, height, 0}, + + {0, 0, depth}, + {width, 0, depth}, + {width, height, depth}, + + {0, 0, depth}, + {width, height, depth}, + {0, height, depth}, + + {0, 0, 0}, + {width, 0, 0}, + {width, 0, depth}, + + {0, 0, 0}, + {width, 0, depth}, + {0, 0, depth}, + + {width, height, 0}, + {0, height, 0}, + {0, height, depth}, + + {width, height, 0}, + {0, height, depth}, + {width, height, depth}, + }; // These are technically inverted relative to the vertex coordinates. // But for some strange reason the faces are rendered inverted. @@ -109,6 +110,62 @@ Mesh generateBox(float width, float height, float depth, bool flipFaces) { {0.0, -1.0, 0.0}, }; + float texScaleFactorX = depth / height; + float texScaleFactorY = width / depth; + float texScaleFactorZ = width / height; + + std::vector textureCoordinates = { + {0, 0}, + {texScaleFactorX, 0}, + {texScaleFactorX, 1}, + + {0, 0}, + {texScaleFactorX, 1}, + {0, 1}, + + {0, 0}, + {texScaleFactorX, 1}, + {texScaleFactorX, 0}, + + {0, 0}, + {0, 1}, + {texScaleFactorX, 1}, + + {0, 0}, + {texScaleFactorZ, 0}, + {texScaleFactorZ, 1}, + + {0, 0}, + {texScaleFactorZ, 1}, + {0, 1}, + + {0, 0}, + {texScaleFactorZ, 0}, + {texScaleFactorZ, 1}, + + {0, 0}, + {texScaleFactorZ, 1}, + {0, 1}, + + {0, 0}, + {texScaleFactorY, 0}, + {texScaleFactorY, 1}, + + {0, 0}, + {texScaleFactorY, 1}, + {0, 1}, + + {0, 0}, + {texScaleFactorY, 0}, + {texScaleFactorY, 1}, + + {0, 0}, + {texScaleFactorY, 1}, + {0, 1}, + + }; + + std::vector indices = { 0, 1, 2, 3, 4, 5, @@ -139,6 +196,7 @@ Mesh generateBox(float width, float height, float depth, bool flipFaces) { Mesh mesh; mesh.vertices = vertices; mesh.normals = normals; + mesh.textureCoordinates = textureCoordinates; mesh.indices = indices; return mesh;