简体   繁体   中英

How to use fragment shader with an image

I'm trying to perform simple color correction operations using GLSL(orange book).

I'm struggling to apply the shaders to images. This is my fragment shader to adjust saturation, stolen from the Orange book. I don't understand how to use this with an image?

const vec3 lumCoeff = vec3(0.2125,0.7154,0.0721);
uniform float Alpha;

void main()
{
    vec3 intensity = vec3(dot(gl_Color.rgb, lumCoeff));
    vec3 color = mix(intensity, gl_color.rgb, Alpha);
    gl_FragColor = vec4(color, 1.0);
}

And then my vertex shader is

void main(void)
{
    gl_Position = ftransform();
}

I've been trying to read an image in using OpenCv and then I use glTexImage2d to turn it into a texture but, I dont understand how shaders are used in OpenGL and C++.

When and how do I apply the shaders to the images?

Here is the code I am trying to run.

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

//#include <GL/glew.h>
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include "textfile.h"

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#define VIEWPORT_WIDTH              320 // 1280
#define VIEWPORT_HEIGHT             320 // 800

IplImage *Image;
static GLuint texName;
GLuint v,f,f2,p;
float lpos[4] = {1,0.5,1,0};

void changeSize(int w, int h) {

    // Prevent a divide by zero, when window is too short
    // (you cant make a window of zero width).
    if(h == 0)
        h = 1;

    float ratio = 1.0* w / h;

    // Reset the coordinate system before modifying
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // Set the viewport to be the entire window
    glViewport(0, 0, w, h);

    // Set the correct perspective.
    gluPerspective(45,ratio,1,1000);
    glMatrixMode(GL_MODELVIEW);


}


void renderScene(void) {

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);

    glGenTextures(1, &texName);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texName);

    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_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glPixelStorei (GL_UNPACK_ALIGNMENT,  Image->align);
    glPixelStorei (GL_UNPACK_ROW_LENGTH, Image->widthStep / Image->nChannels);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, Image->width, Image->height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->imageData);
    glViewport(0, 0, VIEWPORT_WIDTH , VIEWPORT_HEIGHT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, VIEWPORT_WIDTH , 0, VIEWPORT_HEIGHT, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    glBindTexture(GL_TEXTURE_2D, texName);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
    glTexCoord2f(0, 1); glVertex3f(0, VIEWPORT_HEIGHT, 0);
    glTexCoord2f(1, 1); glVertex3f(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0);
    glTexCoord2f(1, 0); glVertex3f(VIEWPORT_WIDTH, 0, 0);
    char *vs = NULL,*fs = NULL,*fs2 = NULL;

    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);
    //f2 = glCreateShader(GL_FRAGMENT_SHADER);


    vs = textFileRead("toon.vert");
    fs = textFileRead("toon.frag");
    //fs2 = textFileRead("toon2.frag");

    const char * ff = fs;
    //const char * ff2 = fs2;
    const char * vv = vs;

    glShaderSource(v, 1, &vv,NULL);
    glShaderSource(f, 1, &ff,NULL);
    //glShaderSource(f2, 1, &ff2,NULL);

    free(vs);free(fs);

    glCompileShader(v);
    glCompileShader(f);
    //glCompileShader(f2);

    p = glCreateProgram();
    glAttachShader(p,f);
    //glAttachShader(p,f2);
    glAttachShader(p,v);

    glLinkProgram(p);
    glUseProgram(p);
    glEnd();
    glFlush();
    glDisable(GL_TEXTURE_2D);

    // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // glLoadIdentity();
    // gluLookAt(0.0,0.0,5.0, 
    //        0.0,0.0,-1.0,
    //        0.0f,1.0f,0.0f);

    // glLightfv(GL_LIGHT0, GL_POSITION, lpos);
    // glutSolidTeapot(1);

    glutSwapBuffers();
}

void processNormalKeys(unsigned char key, int x, int y) {

    if (key == 27) 
        exit(0);
}


void setShaders() {

    char *vs = NULL,*fs = NULL,*fs2 = NULL;

    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);
    //f2 = glCreateShader(GL_FRAGMENT_SHADER);


    vs = textFileRead("toon.vert");
    fs = textFileRead("toon.frag");
    //fs2 = textFileRead("toon2.frag");

    const char * ff = fs;
    //const char * ff2 = fs2;
    const char * vv = vs;

    glShaderSource(v, 1, &vv,NULL);
    glShaderSource(f, 1, &ff,NULL);
    //glShaderSource(f2, 1, &ff2,NULL);

    free(vs);free(fs);

    glCompileShader(v);
    glCompileShader(f);
    //glCompileShader(f2);

    p = glCreateProgram();
    glAttachShader(p,f);
    //glAttachShader(p,f2);
    glAttachShader(p,v);

    glLinkProgram(p);
    glUseProgram(p);
}


int main(int argc, char **argv) {

    Image = cvLoadImage("lena.tiff",1);

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("MM 2004-05");

    glutDisplayFunc(renderScene);
    glutIdleFunc(renderScene);
    glutReshapeFunc(changeSize);
    glutKeyboardFunc(processNormalKeys);

    glEnable(GL_DEPTH_TEST);
    glClearColor(1.0,1.0,1.0,1.0);
//  glEnable(GL_CULL_FACE);

    // glewInit();
    // if (glewIsSupported("GL_VERSION_2_0"))
    //  printf("Ready for OpenGL 2.0\n");
    // else {
    //  printf("OpenGL 2.0 not supported\n");
    //  exit(1);
    // }
    //setShaders();

    glutMainLoop();

    // just for compatibiliy purposes
    return 0;
}

You have not passed any uniform sampler to your shader.

Well there are many things that you should notice.

  1. You need not to dump all initialization code in render loop. Your are just killing your program. like this texture generation code. It only needs to execute once. Just move it to some init() function.

     glGenTextures(1, &texName); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texName); 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_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glPixelStorei (GL_UNPACK_ALIGNMENT, Image->align); glPixelStorei (GL_UNPACK_ROW_LENGTH, Image->widthStep / Image->nChannels); glTexImage2D(GL_TEXTURE_2D, 0, 3, Image->width, Image->height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->imageData); 
  2. then this shader program creation, compilation and linking this this is usually done at application start-up and only once. After that you can just call glUseProgram(handle) in your render loop.

     char *vs = NULL,*fs = NULL,*fs2 = NULL; v = glCreateShader(GL_VERTEX_SHADER); f = glCreateShader(GL_FRAGMENT_SHADER); //f2 = glCreateShader(GL_FRAGMENT_SHADER); vs = textFileRead("toon.vert"); fs = textFileRead("toon.frag"); //fs2 = textFileRead("toon2.frag"); const char * ff = fs; //const char * ff2 = fs2; const char * vv = vs; glShaderSource(v, 1, &vv,NULL); glShaderSource(f, 1, &ff,NULL); //glShaderSource(f2, 1, &ff2,NULL); free(vs);free(fs); glCompileShader(v); glCompileShader(f); //glCompileShader(f2); p = glCreateProgram(); glAttachShader(p,f); //glAttachShader(p,f2); glAttachShader(p,v); glLinkProgram(p); 
  3. Its important to check for errors while shader initialization. Follow these excellent tutorials to know how do that.

  4. You need to pass texture that you created using OpenCV as a Uniform Variable to shader. See here to know what uniform variables are.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM