Problems with tinygl, depth buffer problem?
  • 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
  • MorphOS Developer
    kiero
    Posts: 129 from 2003/2/28
    your problem is that even if blending is enabled pixels are always written to the buffers (color/depth). even completely transparent ones. if you want to disable writing of transparent pixels you should enable alpha testing. another solution (but this depends what you want to achieve) is to disable writing to depthbuffer completely (glDepthMask(GL_FALSE) or disable depth buffer testing. this way elements won't be 'sorted' but with this example it doesn't really matter.
  • »07.08.10 - 12:03
    Profile Visit Website
  • Order of the Butterfly
    Order of the Butterfly
    BalrogSoft
    Posts: 171 from 2006/10/6
    From: Spain
    This is an example to see what is the problem, but for my effect i need depth buffer, i tried before to enable glEnable(GL_ALPHA_TEST), and it didn't work when i tried, but now it works, i added glAlphaFunc(GL_GREATER, 0.4f) and this was the part missing.

    Thanks a lot, Kiero!
    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
  • »07.08.10 - 12:38
    Profile Visit Website