PDA

View Full Version : Problem with glutSwapBuffers when using multiple shader programs



sueyllam
04-21-2015, 11:48 PM
I have the following Pong game program which is working fine using one set of shader programs for displaying the red ball and the green pads passing the color as a uniform to set the color in the fragment shader, and using the fixed pipeline to display the score text.
Here it is for reference:



#include<math.h>
#define PI 3.14159265f
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm\glm.hpp>

using namespace std;

const int WIDTH = 600;
const int HEIGHT = 600;

// Define a helpful macro for handling offsets into buffer objects
#define BUFFER_OFFSET( offset ) ((GLvoid*) (offset))

GLuint InitShader(const char* vShaderFile, const char* fShaderFile);
GLuint program;

GLfloat ballRadius = 0.02;
GLfloat ballX = 0.0f;
GLfloat ballY = 0.0f;
GLfloat ballXMax,ballXMin,ballYMax,ballYMin;
GLfloat xSpeed = 0.02f;
GLfloat ySpeed = 0.007f;
int refreshMills = 30;
int score = 0;
GLfloat cur_mx = 0, cur_my = 0;
GLdouble clipAreaXLeft,clipAreaXRight,clipAreaYBottom,clipA reaYTop;
int ww=WIDTH,wh=HEIGHT;
glm::vec4 points[110],pointsT[110];
GLfloat pad[2][4][2];
GLuint vPosition,colorUnif;
GLuint vao;
GLfloat wp2 =0.02f, hp2 =0.08f;

void
OnInit( void )
{
// Specify the vertices for a triangle fan to draw the ball
points[0] = glm::vec4(0.0f,0.0f,0.0f,1.0f);
GLfloat angle;
int i;
for(i=0;i<=100;i++)
{
angle = i*2.0f*PI/100;
points[i+1] = glm::vec4(cos(angle)*ballRadius,sin(angle)*ballRad ius,0.0f,1.0f);
}
//Now specify the pads: first left pad
points[102][0] = -1.0f; points[102][1] = -hp2;
points[102][2] = 0.0f; points[102][3] = 1.0f;
points[103][0] = -1.0f + wp2; points[103][1] = -hp2;
points[103][2] = 0.0f; points[103][3] = 1.0f;
points[104][0] = -1.0f + wp2; points[104][1] = hp2;
points[104][2] = 0.0f; points[104][3] = 1.0f;
points[105][0] = -1.0f; points[105][1] = hp2;
points[105][2] = 0.0f; points[105][3] = 1.0f;
//Now the right pad
points[106][0] = 1.0f; points[106][1] = -hp2;
points[106][2] = 0.0f; points[106][3] = 1.0f;
points[107][0] = 1.0f; points[107][1] = hp2;
points[107][2] = 0.0f; points[107][3] = 1.0f;
points[108][0] = 1.0f - wp2; points[108][1] = hp2;
points[108][2] = 0.0f; points[108][3] = 1.0f;
points[109][0] = 1.0f - wp2; points[109][1] = -hp2;
points[109][2] = 0.0f; points[109][3] = 1.0f;

pad[0][0][0] = -1.0f; pad[0][0][1] = -hp2;
pad[0][1][0] = -1.0f + wp2; pad[0][1][1] = -hp2;
pad[0][2][0] = -1.0f + wp2; pad[0][2][1] = hp2;
pad[0][3][0] = -1.0f; pad[0][3][1] = hp2;
pad[1][0][0] = 1.0f; pad[1][0][1] = -hp2;
pad[1][1][0] = 1.0f; pad[1][1][1] = hp2;
pad[1][2][0] = 1.0f - wp2; pad[1][2][1] = hp2;
pad[1][3][0] = 1.0f - wp2; pad[1][3][1] = -hp2;

// Create a vertex array object
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );

// Create and initialize a buffer object
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );

// Load shaders and use the resulting shader program
program = InitShader( "vshaderBallUnif.glsl", "fshaderBallUnif.glsl" );

// set up vertex arrays
vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0) );
colorUnif = glGetUniformLocation(program, "color");

glClearColor( 0.0, 0.0, 0.0, 1.0 ); // black background
cout<<"Initialization successfull"<<endl;
}

void OnShutdown() {
cout<<"Shutdown successfull"<<endl;
}

void OnResize(int nw, int nh) {
if (nh==0) nh = 1;
GLfloat aspect = (GLfloat) nw/ (GLfloat) nh;
glViewport(0,0,nw,nh);
if (nw>=nh) {
clipAreaXLeft = -1.0 * aspect;
clipAreaXRight = 1.0 * aspect;
clipAreaYBottom = -1.0;
clipAreaYTop = 1.0;
}
else {
clipAreaXLeft = -1.0;
clipAreaXRight = 1.0 ;
clipAreaYBottom = -1.0 / aspect;
clipAreaYTop = 1.0/ aspect;
}
ballXMin = clipAreaXLeft + ballRadius;
ballXMax = clipAreaXRight - ballRadius;
ballYMin = clipAreaYBottom + ballRadius;
ballYMax = clipAreaYTop - ballRadius;
ww=nw;
wh=nh;
//adjust the pads
points[102][0] = clipAreaXLeft; points[102][1] = -hp2;
points[103][0] = clipAreaXLeft + wp2; points[103][1] = -hp2;
points[104][0] = clipAreaXLeft + wp2; points[104][1] = hp2;
points[105][0] = clipAreaXLeft; points[105][1] = hp2;
//right pad
points[106][0] = clipAreaXRight; points[106][1] = -hp2;
points[107][0] = clipAreaXRight; points[107][1] = hp2;
points[108][0] = clipAreaXRight - wp2; points[108][1] = hp2;
points[109][0] = clipAreaXRight - wp2; points[109][1] = -hp2;

pad[0][0][0] = clipAreaXLeft; pad[0][0][1] = -hp2;
pad[0][1][0] = clipAreaXLeft + wp2; pad[0][1][1] = -hp2;
pad[0][2][0] = clipAreaXLeft + wp2; pad[0][2][1] = hp2;
pad[0][3][0] = clipAreaXLeft; pad[0][3][1] = hp2;
pad[1][0][0] = clipAreaXRight; pad[1][0][1] = -hp2;
pad[1][1][0] = clipAreaXRight; pad[1][1][1] = hp2;
pad[1][2][0] = clipAreaXRight - wp2; pad[1][2][1] = hp2;
pad[1][3][0] = clipAreaXRight - wp2; pad[1][3][1] = -hp2;
}

void paddisp()
{
for(int i=102;i<=109;i++)
{ //ortho2D projection
pointsT[i][0] = 2.0/(clipAreaXRight-clipAreaXLeft)*points[i][0] -(clipAreaXRight+clipAreaXLeft)/(clipAreaXRight-clipAreaXLeft);
pointsT[i][1] = 2.0/(clipAreaYTop-clipAreaYBottom)*points[i][1] - (clipAreaYTop+clipAreaYBottom)/(clipAreaYTop-clipAreaYBottom);
pointsT[i][2] = 0.0f;
pointsT[i][3] = 1.0f;
}
glUniform3f(colorUnif, 0.0f, 1.0f, 0.0f);
glBufferData( GL_ARRAY_BUFFER, sizeof(pointsT), pointsT, GL_STREAM_DRAW );
glDrawArrays( GL_QUADS, 102, 8 ); // draw the points
}

void scoredisp()
{
glUseProgram(0);
int z,j=0,k=0,s=0;
if (score<0) {
s=1;
z = -score;
}
else {
s = 0;
z = score;
}
glColor3f(1.0,1.0,1.0);
glRasterPos2f(-1,0.8 );
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'S');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'C');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'O');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'R');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'E');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,' ');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,':');
GLfloat post = -0.42;
while(z > 9)
{
k = z % 10;
glRasterPos2f (post,0.8);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,48+ k);
z /= 10;
post -= 0.04;
}
glRasterPos2f (post,0.8);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,48+ z);
if (s) {
post -= 0.06;
glRasterPos2f (post,0.8);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'-');
}
}

void OnRender() {
glUseProgram(program);
glClear( GL_COLOR_BUFFER_BIT ); // clear the window
for(int i=0;i<=101;i++) {
pointsT[i][0] = points[i][0] + ballX;
pointsT[i][1] = points[i][1] + ballY;
pointsT[i][2] = 0.0f;
pointsT[i][3] = 1.0f;
}
for(int i=0;i<=101;i++) { //ortho2D projection
pointsT[i][0] = 2.0/(clipAreaXRight-clipAreaXLeft)*pointsT[i][0] -(clipAreaXRight+clipAreaXLeft)/(clipAreaXRight-clipAreaXLeft);
pointsT[i][1] = 2.0/(clipAreaYTop-clipAreaYBottom)*pointsT[i][1] - (clipAreaYTop+clipAreaYBottom)/(clipAreaYTop-clipAreaYBottom);
}
glUniform3f(colorUnif, 1.0f, 0.0f, 0.0f);
glBufferData( GL_ARRAY_BUFFER, sizeof(pointsT), pointsT, GL_STREAM_DRAW );
glDrawArrays( GL_TRIANGLE_FAN, 0, 102 ); // draw the points
paddisp();
scoredisp();
glutSwapBuffers();
}

void onMouseMove(int x, int y) {
static GLfloat oldx = 0, oldy = 0;
cur_mx = (clipAreaXRight-clipAreaXLeft)/(float)ww * x + clipAreaXLeft;
cur_my = (clipAreaYTop-clipAreaYBottom)/(float)wh * (wh-y) + clipAreaYBottom;
if ((cur_mx<=clipAreaXLeft+wp2) && (cur_my>=points[102][1]) && (cur_my<=points[104][1])) {
GLfloat yd = cur_my-oldy;
if (points[102][1]+yd<clipAreaYBottom)
yd = clipAreaYBottom - points[102][1];
else if (points[104][1]+yd>clipAreaYTop)
yd = clipAreaYTop - points[104][1];
points[102][1] += yd;
points[103][1] += yd;
points[104][1] += yd;
points[105][1] += yd;
oldy = cur_my;
glutPostRedisplay();
}
}

void Timer(int value) {
ballX += xSpeed;
ballY += ySpeed;

if (ballX<ballXMin+wp2 && ballY<points[104][1] && ballY>points[102][1]){
score++;
ballX = ballXMin+wp2;
xSpeed = -xSpeed;
}
else if (ballX>ballXMax-wp2 && ballY<points[107][1] && ballY>points[106][1]){
xSpeed = -xSpeed;
ballX = ballXMax-wp2;
}
else if(ballX > ballXMax) {
ballX = ballXMax;
xSpeed = -xSpeed;
}
else if(ballX < ballXMin) {
ballX = ballXMin;
score--;
xSpeed = -xSpeed;
}

if(ballY > ballYMax) {
ballY = ballYMax;
ySpeed = -ySpeed;
}
else if(ballY < ballYMin) {
ballY = ballYMin;
ySpeed = -ySpeed;
}
//right pad should follow the ball
GLfloat yd = ballY;
if ((pad[1][0][1]+ ballY)<clipAreaYBottom)
yd = clipAreaYBottom - pad[1][0][1];
else if ((pad[1][1][1] + ballY) > clipAreaYTop)
yd = clipAreaYTop - pad[1][1][1];

points[106][1] = pad[1][0][1] + yd;
points[107][1] = pad[1][1][1] + yd;
points[108][1] = pad[1][2][1] + yd;
points[109][1] = pad[1][3][1] + yd;
glutPostRedisplay();
glutTimerFunc(refreshMills,Timer,10);
}

//----------------------------------------------------------------------------

void
keyboard( unsigned char key, int x, int y )
{
switch ( key ) {
case 033:
exit( EXIT_SUCCESS );
break;
}
}

//----------------------------------------------------------------------------

int
main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitContextVersion (3, 3);
glutInitContextFlags (GLUT_CORE_PROFILE | GLUT_DEBUG);
glutInitContextProfile(GLUT_FORWARD_COMPATIBLE);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Getting started Drawing A Triangle");
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err) {
cerr<<"Error: "<<glewGetErrorString(err)<<endl;
}
else if (GLEW_VERSION_3_3) {
cout<<"Driver supports OpenGL 3.3\nDetails:"<<endl;
}
OnInit();
glutMotionFunc(onMouseMove);
glutCloseFunc(OnShutdown);
glutDisplayFunc(OnRender);
glutReshapeFunc(OnResize);
glutKeyboardFunc( keyboard );
glutTimerFunc(0,Timer,0);
glutMainLoop();
return 0;
}


the shaders are very basic the vertex shader simply set gl_Position and the fragment shader set the ouput color.

Now for the sake of experimentation, i decided to rewrite using 2 sets of shader programs one for displaying the ball in red and the other for displaying the pads in green plus the fixed pipeline for the score text.
Unfortunately, the program crashes and by inserting appropriate cout statements I found that it crashes inside glutSwapBuffers.....Cannot figure out what is wrong.
Here is the code:



#include<math.h>
#define PI 3.14159265f
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm\glm.hpp>

using namespace std;

const int WIDTH = 600;
const int HEIGHT = 600;

// Define a helpful macro for handling offsets into buffer objects
#define BUFFER_OFFSET( offset ) ((GLvoid*) (offset))

GLuint InitShader(const char* vShaderFile, const char* fShaderFile);
GLuint program, program1;

GLfloat ballRadius = 0.02;
GLfloat ballX = 0.0f;
GLfloat ballY = 0.0f;
GLfloat ballXMax,ballXMin,ballYMax,ballYMin;
GLfloat xSpeed = 0.02f;
GLfloat ySpeed = 0.007f;
int refreshMills = 30;
int score = 0;
GLfloat cur_mx = 0, cur_my = 0;
GLdouble clipAreaXLeft,clipAreaXRight,clipAreaYBottom,clipA reaYTop;
int ww=WIDTH,wh=HEIGHT;
glm::vec4 points[102];
GLuint vPosition, vPositionPad;
GLuint vao, vao1;
GLfloat wp2 =0.02f, hp2 =0.05f;
glm::vec4 pointsT[102],pad[2][4]={{glm::vec4(-1.0f,-hp2,0.0f,1.0f),
glm::vec4(-1.0f+wp2,-hp2,0.0f,1.0f),glm::vec4(-1.0f+wp2,hp2,0.0f,1.0f),
glm::vec4(-1.0f,hp2,0.0f,1.0f)},{glm::vec4(1.0f,-hp2,0.0f,1.0f),
glm::vec4(1.0f,hp2,0.0f,1.0f),glm::vec4(1.0f-wp2,hp2,0.0f,1.0f),
glm::vec4(1.0f-wp2,-hp2,0.0f,1.0f)}}, padi[2][4];

void
OnInit( void )
{
// Specify the vertices for a triangle fan to draw the ball
points[0] = glm::vec4(0.0f,0.0f,0.0f,1.0f);
GLfloat angle;
int i;
for(i=0;i<=100;i++)
{
angle = i*2.0f*PI/100;
points[i+1] = glm::vec4(cos(angle)*ballRadius,sin(angle)*ballRad ius,0.0f,1.0f);
}
pad[0][0][0] = -1.0f; pad[0][0][1] = -hp2;
pad[0][0][2] = 0.0f; pad[0][0][3] = 1.0f;
pad[0][1][0] = -1.0f + wp2; pad[0][1][1] = -hp2;
pad[0][1][2] = 0.0f; pad[0][1][3] = 1.0f;
pad[0][2][0] = -1.0f + wp2; pad[0][2][1] = hp2;
pad[0][2][2] = 0.0f; pad[0][2][3] = 1.0f;
pad[0][3][0] = -1.0f; pad[0][3][1] = hp2;
pad[0][3][2] = 0.0f; pad[0][3][3] = 1.0f;
pad[1][0][0] = 1.0f; pad[1][0][1] = -hp2;
pad[1][0][2] = 0.0f; pad[1][0][3] = 1.0f;
pad[1][1][0] = 1.0f; pad[1][1][1] = hp2;
pad[1][1][2] = 0.0f; pad[1][1][3] = 1.0f;
pad[1][2][0] = 1.0f - wp2; pad[1][2][1] = hp2;
pad[1][2][2] = 0.0f; pad[1][2][3] = 1.0f;
pad[1][3][0] = 1.0f - wp2; pad[1][3][1] = -hp2;
pad[1][3][2] = 0.0f; pad[1][3][3] = 1.0f;

padi[0][0][0] = -1.0f; padi[0][0][1] = -hp2;
padi[0][0][2] = 0.0f; padi[0][0][3] = 1.0f;
padi[0][1][0] = -1.0f + wp2; padi[0][1][1] = -hp2;
padi[0][1][2] = 0.0f; padi[0][1][3] = 1.0f;
padi[0][2][0] = -1.0f + wp2; padi[0][2][1] = hp2;
padi[0][2][2] = 0.0f; padi[0][2][3] = 1.0f;
padi[0][3][0] = -1.0f; padi[0][3][1] = hp2;
padi[0][3][2] = 0.0f; padi[0][3][3] = 1.0f;
padi[1][0][0] = 1.0f; padi[1][0][1] = -hp2;
padi[1][0][2] = 0.0f; padi[1][0][3] = 1.0f;
padi[1][1][0] = 1.0f; padi[1][1][1] = hp2;
padi[1][1][2] = 0.0f; padi[1][1][3] = 1.0f;
padi[1][2][0] = 1.0f - wp2; padi[1][2][1] = hp2;
padi[1][2][2] = 0.0f; padi[1][2][3] = 1.0f;
padi[1][3][0] = 1.0f - wp2; padi[1][3][1] = -hp2;
padi[1][3][2] = 0.0f; padi[1][3][3] = 1.0f;

// Create a vertex array object
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );

// Create and initialize a buffer object
GLuint buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );

// Load shaders and use the resulting shader program
program = InitShader( "vshaderBall.glsl", "fshaderBall.glsl" );

// set up vertex arrays
vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0) );

glGenVertexArrays( 1, &vao1 );
glBindVertexArray( vao1 );
program1 = InitShader( "vshaderBallPong.glsl", "fshaderBallPong.glsl" );
GLuint buffer1;
glGenBuffers( 1, &buffer1 );
glBindBuffer( GL_ARRAY_BUFFER, buffer1 );

vPositionPad = glGetAttribLocation( program, "vPositionPad" );
glEnableVertexAttribArray( vPositionPad );
glVertexAttribPointer( vPositionPad, 4, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(0) );

glClearColor( 0.0, 0.0, 0.0, 1.0 ); // black background
cout<<"Initialization successfull"<<endl;
}

void OnShutdown() {
cout<<"Shutdown successfull"<<endl;
}

void OnResize(int nw, int nh) {
cout <<"Inside Reshape\n";
if (nh==0) nh = 1;
GLfloat aspect = (GLfloat) nw/ (GLfloat) nh;
glViewport(0,0,nw,nh);
if (nw>=nh)
{
clipAreaXLeft = -1.0 * aspect;
clipAreaXRight = 1.0 * aspect;
clipAreaYBottom = -1.0;
clipAreaYTop = 1.0;
}
else
{
clipAreaXLeft = -1.0;
clipAreaXRight = 1.0 ;
clipAreaYBottom = -1.0 / aspect;
clipAreaYTop = 1.0/ aspect;
}
ballXMin = clipAreaXLeft + ballRadius;
ballXMax = clipAreaXRight - ballRadius;
ballYMin = clipAreaYBottom + ballRadius;
ballYMax = clipAreaYTop - ballRadius;
ww=nw;
wh=nh;

pad[0][0][0] = clipAreaXLeft; pad[0][0][1] = -hp2;
pad[0][1][0] = clipAreaXLeft + wp2; pad[0][1][1] = -hp2;
pad[0][2][0] = clipAreaXLeft + wp2; pad[0][2][1] = hp2;
pad[0][3][0] = clipAreaXLeft; pad[0][3][1] = hp2;
pad[1][0][0] = clipAreaXRight; pad[1][0][1] = -hp2;
pad[1][1][0] = clipAreaXRight; pad[1][1][1] = hp2;
pad[1][2][0] = clipAreaXRight - wp2; pad[1][2][1] = hp2;
pad[1][3][0] = clipAreaXRight - wp2; pad[1][3][1] = -hp2;

padi[0][0][0] = clipAreaXLeft; padi[0][0][1] = -hp2;
padi[0][1][0] = clipAreaXLeft + wp2; padi[0][1][1] = -hp2;
padi[0][2][0] = clipAreaXLeft + wp2; padi[0][2][1] = hp2;
padi[0][3][0] = clipAreaXLeft; padi[0][3][1] = hp2;
padi[1][0][0] = clipAreaXRight; padi[1][0][1] = -hp2;
padi[1][1][0] = clipAreaXRight; padi[1][1][1] = hp2;
padi[1][2][0] = clipAreaXRight - wp2; padi[1][2][1] = hp2;
padi[1][3][0] = clipAreaXRight - wp2; padi[1][3][1] = -hp2;

}

void paddisp()
{glUseProgram(program1);
glBindVertexArray( vao1 );
glm::vec4 padT[2][4];
for (int j=0;j<2;j++)
for(int i=0;i<=3;i++)
{
padT[j][i][0] = 2.0/(clipAreaXRight-clipAreaXLeft)*pad[j][i][0] -(clipAreaXRight+clipAreaXLeft)/(clipAreaXRight-clipAreaXLeft);
padT[j][i][1] = 2.0/(clipAreaYTop-clipAreaYBottom)*pad[j][i][1] - (clipAreaYTop+clipAreaYBottom)/(clipAreaYTop-clipAreaYBottom);
padT[j][i][2] = 0.0f;
padT[j][i][3] = 1.0f;
}

glBufferData( GL_ARRAY_BUFFER, sizeof(padT),
padT, GL_STREAM_DRAW );//intialize the data
glDrawArrays( GL_QUADS, 0, 8 ); // draw the points
}

void scoredisp()
{
int z,j=0,k=0,s;
glUseProgram(0);
glBindVertexArray( 0 );
if (score<0) {
s = 1;
z = -score;
}
else {
s = 0;
z=score;
}
glColor3f(1.0,1.0,1.0);
glRasterPos2f(-1,0.80 );
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'S');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'C');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'O');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'R');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'E');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,' ');
glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,':');
GLfloat post = -0.42;
while(z > 9)
{
k = z % 10;
glRasterPos2f (post,0.80);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,48+ k);
z /= 10;
post -= 0.04;
}
glRasterPos2f (post,0.80);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,48+ z);
if (s) {
post -= 0.06;
glRasterPos2f (post,0.8);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'-');
}
}

void OnRender() {
glUseProgram(program);
glBindVertexArray( vao );
glClear( GL_COLOR_BUFFER_BIT ); // clear the window
for(int i=0;i<=101;i++)
{
pointsT[i][0] = points[i][0] + ballX;
pointsT[i][1] = points[i][1] + ballY;
pointsT[i][2] = 0.0f;
pointsT[i][3] = 1.0f;
}
for(int i=0;i<=101;i++)
{
pointsT[i][0] = 2.0/(clipAreaXRight-clipAreaXLeft)*pointsT[i][0] -(clipAreaXRight+clipAreaXLeft)/(clipAreaXRight-clipAreaXLeft);
pointsT[i][1] = 2.0/(clipAreaYTop-clipAreaYBottom)*pointsT[i][1] - (clipAreaYTop+clipAreaYBottom)/(clipAreaYTop-clipAreaYBottom);
}

glBufferData( GL_ARRAY_BUFFER, sizeof(pointsT),
pointsT, GL_STREAM_DRAW );//intialize the data
glDrawArrays( GL_TRIANGLE_FAN, 0, 102 ); // draw the points
paddisp();
scoredisp();
cout <<"Swapping buffers\n";
glutSwapBuffers();
cout << "Done Swapping Buffers\n";
}

void onMouseMove(int x, int y) /// I want help here to detect mouse over the ball
{static GLfloat oldx = 0, oldy = 0;
cur_mx = (clipAreaXRight-clipAreaXLeft)/(float)ww * x + clipAreaXLeft;
cur_my = (clipAreaYTop-clipAreaYBottom)/(float)wh * (wh-y) + clipAreaYBottom;
if ((cur_mx<=clipAreaXLeft+wp2) && (cur_my>=pad[0][0][1]) && (cur_my<=pad[0][2][1])) {
GLfloat yd = cur_my-oldy;
if (pad[0][0][1]+yd<clipAreaYBottom)
yd = clipAreaYBottom - pad[0][0][1];
else if (pad[0][2][1]+yd>clipAreaYTop)
yd = clipAreaYTop - pad[0][2][1];
pad[0][0][1] += yd;
pad[0][1][1] += yd;
pad[0][2][1] += yd;
pad[0][3][1] += yd;
oldy = cur_my;
glutPostRedisplay();
}
}

void Timer(int value)
{ cout<<"Inside Timer\n";
if (ballX<ballXMin+wp2 && ballY<pad[0][2][1] && ballY>pad[0][0][1]){
score++;
ballX = ballXMin+wp2;
xSpeed = -xSpeed;
}
else if (ballX>ballXMax-wp2 && ballY<pad[1][1][1] && ballY>pad[1][0][1]){
xSpeed = -xSpeed;
ballX = ballXMax-wp2;
}
else if(ballX > ballXMax) {
ballX = ballXMax;
xSpeed = -xSpeed;
}
else if(ballX < ballXMin) {
ballX = ballXMin;
score--;
xSpeed = -xSpeed;
}

if(ballY > ballYMax) {
ballY = ballYMax;
ySpeed = -ySpeed;
}
else if(ballY < ballYMin) {
ballY = ballYMin;
ySpeed = -ySpeed;
}
//right pad should follow the ball
GLfloat yd = ballY;
if ((padi[1][0][1]+ ballY)<clipAreaYBottom)
yd = clipAreaYBottom - padi[1][0][1];
else if ((padi[1][1][1] + ballY) > clipAreaYTop)
yd = clipAreaYTop - padi[1][1][1];

pad[1][0][1] = padi[1][0][1] + yd;
pad[1][1][1] = padi[1][1][1] + yd;
pad[1][2][1] = padi[1][2][1] + yd;
pad[1][3][1] = padi[1][3][1] + yd;
glutPostRedisplay();
glutTimerFunc(refreshMills,Timer,10);
}


//----------------------------------------------------------------------------

void
keyboard( unsigned char key, int x, int y )
{
switch ( key ) {
case 033:
exit( EXIT_SUCCESS );
break;
}
}

//----------------------------------------------------------------------------

int
main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitContextVersion (3, 3);
glutInitContextFlags (GLUT_CORE_PROFILE | GLUT_DEBUG);
glutInitContextProfile(GLUT_FORWARD_COMPATIBLE);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Getting started Drawing A Triangle");
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err){
cerr<<"Error: "<<glewGetErrorString(err)<<endl;
} else {
if (GLEW_VERSION_3_3)
{
cout<<"Driver supports OpenGL 3.3\nDetails:"<<endl;
}
}
OnInit();
glutMotionFunc(onMouseMove);
glutCloseFunc(OnShutdown);
glutDisplayFunc(OnRender);
glutReshapeFunc(OnResize);
glutKeyboardFunc( keyboard );
glutTimerFunc(0,Timer,0);
glutMainLoop();
return 0;
}



the output I get when run is as in this display:
1755

GClements
04-22-2015, 09:35 AM
the program crashes and by inserting appropriate cout statements I found that it crashes inside glutSwapBuffers.....Cannot figure out what is wrong.

Calling an OpenGL function simply inserts the command into the execution pipeline; it doesn't wait for it to be executed. glutSwapBuffers() performs an implicit glFinish(), which forces any pending commands to be executed. Consequently, any problems with issued commands might not manifest until the glutSwapBuffers() call.

The most likely cause of a crash is calling glVertexAttribPointer() (or fixed-function equivalents) with an invalid pointer; either using a buffer offset when no buffer is bound, or a pointer/offset to an array which contains insufficient data for the specified number of vertices.

sueyllam
04-22-2015, 04:41 PM
Calling an OpenGL function simply inserts the command into the execution pipeline; it doesn't wait for it to be executed. glutSwapBuffers() performs an implicit glFinish(), which forces any pending commands to be executed. Consequently, any problems with issued commands might not manifest until the glutSwapBuffers() call.

The most likely cause of a crash is calling glVertexAttribPointer() (or fixed-function equivalents) with an invalid pointer; either using a buffer offset when no buffer is bound, or a pointer/offset to an array which contains insufficient data for the specified number of vertices.

Thanks for the enlightening reply, but I still do not understand why the glutSwapBuffers(), i.e., the onRender() function was called a second time immediately after the first time it was called from Timer through glutPostRedisplay(); the second call that crashed (the first one went fine and returned as you can see in the command window attached to my original post) was not called from Timer; how was it called?!

Alfonse Reinheart
04-22-2015, 05:46 PM
The function you register with GLUT to display stuff will be called whenever GLUT thinks the display needs to be updated. Such as, for example, when the window is first shown to the user. Or when it's resized. Or when something covers it up. Or uncovers part of it. Things like that.

You should not assume that your timer function is the only thing that can provoke a call to display.

sueyllam
04-22-2015, 06:19 PM
OK, but that does not explain why it succeeded the first time and crashed on the second call. If it were a problem with pointers or buffer offset or insufficient data, shouldn't it crash the first time?

sueyllam
04-22-2015, 07:38 PM
Never mind I found the problem, it was this line:
vPositionPad = glGetAttribLocation( program, "vPositionPad" );
in the OnInit() function, it should be program1 and not program. The vertex shader in program defines vPosition; while the vertex shader in program1 defines vPositionPad.
Shouldn't glGetAttribLocation generates an error?! for undefined attributes...
I still have no answer to my question in the previous post...

sueyllam
04-23-2015, 09:43 AM
Well this was wrong but that was not the reason for the program crashing. I finally figured it out thanks to replies by GClements and Reinheart, I kept looking for problems with buffers and I was blinded by my assumption that the GL_ARRAY_BUFFER binding is part of the VAO state but clearly this is totally wrong and as I was 2 different buffer arrays and after glUseProgram and glBindVertexArray I did not bind the proper array buffer so it was using the wrong one and causing the crash. By adding:
glBindBuffer( GL_ARRAY_BUFFER, buffer ); and glBindBuffer( GL_ARRAY_BUFFER, buffer1 );
after the proper glUseProgram and glBindVertexArray everything works fine now.
Just thought this bit of result might be useful to another newbie.

GClements
04-23-2015, 11:33 AM
Shouldn't glGetAttribLocation generates an error?! for undefined attributes..
No, it returns -1 if the attribute doesn't exist. It generates an error if the program is invalid or the function is called between glBegin() and glEnd().


I was blinded by my assumption that the GL_ARRAY_BUFFER binding is part of the VAO state but clearly this is totally wrong
For each attribute, the VAO stores the buffer which was bound at the time of the last glVertexAttribPointer() (or similar) call for that attribute, but not the current binding. It does store the current binding for GL_ELEMENT_ARRAY_BUFFER.