Working from ShaderToy (no texture)
[ATTACH=CONFIG]1581[/ATTACH]
C++ Test: Oversized Triangle (no seem reflection)
[ATTACH=CONFIG]1582[/ATTACH]
C++ Test: Quad (triangles seem reflection)
[ATTACH=CONFIG]1583[/ATTACH]
ShaderTest.cpp
//
// code based on https://github.com/yasuohasegawa/OpenGL-Multipass-Shader-Sample
//
#include <GL/glew.h>
#include <GL/glut.h>
#include "ShaderTest.h"
#define TIMER_MS 25
#define CYCLE 1000.0f
#define APP_WIDTH 640
#define APP_HEIGHT 360
static GLuint _s_program1 = 0;
static GLuint _s_program2 = 0;
static GLuint _s_fb = 0;
static GLuint _s_texBuffer = 0;
static GLuint _s_texImage = 0;
static GLuint _s_frame = 0;
void init(){
glewInit();
_s_program1 = loadShader("./shaders/shader.vert","./shaders/ripples1_buffer.frag");
_s_program2 = loadShader("./shaders/shader.vert","./shaders/ripples1_image.frag");
// buffer texture
glGenTextures(1, &_s_texBuffer);
glBindTexture(GL_TEXTURE_2D, _s_texBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, APP_WIDTH, APP_HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
// image buffer
glGenTextures(1, &_s_texImage);
glBindTexture(GL_TEXTURE_2D, _s_texImage);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, APP_WIDTH, APP_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, APP_WIDTH, APP_HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
// fbo
glGenFramebuffers(1, &_s_fb);
glBindFramebuffer(GL_FRAMEBUFFER, _s_fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _s_texBuffer, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void draw_quad(){
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2i(0, 0);
glTexCoord2f(1.0, 0.0); glVertex2i(APP_WIDTH, 0);
glTexCoord2f(1.0, 1.0); glVertex2i(APP_WIDTH, APP_HEIGHT);
glTexCoord2f(0.0, 1.0); glVertex2i(0, APP_HEIGHT);
glEnd();
}
void draw_triangle(){
glBegin(GL_TRIANGLES);
glVertex2i(0, 0);
glVertex2i(0, APP_HEIGHT);
glVertex2i(APP_WIDTH, APP_HEIGHT);
glEnd();
}
void update_shader(){
bool draw_oversized_triangle_instead_of_quad = true;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, APP_WIDTH, APP_HEIGHT);
glOrtho(0, APP_WIDTH, 0, APP_HEIGHT, -1, 1);
if (draw_oversized_triangle_instead_of_quad){
glTranslatef(0.0, -APP_HEIGHT, 0.0);
glScalef(2.0, 2.0, 0.0);
}
// buffer
glBindFramebuffer(GL_FRAMEBUFFER, _s_fb);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _s_texBuffer);
glUseProgram(_s_program1);
glUniform2f(glGetUniformLocation(_s_program1, "iViewportResolution"), (float) APP_WIDTH, (float) APP_HEIGHT);
glUniform1f(glGetUniformLocation(_s_program1, "iTime"), (float) glutGet(GLUT_ELAPSED_TIME) / CYCLE);
glUniform1i(glGetUniformLocation(_s_program1, "iFrame"), _s_frame);
glUniform1i(glGetUniformLocation(_s_program1, "iChannel0"), 0);
if (draw_oversized_triangle_instead_of_quad)
draw_triangle();
else draw_quad();
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// image
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _s_texBuffer);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _s_texImage);
glUseProgram(_s_program2);
glUniform2f(glGetUniformLocation(_s_program2, "iViewportResolution"), (float) APP_WIDTH, (float) APP_HEIGHT);
glUniform1i(glGetUniformLocation(_s_program2, "iChannel0"), 0);
glUniform1i(glGetUniformLocation(_s_program2, "iChannel1"), 1);
if (draw_oversized_triangle_instead_of_quad)
draw_triangle();
else draw_quad();
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
glFlush();
_s_frame++;
}
void timer(int){
update_shader();
glutTimerFunc(TIMER_MS, timer, 0);
}
void display(){}
int main(int argc, char *argv[]){
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(APP_WIDTH, APP_HEIGHT);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow(argv[0]);
glutDisplayFunc(display);
glutTimerFunc(TIMER_MS, timer, 0);
init();
glutMainLoop();
return 0;
}
ShaderTest.h
//
// code based on https://github.com/yasuohasegawa/OpenGL-Multipass-Shader-Sample
//
#include <fstream>
#include <iostream>
int read_shader_file(GLuint shader, const char *name){
int ret;
std::ifstream file(name, std::ios::binary);
if (file.fail()) {
std::cerr << "Can't open file: " << name << std::endl;
ret = -1;
} else {
file.seekg(0L, std::ios::end);
GLsizei length = file.tellg();
const GLchar *source = new GLchar[length];
file.seekg(0L, std::ios::beg);
file.read((char *)source, length);
if (file.bad()) {
std::cerr << "Could not read file: " << name << std::endl;
ret = -1;
} else {
glShaderSource(shader, 1, &source, &length);
ret = 0;
}
delete[] source;
}
return ret;
}
void print_shader_info(GLuint shader){
GLsizei bufSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &bufSize);
if (bufSize > 1) {
GLchar *infoLog;
infoLog = (GLchar *)malloc(bufSize);
if (infoLog != NULL) {
GLsizei length;
glGetShaderInfoLog(shader, bufSize, &length, infoLog);
fprintf(stderr, "InfoLog:
%s
", infoLog);
free(infoLog);
} else fprintf(stderr, "Could not allocate InfoLog buffer.
");
}
}
void print_program_info(GLuint program){
GLsizei bufSize;
glGetProgramiv(program, GL_INFO_LOG_LENGTH , &bufSize);
if (bufSize > 1) {
GLchar *infoLog;
infoLog = (GLchar *)malloc(bufSize);
if (infoLog != NULL) {
GLsizei length;
glGetProgramInfoLog(program, bufSize, &length, infoLog);
fprintf(stderr, "InfoLog:
%s
", infoLog);
free(infoLog);
} else fprintf(stderr, "Could not allocate InfoLog buffer.
");
}
}
GLuint loadShader(const char *vert, const char *frag){
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
if (read_shader_file(vertShader, vert)) exit(1);
if (read_shader_file(fragShader, frag)) exit(1);
GLint compiled, linked;
glCompileShader(vertShader);
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &compiled);
print_shader_info(vertShader);
if (compiled == GL_FALSE) {
fprintf(stderr, "Compile error in vertex shader.
");
exit(1);
}
glCompileShader(fragShader);
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &compiled);
print_shader_info(fragShader);
if (compiled == GL_FALSE) {
fprintf(stderr, "Compile error in fragment shader.
");
exit(1);
}
GLuint gl2Program = glCreateProgram();
glAttachShader(gl2Program, vertShader);
glAttachShader(gl2Program, fragShader);
glDeleteShader(vertShader);
glDeleteShader(fragShader);
glLinkProgram(gl2Program);
glGetProgramiv(gl2Program, GL_LINK_STATUS, &linked);
print_program_info(gl2Program);
if (linked == GL_FALSE) {
fprintf(stderr, "Link error.
");
exit(1);
}
return gl2Program;
}
shader.vert
void main(){
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
ripples1_buffer.frag
// https://www.shadertoy.com/view/4dK3Ww
#version 130
uniform vec2 iViewportResolution;
uniform float iTime; // shader playback time (in seconds)
uniform int iFrame; // shader playback frame
//uniform samplerXX iChannel0..3; // input channel. XX = 2D/Cube
uniform sampler2D iChannel0;
void main(){
vec3 e = vec3(vec2(1.)/iViewportResolution.xy,0.);
vec2 q = gl_FragCoord.xy/iViewportResolution.xy;
vec4 c = texture(iChannel0, q);
float p11 = c.y;
float p10 = texture(iChannel0, q-e.zy).x;
float p01 = texture(iChannel0, q-e.xz).x;
float p21 = texture(iChannel0, q+e.xz).x;
float p12 = texture(iChannel0, q+e.zy).x;
float d = 0.;
// --------------------
// MOUSE CODE REMOVED
// --------------------
//if (iTime >= 2.5 && iTime < 3.0){
// Simulate rain drops
float t = iTime*2.;
vec2 pos = fract(floor(t)*vec2(0.456665,0.708618))*iViewportResolution.xy;
float amp = 1.-step(.05,fract(t));
d = -amp*smoothstep(2.5,.5,length(pos - gl_FragCoord.xy));
//}
// The actual propagation:
d += -(p11-.5)*2. + (p10 + p01 + p21 + p12 - 2.);
d *= .99; // dampening
d *= float(iFrame>=50); // clear the buffer at iFrame < 2
d = d*.5 + .5;
// Put previous state as "y":
gl_FragColor = vec4(d, c.x, 0, 0);
}
ripples1_image.frag
// https://www.shadertoy.com/view/4dK3Ww
#version 130
uniform vec2 iViewportResolution;
uniform vec2 iImageResolution;
//uniform samplerXX iChannel0..3; // input channel. XX = 2D/Cube
uniform sampler2D iChannel0;
uniform sampler2D iChannel1;
void main(){
vec2 q = gl_FragCoord.xy/iViewportResolution.xy;
// -----------------------
// FORCING NON-TEXTURED VERSION
// -----------------------
float h = texture(iChannel0, q).x;
float sh = 1.35 - h*2.;
vec3 c =
vec3(exp(pow(sh-.75,2.)*-10.),
exp(pow(sh-.50,2.)*-20.),
exp(pow(sh-.25,2.)*-10.));
gl_FragColor = vec4(c,1.);
}