I have no idea why when i run this code and use the menu i do not see any of the shapes on the screen. When i replace the glCallLists line with a glu[insertshape] and the same parameters it works perfectly but the exact same line of code but this time called through a display list and it doesn't work.
Ive even used print statements to check and the code is definitely being run
Can anyone help?
#include <GL/freeglut.h>
#include <GL/gl.h>
#include <cstdio>
GLUquadricObj* ptrSphere;
GLUquadricObj* ptrCylinder;
GLUquadricObj* ptrDisk;
GLUquadricObj* ptrPartDisk;
GLuint sphereListID;
GLuint cylinderListID;
GLuint diskListID;
GLuint partialDiskListID;
GLuint menuID;
GLuint currentListID;
void drawSphere()
{
gluSphere(ptrSphere, 2, 25, 25);
printf("sphere");
}
void drawCylinder()
{
gluCylinder(ptrCylinder, 3, 3, 4, 25, 25);
printf("cylinder");
}
void drawDisk()
{
gluDisk(ptrDisk, 1.5, 3, 25, 25);
printf("disk");
}
void drawPartDisk()
{
gluPartialDisk(ptrPartDisk, 1.5, 3, 25, 25, 0, 90);
printf("part disk");
}
void initQuadrics()
{
ptrSphere = gluNewQuadric();
gluQuadricDrawStyle(ptrSphere, GLU_LINE);
ptrCylinder = gluNewQuadric();
gluQuadricDrawStyle(ptrCylinder, GLU_LINE);
ptrDisk = gluNewQuadric();
gluQuadricDrawStyle(ptrDisk, GLU_LINE);
ptrPartDisk = gluNewQuadric();
gluQuadricDrawStyle(ptrPartDisk, GLU_LINE);
}
void initLists()
{
sphereListID = glGenLists(0);
cylinderListID = glGenLists(0);
diskListID = glGenLists(0);
partialDiskListID = glGenLists(0);
glNewList(sphereListID, GL_COMPILE);
drawSphere();
glEndList();
glNewList(cylinderListID, GL_COMPILE);
drawCylinder();
glEndList();
glNewList(diskListID, GL_COMPILE);
drawDisk();
glEndList();
glNewList(partialDiskListID, GL_COMPILE);
drawPartDisk();
glEndList();
currentListID = sphereListID;
}
void myMenu(int value)
{
switch(value)
{
case(1):
currentListID = sphereListID;
break;
case(2):
currentListID = cylinderListID;
break;
case(3):
currentListID = diskListID;
break;
case(4):
currentListID = partialDiskListID;
break;
}
glutPostRedisplay();
}
void initMenu()
{
menuID = glutCreateMenu(myMenu);
glutSetMenu(menuID);
glutAddMenuEntry("Sphere", 1);
glutAddMenuEntry("Cylinder", 2);
glutAddMenuEntry("Disk", 3);
glutAddMenuEntry("Partial Disk", 4);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
void init()
{
initQuadrics();
initLists();
initMenu();
}
void display()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glCallList(currentListID);
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow("OpenGL - First window demo");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
init();
glutMainLoop();
return 0;
}
I'm not sure whether this is the only issue in OPs program but it's definitely one:
void initLists()
{
sphereListID = glGenLists(0);
cylinderListID = glGenLists(0);
diskListID = glGenLists(0);
partialDiskListID = glGenLists(0);
The doc. of glGenLists() is quite explicit about this:
glGenLists has one argument, range. It returns an integer n such that range contiguous empty display lists, named n, n + 1 , ... , n + range - 1 , are created. If range is 0, if there is no group of range contiguous names available, or if any error is generated, no display lists are generated, and 0 is returned.
(Emphasize mine.)
So, I would recommend:
Use glGenLists(1) instead of glGenLists(0) (or even use a single glGenLists(4) to generate all list IDs at once).
Check that the return value of glGenLists() is not 0.
Before we switched to OpenGL 3+, we used display lists to improve the performance in our Visual Simulation applications. That worked amazingly well (and we even had difficulties to gain the same performance in OpenGL 3+ using buffers and shaders).
Using display lists still works well with recent professional (expensive) graphics cards. On (much cheaper) consumer graphics cards, we noticed an unsatisfying performance drop with our legacy code while we achieve comparable performance when we use OpenGL 3+ functions only.
Related
I want to do something like a 3d-shooter.
The calculations seems to be correct, but it is works every other time with a spread with 180 degree rotation on every call glutPostRedisplay(). I understood that thanks to that red line.
I do this with such IDE: Code Blocks / Qt Creator under Linux(Ubuntu x64).
main.cpp
#include "Functions.h"
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(wnd_width, wnd_height);
glutInitWindowPosition(300, 100);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glutCreateWindow("OpenGL my");
glutDisplayFunc(display);
glutIdleFunc(Idle);
glutSpecialFunc(KeyPressed);
GLdouble aspect = wnd_width/wnd_height;
gluPerspective(90, aspect, 0.1, 10);
glTranslatef(0, -0.3, 0);
glutMainLoop();
return 0;
}
Functions.h
#include <GL/glut.h>
#include <math.h>
#include <iostream>
int wnd_width=1300;
int wnd_height=900;
float pos_x=0, pos_z=0.1;
float angle = 0;
float speed = 0.1;
void DrawFloor(){
glVertex3d(1, 0, 2.5);
glVertex3d(1, 0, 0);
glVertex3d(-1, 0, 0);
glVertex3d(-1, 0, 2.5);
}
void DrawWall(float x, float width, float height){
glVertex3f(x, height, 0);
glVertex3f(x, height, width);
glVertex3f(x, 0, width);
glVertex3f(x, 0, 0);
}
void DrawLine(){
glVertex3f(0, 0.1, -1);
glVertex3f(0, 0.1, 1);
}
void KeyPressed(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: {
//pos_x = speed * cos(3.14*angle/180);
//pos_z = speed * sin(3.14*angle/180);
pos_z+=0.1;
break;
}
case GLUT_KEY_DOWN: {
pos_x = speed*cos(angle);
pos_z = speed*sin(angle);
break;
}
case GLUT_KEY_LEFT: {
angle += 1;
pos_x = speed * cos(3.14 * angle/180);
pos_z = speed * sin(3.14 * angle/180);
break;
}
case GLUT_KEY_RIGHT: {
angle -= 3;
pos_x = speed * cos(3.14 * angle/180);
pos_z = speed * sin(3.14 * angle/180);
break;
}
}
std::cout<<"x: "<<pos_x<<'\t';
std::cout<<"z: "<<pos_z<<'\n';
glutPostRedisplay();
}
void display(){
glClearColor(0.6, 0.8, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(pos_x, 0, pos_z, pos_x, 0, pos_z+0.2, 0, 1, 0);
glBegin(GL_QUADS);
glColor3f(0, 0, 0.7);
DrawFloor();
glColor3f(0, 0.8, 0.1);
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glLineWidth(2);
glColor3f(0.7, 0.2, 0.2);
glBegin(GL_LINES);
DrawLine();
glEnd();
glutSwapBuffers();
}
void Idle(){
//pos_z+=0.01;
//glutPostRedisplay();
}
You're using the fixed function stack, so you'll have to learn what glMatrixMode does and how transformation matrices are managed in those old ways.
Anyway, consider this a possible implementation of glMatrixMode
void glMatrixMode(GLenum m)
{
switch(m){
case GL_MODELVIEW: ctx->M = &ctx->matrix_modelview; break;
case GL_PROJECTION: ctx->M = &ctx->matrix_projection; break;
case GL_TEXTURE: ctx->M = &ctx->matrix_texture; break;
case GL_COLOR: ctx->M = &ctx->matrix_color; break;
}
}
On other words, there's a (context) global matrix selected with glMatrixMode, that's subsequently used for all folloing matrix manipulations.
Hence, glMatrixMode is not some form of initialization, but something you use to switch (often several times) during rendering a frame! Your use of it in the main function is kind of pointless. You must use it in your drawing function.
Furthermore, every matrix manipulation multiplies on top, of what's currently in ctx->M. gluLookAt is normally used with a identity matrix. If you don't reset you identity, that gluLookAt will work relative to the look-at done previously. So what you want is this:
void display(){
glClearColor(0.6, 0.8, 1., 1.); /* <<<----* */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTIOM);
glLoadIdentity();
setup_projection_here();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(pos_x, 0, pos_z, pos_x, 0, pos_z+0.2, 0, 1, 0);
glBegin(GL_QUADS);
/* ... */
glutSwapBuffers();
}
(*) Also you normally want to clear to alpha = 1 on the main framebuffer, unless you're planning on drawing window-translucent imagery. With alpha = 0 things might look correct in the window, but if a screenshot is taken, or some screen recording or sharing is used, it may cause undesired transparence.
I am trying this sample open gl program on my codelite ide.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
GLenum doubleBuffer;
GLint thing1, thing2;
static void Init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearAccum(0.0, 0.0, 0.0, 0.0);
thing1 = glGenLists(1);
glNewList(thing1, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glRectf(-1.0, -1.0, 1.0, 0.0);
glEndList();
thing2 = glGenLists(1);
glNewList(thing2, GL_COMPILE);
glColor3f(0.0, 1.0, 0.0);
glRectf(0.0, -1.0, 1.0, 1.0);
glEndList();
}
static void Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case '1':
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glutPostRedisplay();
break;
case '2':
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glutPostRedisplay();
break;
case 27:
exit(0);
}
}
static void Draw(void)
{
glPushMatrix();
glScalef(0.8, 0.8, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glCallList(thing1);
glAccum(GL_LOAD, 0.5);
glClear(GL_COLOR_BUFFER_BIT);
glCallList(thing2);
glAccum(GL_ACCUM, 0.5);
glAccum(GL_RETURN, 1.0);
glPopMatrix();
if (doubleBuffer) {
glutSwapBuffers();
} else {
glFlush();
}
}
static void Args(int argc, char **argv)
{
GLint i;
doubleBuffer = GL_FALSE;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-sb") == 0) {
doubleBuffer = GL_FALSE;
} else if (strcmp(argv[i], "-db") == 0) {
doubleBuffer = GL_TRUE;
}
}
}
int main(int argc, char **argv)
{
GLenum type;
glutInit(&argc, argv);
Args(argc, argv);
type = GLUT_RGB | GLUT_ACCUM;
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(type);
glutInitWindowSize(300, 300);
glutCreateWindow("Accum Test");
Init();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Draw);
glutMainLoop();
}
Program compiles fine on my machine, when tried to run it just output press any key to continue and program exits after key is pressed.
What I am missing ?
What command line arguments have you passed? You have no choice but to use -db for reasons I will explain.
In Windows 7, you cannot draw a single-buffered window because the window manager makes a copy of the framebuffer when you swap buffers and that is what it displays (composites). Without swapping buffers, nothing will ever be displayed. This modern window system design prevents painting partially completed frames, but it mandates double-buffered rendering.
In fact, you should re-write your software so that it defaults to double-buffered rendering unless you specify a command line argument instead of the other way around. This issue affects other platforms besides modern Windows (Vista and newer).
I have simple studyng project representing some space star's system. I have a star and several planets with moons rotating around the star. I'm using depth buffer, but planets are always in front of the star even if planet should be shadowed by the star. What can be the issue reason?
void drawPlanet(float orbitRadius, float planetRadius, float daysInYear, float hoursInDay){
static float year = 0;
static float days = 0;
static float hours = 0;
glPushMatrix();
glRotatef(year, 0, 1, 0);
glTranslatef(orbitRadius, 0 ,0);
glRotatef(days, 1, 2, 0);
glutWireSphere(planetRadius, 20, 16);
drawLuna(0.3, 0.1, 30, 15);
glPopMatrix();
hours++;
days = hours/hoursInDay;
year=days/daysInYear;
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0,0,5, 0, 0, 0, 0 ,1, 0);
glColor3f(1.0, 0.647059, 0.00);
glutSolidSphere(0.5, 20, 16);
glColor3b(197, 96, 63);
drawPlanet(2, 0.2, 50, 12);
drawPlanet(1, 0.15, 30, 15);
glFlush();
}
int main(int argc, char** argv)
{
....
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glEnable(GL_DEPTH_TEST);
....
}
Your call to glEnable(GL_DEPTH_TEST) has no effect if there's no OpenGL context. GLUT creates the OpenGL context only after glutCreateWindow has been called.
As a general rule you should not call glEnable outside of the display function. You will also have to clear the depth buffer, so make this
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
I am trying to move the camera with the use of the keyboard. I am calling the glulookat function in the draw method as follows:
gluLookAt(posx,posy,posz,lookx,looky,lookz,upx,upy,upz);
Also I have, for example, for moving the position of the camera on the X axis the following code:
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case 'w' :
break;
case 'a' :
posx-=1.0;
break;
case 's' :
break;
case 'd' :
posx+=1.0;
break;
}
}
The posx,posy,posz,lookx,looky,lookz,upx,upy,upz variables are declared as global double variables. I have tried to initialize them in two ways: when declaring them, as well as in the init() method, but with no success. The camera isn't moving, although the program receives the keyboard input properly, as I have tested this aspect separately. Any ideas of what I am doing wrong?
EDIT: I provided the main code for a better understanding:
Outer_space* space;
Light* sceneLight;
Light* sceneLight2;
Light* sceneLight3;
Satelite* satelite1;
double posx=35.0,posy=35.0,posz=35.0,lookx=0,looky=1,lookz=0,upx=0,upy=0,upz=-1;
void init(void) {
//random number generator
srand(time(NULL));
space = new Outer_space(12, 12,12, new Vector3D(0.5f, 0.7f, 0.9f));
sceneLight = new Light(0, 0);
sceneLight->setTranslation(new Vector3D(0, 20, 0));
sceneLight->setConstantAttenuation(0.09f);
sceneLight->setLinearAttenuation(0.08f);
sceneLight2 = new Light(1, 0);
sceneLight2->setTranslation(new Vector3D(20, 0, 0));
sceneLight2->setConstantAttenuation(0.09f);
sceneLight2->setLinearAttenuation(0.08f);
sceneLight3 = new Light(2, 0);
sceneLight3->setTranslation(new Vector3D(0, 0, 20));
sceneLight3->setConstantAttenuation(0.09f);
sceneLight3->setLinearAttenuation(0.08f);
satelite1 = new Satelite(2,new Vector3D(0.2f,0.3f,0.5f));
satelite1->setTranslation(new Vector3D(10,10,10));
satelite1->setRotation(new Vector3D(-90, 0, 0));
satelite1->setScale(new Vector3D(10, 10, 10));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
}
void draw(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0,20,0, 0, 0, 0, 0, 1, 0);
gluLookAt(posx,posy,posz,lookx,looky,lookz,upx,upy,upz);
space->draw();
sceneLight->draw();
sceneLight2->draw();
sceneLight3->draw();
satelite1->draw();
glPushMatrix();
glRasterPos3f(-8.5, 4, -6);
glutSwapBuffers();
}
void update(void){
glutPostRedisplay();
}
void resize(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
GLfloat aspect = (GLfloat)w / (GLfloat)h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 1.0, 60);
}
void keyboard(unsigned char key, int x, int y) {
switch (key)
{
case 'w' :
break;
case 'a' :
posx-=1.0;
break;
case 's' :
break;
case 'd' :
posx+=1.0;
break;
}
}
void specialKeyboard(int key, int x, int y) {
switch (key)
{
case GLUT_KEY_RIGHT:
posx+=1;
break;
case GLUT_KEY_LEFT:
posx-=1;
break;
case GLUT_KEY_UP:
break;
case GLUT_KEY_DOWN:
break;
}
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("Asteroid Escape");
init();
glutIdleFunc(update);
glutDisplayFunc(draw);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialKeyboard);
glutMainLoop();
return 0;
}
EDIT2:
I have commented out the glPushMatrix(); call from the draw() method and now the camera seems to be moving. What is the explanation?
glPushMatrix is supposed to be followed by glPopMatrix.
It seems that you overflow the matrix stack, did you check glGetError result ?
Besides, jour call to glPushMatrix seems pretty useless like this, what do you expect it to do ?
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.