Original Post
I was working on the gui within this months. I also gained quite a good and helpful replies from these topics, since I haven't used virtual functions , function pointers , and derived classes that much before: http://www.gamedev.net/community/forums/topic.asp?topic_id=335040 http://www.gamedev.net/community/forums/topic.asp?topic_id=337252 But eventually I am done with most of the structure and general work. the GUI is ready. Here are some shots of the GUI, the design is made by an artist Denny who is helping me allot.
larger screens I did actually made it the way I wanted it to be, something similar to C# WinForms style, where you create static component , add it to the window and manipulate it anyway you like. Here is working sample I am going to use for demonstration, it is actually from SDL tutorials page, I modified it to show how Windows can be created and be used: The application can be found here: kna_gui.zip [Edited by - DMINATOR on August 27, 2005 6:19:59 PM]
/*
* SDL OpenGL Tutorial.
* (c) Michael Vance, 2000
* briareos@lokigames.com
*
* Distributed under terms of the LGPL.
*/
//modified by DMINATOR - dminator.blogspot.com or kna_int@mail.ru
// REQUIRED LIB:
//! opengl32.lib sdl.lib sdlmain.lib glu32.lib
// kernel32.lib user32.lib gdi32.lib opengl32.lib sdl.lib sdlmain.lib glu32.lib msvcrt.lib glaux.lib advapi32.lib
//devil-d.lib ilu-d.lib
// Here is the GUI header that needs to be included
#include "KNA_GUI.h"
#include <SDL.h>
#include <SDL_opengl.h>
#include <GL\gl.h>
#include <GL\glu.h>
#include <stdio.h>
#include <stdlib.h>
static GLboolean should_rotate = GL_TRUE;
static void quit_tutorial( int code );
void DrawCube();
//data used for storing cube
static GLfloat v0[] = { -1.0f, -1.0f, 1.0f };
static GLfloat v1[] = { 1.0f, -1.0f, 1.0f };
static GLfloat v2[] = { 1.0f, 1.0f, 1.0f };
static GLfloat v3[] = { -1.0f, 1.0f, 1.0f };
static GLfloat v4[] = { -1.0f, -1.0f, -1.0f };
static GLfloat v5[] = { 1.0f, -1.0f, -1.0f };
static GLfloat v6[] = { 1.0f, 1.0f, -1.0f };
static GLfloat v7[] = { -1.0f, 1.0f, -1.0f };
static GLubyte red[] = { 255, 0, 0, 255 };
static GLubyte green[] = { 0, 255, 0, 255 };
static GLubyte blue[] = { 0, 0, 255, 255 };
static GLubyte white[] = { 255, 255, 255, 255 };
static GLubyte yellow[] = { 0, 255, 255, 255 };
static GLubyte black[] = { 0, 0, 0, 255 };
static GLubyte orange[] = { 255, 255, 0, 255 };
static GLubyte purple[] = { 255, 0, 255, 0 };
/* Our angle of rotation. */
static float angle = 0.0f;
static float bangle = 0.0f;
// this shows the last time since we called update
Uint32 timeBefore;
Uint32 msecPassed;
unsigned short fps;
//the string for frames per second is stored here
char frames[10];
//this is the gui place holder
KNA_Gui gui;
//here is the gui objects
//windows
GUI_Window form1;
GUI_Window form2;
//scrolls
GUI_HScroll scroll1;
GUI_VScroll scroll2;
//and button
GUI_Button close_button;
//here are the actions that are going
//to be callbacked
void scroll1_change(GUI_HScroll* sender)
{
angle = scroll1.pos;
}
void scroll2_change(GUI_VScroll* sender)
{
bangle = scroll2.pos;
}
void close_button_Click(GUI_Abstract *sender)
{
quit_tutorial(1 );
}
//activated when form1 starts to draw
void f1_OnAdDraw(GUI_Window* sender)
{
/* Move down the z-axis. */
glTranslatef( 0.0, 0.0, -5.0 );
glRotatef( bangle, 1.0, 0.0, 0.0 );
/* Rotate. */
glRotatef( angle, 0.0, 1.0, 0.0 );
/* Send our triangle data to the pipeline. */
glBegin( GL_TRIANGLES );
DrawCube();
glEnd();
}
//activated when form2 starts to draw
void f2_OnAdDraw(GUI_Window* sender)
{
/* Move down the z-axis. */
glTranslatef( 0.0, 0.0, -5.0 );
glRotatef( bangle, 1.0, 0.0, 0.0 );
/* Rotate. */
glRotatef( 360 - angle, 0.0, 1.0, 0.0 );
//let's add some fancy effects
glBegin(GL_LINES);
DrawCube();
glEnd();
}
//let's add components to the gui
void AddGuiComponents()
{
//COMPONENTS:
//add callback function when button is clicked
close_button.OnClick = &close_button_Click;
close_button.caption = "Exit";
scroll1.left = 0.17f;
scroll1.width = 0.3f;
scroll1.min = 0;
scroll1.max = 360;
scroll1.OnPosChange = &scroll1_change;
scroll2.top = 0.07f;
scroll2.height = 0.3f;
scroll2.width = 0.04f;
scroll2.min = 0;
scroll2.max = 360;
scroll2.OnPosChange = &scroll2_change;
// WINDOWS:
//add drawing on the window
form1.OnAdDraw = &f1_OnAdDraw;
form1.AddComponent(&close_button);
form1.AddComponent(&scroll1);
form1.AddComponent(&scroll2);
form1.Resize(0.5f,0.5f);
form2.OnAdDraw = &f2_OnAdDraw;
form2.left = 0.45f;
form2.Resize(0.3f,0.3f);
//GUI:
gui.AddWindow(&form2);
gui.AddWindow(&form1);
}
//draws simple cube
void DrawCube()
{
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( black );
glVertex3fv( v5 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( black );
glVertex3fv( v5 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( black );
glVertex3fv( v5 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( black );
glVertex3fv( v5 );
}
static void quit_tutorial( int code )
{
//destroy gui
gui.Destroy();
SDL_Quit( );
/* Exit program. */
exit( code );
}
//calculates time and fps
void PERF_Time()
{
//msec passed since last
msecPassed = SDL_GetTicks() - timeBefore;
//now we need to update the counter
timeBefore = SDL_GetTicks();
//for special case - a very fast PC's let's check if the msec passed != 0
if(msecPassed == 0)
{
msecPassed = 1;
}
//let's count the fps passed
if( (int)(1000/msecPassed) >= fps)
{
fps++;
sprintf(frames,"FPS=%d",fps);
form1.caption = frames;
}
else
{
fps--;
sprintf(frames,"FPS=%d",fps);
form1.caption = frames;
}
}
static void draw_screen( void )
{
/* Clear the color and depth buffers. */
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
/* We don't want to modify the projection matrix. */
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
/* Move down the z-axis. */
glTranslatef( 0.0, 0.0, -5.0 );
//draw gui
gui.Draw();
SDL_GL_SwapBuffers( );
}
static void setup_opengl( int width, int height )
{
float ratio = (float) width / (float) height;
/* Our shading model--Gouraud (smooth). */
glShadeModel( GL_SMOOTH );
/* Culling. */
glCullFace( GL_BACK );
glFrontFace( GL_CCW );
glEnable( GL_CULL_FACE );
/* Set the clear color. */
glClearColor( 0, 0, 0, 0 );
/* Setup our viewport. */
glViewport( 0, 0, width, height );
/*
* Change to the projection matrix and set
* our viewing volume.
*/
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
/*
* EXERCISE:
* Replace this with a call to glFrustum.
*/
gluPerspective( 60.0, ratio, 1.0, 1024.0 );
}
int main( int argc, char* argv[] )
{
/* Information about the current video settings. */
const SDL_VideoInfo* info = NULL;
/* Dimensions of our window. */
int width = 0;
int height = 0;
/* Color depth in bits of our window. */
int bpp = 0;
/* Flags we will pass into SDL_SetVideoMode. */
int flags = 0;
/* First, initialize SDL's video subsystem. */
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
/* Failed, exit. */
fprintf( stderr, "Video initialization failed: %s\n",
SDL_GetError( ) );
quit_tutorial( 1 );
}
/* Let's get some video information. */
info = SDL_GetVideoInfo( );
if( !info ) {
/* This should probably never happen. */
fprintf( stderr, "Video query failed: %s\n",
SDL_GetError( ) );
quit_tutorial( 1 );
}
//set screen
width = 640;
height = 480;
bpp = info->vfmt->BitsPerPixel;
//setting up SDL GL params
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
/*
* We want to request that SDL provide us
* with an OpenGL window, in a windowed
* video mode.
*
*/
flags = SDL_OPENGL;// | SDL_FULLSCREEN;
/*
* Set the video mode
*/
if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
/*
* This could happen for a variety of reasons,
* including DISPLAY not being set, the specified
* resolution not being available, etc.
*/
fprintf( stderr, "Video mode set failed: %s\n",
SDL_GetError( ) );
quit_tutorial( 1 );
}
/*
* At this point, we should have a properly setup
* double-buffered window for use with OpenGL.
*/
setup_opengl( width, height );
//now let's start gui
gui.Start("gui/denny.cfg",width,height);
AddGuiComponents();
/*
* Now we want to begin our normal app process--
* an event loop with a lot of redrawing.
*/
while( 1 ) {
/* Process incoming events. */
// process_events( );
//calculate fps
PERF_Time();
/* Draw the screen. */
draw_screen( );
//rotate the cube
if( should_rotate ) {
if( angle > 360.0f ) {
angle = 0.0f;
}
angle += 0.01f;
//change the scroll position
scroll1.pos = angle;
}
//process GUI events
gui.Update(msecPassed);
}
/* Never reached. */
return 0;
}