how do I get my C++ glut project to have smooth input?
the only way I could get input was with a slight delay, which is annoying. I am new to C++ glut so pls help me.
#include <windows.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <stdio.h>
#include <iostream>
GLboolean upPressed = false;
using namespace std;
void display();
void reshape(int,int);
void timer(int);
void keyboard_callback(int, int, int);
void SpecialKeysUp(int, int, int);
void update();
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
}
int main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(200, 100);
glutInitWindowSize(500, 500);
glutCreateWindow("window");
glutSpecialFunc(keyboard_callback);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0,timer,0);
glutSpecialUpFunc(SpecialKeysUp);
glutIdleFunc(update);
init();
glutMainLoop();
}
// sy is the first squares y position. no x value needed since the x value is static.
// also note that the "s" in sy stands for square, squarey_position
float x_position = 0.0;
float sy_position = -4.0;
int state = 1;
char input;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,0.0);
glVertex2f(x_position,1.0);
glVertex2f(x_position,-1.0);
glVertex2f(x_position+2.0,-1.0);
glVertex2f(x_position+2.0,1.0);
glColor3f(1.0,0.0,0.0);
glVertex2f(-8.0,sy_position);
glVertex2f(-9.0,sy_position);
glVertex2f(-9.0,sy_position+8.0);
glVertex2f(-8.0,sy_position+8.0);
glEnd();
glutSwapBuffers();
}
void reshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-10, 10, -10, 10);
glMatrixMode(GL_MODELVIEW);
}
void timer(int)
{
glutPostRedisplay();
glutTimerFunc(1000/60,timer,0);
switch(state)
{
case 1:
if(x_position<8)
x_position+=0.15;
else
state = -1;
break;
case -1:
if(x_position>-10)
x_position-=0.15;
else
state=1;
break;
}
}
void keyboard_callback(int key, int, int)
{
if(GLUT_KEY_UP == key)
upPressed = true;
}
void SpecialKeysUp(int key, int, int)
{
if(GLUT_KEY_UP == key)
upPressed = false;
}
void update()
{
// glutPostRedisplay();
// glutTimerFunc(1000/60,update,0);
if(upPressed)
sy_position+=0.15;
}
It is a ping pong game and currently the ball is working fine, however I am trying to get smooth input for the rectangle but the only way I could was with input delay.
I am new to glut C++ so pls help me
Actually I figured out how to do it. The glutTimerFunc updates and resets every 1000/60 milliseconds so valuing a bool at "true" whilst the up key is pressed(with GLUT_KEY_UP) and then valuing a bool at "false" when the key is not pressed(with the SpecialUpFunc) makes for smoother input since the update function resets must faster than just holding the key down.
Related
This program is able to create a window and locate my mouse when it is on the window, however the display function does seem to work. What am I missing here?
float pointSize = 10.0f;
bool leftBottState;
float xvalue;
float yvalue;
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
}
void dots()
{
glBegin(GL_POINTS);
glVertex3f(xvalue, yvalue, 0.0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 1);
dots();
glEnd();
glFlush();
}
void mouse(int button, int state, int x, int y)
{
y = 600 - y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
leftBottState = true;
}
else
{
leftBottState = false;
}
}
void motion(int x, int y)
{
if (leftBottState)
{
std::cout << "LEFt bUTTON " << std::endl;
xvalue = x;
yvalue = y;
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutCreateWindow("test");
glutMotionFunc(motion);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return(0);
}
You're using a double buffered window (see glutInitDisplayMode).
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
Therefore you must call glutSwapBuffers to swaps the buffers after rendering the scene:
void dots()
{
glBegin(GL_POINTS);
glVertex3f(xvalue, yvalue, 0.0);
glEnd();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 1);
dots();
// glFlush();
glutSwapBuffers();
}
Note, a glBegin \ glEnd sequence delimits the vertices of a primitive. I recommend to call this instructions in the same function, immediately before and after specifying the vertices.
glClear clears the buffers and thus the entire scene. If you want to draw the points permanently, you have to remove the glClear instruction from the display function.
glClear(GL_COLOR_BUFFER_BIT);
So i'm making a game(something similar to a pong)using openGl in cpp , and when i try running the program , the image rendering is too slow ,i feel something is taking a huge toll on my GPU memory ,
(So far i have competed the drawing and movement of the paddle which works fine and the problem arises when the ball is set to motion on the press of a button , Everything slows down after this )
Here i have attached a portion of my code
Point out any deficiencies in my code
#include<stdlib.h>
#include<GL/glut.h>
#include<windows.h>
#include<iostream>
//#include<sstream>
#include<stdio.h>
#include<ctime>
#include<string.h>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
//GLvoid player1_box();
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key){
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
//printf("Inside switch r");
break;
}
glutPostRedisplay();
}
void display()
{
Sleep(2);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
//printf("x move in disp:%1f \n",xmove);
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball(); //To draw the ball
glPopMatrix();
glFlush();
}
void moveBall(){ //glutidlefunction
if(release==1)
{ //Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
Sleep(500);
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void reshape(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0,0,w,h);
//glutPostRedisplay();
//Use the whole window for rendering
}
int main(int argc ,char **argv)
{
//clock_t begin= clock();
char n1,n2;
int ack;
/*printf("The object of Tic Tac Toe is to get three in a row. \n . Players alternate placing Xs and Os(Traingles and Boxes in this version) \n on the game board until either opponent has three \n in a row or all nine squares are filled(Which would be a drawObviously). \n");
printf("\n Press 1 if acknowledged \n");
scanf("%d",&ack);*/
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutReshapeFunc(reshape);
glutIdleFunc(moveBall);
glClearColor(1,1,1,1);
glutMainLoop();
//clock_t end=clock();
}
You're using c++, use C++-style (stdlib.h -> cstdlib) headers.
Apply your projection/modelview matrices each time through display() instead of a reshape callback, helps prevent annoying matrix stack issues.
Don't Sleep(), use a timer/idle callback to glutPostRedisplay(). Bonus points for framerate-independent movement (you can use glutGet(GLUT_ELAPSED_TIME) to calculate delta-t).
Without Sleep() there's no reason to drag windows.h into things.
All together:
#include <GL/glut.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cstring>
typedef double point[3];
point a,b,c,d;
static float xmove=0.0;
static int release=0;
static float ii=0.00;
static int reac_top;
using namespace std;
GLfloat xangle=0.0;
float changeDir=1;// positive direction
double vv[4][3]={ {0.5,0.2,0.0},{ 0.5,0.25,0.0},{0.7,0.25,0.0},{0.7,0.2,0.0}};
void renderoutline()
{
glBegin(GL_LINE_LOOP);
glColor3f(1,0,0);
glVertex2f(0.0,0.0);
glColor3f(1,0,0);
glVertex2f(0,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,1.2);
glColor3f(1,0,0);
glVertex2f(1.2,0);
glEnd();
}
void ball()
{
glBegin(GL_POLYGON);
glColor3f(0,0,1);
glVertex3f(0.6,0.25,0.0);
glColor3f(0,0,1);
glVertex3f(0.6,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.28,0.0);
glColor3f(0,0,1);
glVertex3f(0.62,0.25,0.0);
glEnd();
}
void renderbox1( point a , point b , point c, point d)
{
glBegin(GL_POLYGON);
glColor3f(0,0,0);
glVertex3dv(a);
glColor3f(0,0,0);
glVertex3dv(b);
glColor3f(0,0,0);
glVertex3dv(c);
glColor3f(0,0,0);
glVertex3dv(d);
glEnd();
}
void keyboard(unsigned char key,int x,int y)
{
switch(key)
{
case 'a':xangle-=0.1;
++xmove;
while(xmove>5)
{
xmove=-5;
xangle=0.5;
continue;
}
break;
case 'd':xangle+=0.1;
--xmove;
while(xmove<-5)
{
xmove=5;
xangle =-0.5;
continue;
}
break;
case 'r':
release=1;
break;
}
}
void display()
{
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1.2, 0, 1.2,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glLineWidth(3.0);
glLoadIdentity();
glTranslatef(xangle,0,0);
renderbox1(vv[0],vv[1],vv[2],vv[3]); // To draw the paddle
glPopMatrix();
renderoutline();
glPushMatrix();
glTranslatef(0,ii,0);
ball();
glPopMatrix();
glFlush();
}
void moveBall()
{
if(release==1)
{
//Release becomes one when the key 'r' is pressed (glutkeyboardfunc)
if(ii>=0&&ii<=0.9 )
{
reac_top=false;
ii=ii+0.05;printf("1\n");//The ball which was intially on the paddle starts moving till it reaches the top edge of thescreen
}
else if(ii>=0.9)
{
//when the boll reaches top
ii=ii-0.05;
reac_top=3;
printf("2\n");
}
else if( (ii<0.9)&& (reac_top==3)&&(ii>0.05)) //The balls journey back to the paddle
{
printf("3\n");
ii=ii-0.05;
}
release=1;
}
}
void timer( int value )
{
moveBall();
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}
int main(int argc ,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(1000,500);
glutInitWindowPosition(200,0);
glutCreateWindow("3d Gasket");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
}
I'm new to OpenGL and I'm trying to paint a stickman and then move it using the arrow-keys from the keyboard.
My idea was to use global variables for the stickman and to change them when a certain key is pressed. Afterwards the draw-function (myDisplay()) is called again.
Unfortunately i always get the following error-message:
"Error 10 error C2371: 'myDisplay' : redefinition; different basic types "
When I replace the myDisplay()-call in the keyboard-function with glutPostRedisplay() as suggested in some tutorials I read the error message disapears and the build is successful. But the stickman doesn't move when pressing the keys.
Here's my code:
#include <GL/glut.h>
GLint x; GLint y; GLint d; //parameters for the stickman
void myKeyboard(unsigned char key, int mx, int my) {
int x1 = mx;
int y1 = 480 - my;
switch(key){
case GLUT_KEY_LEFT :
x = x-50;
myDisplay();
break;
case 'E' :
exit(-1);
break;
default:
break;
}
}
void stickman () {
glBegin(GL_LINES); //body
glVertex2i(x, y);
glVertex2i(x, y-2*d);
glVertex2i(x-d, y-d);
glVertex2i(x+d, y-d);
glVertex2i(x, y-2*d);
glVertex2i(x-d, y-3*d);
glVertex2i(x, y-2*d);
glVertex2i(x+d, y-3*d);
glEnd();
glBegin(GL_LINE_LOOP); //head
glVertex2i(x,y);
glVertex2i(x+0.5*d, y);
glVertex2i(x+0.5*d, y+0.5*d);
glVertex2i(x-0.5*d, y+0.5*d);
glVertex2i(x-0.5*d, y);
glEnd();
}
void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
stickman();
glFlush();
}
void myInit() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
void main(int argc, char** argv) {
x = 320;
y = 350;
d = 100;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(200, 50);
glutCreateWindow("Stickman");
glutDisplayFunc(myDisplay);
glutKeyboardFunc(myKeyboard);
glutPostRedisplay();
myInit();
glutMainLoop();
}
As I found out (GLUT Keyboard Tutorial) the problem wasn't the repaint of the picture, but rather that the left arrow key wasn't recognized.
I needed to write another keyboard-function for my special keys such as the arrow keys.
Now my code looks like this and it works:
void processNormalKeys (unsigned char key, int mx, int my) {
if (key == 'E')
exit(-1);
}
void processSpecialKeys (int key, int mx, int my) {
switch(key){
case GLUT_KEY_LEFT :
x = x-5;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT :
x = x+5;
glutPostRedisplay();
break;
case GLUT_KEY_UP :
y = y+5;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN :
y = y-5;
glutPostRedisplay();
break;
default:
break;
}
}
I also had to adjust the main function:
glutKeyboardFunc(processNormalKeys);
glutSpecialFunc(processSpecialKeys);
But thanks for your help anyways!
glutPostRedisplay() is used to tell mark that the current window needs to be redisplayed as said in the documentation. That means that you need to call this function at the end of your myKeyboard function.
I will also recommend you to use double or tripple buffer to avoid undesired results. For double buffer you need to change glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ); with glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB ); and then at the end of your display function you need to add glutSwapBuffers();. You can find more info here http://www.swiftless.com/tutorials/opengl/smooth_rotation.html.
I have a problem, i'm using glut (the openGL utility toolkit). I'm making a subwindow in a mainwindow. The mainwindow displays a simple figure and the subwindow displays the figure from another view. The figure rotates so the mainwindow and the subwindow should always be redisplayed.
But only one of the two displays the rotating figure. So when I start the program the figure in the mainwindow rotates but in the subwindow it don't rotate, it just stands still.
When I move my mouse in the subwindow and press any key the roles changes so the figure rotates in the subwindow and stands still in the mainwindow.
How can I let them both display simultaneous. I followed the tutorial from Lighthouse, but it didn't give me an answer.
Do I have to do something with my viewport?
* GLUT Shapes Demo
*
* Written by Nigel Stewart November 2003
*
* This program is test harness for the sphere, cone
* and torus shapes in GLUT.
*
* Spinning wireframe and smooth shaded shapes are
* displayed until the ESC or q key is pressed. The
* number of geometry stacks and slices can be adjusted
* using the + and - keys.
*/
#include <windows.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <math.h>
#include <stdlib.h>
static int slices = 16;
static int stacks = 16;
int m=0;
int mainWindow,SubWindow, SubWindow2;
/* GLUT callback Handlers */
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10,10,-10,10,-10,10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
static void key(unsigned char key, int x, int y)
{
switch (key)
{
case 27 :
case 'q':
exit(0);
break;
case '+':
slices++;
stacks++;
break;
case '-':
if (slices>3 && stacks>3)
{
slices--;
stacks--;
}
break;
}
//glutPostRedisplay();
}
void keyp(int key, int xx, int yy) {
glutSetWindow(mainWindow);
glutPostRedisplay();
}
void displaysub()
{const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*90.0;
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClearColor(20,1,1,1);
glLoadIdentity();
glOrtho(-5,5,-5,5,-5,5);
glColor3f(0,0,0);
glRotated(a,0,0,10);
glPushMatrix();
glTranslated(0,0,0);
glutSolidSphere(2,10,10);
glPopMatrix();
glutSwapBuffers();
}
void display()
{const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*90.0;
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClearColor(3,0,0,1);
glLoadIdentity();
glOrtho(-10,10,-10,10,-10,10);
glRotated(a,10,10,0);
displaysub();
}
static void idle(void)
{
glutPostRedisplay();
}
/* Program entry point */
void init()
{
glClearColor(3,0,0,1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// register callbacks
glutIgnoreKeyRepeat(1);
glutKeyboardFunc(key);
glutSpecialFunc(keyp);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
mainWindow = glutCreateWindow("GLUT Shapes");
glutSetWindow(mainWindow);
glClearColor(3,0,0,1);
glutDisplayFunc(display);
init();
SubWindow = glutCreateSubWindow(mainWindow,0,0,50,50);
glutSetWindow(SubWindow);
glClearColor(3,0,0,1);
glutDisplayFunc(displaysub);
init();
glutIdleFunc(idle);
glutMainLoop();
return 1;
}
The documentation on glutPostRedisplay specifies that only the display func of the current window will be called. In this case there are two windows. I am not an expert using glut but I would suggest two changes
Remove displaysub() from the display() function and rewrite idle()
static void idle()
{
int currentWindow = glutGetWindow();
glutSetWindw(mainWindow);
glutPostRedisplay();
glutSetWindw(subWindow);
glutPostRedisplay();
glutSetWindow(currentWindow);
}
glutPostRedisplay just marks the window for update in the main loop, which I guess is the one with mouse focus. By doing a post for each window independent of the current window all windows will receive their respective display calls
I am looking for a way to display two png images (in fact, it will be numbers, my aim is to create an overlay for live streaming to display players score and some further additional content) on a window with transparent background with no border. So that we just see the score over the window placed behind.
Is there any way to do something like that ? I have already tried many things with SDL, textures, but nothing led me to any satisfying result. The best I found was some dirty code almost working but completely unusable.
If possible, the solution may let possible to add the functionality that when you click left or right on one of the 2 scores, it is incremented or decremented.
Edit: Here is my current code. I started new without any bit of the dirty code I had before, because I would like to understand what I am doing. I have my 2 numbers displayed as textures, now I would like to remove borders and title bar of my window, and make my background transparent.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
#include <windowsx.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include "sdlglutils.h"
#include <assert.h>
#include <tchar.h>
using namespace std;
int overlay;
int TimerEnabled;
GLfloat posX, posY, posZ;
GLuint texture_0, texture_1, texture_2, texture_3;
void Initialize()
{
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
glEnable(GL_TEXTURE_2D);
}
void Reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)w/(GLfloat)h,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
texture_0 = loadTexture("0.png");
texture_1 = loadTexture("1.png");
texture_2 = loadTexture("2.png");
texture_3 = loadTexture("3.png");
return;
}
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glTranslatef(posX,posY,posZ);
glScalef(1.0f,1.0f,1.0f);
glPushMatrix();
glTranslated(-6, 8, 0);
glBindTexture(GL_TEXTURE_2D, texture_1);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2d(0,0);
glTexCoord2d(1,0); glVertex2d(1,0);
glTexCoord2d(1,1); glVertex2d(1,1);
glTexCoord2d(0,1); glVertex2d(0,1);
glEnd();
glPopMatrix();
glPushMatrix();
glTranslated(6, 8, 0);
glBindTexture(GL_TEXTURE_2D, texture_2);
glBegin(GL_QUADS);
glTexCoord2d(0,0); glVertex2d(0,0);
glTexCoord2d(1,0); glVertex2d(1,0);
glTexCoord2d(1,1); glVertex2d(1,1);
glTexCoord2d(0,1); glVertex2d(0,1);
glEnd();
glPopMatrix();
glFlush();
}
void Display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Draw();
glutSwapBuffers();
}
void KeyboardSpecialEvent( int key, int x, int y)
{
switch(key)
{
case(GLUT_KEY_UP) :
{
posY += 0.3;
}break;
case(GLUT_KEY_DOWN) :
{
posY -= 0.3;
}break;
case(GLUT_KEY_LEFT) :
{
posX -= 0.3;
}break;
case(GLUT_KEY_RIGHT) :
{
posX += 0.3;
}break;
}
}
void MouseEvent( int button, int state, int x, int y){ };
void MotionMouseEvent( int x, int y ){ };
void IdleEvent(){ };
void TimerEvent(int time)
{
glutPostRedisplay();
if(TimerEnabled)
glutTimerFunc(10, TimerEvent, time);
}
void KeyboardEvent( unsigned char key, int x, int y)
{
switch(key)
{
case ' ' :
{
TimerEnabled = !TimerEnabled;
if (TimerEnabled)
glutTimerFunc(40, TimerEvent, 0);
}
break;
case 'q' :
{
exit(0);
}
break;
}
}
int main(int argc, char** argv)
{
posX = 0;
posY = 0;
posZ = -25;
TimerEnabled = 1;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(1600,900);
glutInitWindowPosition(0,0);
overlay = glutCreateWindow("ScoreOverlay");
//glutFullScreen();
Initialize();
glutDisplayFunc(Display);
glutReshapeFunc(Reshape);
glutKeyboardFunc(KeyboardEvent);
glutSpecialFunc(KeyboardSpecialEvent);
glutMouseFunc(MouseEvent);
glutMotionFunc(MotionMouseEvent);
glutIdleFunc(IdleEvent);
glutTimerFunc(40, TimerEvent, 0);
glutMainLoop();
return 0;
}
Here is a working base sample (using c++ with clr support) that could help you.
You need to adapt it to your need (for example use DrawImage instead of FillEllipse)
using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
ref class MyForm : public Form
{
public:
MyForm()
{
this->m_brush = gcnew SolidBrush(Color::Blue);
this->m_canvas = gcnew System::Windows::Forms::Panel();
this->m_canvas->BackColor = Color::Pink;
this->m_canvas->Dock = System::Windows::Forms::DockStyle::Fill;
this->m_canvas->Location = System::Drawing::Point(0, 0);
this->m_canvas->Margin = System::Windows::Forms::Padding(0);
this->m_canvas->Name = "Canvas";
this->m_canvas->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &MyForm::canvas_Paint);
this->m_canvas->TabIndex = 0;
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = Color::Pink;
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
this->ClientSize = System::Drawing::Size(200, 200);
this->Controls->Add(this->m_canvas);
this->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &MyForm::form_KeyDown);
this->TransparencyKey = Color::Pink;
this->Name = "MyForm";
this->Text = "MyForm";
}
private:
void canvas_Paint(Object^ sender, PaintEventArgs^ e) {
e->Graphics->FillEllipse(this->m_brush, Rectangle(50, 50, 100, 100));
}
void form_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
// Test key ...
this->m_canvas->Invalidate();
// ...
}
Brush^ m_brush;
Panel^ m_canvas;
};
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew MyForm());
return 0;
}
It looks like you need this on Windows. Have you looked at Layered Windows?
Unless you need OpenGL for the graphics for some reason I think you'll be better off loading your images as regular bitmaps and blitting them to the layered window directly. Using OpenGL you would need to draw to a texture map, then take that texture and blit it to the layered window.