Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

now using FBO instead of OpenGL back-buffer

  • Loading branch information...
commit bb7a909245e97852497e3f5c6672aa026e149d66 1 parent 90ab593
Suraj Kurapati authored
Showing with 200 additions and 61 deletions.
  1. +57 −35 board.c
  2. +72 −0 fbo.c
  3. +8 −1 main.c
  4. +0 −1  make.bat
  5. +37 −12 naive.cg
  6. +26 −12 texture.c
View
92 board.c
@@ -1,39 +1,48 @@
GLuint board__width;
GLuint board__texture;
+GLuint board__display;
+float* board__data;
void board_init(const GLuint aWidth, const GLuint aKnightRow, const GLuint aKnightCol)
{
- unsigned i;
- float* data;
-
board__width = aWidth;
// generate the board data
- if((data = (float*)malloc(4*board__width*board__width*sizeof(float))) == NULL)
+ if((board__data = (float*)malloc(4*board__width*board__width*sizeof(float))) == NULL)
{
- printf("\n*** out of memory allocating data ***\n");
+ printf("\n*** out of memory allocating board__data ***\n");
exit(2);
}
- for (i = 0; i < board__width*board__width*4; i += 4)
+ for (unsigned i = 0; i < board__width*board__width*4; i += 4)
{
- data[i+0] = 0; //(rand() >= (RAND_MAX/4) ? 1.0 : 0.0); // set red
- data[i+1] = 0; // set green
- data[i+2] = 0; // set blue
- data[i+3] = 0; // set alpha
+ board__data[i+0] = 0; //(rand() >= (RAND_MAX/4) ? 1.0 : 0.0); // set red
+ board__data[i+1] = 0; // set green
+ board__data[i+2] = 0; // set blue
+ board__data[i+3] = 0; // set alpha
}
- // set initial position of knight
- // data[(board__width * aKnightRow) + (4 * aKnightCol) + 1] = 1;
- data[1] = 1;
+ // set initial position of knight
+ // board__data[(aKnightRow * board__width) + (aKnightCol * 4) + 0] = 1;
+ board__data[0] = 1;
+
+ // Generate, set up, and bind the texture
+ texture_new(&board__texture, board__width, board__width, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA32F_ARB, NULL);
+
+ // Attach the texture to the framebuffer object
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, board__texture, 0);
- texture_new(&board__texture, board__width, board__width, data);
+ // Check the FBO for completeness
+ fbo_check();
- free(data);
+ // generate texture for board display
+ texture_new(&board__display, board__width, board__width, GL_TEXTURE_2D, GL_RGBA, NULL);
}
void board_fini() {
+ glDeleteTextures(1, &board__display);
glDeleteTextures(1, &board__texture);
+ free(board__data);
}
void board_draw()
@@ -48,39 +57,52 @@ void board_draw()
void board_update()
{
- CGparameter textureCg;
- textureCg = cgGetNamedParameter(cg__fragmentProgram, "aBoard");
-
cgGLEnableProfile(cg__fragmentProfile);
cgGLBindProgram(cg__fragmentProgram);
- // give input to simulation
+ // transfer data to texture
+ texture_load_array(board__texture, GL_TEXTURE_RECTANGLE_ARB, board__width, board__width, board__data);
+
+ // perform computation
+ CGparameter textureCg = cgGetNamedParameter(cg__fragmentProgram, "aBoard");
cgGLSetTextureParameter(textureCg, board__texture);
cgGLEnableTextureParameter(textureCg);
- // GPGPU CONCEPT 4: Viewport-Sized Quad = Data Stream Generator.
- // perform computation
- board_draw();
+ board_draw(); // GPGPU CONCEPT 4: Viewport-Sized Quad = Data Stream Generator.
+
+ cgGLDisableTextureParameter(textureCg);
+ cgGLDisableProfile(cg__fragmentProfile);
- cgGLDisableTextureParameter(textureCg);
- cgGLDisableProfile(cg__fragmentProfile);
-
- // copy results of simulation from back buffer to texture
- glBindTexture(GL_TEXTURE_2D, board__texture);
- glCopyTexSubImage2D(
- GL_TEXTURE_2D, // only choice
- 0, // mipmap level
- 0, 0, // texel offsets in x and y
- 0, 0, // pixel offset from ll corner
- board__width, board__width // width and heigth of sub-image to copy
- );
+ // Read back the results
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ // The glReadBuffer function selects a color buffer source for pixels.
+ // void glReadBuffer(GLenum mode); mode is a color buffer
+
+ // The glReadPixels function reads a block of pixels from the framebuffer.
+ glReadPixels(
+ 0, 0, // GLint x, y The window coordinates of the first pixel that is read from the framebuffer. This location is the lower-left corner of a rectangular block of pixels
+ board__width, // GLsizei width
+ board__width, // GLsizei height
+ GL_RGBA, // GLenum format
+ GL_FLOAT, // GLenum type
+ board__data); // GLvoid *pixels
}
void board_display() {
board_update();
- glBindTexture(GL_TEXTURE_2D, board__texture);
+ /*
+ for(unsigned i = 0; i < board__width*board__width*4; ++i)
+ printf("%6d: %30.15f\n", i % 4 ? i : 0, board__data[i]);
+
+ printf("------");
+ exit(0);
+ */
+
+ fbo_disable(); // render to screen, not the FBO
+ texture_load_array(board__display, GL_TEXTURE_2D, board__width, board__width, board__data);
glEnable(GL_TEXTURE_2D);
board_draw();
glDisable(GL_TEXTURE_2D);
+ fbo_enable();
}
View
72 fbo.c
@@ -0,0 +1,72 @@
+#include <GL/glu.h>
+
+GLuint fbo__id;
+
+void fbo_init(const float aTexWidth, const float aTexHeight) {
+ // create FBO and bind it (that is, use offscreen render target)
+ glGenFramebuffersEXT(1, &fbo__id);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo__id);
+
+ // set viewport for 1:1 pixel to texel mapping
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0, aTexWidth, 0, aTexHeight);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glViewport(0, 0, aTexWidth, aTexHeight);
+}
+
+void fbo_fini() {
+ glDeleteFramebuffersEXT(1, &fbo__id);
+}
+
+void fbo_enable() {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo__id);
+}
+
+void fbo_disable() {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+}
+
+void fbo_check() {
+ switch(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT))
+ {
+ case GL_FRAMEBUFFER_COMPLETE_EXT:
+ printf("Framebuffer ok\n");
+ break;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+ printf("Framebuffer incomplete, incomplete attachment\n");
+ exit(EXIT_FAILURE);
+
+ case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ printf("Unsupported framebuffer format\n");
+ exit(EXIT_FAILURE);
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+ printf("Framebuffer incomplete, missing attachment\n");
+ exit(EXIT_FAILURE);
+
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+ printf("Framebuffer incomplete, attached images must have "
+ "same dimensions\n");
+ exit(EXIT_FAILURE);
+
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+ printf("Framebuffer incomplete, attached images must have "
+ "same format\n");
+ exit(EXIT_FAILURE);
+
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+ printf("Framebuffer incomplete, missing draw buffer\n");
+ exit(EXIT_FAILURE);
+
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+ printf("Framebuffer incomplete, missing read buffer\n");
+ exit(EXIT_FAILURE);
+
+ default:
+ printf("*** Unknown framebuffer status! ***\n");
+ exit(EXIT_FAILURE);
+ }
+}
View
9 main.c
@@ -8,12 +8,14 @@
#include <stdlib.h>
#include <assert.h>
+#include "glew.c"
#include "glut.c"
#include "cg.c"
+#include "fbo.c"
#include "texture.c"
#include "board.c"
-#define SIZE 512
+#define SIZE 8
void main_display(void)
{
@@ -26,6 +28,9 @@ int main(int argc, char **argv)
// set up
glut_init(argc, argv, "Knight's Tour in Cg", SIZE, SIZE);
+ glew_init();
+ fbo_init(SIZE, SIZE);
+
cg_init();
cg_register_fragment_program("naive.cg", "main");
@@ -37,6 +42,8 @@ int main(int argc, char **argv)
// tear down
board_fini();
cg_fini();
+ fbo_fini();
+ glew_fini();
return 0;
}
View
1  make.bat
@@ -9,7 +9,6 @@ call "C:\Program Files\Microsoft Visual Studio\VC98\Bin\vcvars32.bat"
rem compile the C program
cl /nologo /TP /MTd /W3 /GX /Od /I "C:\Program Files\NVIDIA Corporation\Cg\include" /I "C:\Documents and Settings\All Users\glew\include" /D GLEW_STATIC /D WIN32 /D _DEBUG /D _CONSOLE /D _MBCS /GZ /c %src%.c
-
rem link the C program
link /nologo /subsystem:console /debug /machine:I386 /out:%src%.exe %src%.obj /pdbtype:sept kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /libpath:"C:\Program Files\NVIDIA Corporation\Cg\lib" cg.lib cgGL.lib /libpath:"C:\Documents and Settings\All Users\glew\lib" glew32s.lib /NODEFAULTLIB:"libc"
View
49 naive.cg
@@ -14,20 +14,45 @@
// bl br
//
float4 main(
- uniform sampler2D aBoard,
- half2 iPos: TEX0
+ uniform samplerRECT aBoard,
+ half2 iPos: WPOS
) : COLOR
{
- static const half offset = 1.0 / 512.0;
- float4 s = tex2D(aBoard, iPos);
- float4 tl = tex2D(aBoard, iPos + half2(-offset, -offset*2));
- float4 tr = tex2D(aBoard, iPos + half2( offset, -offset*2));
- float4 bl = tex2D(aBoard, iPos + half2(-offset, offset*2));
- float4 br = tex2D(aBoard, iPos + half2( offset, offset*2));
- float4 rt = tex2D(aBoard, iPos + half2( offset*2, -offset));
- float4 rb = tex2D(aBoard, iPos + half2( offset*2, offset));
- float4 lt = tex2D(aBoard, iPos + half2(-offset*2, -offset));
- float4 lb = tex2D(aBoard, iPos + half2(-offset*2, offset));
+ // relative pixel offsets for neighboring cells
+ static const half2
+ POS_TL = half2(-1, -2),
+ POS_TR = half2( 1, -2),
+ POS_BL = half2(-1, 2),
+ POS_BR = half2( 1, 2),
+ POS_RT = half2( 2, -1),
+ POS_RB = half2( 2, 1),
+ POS_LT = half2(-2, -1),
+ POS_LB = half2(-2, 1)
+ ;
+
+ // encoding of neighboring positions as
+ // [0,1] clamped floating point numbers
+ static const half
+ MOVE_TL = 0.8,
+ MOVE_TR = 0.7,
+ MOVE_BL = 0.6,
+ MOVE_BR = 0.5,
+ MOVE_RT = 0.4,
+ MOVE_RB = 0.3,
+ MOVE_LT = 0.2,
+ MOVE_LB = 0.1,
+ MOVE_NONE = 0.0
+ ;
+
+ float4 s = texRECT(aBoard, iPos);
+ float4 tl = texRECT(aBoard, iPos + POS_TL);
+ float4 tr = texRECT(aBoard, iPos + POS_TR);
+ float4 bl = texRECT(aBoard, iPos + POS_BL);
+ float4 br = texRECT(aBoard, iPos + POS_BR);
+ float4 rt = texRECT(aBoard, iPos + POS_RT);
+ float4 rb = texRECT(aBoard, iPos + POS_RB);
+ float4 lt = texRECT(aBoard, iPos + POS_LT);
+ float4 lb = texRECT(aBoard, iPos + POS_LB);
return s;
}
View
38 texture.c
@@ -1,21 +1,20 @@
-void texture_new(GLuint* aTexId, const GLuint aTexWidth, const GLuint aTexHeight, const float* const aTexData) {
+void texture_new(GLuint* aTexId, const GLuint aTexWidth, const GLuint aTexHeight, const GLenum aTexType, const int aTexFormat, const float* const aTexData) {
// generate texture
glGenTextures(1, aTexId);
// bind the texture
- glBindTexture(GL_TEXTURE_2D, *aTexId);
+ glBindTexture(aTexType, *aTexId);
// turn off filtering and set wrap mode
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glTexParameteri(aTexType, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(aTexType, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(aTexType, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(aTexType, GL_TEXTURE_WRAP_T, GL_CLAMP);
// allocate and initialize graphics memory
- glTexImage2D(GL_TEXTURE_2D,
+ glTexImage2D(aTexType,
0, // mipmap level
- GL_RGBA, // format
+ aTexFormat, // format
aTexWidth, // size
aTexHeight,
0, // no border
@@ -24,13 +23,28 @@ void texture_new(GLuint* aTexId, const GLuint aTexWidth, const GLuint aTexHeight
aTexData); // allocate and initialize
}
-void texture_load_framebuffer(const GLuint aTexId, const GLuint aTexWidth, const GLuint aTexHeight) {
- glBindTexture(GL_TEXTURE_2D, aTexId);
+void texture_load_screen(const GLuint aTexId, const GLenum aTexType, const GLuint aTexWidth, const GLuint aTexHeight, const float* const aTexData) {
+ glBindTexture(aTexType, aTexId);
glCopyTexSubImage2D(
- GL_TEXTURE_2D, // only choice
+ aTexType, // only choice
0, // mipmap level
0, 0, // texel offsets in x and y
0, 0, // pixel offset from ll corner
aTexWidth, aTexHeight // width and heigth of sub-image to copy
);
}
+
+void texture_load_array(const GLuint aTexId, const GLenum aTexType, const GLuint aTexWidth, const GLuint aTexHeight, const float* const aTexData) {
+ glBindTexture(aTexType, aTexId);
+ glTexSubImage2D(
+ aTexType, // GLenum target
+ 0, // GLint mipmap level
+ 0, // GLint xoffset in the x direction within the texture array
+ 0, // GLint yoffset in the y direction within the texture array
+ aTexWidth, // GLsizei width of the texture sub-image
+ aTexHeight, // GLsizei height of the texture sub-image
+ GL_RGBA, // GLenum format of the pixel data
+ GL_FLOAT, // GLenum type of the pixel data
+ aTexData // const GLvoid *pixels - A pointer to the image data in mem
+ );
+}
Please sign in to comment.
Something went wrong with that request. Please try again.