#include <stdio.h> #include <stdlib.h> #include <string.h> #include <GL/glew.h> #include <GL/glut.h> GLuint v,f,f2,p; float lpos[4] = {1,0.5,1,0}; GLint loc; GLint uvloc; GLint samp; GLint sach; GLuint textureId; GLuint rboId; GLuint fboId; bool fboUsed; float vertices[8] = {-2,2, 2,2, -2,-2, 2,-2}; float heights[4] = {2,2,-2,-2}; float uvm[8]={0,0,0,1,1,0,1,1}; char *textFileRead(char *fn) { FILE *fp; char *content = NULL; int count=0; if (fn != NULL) { fp = fopen(fn,"rt"); if (fp != NULL) { fseek(fp, 0, SEEK_END); count = ftell(fp); rewind(fp); if (count > 0) { content = (char *)malloc(sizeof(char) * (count+1)); count = fread(content,sizeof(char),count,fp); content[count] = '\0'; } fclose(fp); } } return content; } int textFileWrite(char *fn, char *s) { FILE *fp; int status = 0; if (fn != NULL) { fp = fopen(fn,"w"); if (fp != NULL) { if (fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) status = 1; fclose(fp); } } return(status); } 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); gluLookAt(0.0,5.0,0.0, 0.0,0.0,0.0, 1.0f,0.0f,0.0f); } float a = 0; void renderScene(void) { glBindTexture(GL_TEXTURE_2D, 0); glViewport(0, 0, 512,512); glBindFramebuffer(GL_FRAMEBUFFER, fboId); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_VIEWPORT_BIT); glLoadIdentity(); /*if(a<50) glClearColor(0.02*a,1.0,0.0,1.0);*/ // glClearColor(1.0,0.0,1.0,1.0); gluLookAt(0.0,5.0,0.0, 0.0,0.0,0.0, 1.0f,0.0f,0.0f); //glutSolidTeapot(2.0); //Lightfv(GL_LIGHT0, GL_POSITION, lpos); glUniform1i(samp,0); glUniform1f(sach,1.0f); glRotatef(a,0,1,0); glDrawArrays(GL_TRIANGLE_STRIP,0,4); glPopAttrib(); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT| GL_STENCIL_BUFFER_BIT); //glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, 512,512); glClearColor(0.0,0.0,1.0,1.0); /*glBegin(GL_QUADS); //glMatrixMode(GL_MODELVIEW); //glLoadIdentity(); glColor3f(1, 1, 1); glTexCoord2f(1, 1); glVertex3d( 1, 1, 0); glTexCoord2f(0, 1); glVertex3d(-1, 1, 0); glTexCoord2f(0, 0); glVertex3d(-1, -1, 0); glTexCoord2f(1, 0); glVertex3d( 1, -1, 0); glEnd();*/ // glMatrixMode(GL_MODELVIEW); //glLoadIdentity(); glBindTexture(GL_TEXTURE_2D, textureId); glUniform1i(samp,0); glUniform1f(sach,0.0f); glDrawArrays(GL_TRIANGLE_STRIP,0,4); a+=0.01; glutSwapBuffers(); } void processNormalKeys(unsigned char key, int x, int y) { if (key == 27) exit(0); } #define printOpenGLError() printOglError(__FILE__, __LINE__) int printOglError(char *file, int line) { // // Returns 1 if an OpenGL error occurred, 0 otherwise. // GLenum glErr; int retCode = 0; glErr = glGetError(); while (glErr != GL_NO_ERROR) { printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr)); retCode = 1; glErr = glGetError(); } return retCode; } void printShaderInfoLog(GLuint obj) { int infologLength = 0; int charsWritten = 0; char *infoLog; glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength); if (infologLength > 0) { infoLog = (char *)malloc(infologLength); glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog); printf("%s\n",infoLog); free(infoLog); } } void printProgramInfoLog(GLuint obj) { int infologLength = 0; int charsWritten = 0; char *infoLog; glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength); if (infologLength > 0) { infoLog = (char *)malloc(infologLength); glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog); printf("%s\n",infoLog); free(infoLog); } } 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("height.vert"); fs = textFileRead("height.frag"); const char * vv = vs; const char * ff = fs; glShaderSource(v, 1, &vv,NULL); glShaderSource(f, 1, &ff,NULL); free(vs);free(fs); glCompileShader(v); glCompileShader(f); printShaderInfoLog(v); printShaderInfoLog(f); printShaderInfoLog(f2); p = glCreateProgram(); glAttachShader(p,v); glAttachShader(p,f); glLinkProgram(p); printProgramInfoLog(p); glUseProgram(p); loc = glGetAttribLocation(p,"height"); glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(loc); uvloc = glGetAttribLocation(p,"uvco"); //glEnableClientState(GL_VERTEX_ARRAY); glEnableVertexAttribArray(uvloc); glVertexPointer(2,GL_FLOAT,0,vertices); glVertexAttribPointer(loc,1,GL_FLOAT,0,0,heights); glVertexAttribPointer(uvloc,2,GL_FLOAT,0,0,uvm); samp=glGetUniformLocation(p,"picx"); sach=glGetUniformLocation(p,"sach"); /* glVertexAttrib1f(loc,2.0); glVertex2f(-1,1); glVertexAttrib1f(loc,2.0); glVertex2f(1,1); glVertexAttrib1f(loc,-2.0); glVertex2f(-1,-1); glVertexAttrib1f(loc,-2.0); glVertex2f(1,-1); */ } void initf(){ /* GLubyte texas[128][128][4]; GLubyte blued=230; for(int i=0;i<128;i++) for(int j=0;j<128;j++){ texas[i][j][0]=blued-i; texas[i][j][1]=0; texas[i][j][2]=blued-j; }*/ glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); //glBindTexture(GL_TEXTURE_2D, 0); //glBindTexture(GL_TEXTURE_2D, textureId); // create a renderbuffer object to store depth info glGenRenderbuffers(1, &rboId); glBindRenderbuffer(GL_RENDERBUFFER, rboId); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 512,512); glBindRenderbuffer(GL_RENDERBUFFER, 0); // create a framebuffer object glGenFramebuffers(1, &fboId); glBindFramebuffer(GL_FRAMEBUFFER, fboId); // attach the texture to FBO color attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); // attach the renderbuffer to depth attachment point glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId); // check FBO status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if(status != GL_FRAMEBUFFER_COMPLETE) printf("byfgydzfgh"); // switch back to window-system-provided framebuffer glBindFramebuffer(GL_FRAMEBUFFER, 0); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(512,512); glutCreateWindow("MY FBO"); glutDisplayFunc(renderScene); glutIdleFunc(renderScene); glutReshapeFunc(changeSize); glutKeyboardFunc(processNormalKeys); glEnable(GL_DEPTH_TEST); // glClearColor(0.0,1.0,0.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); } initf(); setShaders(); glutSetCursor(GLUT_CURSOR_DESTROY); glutMainLoop(); return 0; }
走了不少弯路终于做出来了,只是没明白为什么纹理会有一个向黑色的渐变,还可以再完善。