• Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    I have some problems with tinygl using generated textures with alpha, but i guess that is a depth buffer problem because sometimes the zone of texture with alpha is drawed properly, but it draws the background color sometimes, i revised all code, i checked my 2d engine in opengl for iphone to check if there is something i forgot, i searched on google dozens of webs without any result. Maybe someone see the error, i don't have any idea on this moment. Here is the code and makefile:

    Makefile:
    Code:

    CC = gcc
    LD = ld
    STRIP = strip
    CFLAGS = -O1 -s -fomit-frame-pointer -noixemul -ISDK:tinygl-sdk/include

    NOSTARTUPFILES = 1
    #GOTO = 1
    REMOVE = 1

    ifdef NOSTARTUPFILES
    CFLAGS+= -DNOSTARTUPFILES -nostartfiles
    endif

    ifdef GOTO
    CFLAGS+= -DGOTO
    endif

    ifdef REMOVE
    CFLAGS+= -DREMOVE
    endif

    INTRO_OBJS = intro.o

    all: intro

    intro: $(INTRO_OBJS)
    $(CC) $(CFLAGS) -o $@ $(INTRO_OBJS)
    $(STRIP) -s -R .comment -R .gnu.version -R .gnu.version_d -R .gnu.version_r $@
    chmod u+x $@

    intro_map:
    $(CC) $(CFLAGS) intro.c -Wl,-Map=foobar.map,--traditional-format

    clean:
    rm -f *.o intro


    intro.c:
    Code:

    /*
    * 4Kb Intro startup by Pedro Gil (Balrog Soft)
    * www.amigaskool.net
    *
    * TinyGL and AHI device startup code,
    * and music synth for 4k intros.
    * The song was ripped from howagen intro by tonic.
    *
    * Special thanks to Piru for his small opts,
    * and Morphzone.org people!
    *
    */

    #include <devices/ahi.h>

    #include <proto/exec.h>
    #include <proto/dos.h>
    #include <proto/tinygl.h>
    #include <proto/ahi.h>

    #include <stdio.h>

    #define FREQUENCY 8000
    #define TYPE AHIST_M8S
    #define BUFFERSIZE 24000

    #define TONEFREQ 440.0f
    #define TONEBASE 1.059463094359f
    #define TONEBYTES 2047

    #define CHANELS 3
    #define WAVE_SAWTOOTH 0
    #define WAVE_SQUARE 1
    #define VOL_DECAY -1
    #define VOL_MAX 32

    #ifndef M_PI
    #define M_PI 3.14159265
    #define M_PI2 6.283185
    #endif

    #define MAX_PARTICLES 32

    #define sawtooth(O,D) ((O - 32) * D) >> 4
    #define square(O,D) (((O&31) < 16 ? 31 : -32) * D) >> 4

    static void display(void);
    #ifndef GOTO
    static void fill_buffer(void);
    #endif

    struct ExecBase *SysBase;
    struct DosLibrary *DOSBase;
    struct Library *TinyGLBase;

    GLContext *__tglContext;

    static struct MsgPort *AHImp = NULL;
    static struct AHIRequest *AHIios1 = NULL;
    static struct AHIRequest *AHIios2 = NULL;
    static struct AHIRequest *link = NULL;
    static struct Task *self;

    static GLuint texture[1]; // Storage For Our Particle Texture

    static GLfloat vertex [MAX_PARTICLES*18];
    static GLfloat texcoords[MAX_PARTICLES*12];
    static LONG tex[32 * 32];

    static BYTE AHIDevice = -1, ch;
    static BYTE buffer1[BUFFERSIZE], buffer2[BUFFERSIZE], vol[CHANELS], wave[CHANELS];
    static BYTE *p1=buffer1, *p2=buffer2;
    static void *tmp;
    static BOOL init = TRUE;
    static ULONG signals;
    static FLOAT anote[CHANELS], freq[CHANELS];
    static LONG i, j, tbuf = 0, track_note = 0,
    m_w = 19298, m_z = 84729;
    static char cnote[CHANELS];
    static char *song[] = {"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@EEHGHJHGAAHGHJHGCCJHJLJHEHGHJH"
    "GDEELJJJHHEEJHHHGGCCJHHHGGEEDEEEGGE@EGJHGEA@AHJLHGC@CJLJHGEHGHJ"
    "LHGE",
    "QQXQQXQXMMTMMTMTOOVOOVOVLLSLLSLS",
    "EEEEEEEEHEEEEEEEJEEEEEEELEEEEEEE"};

    #define __TEXTSECTION__ __attribute__((section(".text")))

    #ifdef NOSTARTUPFILES
    int entry(void)
    #else
    int main(void)
    #endif
    {
    SysBase = *(struct ExecBase **) 4;

    DOSBase = OpenLibrary("dos.library", 50);
    TinyGLBase = OpenLibrary("tinygl.library", 50);

    if (TinyGLBase)
    {
    self = FindTask(NULL);

    // Initialize AHI device
    AHImp=CreateMsgPort();
    #ifndef REMOVE
    if(AHImp != NULL)
    {
    #endif
    AHIios1 = (struct AHIRequest *) CreateIORequest(AHImp, sizeof(struct AHIRequest));
    AHIios1->ahir_Version = 4;
    AHIDevice = OpenDevice(AHINAME, 0, (struct IORequest *)AHIios1, 0);
    #ifndef REMOVE
    }
    #endif

    // Make a copy of the request (for double buffering)
    AHIios2 = AllocMem(sizeof(struct AHIRequest), MEMF_ANY);
    CopyMem(AHIios1, AHIios2, sizeof(struct AHIRequest));

    // Configure synth chanels
    vol[0] = 16;
    vol[1] = VOL_DECAY;
    vol[2] = VOL_DECAY;

    wave[0] = WAVE_SQUARE;
    wave[1] = WAVE_SAWTOOTH;
    wave[2] = WAVE_SAWTOOTH;

    __tglContext = GLInit();
    if (__tglContext)
    {

    glutInit(NULL,NULL);

    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    #ifndef REMOVE
    glutInitWindowSize(640, 480);
    #endif
    glutFullScreen();
    glutCreateWindow(NULL);

    glClearColor(0.0f, 0.0f, 1.0f, 0.0f);

    // Enable depth test
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);

    // Enable blending function
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    //glBlendFunc(GL_SRC_ALPHA,GL_ONE);

    // Create texture
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &texture[0]);
    LONG n;
    for (i = 0; i < 32; i++)
    {
    for (j = 0; j < 32; j++)
    {
    n = (i-16)+(j-16);
    if (n > -24 & n < 24)
    tex[i*32+j] = 0xffffffff;
    else
    tex[i*32+j] = 0x00000000;
    }
    }
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_BGRA, GL_UNSIGNED_BYTE, tex);

    glBindTexture(GL_TEXTURE_2D, texture[0]);

    // Create vertex and texture coords arrays
    for (i = 0; i < MAX_PARTICLES; i++)
    {
    GLfloat x = (rand()%10-5)*1.5f;
    GLfloat y = (rand()%10-5)*1.5f;
    GLfloat z = ((rand()%10-5)-40)*1.0f;
    FLOAT s = (rand()%10)*0.5f;

    n = i * 18;
    vertex[n] = x+0.5f*s;
    vertex[n+1] = y+0.5f*s;
    vertex[n+2] = z;

    vertex[n+3] = x-0.5f*s;
    vertex[n+4] = y+0.5f*s;
    vertex[n+5] = z;

    vertex[n+6] = x+0.5f*s;
    vertex[n+7] = y-0.5f*s;
    vertex[n+8] = z;

    vertex[n+9] = x-0.5f*s;
    vertex[n+10] = y+0.5f*s;
    vertex[n+11] = z;

    vertex[n+12] = x+0.5f*s;
    vertex[n+13] = y-0.5f*s;
    vertex[n+14] = z;

    vertex[n+15] = x-0.5f*s;
    vertex[n+16] = y-0.5f*s;
    vertex[n+17] = z;

    n = i * 12;
    texcoords[n] = 1.0f;
    texcoords[n+1] = 1.0f;

    texcoords[n+2] = 0.0f;
    texcoords[n+3] = 1.0f;

    texcoords[n+4] = 1.0f;
    texcoords[n+5] = 0.0f;

    texcoords[n+6] = 0.0f;
    texcoords[n+7] = 1.0f;

    texcoords[n+8] = 1.0f;
    texcoords[n+9] = 0.0f;

    texcoords[n+10] = 0.0f;
    texcoords[n+11] = 0.0f;

    }

    // Enable client state for vertex and texture coords
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Set projecto matrix
    glMatrixMode(GL_PROJECTION);
    gluPerspective(80, 640.0 / 480.0, 1.0, 500.0);
    glMatrixMode(GL_MODELVIEW);

    // Set pointers to arrays
    glVertexPointer(3, GL_FLOAT, 0, vertex);
    glTexCoordPointer(2, GL_FLOAT, 0, texcoords);

    glutIdleFunc(display);

    glutMainLoop();

    GLClose(__tglContext);
    }

    // Abort any pending iorequests
    AbortIO((struct IORequest *) AHIios1);
    WaitIO((struct IORequest *) AHIios1);

    if(link) // Only if the second request was started
    {
    AbortIO((struct IORequest *) AHIios2);
    WaitIO((struct IORequest *) AHIios2);
    }

    CloseLibrary(TinyGLBase);

    CloseLibrary(DOSBase);
    }
    return 0;
    }

    static void display(void)
    {
    // Ahi device handle code

    // Send io request to the device
    if ((signals & (1L << AHImp->mp_SigBit) || init))
    {
    if (init && link)
    init = FALSE;
    if (!link)
    #ifdef GOTO
    {
    tmp = &&ret1;
    goto synth;
    }
    ret1:
    #else
    fill_buffer();
    ret1:
    #endif
    AHIios1->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
    AHIios1->ahir_Std.io_Command = CMD_WRITE;
    AHIios1->ahir_Std.io_Data = p1;
    AHIios1->ahir_Std.io_Length = BUFFERSIZE;
    AHIios1->ahir_Std.io_Offset = 0;
    AHIios1->ahir_Frequency = FREQUENCY;
    AHIios1->ahir_Type = TYPE;
    AHIios1->ahir_Volume = 0x10000; // Full volume
    AHIios1->ahir_Position = 0x8000; // Centered
    AHIios1->ahir_Link = link;
    SendIO((struct IORequest *) AHIios1);
    }

    // Check if there are any signals from ahi device
    if(link)
    {
    // Send a fake signal to not stop the loop
    Signal(self, SIGBREAKF_CTRL_D);
    signals = Wait(SIGBREAKF_CTRL_D | (1L << AHImp->mp_SigBit));
    }

    link = AHIios1;

    // Swap ahi buffers
    if ((signals & (1L << AHImp->mp_SigBit)) || init)
    {
    if (!init)
    WaitIO((struct IORequest *) AHIios2);

    // Swap buffer and request pointers, and restart
    tmp = p1;
    p1 = p2;
    p2 = tmp;

    #ifdef GOTO
    tmp = &&ret2;
    goto synth;
    ret2:
    #else
    fill_buffer();
    #endif

    tmp = AHIios1;
    AHIios1 = AHIios2;
    AHIios2 = tmp;
    }


    // TinyGL stuff goes here

    // Clear Screen And Depth Buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //glLoadIdentity();

    glTranslatef(0.0f,0.0f,-40.0f);
    glRotatef(0.5f, 0.0f, 1.0f, 0.0f);
    glTranslatef(0.0f,0.0f,40.0f);

    glDrawArrays(GL_TRIANGLES, 0, MAX_PARTICLES*6);

    glutSwapBuffers();

    #ifdef GOTO
    return;

    // Synth code for testing
    synth:

    // Copy synth code here!!!
    goto *tmp;
    #endif
    }

    #ifndef GOTO
    static void fill_buffer(void)
    {
    LONG n;
    SHORT decay, note, note_pos;
    for (n = 0; n < BUFFERSIZE; n++)
    {
    // Check the position in the buffer
    note_pos = ((tbuf + n + 1) & TONEBYTES);
    note = 0;
    // Calculate decay level
    decay = (1024 - (note_pos - 1024))>>6;
    if (decay < 0)
    decay = 0;
    for (ch = 0; ch < CHANELS; ch++)
    {
    if (note_pos == 0)
    {
    // Set base frequency
    freq[ch] = TONEBASE;

    // Increments the track note to be played
    if (ch == 0)
    track_note ++;

    // And get the notes to play
    char pnote = song[ch][track_note % strlen(song[ch])]-64;
    if (pnote != cnote[ch])
    {
    cnote[ch] = pnote;
    anote[ch] = 0;
    }

    // Get the frequency for the note to be played
    for (j = 1; j < cnote[ch]; j ++)
    freq[ch] *= TONEBASE;

    if (cnote[ch] == 0)
    freq[ch] = 0;

    freq[ch] = (TONEFREQ * freq[ch]) / 512;
    }
    // Increase the note frequency to complete a wave
    anote[ch] += freq[ch];

    // Generate waves with sawtooth and square oscilators
    // Decay can be used to set a volume
    BYTE vol_ch = vol[ch] < 0 ? decay : vol[ch],
    osc = (BYTE)anote[ch] & 63;
    if (wave[ch] == WAVE_SAWTOOTH)
    note += sawtooth(osc, vol_ch) % 32;
    else if (wave[ch] == WAVE_SQUARE)
    note += square(osc, vol_ch) % 32;
    }
    //printf(" %hin",decay);
    if (note > 127)
    note = 127;
    else if (note < -128)
    note = -128;

    // Store wave on buffer
    p1[n] = note;
    }
    tbuf += BUFFERSIZE;

    }
    #endif

    #ifdef NOSTARTUPFILES
    /* __abox__ symbol is required or else the binary is loaded as PowerUP app */
    const int __abox__ __TEXTSECTION__ = 1;
    #endif
    Balrog Software - AmigaSkool.net
    Mac Mini - MorphOS 3.8 - G4 1.5Ghz - Ati 9200 64 Mb
    Efika - MorphOS 3.6 - Ati 9200 64Mb - 80 Gb HD
    Amiga 1200D - OS 3.9 - Blizzard 603e/240mh
  • »06.08.10 - 22:45
    Profile Visit Website