Do ex2
This commit is contained in:
parent
101792b011
commit
9378c685a8
|
@ -32,3 +32,5 @@
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
res/textures/*.png
|
||||||
|
|
|
@ -2,6 +2,20 @@
|
||||||
|
|
||||||
in layout(location = 0) vec3 normal;
|
in layout(location = 0) vec3 normal;
|
||||||
in layout(location = 1) vec3 vertex;
|
in layout(location = 1) vec3 vertex;
|
||||||
|
in layout(location = 2) vec2 UV;
|
||||||
|
in layout(location = 3) mat3 TBN;
|
||||||
|
layout(binding = 0) uniform sampler2D diffuseTexture;
|
||||||
|
layout(binding = 1) uniform sampler2D normalTexture;
|
||||||
|
|
||||||
|
uniform bool isIlluminated;
|
||||||
|
uniform bool isTextured;
|
||||||
|
uniform bool isNormalMapped;
|
||||||
|
uniform bool isInverted;
|
||||||
|
|
||||||
|
uniform layout(location = 6) mat4 MVP;
|
||||||
|
uniform layout(location = 7) mat4 MV;
|
||||||
|
uniform layout(location = 8) mat4 MVnormal;
|
||||||
|
|
||||||
|
|
||||||
// point lights
|
// point lights
|
||||||
struct Light {
|
struct Light {
|
||||||
|
@ -11,6 +25,7 @@ struct Light {
|
||||||
vec3 spot_target; // MV space coordinates
|
vec3 spot_target; // MV space coordinates
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//named
|
||||||
#define N_LIGHTS 3
|
#define N_LIGHTS 3
|
||||||
|
|
||||||
uniform Light light[N_LIGHTS];
|
uniform Light light[N_LIGHTS];
|
||||||
|
@ -23,18 +38,24 @@ vec3 c_diffuse = vec3(0.75390625, 0.4296875, 0.4375);
|
||||||
vec3 c_emissive = vec3(0.01171875, 0.0, 0.15234375);
|
vec3 c_emissive = vec3(0.01171875, 0.0, 0.15234375);
|
||||||
vec3 c_specular = vec3(0.9453125, 0.94921875, 0.84765625);
|
vec3 c_specular = vec3(0.9453125, 0.94921875, 0.84765625);
|
||||||
|
|
||||||
float spot_cuttof_angle = cos(4 / 180.0 * 3.1415926535);
|
float spot_cuttof_angle = cos(1.5 / 180.0 * 3.1415926535);
|
||||||
|
|
||||||
void main()
|
void main_(vec4 basecolor) {
|
||||||
{
|
vec3 nnormal;
|
||||||
vec3 nnormal = normalize(normal);
|
if (isNormalMapped) {
|
||||||
|
vec3 tangential = texture(normalTexture, UV).rgb * 2.0 - 1.0;
|
||||||
|
nnormal = TBN * -normalize(tangential);
|
||||||
|
} else {
|
||||||
|
nnormal = normalize(normal);
|
||||||
|
}
|
||||||
|
|
||||||
float diffuse_intensity = 0.0;
|
float diffuse_intensity = 0.0;
|
||||||
float specular_intensity = 0.0;
|
float specular_intensity = 0.0;
|
||||||
|
|
||||||
for (int i = 0; i<3; i++) {
|
for (int i = 0; i<3; i++) {
|
||||||
vec3 L = vec3(light[i].MV * vec4(light[i].position, 1.0f)) - vertex;
|
vec3 L = vec3(light[i].MV * vec4(light[i].position, 1.0f)) - vertex;
|
||||||
float attenuation = clamp(1000/(1 + 40*length(L) + 0.1*length(L)*length(L)), 0.0, 1.25);
|
float l = length(L);
|
||||||
|
float attenuation = clamp(2000/(1 + 1*l + 0.1*l*l), 0.0, 1.25);
|
||||||
L = normalize(L);
|
L = normalize(L);
|
||||||
|
|
||||||
if (light[i].is_spot) {
|
if (light[i].is_spot) {
|
||||||
|
@ -42,7 +63,7 @@ void main()
|
||||||
if (dot(L2, L) < spot_cuttof_angle) {
|
if (dot(L2, L) < spot_cuttof_angle) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
attenuation *= 70;
|
attenuation *= 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
float diffuse_i = dot(nnormal, L);
|
float diffuse_i = dot(nnormal, L);
|
||||||
|
@ -61,7 +82,30 @@ void main()
|
||||||
//float intensity = dot(normalize(normal), normalize(light_pos_2));
|
//float intensity = dot(normalize(normal), normalize(light_pos_2));
|
||||||
//color = vec4(0.5 * normal + 0.5, 1.0);
|
//color = vec4(0.5 * normal + 0.5, 1.0);
|
||||||
|
|
||||||
color = vec4(c_emissive
|
color = basecolor * vec4(c_emissive
|
||||||
+ c_diffuse*diffuse_intensity
|
+ c_diffuse*diffuse_intensity, 1.0f)
|
||||||
+ c_specular*specular_intensity, 1.0f);
|
+ vec4(c_specular*specular_intensity, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if(isIlluminated) {
|
||||||
|
if (isTextured) {
|
||||||
|
c_diffuse = vec3(0.9);
|
||||||
|
c_emissive = vec3(0.2);
|
||||||
|
main_(texture(diffuseTexture, UV));
|
||||||
|
} else {
|
||||||
|
main_(vec4(1.0));
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
color = texture(diffuseTexture, UV);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (isInverted) {
|
||||||
|
color.r = 1 - color.r;
|
||||||
|
color.g = 1 - color.g;
|
||||||
|
color.b = 1 - color.b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,33 @@
|
||||||
|
|
||||||
in layout(location = 0) vec3 position;
|
in layout(location = 0) vec3 position;
|
||||||
in layout(location = 1) vec3 normal_in;
|
in layout(location = 1) vec3 normal_in;
|
||||||
|
in layout(location = 2) vec2 UV;
|
||||||
|
in layout(location = 3) vec3 tangent;
|
||||||
|
in layout(location = 4) vec3 bitangent;
|
||||||
|
|
||||||
uniform layout(location = 3) mat4 MVP;
|
uniform layout(location = 6) mat4 MVP;
|
||||||
uniform layout(location = 4) mat4 MV;
|
uniform layout(location = 7) mat4 MV;
|
||||||
uniform layout(location = 5) mat4 MVnormal;
|
uniform layout(location = 8) mat4 MVnormal;
|
||||||
|
|
||||||
|
//named
|
||||||
|
uniform bool isIlluminated;
|
||||||
|
uniform bool isTextured;
|
||||||
|
uniform bool isNormalMapped;
|
||||||
|
|
||||||
out layout(location = 0) vec3 normal_out;
|
out layout(location = 0) vec3 normal_out;
|
||||||
out layout(location = 1) vec3 vertex_out;
|
out layout(location = 1) vec3 vertex_out;
|
||||||
|
out layout(location = 2) vec2 uv_out;
|
||||||
|
out layout(location = 3) mat3 TBN;
|
||||||
|
|
||||||
void main()
|
void main() {
|
||||||
{
|
TBN = mat3(
|
||||||
|
normalize(vec3(MV * vec4(tangent, 0.0))),
|
||||||
|
normalize(vec3(MV * vec4(bitangent, 0.0))),
|
||||||
|
normalize(vec3(MV * vec4(normal_in, 0.0)))
|
||||||
|
);
|
||||||
|
|
||||||
normal_out = normalize(vec3(MVnormal * vec4(normal_in, 1.0f)));
|
normal_out = normalize(vec3(MVnormal * vec4(normal_in, 1.0f)));
|
||||||
vertex_out = vec3(MV*vec4(position, 1.0f));
|
vertex_out = vec3(MV*vec4(position, 1.0f));
|
||||||
|
uv_out = UV;
|
||||||
gl_Position = MVP * vec4(position, 1.0f);
|
gl_Position = MVP * vec4(position, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <utilities/mesh.h>
|
#include <utilities/mesh.h>
|
||||||
#include <utilities/shapes.h>
|
#include <utilities/shapes.h>
|
||||||
#include <utilities/glutils.h>
|
#include <utilities/glutils.h>
|
||||||
|
#include <utilities/glfont.h>
|
||||||
|
#include <utilities/imageLoader.hpp>
|
||||||
#include <SFML/Audio/Sound.hpp>
|
#include <SFML/Audio/Sound.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
@ -33,6 +35,8 @@ SceneNode* rootNode;
|
||||||
SceneNode* boxNode;
|
SceneNode* boxNode;
|
||||||
SceneNode* ballNode;
|
SceneNode* ballNode;
|
||||||
SceneNode* padNode;
|
SceneNode* padNode;
|
||||||
|
SceneNode* hudNode;
|
||||||
|
SceneNode* textNode;
|
||||||
|
|
||||||
SceneNode* lightNode[3];
|
SceneNode* lightNode[3];
|
||||||
|
|
||||||
|
@ -61,7 +65,11 @@ bool jumpedToNextFrame = false;
|
||||||
const float debug_startTime = 45;
|
const float debug_startTime = 45;
|
||||||
double totalElapsedTime = debug_startTime;
|
double totalElapsedTime = debug_startTime;
|
||||||
|
|
||||||
|
// textures
|
||||||
|
|
||||||
|
PNGImage t_charmap;
|
||||||
|
PNGImage t_cobble_diff;
|
||||||
|
PNGImage t_cobble_normal;
|
||||||
|
|
||||||
void mouseCallback(GLFWwindow* window, double x, double y) {
|
void mouseCallback(GLFWwindow* window, double x, double y) {
|
||||||
int windowWidth, windowHeight;
|
int windowWidth, windowHeight;
|
||||||
|
@ -107,20 +115,37 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
|
||||||
Mesh sphere = generateSphere(1.0, 40, 40);
|
Mesh sphere = generateSphere(1.0, 40, 40);
|
||||||
|
|
||||||
unsigned int ballVAO = generateBuffer(sphere);
|
unsigned int ballVAO = generateBuffer(sphere);
|
||||||
unsigned int boxVAO = generateBuffer(box);
|
unsigned int boxVAO = generateBuffer(box, true);
|
||||||
unsigned int padVAO = generateBuffer(pad);
|
unsigned int padVAO = generateBuffer(pad);
|
||||||
|
|
||||||
|
// textures
|
||||||
|
t_charmap = loadPNGFile("../res/textures/charmap.png");
|
||||||
|
t_cobble_diff = loadPNGFile("../res/textures/cobble_diff.png");
|
||||||
|
t_cobble_normal = loadPNGFile("../res/textures/cobble_normal.png");
|
||||||
|
|
||||||
|
unsigned int t_charmapID = generateTexture(t_charmap);
|
||||||
|
unsigned int t_cobble_diffID = generateTexture(t_cobble_diff);
|
||||||
|
unsigned int t_cobble_normalID = generateTexture(t_cobble_normal);
|
||||||
|
|
||||||
rootNode = createSceneNode();
|
rootNode = createSceneNode();
|
||||||
boxNode = createSceneNode() ;
|
boxNode = createSceneNode(NORMAL_TEXTURED_GEOMETRY);
|
||||||
padNode = createSceneNode();
|
padNode = createSceneNode();
|
||||||
ballNode = createSceneNode();
|
ballNode = createSceneNode();
|
||||||
|
hudNode = createSceneNode(HUD);
|
||||||
|
textNode = createSceneNode(TEXTURED_GEOMETRY);
|
||||||
|
|
||||||
rootNode->children.push_back(boxNode);
|
rootNode->children.push_back(boxNode);
|
||||||
rootNode->children.push_back(padNode);
|
rootNode->children.push_back(padNode);
|
||||||
rootNode->children.push_back(ballNode);
|
rootNode->children.push_back(ballNode);
|
||||||
|
rootNode->children.push_back(hudNode);
|
||||||
|
|
||||||
|
hudNode->children.push_back(textNode);
|
||||||
|
//rootNode->children.push_back(textNode);
|
||||||
|
|
||||||
boxNode->vertexArrayObjectID = boxVAO;
|
boxNode->vertexArrayObjectID = boxVAO;
|
||||||
boxNode->VAOIndexCount = box.indices.size();
|
boxNode->VAOIndexCount = box.indices.size();
|
||||||
|
boxNode->diffuseTextureID = t_cobble_diffID;
|
||||||
|
boxNode->normalTextureID = t_cobble_normalID;
|
||||||
|
|
||||||
padNode->vertexArrayObjectID = padVAO;
|
padNode->vertexArrayObjectID = padVAO;
|
||||||
padNode->VAOIndexCount = pad.indices.size();
|
padNode->VAOIndexCount = pad.indices.size();
|
||||||
|
@ -138,12 +163,24 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
|
||||||
rootNode->children.push_back(lightNode[1]);
|
rootNode->children.push_back(lightNode[1]);
|
||||||
ballNode->children.push_back(lightNode[2]);
|
ballNode->children.push_back(lightNode[2]);
|
||||||
lightNode[0]->position = {boxDimensions.x/2 - 10, boxDimensions.y/2 - 10, boxDimensions.z/2 - 10};
|
lightNode[0]->position = {boxDimensions.x/2 - 10, boxDimensions.y/2 - 10, boxDimensions.z/2 - 10};
|
||||||
lightNode[1]->position = {300,300,400};
|
lightNode[1]->position = {-300, -500, 300};
|
||||||
lightNode[2]->position = {0, 0, 0};
|
lightNode[2]->position = {0, 0, 0};
|
||||||
|
|
||||||
lightNode[1]->nodeType = SPOT_LIGHT;
|
lightNode[1]->nodeType = SPOT_LIGHT;
|
||||||
padNode->targeted_by = lightNode[1];
|
padNode->targeted_by = lightNode[1];
|
||||||
|
|
||||||
|
|
||||||
|
// hud
|
||||||
|
Mesh hello_world = generateTextGeometryBuffer("Skjer'a bagera?", 1.3, 2);
|
||||||
|
textNode->position = glm::vec3(-1.0, 0.0, 0.0);
|
||||||
|
textNode->rotation = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
textNode->vertexArrayObjectID = generateBuffer(hello_world);
|
||||||
|
textNode->VAOIndexCount = hello_world.indices.size();
|
||||||
|
textNode->diffuseTextureID = t_charmapID;
|
||||||
|
textNode->isIlluminated = false;
|
||||||
|
textNode->isInverted = true;
|
||||||
|
|
||||||
|
|
||||||
getTimeDeltaSeconds();
|
getTimeDeltaSeconds();
|
||||||
|
|
||||||
std::cout << "Ready. Click to start!" << std::endl;
|
std::cout << "Ready. Click to start!" << std::endl;
|
||||||
|
@ -154,6 +191,14 @@ void updateNodeTransformations(SceneNode* node, glm::mat4 transformationThusFar,
|
||||||
glm::mat4 transformationMatrix(1.0);
|
glm::mat4 transformationMatrix(1.0);
|
||||||
|
|
||||||
switch(node->nodeType) {
|
switch(node->nodeType) {
|
||||||
|
case HUD:
|
||||||
|
// We orthographic now, bitches!
|
||||||
|
// set orthographic VP
|
||||||
|
V = glm::mat4(1.0);
|
||||||
|
P = glm::ortho(-float(windowWidth) / float(windowHeight), float(windowWidth) / float(windowHeight), -1.0f, 1.0f);//, -10.0f, 120.0f);
|
||||||
|
break;
|
||||||
|
case NORMAL_TEXTURED_GEOMETRY:
|
||||||
|
case TEXTURED_GEOMETRY:
|
||||||
case GEOMETRY:
|
case GEOMETRY:
|
||||||
transformationMatrix =
|
transformationMatrix =
|
||||||
glm::translate(glm::mat4(1.0), node->position)
|
glm::translate(glm::mat4(1.0), node->position)
|
||||||
|
@ -342,13 +387,25 @@ void updateFrame(GLFWwindow* window) {
|
||||||
|
|
||||||
|
|
||||||
void renderNode(SceneNode* node) {
|
void renderNode(SceneNode* node) {
|
||||||
glUniformMatrix4fv(3, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrix));
|
glUniformMatrix4fv(6, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrix));
|
||||||
glUniformMatrix4fv(4, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMV));
|
glUniformMatrix4fv(7, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMV));
|
||||||
glUniformMatrix4fv(5, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMVnormal));
|
glUniformMatrix4fv(8, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMVnormal));
|
||||||
|
glUniform1ui(shader->location("isNormalMapped"), false);
|
||||||
|
glUniform1ui(shader->location("isTextured"), false);
|
||||||
|
|
||||||
switch(node->nodeType) {
|
switch(node->nodeType) {
|
||||||
|
case NORMAL_TEXTURED_GEOMETRY:
|
||||||
|
glUniform1ui(shader->location("isNormalMapped"), true);
|
||||||
|
glBindTextureUnit(1, node->normalTextureID);
|
||||||
|
[[fallthrough]];
|
||||||
|
case TEXTURED_GEOMETRY:
|
||||||
|
glUniform1ui(shader->location("isTextured"), true);
|
||||||
|
glBindTextureUnit(0, node->diffuseTextureID);
|
||||||
|
[[fallthrough]];
|
||||||
case GEOMETRY:
|
case GEOMETRY:
|
||||||
if(node->vertexArrayObjectID != -1) {
|
if(node->vertexArrayObjectID != -1) {
|
||||||
|
glUniform1ui(shader->location("isIlluminated"), node->isIlluminated);
|
||||||
|
glUniform1ui(shader->location("isInverted"), node->isInverted);
|
||||||
glBindVertexArray(node->vertexArrayObjectID);
|
glBindVertexArray(node->vertexArrayObjectID);
|
||||||
glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
|
@ -365,6 +422,8 @@ void renderNode(SceneNode* node) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case HUD:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(SceneNode* child : node->children) {
|
for(SceneNode* child : node->children) {
|
||||||
|
|
|
@ -24,6 +24,10 @@ void runProgram(GLFWwindow* window, CommandLineOptions options)
|
||||||
// Configure miscellaneous OpenGL settings
|
// Configure miscellaneous OpenGL settings
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
//enable alpha
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
// Set default colour after clearing the colour buffer
|
// Set default colour after clearing the colour buffer
|
||||||
glClearColor(0.3f, 0.5f, 0.8f, 1.0f);
|
glClearColor(0.3f, 0.5f, 0.8f, 1.0f);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
SceneNode* createSceneNode() {
|
SceneNode* createSceneNode() {
|
||||||
return new SceneNode();
|
return new SceneNode();
|
||||||
}
|
}
|
||||||
|
SceneNode* createSceneNode(SceneNodeType type) {
|
||||||
|
return new SceneNode(type);
|
||||||
|
}
|
||||||
|
|
||||||
// Add a child node to its parent's list of children
|
// Add a child node to its parent's list of children
|
||||||
void addChild(SceneNode* parent, SceneNode* child) {
|
void addChild(SceneNode* parent, SceneNode* child) {
|
||||||
|
@ -26,4 +29,3 @@ void printNode(SceneNode* node) {
|
||||||
node->referencePoint.x, node->referencePoint.y, node->referencePoint.z,
|
node->referencePoint.x, node->referencePoint.y, node->referencePoint.z,
|
||||||
node->vertexArrayObjectID);
|
node->vertexArrayObjectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
enum SceneNodeType {
|
enum SceneNodeType {
|
||||||
GEOMETRY, POINT_LIGHT, SPOT_LIGHT
|
GEOMETRY, POINT_LIGHT, SPOT_LIGHT, HUD, TEXTURED_GEOMETRY, NORMAL_TEXTURED_GEOMETRY
|
||||||
};
|
};
|
||||||
|
|
||||||
// In case you haven't got much experience with C or C++, let me explain this "typedef" you see below.
|
// In case you haven't got much experience with C or C++, let me explain this "typedef" you see below.
|
||||||
|
@ -33,6 +33,12 @@ struct SceneNode {
|
||||||
|
|
||||||
nodeType = GEOMETRY;
|
nodeType = GEOMETRY;
|
||||||
targeted_by = nullptr;
|
targeted_by = nullptr;
|
||||||
|
|
||||||
|
isIlluminated = true;
|
||||||
|
isInverted = false;
|
||||||
|
}
|
||||||
|
SceneNode(SceneNodeType type) : SceneNode() {
|
||||||
|
nodeType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A list of all children that belong to this node.
|
// A list of all children that belong to this node.
|
||||||
|
@ -55,6 +61,12 @@ struct SceneNode {
|
||||||
// The ID of the VAO containing the "appearance" of this SceneNode.
|
// The ID of the VAO containing the "appearance" of this SceneNode.
|
||||||
int vertexArrayObjectID;
|
int vertexArrayObjectID;
|
||||||
unsigned int VAOIndexCount;
|
unsigned int VAOIndexCount;
|
||||||
|
|
||||||
|
unsigned int diffuseTextureID;
|
||||||
|
unsigned int normalTextureID;
|
||||||
|
|
||||||
|
bool isIlluminated;
|
||||||
|
bool isInverted;
|
||||||
|
|
||||||
// Node type is used to determine how to handle the contents of a node
|
// Node type is used to determine how to handle the contents of a node
|
||||||
SceneNodeType nodeType;
|
SceneNodeType nodeType;
|
||||||
|
@ -67,6 +79,7 @@ struct SceneNode {
|
||||||
// Struct for keeping track of 2D coordinates
|
// Struct for keeping track of 2D coordinates
|
||||||
|
|
||||||
SceneNode* createSceneNode();
|
SceneNode* createSceneNode();
|
||||||
|
SceneNode* createSceneNode(SceneNodeType type);
|
||||||
void addChild(SceneNode* parent, SceneNode* child);
|
void addChild(SceneNode* parent, SceneNode* child);
|
||||||
void printNode(SceneNode* node);
|
void printNode(SceneNode* node);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth, float totalTextWidth) {
|
Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth, float totalTextWidth) {
|
||||||
float characterWidth = totalTextWidth / float(text.length());
|
float characterWidth = totalTextWidth / float(text.length());
|
||||||
float characterHeight = characterHeightOverWidth * characterWidth;
|
float characterHeight = characterHeightOverWidth * characterWidth;
|
||||||
|
float textureWidth = 1.0 / 128.0;
|
||||||
|
|
||||||
unsigned int vertexCount = 4 * text.length();
|
unsigned int vertexCount = 4 * text.length();
|
||||||
unsigned int indexCount = 6 * text.length();
|
unsigned int indexCount = 6 * text.length();
|
||||||
|
|
||||||
|
@ -12,11 +13,14 @@ Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth
|
||||||
|
|
||||||
mesh.vertices.resize(vertexCount);
|
mesh.vertices.resize(vertexCount);
|
||||||
mesh.indices.resize(indexCount);
|
mesh.indices.resize(indexCount);
|
||||||
|
mesh.textureCoordinates.resize(vertexCount);
|
||||||
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < text.length(); i++)
|
for(unsigned int i = 0; i < text.length(); i++)
|
||||||
{
|
{
|
||||||
float baseXCoordinate = float(i) * characterWidth;
|
float baseXCoordinate = float(i) * characterWidth;
|
||||||
|
float baseXTexture = float(text[i]) * textureWidth;
|
||||||
|
|
||||||
mesh.vertices.at(4 * i + 0) = {baseXCoordinate, 0, 0};
|
mesh.vertices.at(4 * i + 0) = {baseXCoordinate, 0, 0};
|
||||||
mesh.vertices.at(4 * i + 1) = {baseXCoordinate + characterWidth, 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 + 2) = {baseXCoordinate + characterWidth, characterHeight, 0};
|
||||||
|
@ -32,7 +36,17 @@ Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth
|
||||||
mesh.indices.at(6 * i + 3) = 4 * i + 0;
|
mesh.indices.at(6 * i + 3) = 4 * i + 0;
|
||||||
mesh.indices.at(6 * i + 4) = 4 * i + 2;
|
mesh.indices.at(6 * i + 4) = 4 * i + 2;
|
||||||
mesh.indices.at(6 * i + 5) = 4 * i + 3;
|
mesh.indices.at(6 * i + 5) = 4 * i + 3;
|
||||||
|
|
||||||
|
|
||||||
|
mesh.textureCoordinates.at(4 * i + 0) = {baseXTexture, 0};
|
||||||
|
mesh.textureCoordinates.at(4 * i + 1) = {baseXTexture + textureWidth, 0};
|
||||||
|
mesh.textureCoordinates.at(4 * i + 2) = {baseXTexture + textureWidth, 1};
|
||||||
|
|
||||||
|
mesh.textureCoordinates.at(4 * i + 0) = {baseXTexture, 0};
|
||||||
|
mesh.textureCoordinates.at(4 * i + 2) = {baseXTexture + textureWidth, 1};
|
||||||
|
mesh.textureCoordinates.at(4 * i + 3) = {baseXTexture, 1};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <program.hpp>
|
#include <program.hpp>
|
||||||
#include "glutils.h"
|
#include "glutils.h"
|
||||||
|
|
||||||
unsigned int generateBuffer(Mesh &mesh) {
|
unsigned int generateBuffer(Mesh &mesh, bool isNormalMapped) {
|
||||||
unsigned int vaoID;
|
unsigned int vaoID;
|
||||||
glGenVertexArrays(1, &vaoID);
|
glGenVertexArrays(1, &vaoID);
|
||||||
glBindVertexArray(vaoID);
|
glBindVertexArray(vaoID);
|
||||||
|
@ -26,6 +26,93 @@ unsigned int generateBuffer(Mesh &mesh) {
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(unsigned int), mesh.indices.data(), GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(unsigned int), mesh.indices.data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
if (mesh.textureCoordinates.empty()) return vaoID;
|
||||||
|
|
||||||
|
unsigned int textureBufferID;
|
||||||
|
glGenBuffers(1, &textureBufferID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, textureBufferID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, mesh.textureCoordinates.size() * sizeof(glm::vec2), mesh.textureCoordinates.data(), GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
|
if (isNormalMapped) addTangents(vaoID, mesh);
|
||||||
|
|
||||||
return vaoID;
|
return vaoID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addTangents(unsigned int vaoID, Mesh& mesh) {
|
||||||
|
glm::vec3 tangents[mesh.vertices.size()];
|
||||||
|
glm::vec3 bitangents[mesh.vertices.size()];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mesh.indices.size(); i+=3) {
|
||||||
|
const glm::vec3& pos1 = mesh.vertices[mesh.indices[i+0]];
|
||||||
|
const glm::vec3& pos2 = mesh.vertices[mesh.indices[i+1]];
|
||||||
|
const glm::vec3& pos3 = mesh.vertices[mesh.indices[i+2]];
|
||||||
|
|
||||||
|
const glm::vec2& uv1 = mesh.textureCoordinates[mesh.indices[i+0]];
|
||||||
|
const glm::vec2& uv2 = mesh.textureCoordinates[mesh.indices[i+1]];
|
||||||
|
const glm::vec2& uv3 = mesh.textureCoordinates[mesh.indices[i+2]];
|
||||||
|
|
||||||
|
glm::vec3 edge1 = pos2 - pos1;
|
||||||
|
glm::vec3 edge2 = pos3 - pos1;
|
||||||
|
glm::vec2 deltaUV1 = uv2 - uv1;
|
||||||
|
glm::vec2 deltaUV2 = uv3 - uv1;
|
||||||
|
|
||||||
|
float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
|
||||||
|
|
||||||
|
glm::vec3 tangent, bitangent;
|
||||||
|
tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
|
||||||
|
tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
|
||||||
|
tangent.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z);
|
||||||
|
|
||||||
|
bitangent.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x);
|
||||||
|
bitangent.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y);
|
||||||
|
bitangent.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z);
|
||||||
|
|
||||||
|
tangent = glm::normalize(tangent);
|
||||||
|
bitangent = glm::normalize(bitangent);
|
||||||
|
|
||||||
|
// handedness
|
||||||
|
tangents[i+0] = -tangent;
|
||||||
|
tangents[i+1] = -tangent;
|
||||||
|
tangents[i+2] = -tangent;
|
||||||
|
bitangents[i+0] = -bitangent;
|
||||||
|
bitangents[i+1] = -bitangent;
|
||||||
|
bitangents[i+2] = -bitangent;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(vaoID);
|
||||||
|
|
||||||
|
unsigned int tangentBufferID;
|
||||||
|
glGenBuffers(1, &tangentBufferID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, tangentBufferID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(glm::vec3), tangents, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
|
|
||||||
|
unsigned int bitangentBufferID;
|
||||||
|
glGenBuffers(1, &bitangentBufferID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bitangentBufferID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(glm::vec3), bitangents, GL_STATIC_DRAW);
|
||||||
|
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
|
||||||
|
glEnableVertexAttribArray(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int generateTexture(PNGImage& texture) {
|
||||||
|
unsigned int id;
|
||||||
|
glGenTextures(1, &id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
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_RGBA, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.pixels.data());
|
||||||
|
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.pixels.data());
|
||||||
|
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
|
#include "imageLoader.hpp"
|
||||||
|
|
||||||
unsigned int generateBuffer(Mesh &mesh);
|
|
||||||
|
unsigned int generateBuffer(Mesh &mesh, bool isNormalMapped = false);
|
||||||
|
|
||||||
|
void addTangents(unsigned int vaoID, Mesh& mesh);
|
||||||
|
|
||||||
|
unsigned int generateTexture(PNGImage& texture);
|
||||||
|
|
|
@ -38,4 +38,4 @@ PNGImage loadPNGFile(std::string fileName)
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,4 @@ struct Mesh {
|
||||||
std::vector<glm::vec2> textureCoordinates;
|
std::vector<glm::vec2> textureCoordinates;
|
||||||
|
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue