added example opengl shader

This commit is contained in:
shinya 2026-05-20 10:12:35 +02:00
parent 3193a862ec
commit cd9e3cb99b
5 changed files with 9933 additions and 0 deletions

57
shader_example/flake.nix Normal file
View File

@ -0,0 +1,57 @@
{
description = "Simple OpenGL dev/build flake";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
in
{
devShells.${system}.default = pkgs.mkShell {
buildInputs = with pkgs; [
gcc
glfw
glew
];
shellHook = ''
echo "Run:"
echo 'g++ shader.cpp -o test -lglfw -lGLEW -lGL && ./test'
'';
};
packages.${system}.default = pkgs.stdenv.mkDerivation {
pname = "shader";
version = "0.1";
src = ./.;
buildInputs = with pkgs; [
glfw
glew
];
nativeBuildInputs = with pkgs; [
gcc
];
buildPhase = ''
g++ shader.cpp -o shader -lglfw -lGLEW -lGL
'';
installPhase = ''
mkdir -p $out/bin
cp shader $out/bin/
'';
};
apps.${system}.default = {
type = "app";
program = "${self.packages.${system}.default}/bin/shader";
};
};
}

View File

@ -0,0 +1,17 @@
#version 330 core
precision mediump float;
in vec2 uv;
uniform sampler2D texA;
uniform sampler2D texB;
out vec4 outColor;
void main()
{
outColor = abs(
texture(texA, uv) -
texture(texB, uv)
);
}

147
shader_example/shader.cpp Normal file
View File

@ -0,0 +1,147 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include <fstream>
#include <vector>
#include <iostream>
std::string loadFile(const char* path)
{
std::ifstream f(path);
return std::string((std::istreambuf_iterator<char>(f)),
std::istreambuf_iterator<char>());
}
GLuint compile(GLenum t, const std::string& src)
{
GLuint s = glCreateShader(t);
const char* c = src.c_str();
glShaderSource(s, 1, &c, NULL);
glCompileShader(s);
return s;
}
int main()
{
glfwInit();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
GLFWwindow* win = glfwCreateWindow(1,1,"",NULL,NULL);
glfwMakeContextCurrent(win);
glewInit();
// ---------------- LOAD IMAGES ----------------
int w,h,c;
unsigned char* img1 = stbi_load("frame1.jpg",&w,&h,&c,4);
unsigned char* img2 = stbi_load("frame2.jpg",&w,&h,&c,4);
if(!img1 || !img2)
{
std::cout << "image load failed\n";
return 0;
}
// ---------------- TEXTURES ----------------
GLuint texA, texB;
glGenTextures(1,&texA);
glGenTextures(1,&texB);
auto upload = [&](GLuint t, unsigned char* d)
{
glBindTexture(GL_TEXTURE_2D,t);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,d);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_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);
};
upload(texA,img1);
upload(texB,img2);
// ---------------- SHADER ----------------
std::string frag = loadFile("motion.frag");
const char* vs =
"#version 330 core\n"
"layout(location=0) in vec2 pos;\n"
"out vec2 uv;\n"
"void main(){\n"
"uv = pos*0.5+0.5;\n"
"gl_Position = vec4(pos,0,1);\n"
"}";
GLuint v = compile(GL_VERTEX_SHADER,vs);
GLuint f = compile(GL_FRAGMENT_SHADER,frag);
GLuint prog = glCreateProgram();
glAttachShader(prog,v);
glAttachShader(prog,f);
glLinkProgram(prog);
// ---------------- QUAD (FIXED) ----------------
GLuint vao,vbo;
float quad[] = {
-1,-1,
1,-1,
-1, 1,
1, 1
};
glGenVertexArrays(1,&vao);
glBindVertexArray(vao);
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(quad),quad,GL_STATIC_DRAW);
glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(0);
// ---------------- FBO ----------------
GLuint fbo,outTex;
glGenFramebuffers(1,&fbo);
glGenTextures(1,&outTex);
glBindTexture(GL_TEXTURE_2D,outTex);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,w,h,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,outTex,0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "FBO broken\n";
// ---------------- RENDER ----------------
glUseProgram(prog);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texA);
glUniform1i(glGetUniformLocation(prog,"texA"),0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texB);
glUniform1i(glGetUniformLocation(prog,"texB"),1);
glViewport(0,0,w,h);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
// ---------------- READ BACK ----------------
std::vector<unsigned char> out(w*h*4);
glReadPixels(0,0,w,h,GL_RGBA,GL_UNSIGNED_BYTE,out.data());
stbi_write_jpg("frameO.jpg",w,h,4,out.data(),90);
std::cout << "done\n";
}

7988
shader_example/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff