glcraft Utilisateur confirmé: Rang *****
Messages : 1698 Localisation : Entre l'Espagne, l'Italie, la Suisse, L'allemagne et le RU :P Projet Actuel : Jeu de survie avancé
||--------
| Sujet: Class FBO toute faite Lun 16 Jan 2012 - 0:46 | |
| Bonjour a tous, Actuellement, je travaille sur un projet (qui pourrait être mis en ligne d'ici bientôt ici même ^^) tout en C++. Je travaillais sur plusieurs choses pour le projet dont le FrameBuffer Object qui représente entre autre les surfaces sous Game Maker. Pour faire simple, j'en est fait une Class simplifier qui comprend la gestion de 16 textures, FBO et RBO (render buffer object servant pour le depth test, autrement dit, l'ordre d'affichage) Cette class a été fait rapidement, il se peut qu'il y ait quelques bourdes dans le style d'ecriture, mais en tout cas ca fonctionne impecable. Nécessite glew pourr que ca fonctionne pour l'instant. - FBO.h:
- Code:
-
#ifndef FBO_H #define FBO_H #include <GL/glew.h> //#include <SDL/SDL.h> class CFBO { public: CFBO(int, int, int); ~CFBO(); //void SetTexture(int, GLuint*); GLuint GetTexture(int); void Set(int); void Reset(); int GetnFBO(); protected: int nfbo; GLuint tex[16], rbo[16], fbo[16], w, h; }; #endif
- FBO.cpp:
- Code:
-
#include "FBO.h" CFBO::CFBO(int nb, int width, int height) { /*Constructeur de la Class CFBO nb représente le nombre de FrameBufferObj a créer width et height sont les dimensions qui sont respectivement largeur et hauteur Il faut savoir que nb FrameBufferObj seront crée a la même dimension width*height*/ ///GENERATION glGenTextures(nb, tex); glGenFramebuffersEXT(nb, fbo); glGenRenderbuffersEXT(nb, rbo); for(int i=0; i<nb; i++) { ///TEXTURE INIT glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,tex[i]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height,0 , GL_RGB, GL_INT, NULL); /*width et height doivent etre egaux et des puissance de 2. Remplacez GL_TEXTURE_2D par GL_TEXTURE_RECTANGLE_ARB pour pouvoir utiliser des textures avec plus de liberté. Cependant, attention a son utilisation, référencez vous pour l'utilisation de GL_TEXTURE_RECTANGLE_ARB*/ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//si vous voulez un rendu pixelisé comme Minecraft, remplacez GL_LINEAR par GL_NEAREST glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//idem glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); //UNBIND TEXTURE glBindTexture(GL_TEXTURE_2D,0);
///FBO BIND glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[i]); ///Render Buffer BIND & ASSOC -> FBO glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo[i]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); ///ASSIGNATION Texture et Render Buffer glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, tex[i], 0); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, rbo[i]); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } nfbo=nb; w=width; h=height; } CFBO::~CFBO() { /*Destructeur de la Class CFBO Il est très conseillé d'utilisé lorsque vous n'en ayez plus besoin*/ glDeleteFramebuffersEXT(nfbo, fbo); glDeleteRenderbuffersEXT(nfbo, rbo); glDeleteTextures(nfbo, tex); } void CFBO::Set(int i) { /*meme utilisation que surface_set_target() i représente l'id de la texture dans l'instance crée variant de 0 a 15*/ glFlush(); glEnable(GL_TEXTURE_2D); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[i]); glBindTexture(GL_TEXTURE_2D,0); glViewport(0, 0, w, h); } void CFBO::Reset() { /*meme utilisation que surface_set_target() nul besoin de préciser quel id a reset car elle agit sur toute*/ glFlush(); glDisable(GL_TEXTURE_2D); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } GLuint CFBO::GetTexture(int i) { /*Retourne l'id sous forme "GLuint" de la texture d'id i*/ return tex[i]; } int CFBO::GetnFBO() { /*Retourne le nombre de FrameBufferObj que l'on a construit dans le constructeur -> nb*/ return nfbo; }
Je poste un exemple (pas très commenté et non allégé...) pour montrer l'utilisation de la class. Celle ci fait un flou gaussien (un peu lent a cause de GL_BLEND) d'un cube de texture "tex2.png" dans le repertoire du Makefile et de la compilation de projet : Nécessite SDL, glew, sdl_glutils.h (chargement de texture) et les biblioteque d'ecriture dans une console. - main.cpp:
- Code:
-
#include <GL/glew.h> #include <iostream> #include <cstdio> #include <cstdlib> #include <SDL/SDL.h> #include "sdlglutils.h" #include "FBO.h"
///Variable int Largeur=1000, Hauteur=800, FPS=0; int Wfbo=256, Hfbo=256; const SDL_VideoInfo* VideoInfo; char continuer=1; GLuint text; CFBO *FboObj; ///Fonctions int FPSGet(); void FPSControl(float); void drawCube(float x1,float y1,float z1,float x2,float y2,float z2,GLuint tex);
int main(int argc, char** argv) { std::cout<<"Chargement...\n";
SDL_Surface *window; SDL_Init(SDL_INIT_VIDEO); ****("SDL_VIDEO_WINDOW_POS=center"); SDL_WM_SetCaption("Test du FrameBuffer Object",NULL); VideoInfo = SDL_GetVideoInfo(); window = SDL_SetVideoMode(Largeur, Hauteur, 32, SDL_OPENGL|SDL_DOUBLEBUF); GLenum code = glewInit(); text=loadTexture("tex2.png",1); if(code != GLEW_OK) { std::cout<<"erreur glewInit() : "<<code; exit(32); } if (text==NULL) { std::cout<<"erreur Texture non chargée : "<< std::endl; exit(33); } else {std::cout<<"texture : "<<text<<std::endl;} glEnable(GL_DEPTH_TEST);
///Partie FBO GLenum status; status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); SDL_Event event; status==GL_FRAMEBUFFER_COMPLETE_EXT? std::cout << " - FBO supporté - \n": std::cout << " - FBO non supporté - \n Arrété\n"; if (status!=GL_FRAMEBUFFER_COMPLETE_EXT)exit(1);
int taille_max; glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB,&taille_max); std::cout << " Taille max de texture supportée : " << taille_max << std::endl; //GLuint fbo, rbo, texfbo; //FBORenderCreate(1, &fbo, &rbo, &texfbo, 256, 256); std::cout<<"Nouvelle Classe FBO : FboObj"<<std::endl; FboObj = new CFBO(2,Wfbo, Hfbo);
std::cout<<"Chargée\n"; //std::cout << "fbo : " << &fbo << "\ntexture : " << &texfbo1 << std::endl; while (continuer) { SDL_PollEvent(&event); switch (event.type) { case SDL_QUIT: continuer = false; break; case SDL_KEYDOWN: if ((event.key.keysym.sym)==SDLK_ESCAPE) continuer=0; break; } FPS=FPSGet(); char ch[100]; sprintf(ch, "Test du FrameBuffer Object %d FPS", FPS); SDL_WM_SetCaption(ch,NULL ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); //gluPerspective(90,(float)Largeur/Hauteur,0.1f,500); //glFrustum(0,0,HAUTEUR,LARGEUR, 0.1f, 500); //glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); static float xx=0; xx+=0.7;
//FBOSet(); FboObj->Set(0); ///draw 3D ON FBO TEX0 glClearColor(0.0f, 0.5f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
glPushMatrix(); gluPerspective(90, (float)Hfbo/Wfbo,1.0F, 100.0F); gluLookAt(0.0F, 0.0F, 3.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F); glRotatef(xx/5, 1, 0, 0); glRotatef(xx/5, 0, 1, 0); glBindTexture(GL_TEXTURE_2D,text); glColor3f(1.0F,1.0F,1.0F); drawCube(-1,-1,-1,1,1,1,text); glEnd(); glPopMatrix(); //drawCube(-1,-1,-1,1,1,1,0); ///draw 3D OFF FBO TEX0 FboObj->Set(1); ///draw 3D ON FBO TEX1 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix(); gluPerspective(90, (float)Hfbo/Wfbo,1.0F, 100.0F); gluLookAt(0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F);
//glRotatef(90, 0, 1, 0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,FboObj->GetTexture(0));
glEnable(GL_BLEND);glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(1.0F,1.0F,1.0F, 0.1F); glBegin(GL_QUADS); for(int iy=-2;iy<2;iy++) { for(int ix=-2;ix<2;ix++) { glTexCoord2i(0,0); glVertex3f(-1.0F+0.008F*ix,-1.0F+0.008F*iy,0.0001F*(ix+iy*10)); glTexCoord2i(0,1); glVertex3f(-1.0F+0.008F*ix, 1.0F+0.008F*iy,0.0001F*(ix+iy*10)); glTexCoord2i(1,1); glVertex3f( 1.0F+0.008F*ix, 1.0F+0.008F*iy,0.0001F*(ix+iy*10)); glTexCoord2i(1,0); glVertex3f( 1.0F+0.008F*ix,-1.0F+0.008F*iy,0.0001F*(ix+iy*10)); } } glDisable(GL_BLEND); glEnd(); glBindTexture(GL_TEXTURE_2D,0); //drawCube(-1,-1,-1,1,1,1,texfbo); glPopMatrix(); FboObj->Reset(); glViewport(0,0,Largeur, Hauteur); ///draw 3D ON NO-FBO glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); gluPerspective(90, (float)Largeur/Hauteur,1.0F, 100.0F); gluLookAt(0.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F); glColor4f(1.0F,1.0F,1.0F, 1.0F); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,FboObj->GetTexture(1)); glBegin(GL_QUADS); glTexCoord2i(0,0); glVertex3f(-2.0F,-1.0F,0.0F); glTexCoord2i(0,1); glVertex3f(-2.0F, 1.0F,0.0F); glTexCoord2i(1,1); glVertex3f( 0.0F, 1.0F,0.0F); glTexCoord2i(1,0); glVertex3f( 0.0F,-1.0F,0.0F); glEnd(); glPopMatrix(); ///draw 3D OFF NO-FBO
glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glEnable(GL_DEPTH_TEST);
glFlush(); SDL_GL_SwapBuffers(); FPSControl(1230); //XFlush(dpy); } delete FboObj; FboObj=NULL; SDL_Quit(); return 0; } int FPSGet() { static int tcount=0, tP=SDL_GetTicks(), fps=0; tcount++; int tA=SDL_GetTicks(); if (tA-tP>1000.0f) { fps=tcount; tcount=0; tP=tA; } return fps; } void FPSControl(float fps) { static int tP=0; int tA = SDL_GetTicks(); //int _fps=tA - tP; if (tA - tP > (1000.0f/fps)) {tP = tA;} else {SDL_Delay(float(1000.0f/fps) - (tA - tP));}
} void drawCube(float x1,float y1,float z1,float x2,float y2,float z2,GLuint tex) { glBindTexture(GL_TEXTURE_2D, tex); glBegin(GL_QUADS); glTexCoord2d(0,0); glVertex3d(x1,y1,z1); glTexCoord2d(0,1); glVertex3d(x1,y2,z1); glTexCoord2d(1,1); glVertex3d(x2,y2,z1); glTexCoord2d(1,0); glVertex3d(x2,y1,z1);
glTexCoord2d(0,0); glVertex3d(x1,y1,z2); glTexCoord2d(0,1); glVertex3d(x1,y2,z2); glTexCoord2d(1,1); glVertex3d(x2,y2,z2); glTexCoord2d(1,0); glVertex3d(x2,y1,z2);
glTexCoord2d(1,0); glVertex3d(x1,y1,z1); glTexCoord2d(1,1); glVertex3d(x1,y1,z2); glTexCoord2d(0,1); glVertex3d(x2,y1,z2); glTexCoord2d(0,0); glVertex3d(x2,y1,z1);
glTexCoord2d(0,0); glVertex3d(x1,y2,z1); glTexCoord2d(0,1); glVertex3d(x1,y2,z2); glTexCoord2d(1,1); glVertex3d(x2,y2,z2); glTexCoord2d(1,0); glVertex3d(x2,y2,z1);
glTexCoord2d(0,0); glVertex3d(x1,y1,z1); glTexCoord2d(0,1); glVertex3d(x1,y1,z2); glTexCoord2d(1,1); glVertex3d(x1,y2,z2); glTexCoord2d(1,0); glVertex3d(x1,y2,z1);
glTexCoord2d(1,0); glVertex3d(x2,y1,z1); glTexCoord2d(1,1); glVertex3d(x2,y1,z2); glTexCoord2d(0,1); glVertex3d(x2,y2,z2); glTexCoord2d(0,0); glVertex3d(x2,y2,z1); glEnd(); }
Bonne journée a tous ! |
|