Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Yours3!f

Member Since 04 Feb 2011
Online Last Active Today, 02:06 PM
-----

#4976131 Entropy

Posted by Yours3!f on 03 September 2012 - 12:02 PM

and you can embed it in the iotd by writing down the whole link :)
http://www.youtube.com/watch?v = CgD3y-KqzJo
you only need to give the ID of the video like -->
CgD3y-KqzJo
btw nice game! congrats :D


#4973441 Deferred shading and High Range Definition

Posted by Yours3!f on 26 August 2012 - 04:22 AM

since you're doing deferred LIGHTING - and I assume you know the difference between deferred lighting and deferred shading - therefore you have a nice solution by Cryengine 3. In the CE3 slides it is explained how they did this.
Essentially it goes like this:
1. render opaque geometry to the G-Buffer ( 24 bit depth + 8 bit stencil, RGBA8 rgb for normals, a for specular exponent )
2. do the shading pass (ie. read in the 2 textures, do Blinn-Phong shading based on them, and save the result to 2 textures, RGBA16F for diffuse, RGBA16F for specular )
3. re-render the opaque geometry, read in the 2 RGBA16F textures, use early-z using the depth buffer, and combine the shading result with the material properties (ie. surface diffuse color and surface specular color), plus add the ambient term, save the result into a RGBA16F texture.

use this RGBA16F texture for input for further post-processing.

you usually use this resulting texture for depth of field and bloom/hdr/tonemapping. These are usually dependent on each other, so you don't need to blend.


#4966948 OpenGL 4.3 - compute shaders and much more

Posted by Yours3!f on 07 August 2012 - 03:04 AM

CL/GL interop didn't fail to work. It did work quite well. Despite this I have to admit that it is way more complicated than the DX11 compute shaders, BUT it DID work. In fact I could port DX11 compute shaders to OpenCL and make it work together with OpenGL. see:
http://www.gamedev.n...via-opencl-r233
I'm looking forward to trying out OGL compute shaders though, as it seems more reasonable to use it for processing textures / lighting.
The debugging feature is quite an improvement as such functionality was missing.


#4963060 [HELP] Porting SMAA from Direct3D to OpenGL

Posted by Yours3!f on 25 July 2012 - 02:40 PM

Hi,

I hope this doesn't count as resurrecting old topic :)
SMAA got finally fixed, it now works in OGL/GLSL, you can find the source code here: https://github.com/scrawl/smaa-opengl


#4962650 Cleanup at end of program

Posted by Yours3!f on 24 July 2012 - 10:30 AM

its important to distinguish between ogl resources and other resources. ogl resources get freed automatically when your drawing context is deleted, that is when you call Window::close. You only want to delete them manually if you want to unload resources at runtime, and load something else, like streaming textures. if you have time for it then it is advisable to do manual deleting just for the sake of practicing.
other resources such as cpu side memory are usually freed by your os upon exit, but special oses may not. you still want to delete stuff here though to make sure youre not doing memory leaking.
Edit: the non-annoying way would be to encapsulate your objects in classes and make a on_delete function in each class. then when you react to the sf::Event::Close, just call the on_delete function of each object, then in the end call window.close(). you may want to employ some kind of global class that holds all these objects in some way, so that you can access your objects anywhere in your code. by making your global class lightweight and the actual objects heavyweight you can easily manage memory later (ie. the global object will live until your app is closed, everybody else dies as soon as they get deleted / get out of context).


#4958342 Seriously don't understand WHY my framebuffer isn't rendering as a te...

Posted by Yours3!f on 12 July 2012 - 04:31 AM

So as a further note, is there a debug tool available that can check the contents of textures/video memory? I'm not sure if there is a problem with rendering to a texture or something happening to the texture (somehow) between the render to the framebuffer and the render to the full screen quad

google: gDEBugger


#4958135 Seriously don't understand WHY my framebuffer isn't rendering as a te...

Posted by Yours3!f on 11 July 2012 - 01:30 PM

hi,

here's a tiny little program that does fbos, hope this will help you. (The result you should see is a white triangle)

#include <iostream>

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#undef near
#undef far
#endif

#include "GL/glew.h" //the mighty GLEW <img src='http://public.gamedev.net//public/style_emoticons/default/smile.png' class='bbc_emoticon' alt=':)' />
#include "SFML/Window.hpp"

/*
 * Global variables
 */

sf::Window the_window;
sf::Event the_event;

float fps = 1.0f;
int frames = 0;
sf::Clock the_clock;
std::string app_path;
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

GLuint tex;

GLuint fbo;

/*
 * Function declarations
 */

void get_opengl_error( bool ignore = false );

void draw_quad()
{
  glBegin( GL_QUADS );
  glTexCoord2f( 0, 0 );
  glVertex2f( 0, 0 );
  glTexCoord2f( 1, 0 );
  glVertex2f( 1, 0 );
  glTexCoord2f( 1, 1 );
  glVertex2f( 1, 1 );
  glTexCoord2f( 0, 1 );
  glVertex2f( 0, 1 );
  glEnd();
}

void check_fbo()
{
  if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
  {
    std::cerr << "FBO not complete.\n";
    the_window.close();
    exit( 1 );
  }
}


int main( int argc, char* args[] )
{
  /*
   * Initialize OpenGL context
   */

  the_window.create( sf::VideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 32 ), "FBO", sf::Style::Default );

  if( !the_window.isOpen() )
  {
    std::cerr << "Couldn't initialize SFML.\n";
    the_window.close();
    exit( 1 );
  }

  GLenum glew_error = glewInit();

  if( glew_error != GLEW_OK )
  {
    std::cerr << "Error initializing GLEW: " << glewGetErrorString( glew_error ) << "\n";
    the_window.close();
    exit( 1 );
  }

  if( !GLEW_VERSION_3_3 )
  {
    std::cerr << "Error: OpenGL 3.3 is required\n";
    the_window.close();
    exit( 1 );
  }

  /*
   * Initialize and load textures
   */

  glEnable( GL_TEXTURE_2D );

  glGenTextures( 1, &tex );
  glBindTexture( GL_TEXTURE_2D, tex );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RGBA, GL_FLOAT, 0 );

  get_opengl_error();

  /*
   * Initialize FBOs
   */

  GLenum modes[] = { GL_COLOR_ATTACHMENT0 };

  glGenFramebuffers( 1, &fbo );
  glBindFramebuffer( GL_FRAMEBUFFER, fbo );
  glDrawBuffers( 1, modes );
  glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0 );

  check_fbo();

  glBindFramebuffer( GL_FRAMEBUFFER, 0 );

  glBindTexture( GL_TEXTURE_2D, 0 );

  get_opengl_error();


  /*
   * Set up matrices
   */

  glViewport( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT );
  glMatrixMode( GL_PROJECTION );
  //x_min:0, x_max:1, y_min:0, y_max:1, z_min:0, z_max:-1
  float ortho_matrix[] = { 2, 0, 0, 0,
						   0, 2, 0, 0,
						   0, 0, 2, 0,
						   -1, -1, -1, 1
						 };
  glLoadMatrixf( ortho_matrix );
  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();

  get_opengl_error();

  /*
   * Generate input
   */

  glBindFramebuffer( GL_FRAMEBUFFER, fbo );

  glClearColor( 0, 0, 0, 0 );
  glClear( GL_COLOR_BUFFER_BIT );

  glPushMatrix();
  glTranslatef( 0.5f, 0.5f, 0.0f );
  glBegin( GL_TRIANGLES );
  glColor3f( 1, 1, 1 );
  glVertex2f( -0.25f, -0.25f );
  glVertex2f( 0, 0.25f );
  glVertex2f( 0.25f, -0.25f );
  glEnd();
  glPopMatrix();

  glBindFramebuffer( GL_FRAMEBUFFER, 0 );

  get_opengl_error();

  /*
   * MAIN LOOP
   */

  the_clock.restart();

  glEnable( GL_TEXTURE_2D );

  glActiveTexture( GL_TEXTURE0 );
  glBindTexture( GL_TEXTURE_2D, tex );

  while( true )
  {
    /*
	 * Handle events
	 */

    while( the_window.pollEvent( the_event ) )
    {
	  if( the_event.type == sf::Event::Closed )
	  {
	    the_window.close();
	    exit( 0 );
	  }
    }

    /*
	 * DRAW RESULT
	 */

    draw_quad();

    /*
	 * Show the result
	 */

    the_window.display();

    frames++;

    if( the_clock.getElapsedTime().asMilliseconds() > 1000.0f )
    {
	  int timepassed = the_clock.getElapsedTime().asMilliseconds();
	  fps = 1000.0f / ( ( float ) timepassed / ( float ) frames );
	  std::cout << "FPS: " << fps << " Time: " << ( float ) timepassed / ( float ) frames << "\n";
	  frames = 0;
	  timepassed = 0;
	  the_clock.restart();
    }
  }

  return 0;
}

void get_opengl_error( bool ignore )
{
  bool got_error = false;
  GLenum error = 0;
  error = glGetError();
  std::string errorstring = "";

  while( error != GL_NO_ERROR )
  {
    if( error == GL_INVALID_ENUM )
    {
	  //An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.
	  errorstring += "OpenGL error: invalid enum...\n";
	  got_error = true;
    }

    if( error == GL_INVALID_VALUE )
    {
	  //A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.
	  errorstring += "OpenGL error: invalid value...\n";
	  got_error = true;
    }

    if( error == GL_INVALID_OPERATION )
    {
	  //The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.
	  errorstring += "OpenGL error: invalid operation...\n";
	  got_error = true;
    }

    if( error == GL_STACK_OVERFLOW )
    {
	  //This command would cause a stack overflow. The offending command is ignored and has no other side effect than to set the error flag.
	  errorstring += "OpenGL error: stack overflow...\n";
	  got_error = true;
    }

    if( error == GL_STACK_UNDERFLOW )
    {
	  //This command would cause a stack underflow. The offending command is ignored and has no other side effect than to set the error flag.
	  errorstring += "OpenGL error: stack underflow...\n";
	  got_error = true;
    }

    if( error == GL_OUT_OF_MEMORY )
    {
	  //There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded.
	  errorstring += "OpenGL error: out of memory...\n";
	  got_error = true;
    }

    if( error == GL_TABLE_TOO_LARGE )
    {
	  //The specified table exceeds the implementation's maximum supported table size.  The offending command is ignored and has no other side effect than to set the error flag.
	  errorstring += "OpenGL error: table too large...\n";
	  got_error = true;
    }

    error = glGetError();
  }

  if( got_error && !ignore )
  {
    std::cerr << errorstring;
    the_window.close();
    return;
  }
}





#4948291 Clouds in OpenGL?

Posted by Yours3!f on 11 June 2012 - 02:34 PM

http://lmgtfy.com/?q...cloud rendering
>)

or
http://lmgtfy.com/?q=realtime+cloud+rendering


#4941858 Blinn-Phong with Fresnel effect.

Posted by Yours3!f on 21 May 2012 - 02:34 AM


here's the relevant wiki article:
http://en.wikipedia....s_approximation
here's Schlick's original paper from 1994:
http://www.ics.uci.e...s/Schlick94.pdf
and if you're successful with implementing the Schlick method, then you may proceed to more advanced approximations:
http://en.wikipedia....esnel_equations

so for you I think the fresnel term should be:

//Fresnel approximation
float base = 1-dot(f_viewDirection, halfWay);
float exp = pow(base, 5);
float fresnel = fZero + (1 - fZero)*exp;


I've taken a look at the first article (as well as several others that mentioned it). Haven't checked the original paper yet though. Anyhow, the code you wrote is exactly the same as the one I posted, it's just that the one I've posted is re-written. Both of them give: f0 + exp - f0*exp


oh, ok, then you just need to find out how to use the fresnel term, because then you calculated it right...
maybe try to add it:
outputColor.rgb =  ambientReflection + diffuseReflection + specularReflection + fresnel;



#4939092 Position Reconstruction from Depth in OpenGL

Posted by Yours3!f on 10 May 2012 - 01:05 PM


yep I describe the frustum corner method. I made it work in view space, but mjp describes a world space method as well. (so I guess the frustum one doesn't work in worldspace)

OMG!! I didn't know those were your articles! Those are awesome! I honestly take my hat off for you!

Just want to confirm with you that with your method#2 I'd not need to deal with frustum corners, right? Multiplication of view_vector and linear_depth would give me reconstructed position in the view space.

Also, could you suggest some article where I can learn more about view/projection spaces in order to get a better idea how it works and why is the depth projected into [-far, -near] range.

Thank you!
Ruben


ummm... I think you misunderstood me. That is not my article. I just implemented it. That article belongs to MJP: http://www.gamedev.n...ser/118414-mjp/

you DO have to deal with it. That is the basis of the reconstruction. If you read the mjp article #3 (back in the habit) then you'll understand it. View vector is actually constructed from the coordinates of the far plane of the view frustum, that were interpolated along the whole screen.

just a couple of articles:
http://www.songho.ca..._transform.html
http://www.songho.ca...tionmatrix.html
http://www.songho.ca...omogeneous.html
http://www.glprogram.../chapter03.html
http://www.glprogramming.com/red/ ---> this is a whole book (although it is for OGL 1.1, some parts are still relevant like the article above)

this is an awesome book about the maths behind all this:
http://www.amazon.co...y/dp/1556229119
despite it describes maths in a left-handed coordinate system, I'm sure that after reading this you'll be able to apply it in the OpenGL world, the right-handed cooridnate system.


#4938643 Position Reconstruction from Depth in OpenGL

Posted by Yours3!f on 09 May 2012 - 05:54 AM

Hi Everybody,

I'm in a long journey of implementing deferred shading. I've got a clear idea of the algorithm, but have some troubles reconstructing object position. I've followed this article http://mynameismjp.w...ion-from-depth/ but still easily get lots. There are too many uncertainties. So I want to go over it step by step and make that I did not make any mistakes in previous steps.


Storing the depth into a texture:

// Depth Pass Vertex Shader

varying float depth;
void main (void)
{
	 gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
	 vec4 pos = gl_ModelViewMatrix * gl_Vertex;
	 depth = pos.z;
}

// Depth Pass Fragment Shader
varying float depth;
uniform float FarClipPlane;
void main (void)
{
	 float d = - depth / FarClipPlane;
	 gl_FragColor.r = d;
}

My understanding of this is that I do store the liner depth value into the texture. Is that correct?

Thank you,
Ruben


Also, I'm easily getting lost when it gets to the perspective division. Can somebody suggest some article where i can learn about it.


Ashaman73 is correct, however you seem to be having trouble with the theory itself.
before reading take a look at this:
http://mynameismjp.wordpress.com/2010/09/05/position-from-depth-3/
namely method #2

Ok so you store the depth like this:
[vertex shader]

varying float depth;
const float far_plane_distance = 1000.0f; //far plane is at -1000

[...]

//transform the input vertex to view (or eye) space
vec4 viewspace_position = modelview_matrix * input_vertex;

//this is not perspective division but scaling the depth value.
//initially you'd have depth values in the range [-near ... -far distance]
//but you have to linearize them, so that you can get more
//precision
//this is why you divide by the far plane distance
//and you divide by the negative one, so that you can
//check the result in the texture
depth = viewspace_position.z / -far_plane_distance;

[pixel shader]

varying float depth;
out vec4 out_depth;

[...]

//store the depth into the R channel of the texture
//assuming you chose a R16F or R31F format
out_depth.x = depth;


and retrieve (decode) the depth like this:
[vertex shader]

varying vec4 viewspace_position;
varying vec2 texture_coordinates;

[...]

//store the view space position of the far plane
//this gets interpolated as you could see in the mjp drawing
viewspace_position = modelview_matrix * input_vertex;
texture_coordinates = input_texture_coordinates;

[pixel shader]

varying vec4 viewspace_position;
varying vec2 texture_coordinates;
uniform sampler2D depth_texture;
const float far_plane_distance = 1000.0f;

[...]

//sample depth from the texture's R channel
//this will be in range [0 ... 1]
float linear_depth = texture(depth_texture, texture_coordinates).x;

//you have to construct the view vector at the extrapolated viewspace position
//and scale it by the far / z, but this is unnecessary if you use the far plane as the input viewspace position
//since the division will give you 1
//the z coordinate will be the far distance (negative, since we're in viewspace)
vec3 view_vector = vec3(viewspace_position.xy * (-far_plane_distance / viewspace_position.z), -far_plane_distance);

//scaling the view vector with the linear depth will give the true viewspace position
vec3 reconstructed_viewspace_position = view_vector * linear_depth;


hope this helped :) I had trouble with reconstructing position so search for it on gamedev.


#4937739 bump mapping in deferred renderer

Posted by Yours3!f on 06 May 2012 - 03:42 AM

Interpolated normals does not stay normalized. This is basic thing that is done for every lightmodel. Normal is renormalized at pixel shader.

Try to lerp between [1,0,0] and [0,1,0] and you clearly see the unormalized results.
But problem is more like. Is it needed  for normal mapping? Or is the problem too small to be notified.


well, then they that should be done at pixel shader stage...

well, I haven't noticed any visible errors, so I guess the error is neglible.
when I simply displayed the normals, some error is visible, that is when you normalize in the vertex shader the normals in the end are not unit vectors, but they have a little bit less length, which makes lighting a little darker. (see the cubes on the pictures)

Attached Thumbnails

  • pixel.png
  • pixel_light.png
  • vertex.png
  • vertex_light.png



#4928309 bump mapping in deferred renderer

Posted by Yours3!f on 04 April 2012 - 03:57 PM

Ok, I think I got it right, but please confirm.

I had to change the vertex shader to this:
#version 410
uniform mat4 m4_p, m4_mv;
uniform mat3 m3_n;
in vec4 v4_vertex;
in vec3 v3_normal;
in vec3 v3_tangent;
in vec2 v2_texture;
out cross_shader_data
{
  vec2 v2_texture_coords;
  vec4 position;
  mat3 tbn;
} vertex_output;
void main()
{
  vec3 normal = normalize(m3_n * v3_normal);
  vec3 tangent = normalize(m3_n * v3_tangent);
  vec3 bitangent = normalize(cross(normal, tangent));
  vertex_output.tbn = transpose(mat3( tangent.x, bitangent.x, normal.x,
		  tangent.y, bitangent.y, normal.y,
		  tangent.z, bitangent.z, normal.z ));
  vertex_output.v2_texture_coords = v2_texture;
  vertex_output.position = m4_mv * v4_vertex;
  gl_Position = m4_p * vertex_output.position;
}

the issue was the column major tbn matrix vs the row major, which I used in the previous vertex shader.

I attached an image about the normals, but please confirm if it looks right.

Attached Thumbnails

  • normals.png



#4913138 Posssible memory leak in OpenGL Intel Win7 drivers

Posted by Yours3!f on 14 February 2012 - 04:23 PM

@Yours3!f - glMapBuffer doesn't work that way.  I strongly suggest that you read the documentation for it.  The "fix" you gave will actually crash the program (if you're lucky).
@MarkS - the code does make sense.  That's the way glMapBuffer works, and it's correct and in accordance with the documentation (aside from an extra unnecessary glBindBuffer which shouldn't be a cause of the observed leak).

@OP: have you tried this using glBufferSubData instead of glMapBuffer?  It would be interesting to know if the same symptoms are observed with that.  The following should be equivalent:

void mapAndCopyToBuffer(char* img1)
{
	glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pixelbufferHandle);
	glBufferSubData (GL_PIXEL_UNPACK_BUFFER_ARB, 0, w * h * s, img1);
	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
}

Oh - and make sure that the value of s is 4. ;)


hehe now you got me. I didn't read the specs for glMapBuffer, but now I see clearly how it works... :)
I just searched the code quickly to find some error prone stuff, but didn't catch the glMapBuffer

I hope the collision course I gave on pointers at least cleared some stuff in his head :)


#4913132 Posssible memory leak in OpenGL Intel Win7 drivers

Posted by Yours3!f on 14 February 2012 - 04:13 PM

Just to be sure, I tried to delete[] mappedBuf now (before the statement where I set it to NULL). It crashes.


ok, so I was wrong Posted Image but still you're doing pretty intresting things with those pointers...

I tried to decypher what you're trying to do with the pointers so here it is:

img = 0
img points to where texdata1 does
img points to the write-only memory from where OGL will take back the texture data
fill img with 0-s
copy img-s content back to GPU (unmapping to pixelbufferhandle)
since img points to the write-only memory of OGL, you make it point to texdata1
fill mappedbuf with img (essentially texdata1)
upload mappedbuf to GPU (unmapping to pixelbufferhandle)

loop:
img points to texdata1, so set it to texdata2
fill mappedbuf with img (essentially texdata2)
upload mappedbuf to GPU (unmapping to pixelbufferhandle)

img points to texdata2, so set it to texdata1
fill mappedbuf with img (essentially texdata1)
upload mappedbuf to GPU (unmapping to pixelbufferhandle)


the code essentially sets the texture to grey and white very fast, but with setting glutTimerFunc(5, timerCallback, 0); to glutTimerFunc(120, timerCallback, 0);
I can clearly see this behaviour.

So next I tried to modify the source you've given (on Linux Posted Image thanks for the portable code!) so that it makes more sense:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include "GLee.h"
#include "GL/freeglut.h"
unsigned int w = 640;
unsigned int h = 480;
unsigned int s = 4;
char* texData1 = NULL;
char* texData2 = NULL;
char* mappedBuf = NULL;
GLuint pixelbufferHandle;
bool pingpong = true; //so that the first time we use texdata1
void timerCallback ( int value );
void initializeTextureBuffer();
void mapAndCopyToBuffer ( char* img1 );
void paintGL();
void changeSize ( int w, int h );
GLuint errorCode;
#define checkForGLError() \
	    if ((errorCode = glGetError()) != GL_NO_ERROR) \
			    printf("OpenGL error at %s line %i: %s", __FILE__, __LINE__-1, gluErrorString(errorCode) );

int main ( int argc, char **argv )
{
    texData1 = new char[w * h * s];
    texData2 = new char[w * h * s];
    memset ( texData1, 0, w * h * s );
    memset ( texData2, 255, w * h * s );
    glutInit ( &argc, argv );
    glutInitDisplayMode ( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA );
    glutInitWindowPosition ( 300, 300 );
    glutInitWindowSize ( w, h );
    glutCreateWindow ( "Window" );
    glutDisplayFunc ( paintGL );
    glutReshapeFunc ( changeSize );
    glDisable ( GL_BLEND );
    glDepthMask ( GL_FALSE );
    glDisable ( GL_CULL_FACE );
    glDisable ( GL_DEPTH_TEST );
    glEnable ( GL_TEXTURE_2D );
    glEnable ( GL_MULTISAMPLE );
    initializeTextureBuffer();
    timerCallback ( 0 );
    glutMainLoop();
    glDeleteBuffers ( 1, &pixelbufferHandle );
    delete[] texData1;
    delete[] texData2;
    return 0;
}
void initializeTextureBuffer()
{
    glGenBuffers ( 1, &pixelbufferHandle );
    checkForGLError();
    glBindBuffer ( GL_PIXEL_UNPACK_BUFFER, pixelbufferHandle );
    checkForGLError();
    glBufferData ( GL_PIXEL_UNPACK_BUFFER, w * h * s, 0, GL_DYNAMIC_DRAW );
    checkForGLError();
    // Specify filtering and edge actions
    glTexParameteri ( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR );
    glTexParameteri ( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR );
    glTexParameteri ( GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP );
    glTexParameteri ( GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP );
    // initialize and upload the texture
    glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0 );
    checkForGLError();
    mappedBuf = ( char* ) glMapBuffer ( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY );
    checkForGLError();
    if ( !mappedBuf )
    {
	    std::cerr << "Couldn't create write-only mapping buffer.\n Exiting.\n";
	    exit ( 1 );
    }
    memset(mappedBuf, 0, w * h * s);
    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
    checkForGLError();
}
void mapAndCopyToBuffer ( char* img_ptr )
{
    mappedBuf = (char*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
    memcpy ( mappedBuf, img_ptr, w * h * s );
    if (!glUnmapBuffer ( GL_PIXEL_UNPACK_BUFFER ))
    {
	    std::cerr << "Buffer has already been unmapped.\n Exiting.\n";
	    exit(1);
    }
    checkForGLError();
    glTexSubImage2D ( GL_TEXTURE_2D, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0 );
    checkForGLError();
}
void paintGL()
{
    if ( pingpong )
    {
	    mapAndCopyToBuffer ( texData1 );
    }
    else
    {
	    mapAndCopyToBuffer ( texData2 );
    }
    pingpong = !pingpong;
    glMatrixMode ( GL_MODELVIEW );
    glPushMatrix();
    glBegin ( GL_QUADS );
    {
	    glTexCoord2f ( 0,0 );
	    glVertex3f ( -1, 1, 0 );
	    glTexCoord2f ( 1,0 );
	    glVertex3f ( 1, 1, 0 );
	    glTexCoord2f ( 1,1 );
	    glVertex3f ( 1, -1, 0 );
	    glTexCoord2f ( 0,1 );
	    glVertex3f ( -1, -1, 0 );
    }
    glEnd();
    glPopMatrix();
    glutSwapBuffers();
}
void changeSize ( int w, int h )
{
    glViewport ( 0, 0, w, h );
}
void timerCallback ( int value )
{
    glutPostRedisplay();
    glutTimerFunc ( 1, timerCallback, 0 );
}
// kate: indent-mode cstyle; space-indent on; indent-width 0;

EDIT: corrected the not-mapping back issue :)

I don't know if the memory leak is still present with this version since I don't own an intel graphics card... could you please test this?




PARTNERS