繁体   English   中英

如何对图像使用片段着色器

[英]How to use fragment shader with an image

我正在尝试使用GLSL(橙皮书)执行简单的色彩校正操作。

我正在努力将着色器应用于图像。 这是我用来调整饱和度的片段着色器,是从Orange书中偷来的。 我不知道如何在图片中使用它?

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);
}

然后我的顶点着色器是

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

我一直在尝试使用OpenCv读取图像,然后使用glTexImage2d将其转换为纹理,但是,我不了解在OpenGL和C ++中如何使用着色器。

何时以及如何将着色器应用于图像?

这是我要运行的代码。

#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;
}

您尚未将任何统一采样器传递给着色器。

好了,您应该注意很多事情。

  1. 您无需在渲染循环中转储所有初始化代码。 您只是在杀死您的程序。 像这样的纹理生成代码。 它只需要执行一次。 只需将其移动到一些init()函数即可。

     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. 然后,此着色器程序的创建,编译和链接通常是在应用程序启动时完成的,只有一次。 之后,您可以在渲染循环中调用glUseProgram(handle)

     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. 在着色器初始化时检查错误很重要。 遵循这些出色的教程 ,了解如何做。

  4. 您需要将使用OpenCV创建的纹理作为统一变量传递给着色器。 请参阅此处以了解什么是统一变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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