owned this note
owned this note
Published
Linked with GitHub
---
title: code
---
```cpp=
#include <iostream>
#include <cmath>
#include <functional>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <glad/glad.h>
#include <SFML/OpenGL.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
// Vertex Shader
const char *vertexShaderSource = R"glsl(
#version 450 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aVertColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 VertColor;
out vec2 TexCoord;
uniform mat4 vTransform;
void main()
{
gl_Position = vTransform * vec4(aPos, 1.0);
TexCoord = aTexCoord;
VertColor = aVertColor;
}
)glsl";
// Fragment Shader
const char *fragmentShaderSoucre = R"glsl(
#version 450 core
out vec4 FragColor;
in vec2 TexCoord;
in vec3 VertColor;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform vec4 fColor;
uniform float fMix;
void main()
{
vec4 resultColor = mix(texture(tex1, TexCoord), texture(tex2, TexCoord), fMix) * fColor;
// vec4 resultColor = texture(tex1, TexCoord) * fColor;
FragColor = resultColor;
}
)glsl";
uint32_t LoadShader(GLenum type, const char* src)
{
uint32_t shader;
shader = glCreateShader(type);
glShaderSource(shader, 1, &src, nullptr);
glCompileShader(shader);
int success;
char log[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success)
{
glGetShaderInfoLog(shader, 512, nullptr, log);
printf("Error Shader %s compile error\n%s\n", type == GL_VERTEX_SHADER ? "Vertex" : "Fragment", log);
return 0;
}
return shader;
}
uint32_t LinkShaderProgram(uint32_t vertex, uint32_t fragment)
{
uint32_t program = glCreateProgram();
glAttachShader(program, vertex);
glAttachShader(program, fragment);
glLinkProgram(program);
//
int success;
char log[512];
glGetProgramiv(program, GL_LINK_STATUS, &success);
if(!success)
{
glGetProgramInfoLog(program, 512, nullptr, log);
printf("Error Shader Linking error\n%s\n", log);
return 0;
}
return program;
}
float vertices[] = {
// ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 -
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // 右上
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // 左下
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // 左上
};
uint32_t indices[] = {
0, 1, 3, // 第一個三角形
1, 2, 3 // 第二個三角形
};
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, sf::ContextSettings(24, 8, 4, 4, 4));
window.setVerticalSyncEnabled(true);
// Load OpenGL functions using glad
if (!gladLoadGL())
{
printf("Something went wrong!\n");
exit(-1);
}
printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION));
ImGui::SFML::Init(window);
window.setActive(true);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Load shader
uint32_t vertexShader = LoadShader(GL_VERTEX_SHADER, vertexShaderSource);
uint32_t fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentShaderSoucre);
uint32_t program;
if(vertexShader && fragmentShader)
{
program = LinkShaderProgram(vertexShader, fragmentShader);
glUseProgram(program);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
else
{
return 1;
}
// Load vertices
// VAO
uint32_t vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// VBO
uint32_t vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// EBO
uint32_t ebo;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Specify Vertex Attribute
uint32_t aPos = glGetAttribLocation(program, "aPos");
glVertexAttribPointer(aPos, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
glEnableVertexAttribArray(aPos);
uint32_t aVertColor = glGetAttribLocation(program, "aVertColor");
glVertexAttribPointer(aVertColor, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(aVertColor);
uint32_t aTexCoord = glGetAttribLocation(program, "aTexCoord");
glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6*sizeof(float)));
glEnableVertexAttribArray(aTexCoord);
// Texture
auto LoadTexture = [&](std::string path) {
sf::Image img;
img.loadFromFile(path);
img.flipVertically();
// generate a texture
uint32_t texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// texture parameter
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.getSize().x, img.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)img.getPixelsPtr());
glGenerateMipmap(GL_TEXTURE_2D);
return texture;
};
uint32_t wall_tex = LoadTexture("1.png");
uint32_t lambda_tex = LoadTexture("3.jpg");
glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "tex1"), 0);
glUniform1i(glGetUniformLocation(program, "tex2"), 1);
sf::Clock deltaClock;
bool running = true;
while (running)
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
running = false;
else if (event.type == sf::Event::Resized)
glViewport(0, 0, event.size.width, event.size.height);
}
// tint
static float tintColor[4] = {1.f, 1.f, 1.f, 1.f};
// mix
static float mix;
static sf::Clock mixClk;
// background color
static float bgColor[4];
// transform
glm::mat4 trans(1.0f); // identity matrix
static float rotate_degree = 90.f;
rotate_degree = fmod(mixClk.getElapsedTime().asMilliseconds()/10, 360);
trans = glm::rotate(trans, glm::radians(rotate_degree), glm::vec3(0.0, 0.0, 1.0));
static glm::vec3 scaler(0.5, 0.5, 0.5);
trans = glm::scale(trans, scaler);
glClearColor(bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 將 wall_tex 綁到 GL_TEXTURE0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, wall_tex);
// 將 lambda_tex 綁到 GL_TEXTURE1
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, lambda_tex);
// Upload uniforms
glUseProgram(program);
static int colorLoc = glGetUniformLocation(program, "fColor");
glUniform4f(colorLoc, tintColor[0], tintColor[1], tintColor[2], tintColor[3]);
static int mixLoc = glGetUniformLocation(program, "fMix");
glUniform1f(mixLoc, mix);
static int transformLoc = glGetUniformLocation(program, "vTransform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
//
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
window.display();
}
// release resources...
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &ebo);
glDeleteProgram(program);
return 0;
}
```