Hello,
I would like to implement a very simple program before starting the more advanced one, since I am new in writing shaders. My aim is to write simple constant values to first target using my first program and 2 shaders, then read and use them in the second program using a different shader. I am simply working on the lighthouse flatten shader using 2 teapots. By the way I am taking a little help from a code that I found in internet but it is not working either. My result is always black. If I can not manage this simple one, I can not manage the advanced one. I appreciate if you can check my code. Many thanks in advance. Here is my code:
GLint loc;
GLuint v,f,f2,p,p2;
int s;
int texSize = 320;
GLuint outputTextures[2];
GLuint inputTextures;
GLenum myBuffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
GLuint fb;
float* input;
void setupTexture (GLuint id)
{
glBindTexture(GL_TEXTURE_RECTANGLE_ARB,id);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(v, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,GL_FLOAT_R32_NV,texSize,texSize,0,GL_LUMINANCE,GL_FLOAT,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,100);
glMatrixMode(GL_MODELVIEW);
}
float t = 0;
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0,5.0,5.0,
0.0,0.0,0.0,
0.0f,1.0f,0.0f);
glUniform1f(loc, t);
float color1[4] = {1,0,0,1};
float color2[4] = {1,1,0,1};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color1);
glutSolidTeapot(1);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color2);
glTranslatef(0,1,0);
glutSolidTeapot(1);
t+=0.01;
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("flatten.vert");
fs = textFileRead("flattenBegin.frag");
fs2 = textFileRead("flatten1.frag");
const char * vv = vs;
const char * ff = fs;
const char * ff2 = fs2;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
glShaderSource(f2, 1, &ff2,NULL);
free(vs);
free(fs);
free(fs2);
if(s==1)
{
glCompileShader(v);
glCompileShader(f);
printShaderInfoLog(v);
printShaderInfoLog(f);
p = glCreateProgram();
glAttachShader(p,v);
glAttachShader(p,f);
glLinkProgram(p);
printProgramInfoLog(p);
loc = glGetUniformLocation(p,"time");
}
else if (s==2)
{
glCompileShader(v);
glCompileShader(f2);
printShaderInfoLog(v);
printShaderInfoLog(f2);
p2 = glCreateProgram();
glAttachShader(p2,v);
glAttachShader(p2,f2);
glLinkProgram(p2);
printProgramInfoLog(p2);
loc = glGetUniformLocation(p2,"time");
}
}
int main(int argc, char *argv)
{
input = (float)malloc(texSizetexSizesizeof(float));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("SimpleMRT");
glewInit();
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
glutReshapeFunc(changeSize);
glutKeyboardFunc(processNormalKeys);
glGenTextures (1, &inputTextures);
setupTexture (inputTextures);
glGenTextures (2, outputTextures);
for (int i=0; i<2; i++)
setupTexture (outputTextures[i]);
s = 1;
setShaders();
//Bind output textures
for (int i=0; i<2; i++)
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, myBuffers[i], GL_TEXTURE_RECTANGLE_ARB, outputTextures[i], 0);
checkFramebufferStatus();
glUseProgram(p);
//set render destination
glDrawBuffers(2,myBuffers);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex2f(0.0, 0.0);
glTexCoord2f(texSize, 0.0);
glVertex2f(texSize, 0.0);
glTexCoord2f(texSize, texSize);
glVertex2f(texSize, texSize);
glTexCoord2f(0.0, texSize);
glVertex2f(0.0, texSize);
glEnd();
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
//Read from myBuffers
glReadBuffer(myBuffers[1]);
glReadPixels(0, 0, texSize, texSize, GL_LUMINANCE, GL_FLOAT, input);
//Transfer those read values to the input texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, outputTextures[1]);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB,0,0,0,texSize,texSize,GL_LUMINANCE,GL_FLOAT,input);
s = 2;
setShaders();
glUseProgram(p2);
glUniform1i(glGetUniformLocation(p2, "input"),0);
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glDeleteFramebuffersEXT(1,&fb);
glDeleteTextures(1,&inputTextures);
glDeleteTextures(2,outputTextures);
glEnable(GL_DEPTH_TEST);
glClearColor(1.0,1.0,1.0,1.0);
glutMainLoop();
return 0;
}
VERTEX SHADER:
uniform float time;
void main(void)
{
vec4 v = vec4(gl_Vertex);
v.z = sin(5.0*v.x+time)*0.5;
gl_Position = gl_ModelViewProjectionMatrix * v;
}
FRAGMENT SHADER 1:
#extension GL_ARB_draw_buffers : enable
#extension GL_ARB_texture_rectangle : enable
void main()
{
gl_FragData[1].x = 0.3;
}
FRAGMENT SHADER 2:
#extension GL_ARB_draw_buffers : enable
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect input;
void main(void)
{
vec2 coords = gl_TexCoord[0].xy;
float color = texture2DRect(input, coords).x;
gl_FragColor = color * gl_FrontMaterial.ambient;
}