Avatar billede dcgeek Nybegynder
18. september 2002 - 21:31 Der er 15 kommentarer og
1 løsning

OpenGL i Dev-C++ HJÆLP

Jeg har fået fat i noget source-code til et program, hvor man skal bruge SDL. Jeg har installeret SDL helt korrekt (har fuldt punkt og prikke i manualen til hvordan man installerer SDL).
Men jeg får hele tiden fejlen:
Undefined reference to 'GluPerspective@32'

Koden ser således ud:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
#include <gl/gl.h>                                        // Header File For The OpenGL32 Library
#include <gl/glu.h>                                        // Header File For The GLu32 Library

#define SCREEN_WIDTH  800                                  // We want our screen width 800 pixels
#define SCREEN_HEIGHT 600                                  // We want our screen height 600 pixels
#define SCREEN_DEPTH  16                                  // We want 16 bits per pixel

#include "SDL.h"                                          // The SDL Header File

int VideoFlags = 0;                                        // Video Flags for the Create Window function
SDL_Surface * MainWindow = NULL;                          // drawing surface on the SDL window


// This is our main rendering function prototype.  It's up here for now so MainLoop() can call it.
void RenderScene();

// This Quits SDL
void Quit(int);

/////////////////////////////////// TOGGLE FULL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
///////
///////  This function TOGGLES between FULLSCREEN and WINDOWED mode
///////
/////////////////////////////////// TOGGLE FULL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void ToggleFullScreen(void)
{
    if(SDL_WM_ToggleFullScreen(MainWindow) == 0)          // try to toggle fullscreen mode for window 'MainWindow'
    {
        cerr << "Failed to Toggle Fullscreen mode : " << SDL_GetError() << endl;  // report error in case toggle fails
        Quit(0);
    }
}
///////////////////////////////  CREATE MY WINDOW  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
////////
////////  This function CREATES our WINDOW for drawing the GL stuff
////////
///////////////////////////////  CREATE MY WINDOW  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void CreateMyWindow(const char * strWindowName, int width, int height, int VideoFlags)
{
    MainWindow = SDL_SetVideoMode(width, height, SCREEN_DEPTH, VideoFlags);    // SCREEN_DEPTH is macro for bits per pixel

    if( MainWindow == NULL )                                                    // if window creation failed
    {
        cerr << "Failed to Create Window : " << SDL_GetError() << endl;        // report error
        Quit(0);
    }

    SDL_WM_SetCaption(strWindowName, strWindowName);      // set the window caption (first argument) and icon caption (2nd arg)
}

/////////////////////////////  SETUP PIXEL FORMAT  \\\\\\\\\\\\\\\\\\\\\\\\\\\\*
///////
///////  Sets the pixel format for openGL and video flags for SDL
///////
/////////////////////////////  SETUP PIXEL FORMAT  \\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void SetupPixelFormat(void)
{
    //////// SURFACE IS THE DRAWABLE PORTION OF AN SDL WINDOW \\\\\\\\*

      /////////////  we set the common flags here
    VideoFlags    = SDL_OPENGL;                            // it's an openGL window
    VideoFlags  |= SDL_HWPALETTE;                        // exclusive access to hardware colour palette
    VideoFlags  |= SDL_RESIZABLE;                        // the window must be resizeable

    const SDL_VideoInfo * VideoInfo = SDL_GetVideoInfo();  // query SDL for information about our video hardware

    if(VideoInfo == NULL)                                  // if this query fails
    {
        cerr << "Failed getting Video Info : " << SDL_GetError() << endl;          // report error
        Quit(0);
    }

    ///////////// we set the system dependant flags here
    if(VideoInfo -> hw_available)                          // is it a hardware surface
        VideoFlags |= SDL_HWSURFACE;
    else
        VideoFlags |= SDL_SWSURFACE;
   
    // Blitting is fast copying / moving /swapping of contiguous sections of memory
    // for more about blitting check out : http://www.csc.liv.ac.uk/~fish/HTML/blitzman/bm_blitter.html
    if(VideoInfo -> blit_hw)                              // is hardware blitting available
        VideoFlags |= SDL_HWACCEL;

    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );        // tell SDL that the GL drawing is going to be double buffered
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE,  SCREEN_DEPTH);        // size of depth buffer
    SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);          // we aren't going to use the stencil buffer
    SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);        // this and the next three lines set the bits allocated per pixel -
    SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);      // - for the accumulation buffer to 0
    SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
    SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
}

//////////////////////////// RESIZE OPENGL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////    This function resizes the viewport for OpenGL.
/////
//////////////////////////// RESIZE OPENGL SCREEN \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void SizeOpenGLScreen(int width, int height)              // Initialize The GL Window
{
    if (height==0)                                        // Prevent A Divide By Zero error
    {
        height=1;                                          // Make the Height Equal One
    }

    glViewport(0,0,width,height);                          // Make our viewport the whole window
                                                          // We could make the view smaller inside
                                                          // Our window if we wanted too.
                                                          // The glViewport takes (x, y, width, height)
                                                          // This basically means, what our drawing boundries

    glMatrixMode(GL_PROJECTION);                          // Select The Projection Matrix
    glLoadIdentity();                                      // Reset The Projection Matrix

                                                          // Calculate The Aspect Ratio Of The Window
                                                          // The parameters are:
                                                          // (view angle, aspect ration of the width to the height,
                                                          //  The closest distance to the camera before it clips,
                  // FOV        // Ratio                  //  The farthest distance before it stops drawing)
    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 1 ,150.0f);

    // * Note * - The farthest distance should be at least 1 if you don't want some
    // funny artifacts when dealing with lighting and distance polygons.  This is a special
    // thing that not many people know about.  If it's less than 1 it creates little flashes
    // on far away polygons when lighting is enabled.

    glMatrixMode(GL_MODELVIEW);                            // Select The Modelview Matrix
    glLoadIdentity();                                      // Reset The Modelview Matrix
}

////////////////////////////////  INITIALIZE GL  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////        This function handles all the initialization for openGL
/////
////////////////////////////////  INITIALIZE GL  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void InitializeOpenGL(int width, int height)
{
    SizeOpenGLScreen(width, height);                      // resize the OpenGL Viewport to the given height and width
}

///////////////////////////////// INIT GAME WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////  This function initializes the game window.
/////
///////////////////////////////// INIT GAME WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void Init()
{
    InitializeOpenGL(SCREEN_WIDTH,SCREEN_HEIGHT);          // Initialize openGL

    // *Hint* We will put all our game init stuff here
    // Some things include loading models, textures and network initialization
}

//////////////////////////////////      HANDLE KEY PRESS EVENT    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
//////
//////    This function handles the keypress events generated when the user presses a key
//////
//////////////////////////////////      HANDLE KEY PRESS EVENT    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void HandleKeyPressEvent(SDL_keysym * keysym)
{
    switch(keysym -> sym)                                  // which key have we got
    {
        case SDLK_F1 :                                    // if it is F1
            ToggleFullScreen();                            // toggle between fullscreen and windowed mode
            break;

        case SDLK_ESCAPE:                                  // if it is ESCAPE
            Quit(0);                                      // quit after cleaning up
           
        default:                                          // any other key
            break;                                        // nothing to do
    }
}
//////////////////////////////  MAIN GAME LOOP  \\\\\\\\\\\\\\\\\\\\\\\\\\\\*
//////
//////  This function handles the main game loop
//////
//////////////////////////////  MAIN GAME LOOP  \\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void MainLoop(void)
{
    bool done = false;                                    // is our job done ? not yet !
    SDL_Event event;

    while(! done)                                          // as long as our job's not done
    {
        while( SDL_PollEvent(& event) )                    // look for events (like keystrokes, resizing etc.)
        {
            switch ( event.type )                          // what kind of event have we got ?
            {
                case SDL_QUIT :                            // if user wishes to quit
                    done = true;                          // this implies our job is done
                    break;

                case SDL_KEYDOWN :                        // if the user has pressed a key
                    HandleKeyPressEvent( & event. key.keysym );        // callback for handling keystrokes, arg is key pressed
                    break;

                case SDL_VIDEORESIZE :                    // if there is a resize event
                    // request SDL to resize the window to the size and depth etc. that we specify
                    MainWindow = SDL_SetVideoMode( event.resize.w, event.resize.h, SCREEN_DEPTH, VideoFlags );
                    SizeOpenGLScreen(event.resize.w, event.resize.h);  // now resize the OpenGL viewport
   
                    if(MainWindow == NULL)                // if window resize has failed
                    {
                        cerr << " Failed resizing SDL window : " << SDL_GetError() << endl;  // report error
                        Quit(0);
                    }
                    break;

                default:                                  // any other event
                    break;                                // nothing to do
            } // switch
        } // while( SDL_ ...

        RenderScene();                                    // draw our OpenGL scene
    } // while( ! done)
}
//////////////////////////////      MAIN      \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
//////
//////    create the window and calling the initialization functions
//////
//////////////////////////////      MAIN      \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

int main(void)
{
    // print user instructions
    cout << " Hit the F1 key to Toggle between Fullscreen and windowed mode" << endl;
    cout << " Hit ESC to quit" << endl;

    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )                  // try to initialize SDL video module
    {
        cerr << "Failed initializing SDL Video : " << SDL_GetError() << endl;      // report error if it fails
        return 1;                                          // we use this instead of Quit because SDL isn't yet initialized
    }

    // Set up the format for the pixels of the OpenGL drawing surface
    SetupPixelFormat();   
    // Create our window, we pass caption for the window, the width, height and video flags required
    CreateMyWindow("www.GameTutorials.com - First OpenGL Program", SCREEN_WIDTH, SCREEN_HEIGHT, VideoFlags);

    // Initializes our OpenGL drawing surface
    Init();

    // Run our message loop
    MainLoop();

    // quit main returning success
    return 0;
}

///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////    This function renders the entire scene.
/////
///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void RenderScene()
{
    int i=0;   

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear The Screen And The Depth Buffer
    glLoadIdentity();                                      // Reset The View
    glColor3f ( 1.0, 1.0, 1.0 );

    SDL_GL_SwapBuffers();                                  // Swap the backbuffers to the foreground
}
//////////////////////////////    QUIT    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
//////
//////      This will shutdown SDL and quit the program
//////
//////////////////////////////    QUIT    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void Quit(int ret_val)
{
    SDL_Quit();                                            // shuts down SDL stuff

    exit(ret_val);                                        // quit the program
}
Avatar billede soreno Praktikant
18. september 2002 - 21:34 #1
det er fordi du ikke linker med libglu32.a
gå ind i project settings i dev-cpp og vælg noget ala (næsten øverst):
add libs
og tilføj libglu32.a fra c:\dev-cpp\libs
Avatar billede soreno Praktikant
18. september 2002 - 21:39 #2
du kommer nok heller ikke uden om at skulle linke med libopengl32.a samt de libs som følger med sdl
Avatar billede dcgeek Nybegynder
18. september 2002 - 21:45 #3
Nu får jeg bare meddelelsen: undefined reference to 'SDL_main'
Avatar billede dcgeek Nybegynder
18. september 2002 - 21:49 #4
Nu har jeg også linket med alle de *.lib og .a der er, men jeg får bare meddelelsen undefined reference to 'SDL_main'
Avatar billede soreno Praktikant
18. september 2002 - 21:54 #5
dvs, du har linket med:
libglu32.a
libopengl32.a
libSDL.a
libSDLmain.a
??

det kan være en fordel kun at linke med dem du faktisk skal bruge, eller kan der opstå navneinkonsistens - dvs. flere metoder kan hedde det samme i forskellige libs.
Avatar billede dcgeek Nybegynder
18. september 2002 - 21:56 #6
ja, jeg har linket med disse filer... nej der er ikke nogen navneinkonsistens. Den siger der er en undefined reference til SDL_main i funktionen console_main
Avatar billede mbulow Nybegynder
18. september 2002 - 22:20 #7
Kender desværre ikke til hverken SDL eller Dev-C++ (Ikke meget ihvertfald)

Men jeg snublede lige over et par links der måske indholder noget brugbart:

http://docs.deninet.com/sdl_on_dev_c.htm
http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/gfxsdl/tut1
Avatar billede mbulow Nybegynder
18. september 2002 - 22:23 #8
Hov... Fandt lige lidt mere:

Q: I get "Undefined reference to 'SDL_main'" ...
A: Make sure that you are declaring main() as:
#include "SDL.h"

int main(int argc, char *argv[])

You should be using main() instead of WinMain() even though you are creating a Windows application, because SDL provides a version of WinMain() which performs some SDL initialization before calling your main code. If for some reason you need to use WinMain(), take a look at the SDL source code in src/main/win32/SDL_main.c to see what kind of initialization you need to do in your WinMain() function so that SDL works properly.



Jeg bemærkede lige at du brugte en int main(void) i stedet for :)
Måske måske... JEG ved ikke
Avatar billede soreno Praktikant
18. september 2002 - 22:24 #9
ok, nu har jeg hentet sdl og jeg kan altså godt få det til at spille.
nu kender jeg ikke så meget til dev-cpp pakken, men den er jo baseret på mingw - og med mingw har jeg kompileret med følgende makefile:

# Compiler
CC=g++

# Path to libs
LIBS=c:\programmer\gnu\mingw\lib

# lib files (*.a)
LIB=$(LIBS)\libSDL.a $(LIBS)\libSDLmain.a $(LIBS)\libopengl32.a $(LIBS)\libglu32.a

# target
all:    main

main:
    @echo --------------------------main-------------------------
    $(CC) -c "main.cpp" -s -mwindows
    $(CC) -o "main.exe" "main.o" $(LIB) -lmingw32 -lSDLmain -lSDL -mwindows

clean:
    del *.o
    del main.exe
Avatar billede soreno Praktikant
18. september 2002 - 22:25 #10
jeg havde også lidt start problemer, men det handlede tilsyneladende om rækkefølgen på parameterne da jeg linkede :-)
Avatar billede soreno Praktikant
18. september 2002 - 22:29 #11
nå ja, jeg har - som mbulow også har fundet ud af - udskiftet:
int main(void)

med:
int main(int argc, char **argv)
Avatar billede dcgeek Nybegynder
19. september 2002 - 15:53 #12
Nu har jeg ændret koden int main(void) vil
int main(int argc, char *argv[])

og nu kommer der en fejlmeddelelse der siger:
Undefined reference to 'gluPerspective@32'
Avatar billede soreno Praktikant
19. september 2002 - 15:59 #13
prøv at tryk "generate makefile" i en af menuerne og post den her.
Avatar billede mbulow Nybegynder
19. september 2002 - 16:43 #14
Nu tager vi den lige step-by-step her:

1) Download og installeret Dev-C++ (Version 5 Beta'en)
2) Download "SDL-devel-1.2.4-mingw32.tar.gz" fra www.libsdl.org
3) Download "SDL-1.2.4-win32.zip" fra www.libsdl.org
4) Kopier Dll'en fra zip-filen til Windows-biblioteket
5) Kopier filerne i lib-biblioteket fra tar.gz-filen til Dev-C++'s lib-bibliotek
6) Kopier include\SDL-mappen fra tar.gz-filen til Dev-C++'s include-bibliotek (Så mappen SDL nu findes i Dev-C++'s include-mappe)


7) Opret et C++ Conlose Application projekt, og indsæt din kode
8) Ret #include "SDL.h" til #include <SDL/SDL.h>
9) Ret int main(void) til int main(int argc, char *argv[])
10) Project options indtast:
    -lmingw32 -lSDLmain -lSDL -lglu32 -lopengl32 -mwindows
    i Linker options
Avatar billede mbulow Nybegynder
19. september 2002 - 17:22 #15
Hov forresten... Må nok hellere lige fortælle at det der måske ikke er den ultimative løsning, men blot hvordan jeg fik det til at virke.

Kompilerer og starter fint. Undrer mig bare lidt at der kun kommer et vindue frem med helt sort indhold? Er det rigtigt?
(Gider ikke lige kigge hele sovsen igennem, når jeg ikke kender til hverken OpenGL eller SDL)
Avatar billede soreno Praktikant
19. september 2002 - 20:11 #16
det er korrekt at der skal komme et sort vindue frem.
det er vist et hello world eksempel, ideeen er vist at man tilføjer kode til RenderScene()

eks. tilføje en global variabel int angle = 0;
void RenderScene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // Clear The Screen And The Depth Buffer
    glLoadIdentity();                                      // Reset The View
    glRotatef(angle++, 0.0f, 0.0f, 1.0f);
    glBegin(GL_POLYGON);
      glColor3f( 0.8, 0.8, 0.0 ); glVertex3f( 0.3f,  0.3f, -1.0f);
      glColor3f( 0.0, 0.8, 0.8 ); glVertex3f( 0.3f, -0.3f, -1.0f);
      glColor3f( 0.8, 0.0, 0.8 ); glVertex3f(-0.3f, -0.3f, -1.0f);
      glColor3f( 0.0, 0.0, 0.8 ); glVertex3f(-0.3f,  0.3f, -1.0f);
    glEnd();
    SDL_GL_SwapBuffers();                                  // Swap the backbuffers to the foreground
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester