我正在尝试使用GLSL(橙皮书)执行简单的色彩校正操作。
我正在努力将着色器应用于图像。这是我的片段着色器来调整饱和度,从橙色的书偷来的。我不明白如何使用这个图像?
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.0n");
// else {
// printf("OpenGL 2.0 not supportedn");
// exit(1);
// }
//setShaders();
glutMainLoop();
// just for compatibiliy purposes
return 0;
}
你没有传递任何统一采样器到你的着色器
你应该注意很多事情。
-
你不需要在渲染循环中转储所有初始化代码。你只是在扼杀你的程序。像这个纹理生成代码。它只需要执行一次。把它移到某个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);
-
然后这个着色器程序的创建,编译和链接这通常在应用程序启动时完成,只有一次。之后,你可以在渲染循环中调用
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);
-
在着色器初始化时检查错误是很重要的。遵循这些优秀的教程来了解如何做到这一点。
-
你需要将使用OpenCV创建的纹理作为统一变量传递给着色器。看这里知道什么是均匀变量。