Overlay a transparent meme over the crate texture.
This commit is contained in:
parent
7eeaa0fa42
commit
c591275bd1
10 changed files with 75 additions and 36 deletions
BIN
src/awesomeface.png
Normal file
BIN
src/awesomeface.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
|
@ -5,8 +5,9 @@ out vec4 FragColor;
|
||||||
in vec3 ourColor;
|
in vec3 ourColor;
|
||||||
in vec2 TexCoord;
|
in vec2 TexCoord;
|
||||||
|
|
||||||
uniform sampler2D ourTexture;
|
uniform sampler2D texture1;
|
||||||
|
uniform sampler2D texture2;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
FragColor = texture(ourTexture, TexCoord);
|
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "image.hh"
|
#include "image.hh"
|
||||||
#include <stb/stb_image.h>
|
#include <stb/stb_image.h>
|
||||||
|
|
||||||
Image::Image(const char* path) {
|
Image::Image(std::string path) {
|
||||||
data = stbi_load(path, &width, &height, &nrChannels, 0);
|
stbi_set_flip_vertically_on_load(true);
|
||||||
|
data = stbi_load(path.c_str(), &width, &height, &nrChannels, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::~Image() {
|
Image::~Image() {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#ifndef IMAGE_HH
|
#ifndef IMAGE_HH
|
||||||
#define IMAGE_HH
|
#define IMAGE_HH
|
||||||
|
#include <string>
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
class Image {
|
class Image {
|
||||||
public:
|
public:
|
||||||
int width, height, nrChannels;
|
int width, height, nrChannels;
|
||||||
unsigned char* data;
|
unsigned char* data;
|
||||||
Image(const char* path);
|
Image(std::string path);
|
||||||
~Image();
|
~Image();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
59
src/main.cc
59
src/main.cc
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "shader.hh"
|
#include "shader.hh"
|
||||||
#include "utilities.hh"
|
#include "utilities.hh"
|
||||||
|
@ -134,6 +135,7 @@ GlRenderObjects* rectangle() {
|
||||||
int main() {
|
int main() {
|
||||||
glfwInit();
|
glfwInit();
|
||||||
|
|
||||||
|
{
|
||||||
// Set OpenGL version to 3.3.
|
// Set OpenGL version to 3.3.
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
@ -162,22 +164,23 @@ int main() {
|
||||||
std::string currentPath = utilities::getCurrentPath();
|
std::string currentPath = utilities::getCurrentPath();
|
||||||
|
|
||||||
// Create a shader class.
|
// Create a shader class.
|
||||||
Shader* shader = new Shader(std::format("{}/vertex.glsl", currentPath).c_str(), std::format("{}/fragment.glsl", currentPath).c_str());
|
Shader shader(std::format("{}/vertex.glsl", currentPath).c_str(), std::format("{}/fragment.glsl", currentPath).c_str());
|
||||||
|
|
||||||
GlRenderObjects* triangleRenderObjs = triangle();
|
std::unique_ptr<GlRenderObjects> triangleRenderObjs(triangle());
|
||||||
GlRenderObjects* rectangleRenderObjs = rectangle();
|
std::unique_ptr<GlRenderObjects> rectangleRenderObjs(rectangle());
|
||||||
|
|
||||||
unsigned int texture;
|
unsigned int texture1, texture2;
|
||||||
glGenTextures(1, &texture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
{
|
||||||
|
glGenTextures(1, &texture1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
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_WRAP_T, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
{
|
Image texture(utilities::getCurrentPath("container.jpg"));
|
||||||
Image texture(std::format("{}/container.jpg", utilities::getCurrentPath()).c_str());
|
|
||||||
if (texture.data) {
|
if (texture.data) {
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture.width, texture.height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture.data);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture.width, texture.height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture.data);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
@ -186,6 +189,32 @@ int main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
glGenTextures(1, &texture2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture2);
|
||||||
|
|
||||||
|
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);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
Image texture(utilities::getCurrentPath("awesomeface.png"));
|
||||||
|
|
||||||
|
if (texture.data) {
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
} else {
|
||||||
|
std::cout << "Failed to load texture." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// activate the shader
|
||||||
|
shader.activate();
|
||||||
|
|
||||||
|
// tell the shader what texture unit the textures are on
|
||||||
|
shader.setInt("texture1", 0);
|
||||||
|
shader.setInt("texture2", 1);
|
||||||
|
|
||||||
// Create a render loop, which keeps the program open until glfw tells the loop that the window should close.
|
// Create a render loop, which keeps the program open until glfw tells the loop that the window should close.
|
||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
// Process input.
|
// Process input.
|
||||||
|
@ -198,8 +227,12 @@ int main() {
|
||||||
// Clear the screen and use the color from the state.
|
// Clear the screen and use the color from the state.
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
// activate the shader
|
glActiveTexture(GL_TEXTURE0);
|
||||||
shader->activate();
|
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture2);
|
||||||
|
|
||||||
|
shader.activate();
|
||||||
|
|
||||||
if (!rectangleToggled) {
|
if (!rectangleToggled) {
|
||||||
// Bind the state to use the vertexArrayObject object so OpenGL knows what to do with the verticies.
|
// Bind the state to use the vertexArrayObject object so OpenGL knows what to do with the verticies.
|
||||||
|
@ -219,11 +252,7 @@ int main() {
|
||||||
// Check if any events are triggered.
|
// Check if any events are triggered.
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Clean up objects from memory.
|
|
||||||
delete triangleRenderObjs;
|
|
||||||
delete rectangleRenderObjs;
|
|
||||||
delete shader;
|
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -10,6 +10,7 @@ copy = find_program('cp')
|
||||||
fragment = custom_target('fragment', output: 'fragment.glsl', input: 'fragment.glsl', command: [copy, '@INPUT@', '@OUTPUT@'])
|
fragment = custom_target('fragment', output: 'fragment.glsl', input: 'fragment.glsl', command: [copy, '@INPUT@', '@OUTPUT@'])
|
||||||
vertex = custom_target('vertex', output: 'vertex.glsl', input: 'vertex.glsl', command: [copy, '@INPUT@', '@OUTPUT@'])
|
vertex = custom_target('vertex', output: 'vertex.glsl', input: 'vertex.glsl', command: [copy, '@INPUT@', '@OUTPUT@'])
|
||||||
container = custom_target('container', output: 'container.jpg', input: 'container.jpg', command: [copy, '@INPUT@', '@OUTPUT@'])
|
container = custom_target('container', output: 'container.jpg', input: 'container.jpg', command: [copy, '@INPUT@', '@OUTPUT@'])
|
||||||
|
awesomeface = custom_target('awesomeface', output: 'awesomeface.png', input: 'awesomeface.png', command: [copy, '@INPUT@', '@OUTPUT@'])
|
||||||
|
|
||||||
executable('main', [sources] + [fragment, vertex, container], dependencies: [glfw, libepoxy])
|
executable('main', [sources, fragment, vertex, container, awesomeface], dependencies: [glfw, libepoxy])
|
||||||
executable('fixedfunction', ['fixedfunction.cc'], dependencies: [glfw, libepoxy])
|
executable('fixedfunction', ['fixedfunction.cc'], dependencies: [glfw, libepoxy])
|
||||||
|
|
|
@ -94,12 +94,12 @@ void Shader::activate() {
|
||||||
glUseProgram(id);
|
glUseProgram(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::setBool(const std::string &name, bool value) const {
|
void Shader::setBool(const char* name, bool value) const {
|
||||||
glUniform1f(glGetUniformLocation(id, name.c_str()), (int)value);
|
glUniform1i(glGetUniformLocation(id, name), (int)value);
|
||||||
}
|
}
|
||||||
void Shader::setInt(const std::string &name, int value) const {
|
void Shader::setInt(const char* name, int value) {
|
||||||
glUniform1f(glGetUniformLocation(id, name.c_str()), value);
|
glUniform1i(glGetUniformLocation(id, name), value);
|
||||||
}
|
}
|
||||||
void Shader::setFloat(const std::string &name, float value) const {
|
void Shader::setFloat(const char* name, float value) const {
|
||||||
glUniform1f(glGetUniformLocation(id, name.c_str()), value);
|
glUniform1f(glGetUniformLocation(id, name), value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ class Shader {
|
||||||
// activate the shader.
|
// activate the shader.
|
||||||
void activate();
|
void activate();
|
||||||
// utility uniform functions
|
// utility uniform functions
|
||||||
void setBool(const std::string &name, bool value) const;
|
void setBool(const char* name, bool value) const;
|
||||||
void setInt(const std::string &name, int value) const;
|
void setInt(const char* name, int value) ;
|
||||||
void setFloat(const std::string &name, float value) const;
|
void setFloat(const char* name, float value) const;
|
||||||
private:
|
private:
|
||||||
uint compileShader(std::string code, GLenum type, std::string shaderTypeName);
|
uint compileShader(std::string code, GLenum type, std::string shaderTypeName);
|
||||||
uint compileVertexShader(std::string code);
|
uint compileVertexShader(std::string code);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
std::string utilities::getCurrentPath() {
|
std::string utilities::getCurrentPath() {
|
||||||
char result[PATH_MAX];
|
char result[PATH_MAX];
|
||||||
|
@ -14,6 +15,10 @@ std::string utilities::getCurrentPath() {
|
||||||
return utilities::combineString(stringVector, '/');
|
return utilities::combineString(stringVector, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string utilities::getCurrentPath(std::string file) {
|
||||||
|
return std::format("{}/{}", getCurrentPath(), file);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> utilities::splitString(std::string string, char delimiter) {
|
std::vector<std::string> utilities::splitString(std::string string, char delimiter) {
|
||||||
size_t last = 0;
|
size_t last = 0;
|
||||||
size_t next = 0;
|
size_t next = 0;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
namespace utilities {
|
namespace utilities {
|
||||||
std::string getCurrentPath();
|
std::string getCurrentPath();
|
||||||
|
std::string getCurrentPath(std::string file);
|
||||||
std::vector<std::string> splitString(std::string string, char delimiter);
|
std::vector<std::string> splitString(std::string string, char delimiter);
|
||||||
std::string combineString(std::vector<std::string> stringVector, char delimiter);
|
std::string combineString(std::vector<std::string> stringVector, char delimiter);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue