Qbasicnews.com

Full Version: So I want to expiriment with OpenGL for C
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
(I know, I know, I should be using Allegro, but I just want to expiriment)
Questions:
1) Does OpenGL need C++ (i.e., OOP), or can I use C?
2) Where can I download the lib and include files?
3) Does one need 500 lines of code to plot a pixel, or can you (like Allegro) just init OpenGL, set the screen mode, plot a pixel, and exit?
4) Does OpenGL have keyboard functions, sound, image loading, etc? (like DirectX does)
1.- You can do it in C
2.- Google for them if you have DevC, they are included in MSVC so you can start now if you use MSVC Tongue
3.- More than allegro, less than directx. Anyhow, you have to do the windows & message handling (allegro does this for you) and that's a lot of lines.
4.- OpenGL just draws lit triangles and does the transforms. You have to provide the rest. Check AllegroGL: You can use Allegro's features and render using OpenGL, that is, using Keyboard, sound & timers from allegro and GFX from OpenGL.

This is when I tried to learn OpenGL (yea, I got bored too fast Tongue) Not mine completely, I just followed a tutorial Tongue

Code:
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <gl\gl.h>            
#include <gl\glu.h>
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define SCREEN_DEPTH 16

bool  g_bFullScreen = TRUE;            
HWND  g_hWnd;
RECT  g_rRect;                
HDC   g_hDC;                
HGLRC g_hRC;            
HINSTANCE g_hInstance;            

// WinProc to manage messages:

LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// Rendering function:
void RenderScene();

/* Funciones */

void ChangeToFullScreen()
{
   DEVMODE dmSettings;          
   memset(&dmSettings,0,sizeof(dmSettings));      
    
   if(!EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmSettings))
   {
      MessageBox(NULL, "Could Not Enum Display Settings", "Error", MB_OK);
      return;
   }

   dmSettings.dmPelsWidth   = SCREEN_WIDTH;
   dmSettings.dmPelsHeight   = SCREEN_HEIGHT;      

   int result = ChangeDisplaySettings(&dmSettings,CDS_FULLSCREEN);    

   if(result != DISP_CHANGE_SUCCESSFUL)
   {
      MessageBox(NULL, "Display Mode Not Compatible", "Error", MB_OK);
      PostQuitMessage(0);
   }
}

HWND CreateMyWindow(LPSTR strWindowName, int width, int height, DWORD dwStyle, bool bFullScreen, HINSTANCE hInstance)
{
   HWND hWnd;
   WNDCLASS wndclass;
    
   memset(&wndclass, 0, sizeof(WNDCLASS));    
   wndclass.style = CS_HREDRAW | CS_VREDRAW;
   wndclass.lpfnWndProc = WinProc;
   wndclass.hInstance = hInstance;            
   wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
   wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
   wndclass.lpszClassName = "GameTutorials";
   RegisterClass(&wndclass);          
   if(bFullScreen && !dwStyle)            
   {
       dwStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
       ChangeToFullScreen();            
       ShowCursor(FALSE);            
   }
   else if(!dwStyle)
       dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    
   g_hInstance = hInstance;

   RECT rWindow;
   rWindow.left   = 0;
   rWindow.right  = width;
   rWindow.top    = 0;
   rWindow.bottom = height;    
   AdjustWindowRect( &rWindow, dwStyle, false);      
   hWnd = CreateWindow("GameTutorials", strWindowName, dwStyle, 0, 0,
                  rWindow.right  - rWindow.left, rWindow.bottom - rWindow.top,
                  NULL, NULL, hInstance, NULL);

   if(!hWnd) return NULL;
  
   ShowWindow(hWnd, SW_SHOWNORMAL);
   UpdateWindow(hWnd);          
   SetFocus(hWnd);            
   return hWnd;
}

WPARAM MainLoop()
{
   MSG msg;

   while(1)                  {                                      
      // Check if windows message...
      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
         if(msg.message == WM_QUIT)              
            // Message was not quit...
            break;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
      }
      else                                
      // If no messages...
      {
         /* Render */
         RenderScene();
      }
   }

   return(msg.wParam);            
}

bool bSetupPixelFormat(HDC hdc)
{
    PIXELFORMATDESCRIPTOR pfd;
    int pixelformat;
  
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);              
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.dwLayerMask = PFD_MAIN_PLANE;          
    pfd.iPixelType = PFD_TYPE_RGBA;          
    pfd.cColorBits = SCREEN_DEPTH;          
    pfd.cDepthBits = SCREEN_DEPTH;
    pfd.cAccumBits = 0;
    pfd.cStencilBits = 0;

    if ( (pixelformat = ChoosePixelFormat(hdc, &pfd)) == FALSE )
    {
        MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
        return FALSE;
    }

    if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE)
    {
        MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
        return FALSE;
    }
  
    return TRUE;                
}

void SizeOpenGLScreen(int width, int height)      
{
   if (height==0)              
   {
      height=1;
   }
   glViewport(0,0,width,height);            
   glMatrixMode(GL_PROJECTION);    
   glLoadIdentity();            
   gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 1 ,150.0f);

   glMatrixMode(GL_MODELVIEW);            
   glLoadIdentity();            
}

void InitializeOpenGL(int width, int height)
{  
    g_hDC = GetDC(g_hWnd);            
    if (!bSetupPixelFormat(g_hDC))          
        PostQuitMessage (0);            

    g_hRC = wglCreateContext(g_hDC);          
    wglMakeCurrent(g_hDC, g_hRC);      
    SizeOpenGLScreen(width, height);          
}

void Init(HWND hWnd)
{
   g_hWnd = hWnd;              
   GetClientRect(g_hWnd, &g_rRect);        
   InitializeOpenGL(g_rRect.right, g_rRect.bottom);    
}

void RenderScene()
{
   int i=0;    

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
   glLoadIdentity();              
   gluLookAt(0, 0, 6,     0, 0, 0,     0, 1, 0);

   // Draw a triangle:
                
                glBegin (GL_TRIANGLES);
                glVertex3f(0, 1, 0);
                glVertex3f(-1, 0, 0);
                glVertex3f(1, 0, 0);
                glEnd();                

   SwapBuffers(g_hDC);            
}

void DeInit()
{
   if (g_hRC)                                  
   {
      wglMakeCurrent(NULL, NULL);
      wglDeleteContext(g_hRC);        
   }
    
   if (g_hDC)
      ReleaseDC(g_hWnd, g_hDC);

   if(g_bFullScreen)              
   {
      ChangeDisplaySettings(NULL,0);
      ShowCursor(TRUE);
   }

   UnregisterClass("GameTutorials", g_hInstance);    
   PostQuitMessage (0);            
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprev, PSTR cmdline, int ishow)
{    
   HWND hWnd;

   if(MessageBox(NULL, "Click Yes to go to full screen (Recommended)", "Options", MB_YESNO | MB_ICONQUESTION) == IDNO)
      g_bFullScreen = FALSE;
    
   hWnd = CreateMyWindow("www.GameTutorials.com - First OpenGL Program", SCREEN_WIDTH, SCREEN_HEIGHT, 0, g_bFullScreen, hInstance);

   if(hWnd == NULL) return TRUE;

   Init(hWnd);
  
   return MainLoop();
}

LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    LONG    lRet = 0;
    PAINTSTRUCT    ps;

    switch (uMsg)
    {
        case WM_SIZE:                    
            if(!g_bFullScreen)              
            {                    
                SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));
                GetClientRect(hWnd, &g_rRect);        
            }
            break;
  
       case WM_PAINT:                  
           BeginPaint(hWnd, &ps);            
           EndPaint(hWnd, &ps);
           break;

       case WM_KEYDOWN:
           if(wParam == VK_ESCAPE)
              DeInit();
           break;

       case WM_DESTROY:
           DeInit();
           break;

       default:                        
           lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
           break;
    }
  
    return lRet;
}

Argh MSVC messes up tabs Sad EDIT: fixed Smile
Btw, the 90% of code is the damned Windows stuff.
Okay, cya on that idea...I'll stick with Allegro with DX. :o
Only problem is that for some reason MSVC++ with Allegro is really really really slow.
Like, it takes 1 second to plot a pixel. :o
Don't undestand this Allegro nonsense. Just use DirectX/OpenGL directly, it's not hard. Once you've written the init routines, you can reuse them; or put them in a library.

I don't know about you, but I personally avoid things like Allegro like the plague. Who needs two layers of abstraction, except for testing. Yuk.
Well, if it's true that I need to deal with all that Windows handling code, which I haven't even learned yet, Allegro is the way to go for me. Once I learn it (and I will soon enough), perhaps I can get down to the nitty gritty of DX and OpenGL.
With OpenGL, making a Window in Windows is the most time-consuming thing to do, there after, everything is much simpler than DX or so Wink

I use OpenGL as well, I scripted init routines once, and made a 'lib' of them. Never have to script them again Wink Btw, it works much faster than DX Smile
Quote:Only problem is that for some reason MSVC++ with Allegro is really really really slow.
Like, it takes 1 second to plot a pixel. :o

Mind posting your code? As I've never heard anyone say it takes 1 second to plot a pixel I'm really interested in how you're going about plotting that slow pixel. Wink
Code:
#define USE_CONSOLE
#include "allegro.h"
#include <stdlib.h>
int main()
{
    allegro_init ();
    set_gfx_mode (GFX_AUTODETECT_FULLSCREEN,320,200,0,0);
    install_keyboard ();
    while ( !key[KEY_ESC] )
    {
        srand (time (NULL));
        putpixel (screen,rand () % 320,rand () % 200,2);
    }
    return 0;
} END_OF_MAIN()
It plots a pixel every one second or so.
Dont set the freakin' seed every loop! You just need to do it at the beginning Tongue
Oops. :oops: I'm just used to putting a RANDOMIZE TIMER at the beginning of each of my loops in QB. Why is QB's random-number-seed function so much faster than stdlib's?
Pages: 1 2