Questions about TinyGL (was TinyGL and glMaterialv)
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Hello,

    I just ported some gl tests to MorphOs and I wonder why the colors are not correct.
    Corresponding to glMaterialfv the third parameter should be an array of float values in RGBA format.

    Is that still correct on MorphOs, or is the order of RGBA values different (e.g. ABGR)?

    EDIT:
    Hmm, GraphicBoard says that the Radeon uses BGRA, but the colors are still wrong.

    [ Edited by eliot 13.01.2017 - 06:38 ]
    regards
    eliot
  • »12.10.16 - 11:49
    Profile
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Jupp3
    Posts: 1193 from 2003/2/24
    From: Helsinki, Finland
    TinyGL should work as specified by the OpenGL standards.

    However, afaik, there have been some bigger changes recently (using shaders internally for some things) and because of that, some things might not yet work quite as expected (even if they worked before), and might work differently on different gfx cards.

    afaik, f.ex. texture matrix transformations don't work at all, at least on some gfx cards. No idea about glMaterial* (haven't used anything but grayscale on MorphOS myself lately, so might have missed that myself)

    It can help, if you list all the functionality, that doesn't seem to work properly.
  • »12.10.16 - 13:53
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Hm, ok,

    I am using the following code to set the material:

    Code:

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat.ambient.rgba);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat.diffuse.rgba);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat.specular.rgba);
    glMaterialf(GL_FRONT, GL_SHININESS, mat.shininess);


    rgba points to an array of float values (rgba order).

    The result on linux:
    firstperson_linux.png
    The result on mac:
    firstperson_mac.png
    the reult on mos:
    firstperson_mos.png

    In the end it should look like Zeewolf2
    zeewolf2.png

    because I really like clean look of filled polygons.
    Currently it is still the first person game controller, next step will be loading hight maps and implementing a flight controller.

    I tested on a Mac Mini Silent Upgrade with Mos 3.9, but perhaps I can also prepare my Mac MDD with Radeon 9600 and test
    it there.

    [ Edited by eliot 12.10.2016 - 20:11 ]
    regards
    eliot
  • »12.10.16 - 17:07
    Profile
  • MorphOS Developer
    bigfoot
    Posts: 508 from 2003/4/11
    From the screenshots this doesn't look like a colour order problem at all. There's no way you can get yellow from both red, blue and grey with just a messed up colour order. Also, the problem is probably driver related rather than a generic problem in the OpenGL implementation, so it very likely only happens on R200.

    When it comes to OpenGL problems, "help me help you" applies as usual. The easier you can make it for me to reproduce and identify the problem, the more time I have to actually fixing it and the more likely it is that a fix actually happens. So if you do the following things, it would help a lot towards getting this problem fixed:

    1) Test it on a different driver (ie, r300) and see if the problem occurs there as well. It probably doesn't, though.
    2) If you know a MorphOS beta tester, get him to test on a recent MorphOS beta to make sure that the issue hasn't already been fixed, however I don't think this one has.
    3) This is the most important step. Turn the problem into an as simple C code example as possible. Do the required OpenGL setup to reproduce the problem and draw a single primitive to display the issue, and then make the source code for that test app available to me. Bonus points if it uses GLUT for easy compilation/testing on Linux.
    I rarely log in to MorphZone which means that I often miss private messages sent on here. If you wish to contact me, please email me at [username]@asgaard.morphos-team.net, where [username] is my username here on MorphZone.
  • »12.10.16 - 19:37
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    @bigfoot

    Ok, I will test it with my PowerMacc Mdd Radeon 9600 and write a small demo application.
    regards
    eliot
  • »12.10.16 - 20:17
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Ok,

    I prepared my Power Mac Mdd with Radeon 9600 gfx card.
    Sadly with the same result:

    firstperson_mos_r300.png

    So it has nothing to do with the r200 or r300 driver.
    I will code a little test program and provide it to you.
    regards
    eliot
  • »13.10.16 - 18:49
    Profile
  • MorphOS Developer
    bigfoot
    Posts: 508 from 2003/4/11
    I actually expected this one to be driver specific. Interesting that it's not.

    Looking forward to the test program :)
    I rarely log in to MorphZone which means that I often miss private messages sent on here. If you wish to contact me, please email me at [username]@asgaard.morphos-team.net, where [username] is my username here on MorphZone.
  • »13.10.16 - 19:54
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Ok bigfoot,

    some good news for you, some bad for me:
    Simple materials tests looks good on r200 and r300 on mos:
    test_materials_mos_r200.png
    test_materials_mos_r300.png

    the code:
    Code:

    #ifdef __APPLE__
    #include <gl.h>
    #include <glu.h>
    #include <glut.h>
    #else

    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>

    #endif

    #include <assert.h>


    static char *TITLE = "test_materials";


    void init() {
    GLfloat LP[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 10,
    (GLfloat) 1};
    GLfloat A[] = {(GLfloat) 0.1,
    (GLfloat) 0.1,
    (GLfloat) 0.1};
    GLfloat S[] = {(GLfloat) 0.5,
    (GLfloat) 0.5,
    (GLfloat) 0.5};
    GLfloat D[] = {(GLfloat) 0.5,
    (GLfloat) 0.5,
    (GLfloat) 0.5};
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_FRONT);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLightfv(GL_LIGHT0, GL_POSITION, LP);
    glLightfv(GL_LIGHT0, GL_AMBIENT, A);
    glLightfv(GL_LIGHT0, GL_SPECULAR, S);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, D);

    glClearColor(0.f, 0.f, 0.f, 1.f);
    }

    void reshape(int width, int height) {
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(65.0, (float) width / (float) height, 1.0, 100);
    }

    void display() {

    static GLfloat RA[] = {(GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1};
    static GLfloat RS[] = {(GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1};
    static GLfloat RD[] = {(GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1};

    static GLfloat GA[] = {(GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 1};
    static GLfloat GS[] = {(GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 1};
    static GLfloat GD[] = {(GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 1};

    static GLfloat BA[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 1};
    static GLfloat BS[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 1};
    static GLfloat BD[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 1};
    static GLfloat Y = 0;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(0, 0, 5,
    0, 0, 0,
    0, 1, 0);


    glBegin(GL_QUADS);
    glNormal3d(0, 0, 1);
    glMaterialfv(GL_FRONT, GL_AMBIENT, RA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, RD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, RS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);
    glVertex3d(0, 0, 0);
    glVertex3d(1, 0, 0);
    glVertex3d(1, 1, 0);
    glVertex3d(0, 1, 0);
    glEnd();

    glBegin(GL_TRIANGLES);
    glNormal3d(0, 0, 1);
    glMaterialfv(GL_FRONT, GL_AMBIENT, GA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, GD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, GS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);
    glVertex3d(1, 0, 0);
    glVertex3d(2, 0, 0);
    glVertex3d(2, 1, 0);
    glEnd();

    glBegin(GL_TRIANGLES);
    glNormal3d(0, 0, 1);
    glMaterialfv(GL_FRONT, GL_AMBIENT, BA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, BD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, BS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);
    glVertex3d(0, 0, 0);
    glVertex3d(-1, 1, 0);
    glVertex3d(-1, 0, 0);
    glEnd();

    glutSwapBuffers();
    }

    int main(int argc, char **argv) {
    int window = 0;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(0, 0);
    window = glutCreateWindow(TITLE);
    assert(window);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    init();
    glutMainLoop();

    glutDestroyWindow(window);
    return 0;
    }


    compile:
    gcc -o test_materials tests/test_materials.c -ansi -O0 -noixemul -noixemul -lm -lGl -lglut

    The problem is somewhere in my code. Any debugging hints on MorphOs, since there no gdb.

    Thx for your help anyway!
    BTW I am using c++11 in the broken code, is there everything tested on MorphOs?

    [ Edited by eliot 14.10.2016 - 11:52 ]
    regards
    eliot
  • »14.10.16 - 08:32
    Profile
  • ASiegel
    Posts: 1369 from 2003/2/15
    From: Central Europe
    @ eliot

    Interesting. The colors are quite a bit brighter on the r300 screenshot.
  • »14.10.16 - 09:12
    Profile
  • MorphOS Developer
    bigfoot
    Posts: 508 from 2003/4/11
    Are you loading any data from files, such as colour info? Is said data binary? If so, are you sure things are getting byteswapped correctly?
    I rarely log in to MorphZone which means that I often miss private messages sent on here. If you wish to contact me, please email me at [username]@asgaard.morphos-team.net, where [username] is my username here on MorphZone.
  • »14.10.16 - 09:25
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    No, everything is plain text, no binary loading at all.
    I will write a small Logger class and print some debug information.
    It's something in my code or c++11 stuff.
    When I know more I will post it here.
    regards
    eliot
  • »14.10.16 - 09:51
    Profile
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Jupp3
    Posts: 1193 from 2003/2/24
    From: Helsinki, Finland
    I really hope it's just this simple test code, and you're not using immediate mode (glBegin() ...) in a "real" program in 2016 :-)
  • »14.10.16 - 19:19
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Quote:

    Jupp3 wrote:
    I really hope it's just this simple test code, and you're not using immediate mode (glBegin() ...) in a "real" program in 2016 :-)


    Ok, ok, just to it right, here is beter example:

    Code:

    #ifdef __APPLE__
    #include <gl.h>
    #include <glu.h>
    #include <glut.h>
    #else

    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>

    #endif

    static char *TITLE = "test_materials";

    static GLint quadId = 0;
    static GLint triangleAId = 0;
    static GLint triangleBId = 0;

    static void objects() {
    GLfloat RA[] = {(GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1};
    GLfloat RS[] = {(GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1};
    GLfloat RD[] = {(GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1};

    GLfloat GA[] = {(GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 1};
    GLfloat GS[] = {(GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 1};
    GLfloat GD[] = {(GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 0,
    (GLfloat) 1};

    GLfloat BA[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 1};
    GLfloat BS[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 1};
    GLfloat BD[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 1,
    (GLfloat) 1};
    GLfloat Y = 0;

    quadId = glGenLists(1);
    glNewList(quadId, GL_COMPILE);
    glNormal3d(0, 0, 1);
    glMaterialfv(GL_FRONT, GL_AMBIENT, RA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, RD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, RS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);
    glBegin(GL_QUADS);
    glVertex3d(0, 0, 0);
    glVertex3d(1, 0, 0);
    glVertex3d(1, 1, 0);
    glVertex3d(0, 1, 0);
    glEnd();
    glEndList();

    triangleAId = glGenLists(1);
    glNewList(triangleAId, GL_COMPILE);
    glNormal3d(0, 0, 1);
    glMaterialfv(GL_FRONT, GL_AMBIENT, GA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, GD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, GS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);
    glBegin(GL_TRIANGLES);
    glVertex3d(1, 0, 0);
    glVertex3d(2, 0, 0);
    glVertex3d(2, 1, 0);
    glEnd();
    glEndList();

    triangleBId = glGenLists(1);
    glNewList(triangleBId, GL_COMPILE);
    glNormal3d(0, 0, 1);
    glMaterialfv(GL_FRONT, GL_AMBIENT, BA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, BD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, BS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);
    glBegin(GL_TRIANGLES);
    glVertex3d(0, 0, 0);
    glVertex3d(-1, 1, 0);
    glVertex3d(-1, 0, 0);
    glEnd();
    glEndList();
    }

    static void light() {
    GLfloat LP[] = {(GLfloat) 0,
    (GLfloat) 0,
    (GLfloat) 10,
    (GLfloat) 1};
    GLfloat A[] = {(GLfloat) 0.1,
    (GLfloat) 0.1,
    (GLfloat) 0.1};
    GLfloat S[] = {(GLfloat) 0.5,
    (GLfloat) 0.5,
    (GLfloat) 0.5};
    GLfloat D[] = {(GLfloat) 0.5,
    (GLfloat) 0.5,
    (GLfloat) 0.5};

    glEnable(GL_LIGHT0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLightfv(GL_LIGHT0, GL_POSITION, LP);
    glLightfv(GL_LIGHT0, GL_AMBIENT, A);
    glLightfv(GL_LIGHT0, GL_SPECULAR, S);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, D);
    }

    void init() {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_FRONT);
    glEnable(GL_LIGHTING);

    glClearColor(0.f, 0.f, 0.f, 1.f);

    light();
    objects();
    }

    void reshape(int width, int height) {
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(65.0, (float) width / (float) height, 1.0, 100);
    }

    void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(0, 0, 5,
    0, 0, 0,
    0, 1, 0);

    glCallList(quadId);
    glCallList(triangleAId);
    glCallList(triangleBId);

    glutSwapBuffers();
    }

    int main(int argc, char **argv) {
    int window = 0;

    /* init glut */
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(0, 0);

    /* create window */
    window = glutCreateWindow(TITLE);

    /* set callbacks */
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    /* init gl, light and objects */
    init();

    /* enter main loop */
    glutMainLoop();

    /* destroy window */
    glutDestroyWindow(window);
    return 0;
    }
    regards
    eliot
  • »15.10.16 - 08:25
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Finally I found the mistake in my code.
    I wonder why it worked on linux and mac os x.

    firstperson_mos_working.png

    Thx to all of you who helped me.
    But I won't stop to asking questions here ;)

    [ Edited by eliot 15.10.2016 - 14:59 ]
    regards
    eliot
  • »15.10.16 - 09:08
    Profile
  • Order of the Butterfly
    Order of the Butterfly
    igracki
    Posts: 382 from 2003/2/24
    From: Berlin
    Just out of curiosity, what was the mistake?
  • »15.10.16 - 12:13
    Profile Visit Website
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Jupp3
    Posts: 1193 from 2003/2/24
    From: Helsinki, Finland
    Quote:

    eliot wrote:
    Quote:

    Jupp3 wrote:
    I really hope it's just this simple test code, and you're not using immediate mode (glBegin() ...) in a "real" program in 2016 :-)


    Ok, ok, just to it right, here is beter example:



    IMHO, using display lists (which use immediate mode internally) doesn't make the code any better than direct immediate mode usage :-)

    Here is an older forum post by me regarding which functionality I think should be used / avoided on MorphOS.

    Here is a short example program I wrote, that uses the functionality I'd recommend.

    Since then, VBO support has been added to TinyGL, and can be used for some (potential) extra speed. It's built "on top of" vertex arrays, so not much has to be changed.

    Here is a small follow up regarding error handling, as some people thought that assert(!glGetError()); was too extreme (even as this was just a small example code). As said, out of memory error is not (necessarily) a coder error. Everything else is.

    And as said, almost everything works quite differently with shaders. Sadly, we're not there yet...
  • »15.10.16 - 13:26
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Quote:

    igracki wrote:
    Just out of curiosity, what was the mistake?


    It was wrong ordering of glBegin()/glEnd() and glMaterialv().
    regards
    eliot
  • »16.10.16 - 14:40
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    @Jupp3
    When I am using VBOs or vertex arrays, I have to redesign data structures a lot.
    At the moment I am facing two problems:

    1. I need access to the complete model for glTranslate etc.
    2. I have to spilt the model and draw the parts of the models to set the materials and normals.

    I will thing about it and redesign my data structures.
    First I will switch to Display Lists and Vertex Arrays, because as far as I know not all amiga systems
    support VBOs at the moment. Am I right?
    regards
    eliot
  • »16.10.16 - 14:44
    Profile
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Jupp3
    Posts: 1193 from 2003/2/24
    From: Helsinki, Finland
    Quote:

    eliot wrote:
    It was wrong ordering of glBegin()/glEnd() and glMaterialv().


    According to docs:
    Quote:

    glMaterial can be called between a call to glBegin and the corresponding call to glEnd.

    I think it SHOULD work?

    Quote:


    When I am using VBOs or vertex arrays, I have to redesign data structures a lot.
    At the moment I am facing two problems:

    1. I need access to the complete model for glTranslate etc.

    In this, vertex arrays and vbo's work exactly like immediate mode & display lists, so I can't see what would be the problem? Both use "previous" transformation, and if your code allows it, can have own "local" transformations for any "sub-models".
    Quote:


    2. I have to spilt the model and draw the parts of the models to set the materials and normals.

    Usually (if using lighting), you should definitely use per-vertex normals. Same for colors, if you re-define it per-vertex (which I do extremely rarely)

    If you are after an easy way to enable vertex & normal & texture arrays at once, you could take a look at glInterleavedArrays(), which enables & disables & setups interleaved pointers for specified format.

    f.ex. GL_N3F_V3F expects data to be in format:
    Normal0 (3 floats), Vertex0 (3 floats),
    Normal1 (3 floats), Vertex1 (3 floats) ...

    stride is the space used by single vertex (Normal0 & Vertex0 from above example, can include some padding too)

    Color is whatever was previously set, and so are texture coordinates. If you use format with color, it will be defined per-vertex.

    Interleaving different values in this way is generally faster than having N0, N1, ... Nn, V0, V1, ... Vn

    NOTE: This function doesn't exist in OpenGL ES1! (if that matters to you)

    However, the function isn't really THAT complex, and you can always just write a replacement from scratch, if needed.

    Quote:


    I will thing about it and redesign my data structures.


    Really good idea! Ask away, if you have any problems / questions. I was asking myself the same questions years ago, never looked back after the switch.

    Quote:

    First I will switch to Display Lists and Vertex Arrays, because as far as I know not all amiga systems
    support VBOs at the moment. Am I right?

    I think at least minigl lacks VBO support completely (at least currently).

    However, it's very close to vertex arrays in general, you can quite easily make it build-time / run-time. AFAIK, minigl supports vertex arrays just fine. Might be wrong though. Common sense says it should be easier than immediate mode, if anything.

    Also, with vertex arrays, you gain access to indexed modes. Here, in addition to array defining vertices, you have array defining indexes. Then you just do array, in which you define the order, you want to connect them, making it easy to re-use duplicate vertices.

    In addition to that, you could f.ex. have filled geometry in one index array, and wireframe in another (that skips some indexes & vertex elements).
  • »16.10.16 - 17:05
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Finally I changed my code to VBOs.
    On MacOs and Linux everything is ok, sadly on MorphOs there is just a black window.

    Thats what I am doing:
    Code:

    // in method init objects
    // vertices
    glGenBuffers(1, &o.vertexId);
    glBindBuffer(GL_ARRAY_BUFFER, o.vertexId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * o.vertices.size(), o.vertices.data(), GL_STATIC_DRAW);

    // normals
    glGenBuffers(1, &o.normalId);
    glBindBuffer(GL_ARRAY_BUFFER, o.normalId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * o.normals.size(), o.normals.data(), GL_STATIC_DRAW);

    // in method render objects
    // set material
    glMaterialfv(GL_FRONT, GL_AMBIENT, m.ambient.rgba);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, m.diffuse.rgba);
    glMaterialfv(GL_FRONT, GL_SPECULAR, m.specular.rgba);
    glMaterialf(GL_FRONT, GL_SHININESS, m.shininess);

    glBindBuffer(GL_ARRAY_BUFFER, o.vertexId);
    glVertexPointer(3, GL_DOUBLE, sizeof(Vertex), NULL);
    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, o.normalId);
    glNormalPointer(GL_DOUBLE, 0, NULL);
    glEnableClientState(GL_NORMAL_ARRAY);

    glDrawArrays(GL_TRIANGLES, 0, o.vertices.size());


    Anybody sees a mistake in this code?

    EDIT:

    Ok, I just worete a small example, an as usual, the mistake must be somewhere in my code.
    Here is a working example:
    Code:

    #ifdef __APPLE__
    #include <gl.h>
    #include <glu.h>
    #include <glut.h>

    #else
    #define GL_GLEXT_PROTOTYPES
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glut.h>

    #endif


    static char *TITLE = "test_materials_vbos";

    static GLuint verticesId = 0;
    static GLuint normalsId = 0;

    static GLfloat vertices[] = {0, 0, 0, 1, 0, 0, 1, 1, 0};
    static GLfloat normals[] = {0, 0, 1, 0, 0, 1, 0, 0, 1};

    static GLfloat RA[] = {1, 0, 0, 1};
    static GLfloat RS[] = {1, 0, 0, 1};
    static GLfloat RD[] = {1, 0, 0, 1};

    static GLfloat GA[] = {0, 1, 0, 1};
    static GLfloat GS[] = {0, 1, 0, 1};
    static GLfloat GD[] = {0, 1, 0, 1};
    static GLfloat Y = 0;

    static void objects() {
    /* vertices */
    glGenBuffers(1, &verticesId);
    glBindBuffer(GL_ARRAY_BUFFER, verticesId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    /* normals */
    glGenBuffers(1, &normalsId);
    glBindBuffer(GL_ARRAY_BUFFER, normalsId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals, GL_STATIC_DRAW);
    }

    static void light() {
    GLfloat LP[] = {0, 0, 10, 1};
    GLfloat A[] = {0.1, 0.1, 0.1};
    GLfloat S[] = {0.5, 0.5, 0.5};
    GLfloat D[] = {0.5, 0.5, 0.5};

    glEnable(GL_LIGHT0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glLightfv(GL_LIGHT0, GL_POSITION, LP);
    glLightfv(GL_LIGHT0, GL_AMBIENT, A);
    glLightfv(GL_LIGHT0, GL_SPECULAR, S);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, D);
    }

    void init() {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_FRONT);
    glEnable(GL_LIGHTING);

    glClearColor(0.f, 0.f, 0.f, 1.f);

    light();
    objects();
    }

    void reshape(int width, int height) {
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(65.0, (float) width / (float) height, 1.0, 100);
    }

    void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(0, 0, 5,
    0, 0, 0,
    0, 1, 0);

    /* red triangle */
    {
    glPushMatrix();

    glTranslated(1, 0, 0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, RA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, RD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, RS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);

    glBindBuffer(GL_ARRAY_BUFFER, verticesId);
    glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 3, NULL);
    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, normalsId);
    glNormalPointer(GL_FLOAT, 0, NULL);
    glEnableClientState(GL_NORMAL_ARRAY);


    glDrawArrays(GL_TRIANGLES, 0, 3);
    glPopMatrix();
    }

    /* green triangle */
    {
    glPushMatrix();

    glTranslated(-1, 0, 0);

    glMaterialfv(GL_FRONT, GL_AMBIENT, GA);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, GD);
    glMaterialfv(GL_FRONT, GL_SPECULAR, GS);
    glMaterialf(GL_FRONT, GL_SHININESS, Y);

    glBindBuffer(GL_ARRAY_BUFFER, verticesId);
    glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 3, NULL);
    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, normalsId);
    glNormalPointer(GL_FLOAT, 0, NULL);
    glEnableClientState(GL_NORMAL_ARRAY);


    glDrawArrays(GL_TRIANGLES, 0, 3);
    glPopMatrix();
    }
    glutSwapBuffers();
    }

    int main(int argc, char **argv) {
    int window = 0;

    /* init glut */
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(0, 0);

    /* create window */
    window = glutCreateWindow(TITLE);

    /* set callbacks */
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    /* init gl, light and objects */
    init();

    /* enter main loop */
    glutMainLoop();

    /* destroy window */
    glutDestroyWindow(window);
    return 0;
    }


    result:
    test_materials_vbos.png

    I have to find the bug on my side.

    [ Edited by eliot 30.12.2016 - 09:38 ]
    regards
    eliot
  • »30.12.16 - 08:46
    Profile
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Jupp3
    Posts: 1193 from 2003/2/24
    From: Helsinki, Finland
    Quote:

    eliot wrote:
    GL_DOUBLE

    Do you REALLY need double precision for what you're doing? It's using more memory, is slower, and can't say I'd see much benefits really...

    At least in the past, TinyGL has had some "issues" with some formats (glInt at least, I think?).
    Quote:


    glVertexPointer(3, GL_DOUBLE, sizeof(Vertex), NULL);
    glNormalPointer(GL_DOUBLE, 0, NULL);


    Just wondering why you use different stride values, aren't both tightly packed (so 0 will work)?

    Also, see previous comments regarding interleaved arrays.

    Also, a minor logical error here:
    Code:
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * o.normals.size(), o.normals.data(), GL_STATIC_DRAW);

    Shouldn't you use sizeof(Normal) here? Probably both are 3 doubles currently though...
  • »01.01.17 - 13:40
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Thx for your answer.
    You absolutely right with the stride values. They are wrong (I used interleaving before but throw it away later).
    Besides there were two more "errors" in my code:

    1. Static Initializer Problem
    I am using static class member in Color.cpp and Material.cpp for default colors and materials.
    Material used default colors. The ordering on MorphOs was wrong but worked on Linux/MacOs.
    I fixed the issue in my code by not using default colors for default materials (another workaround would
    be to put Materials and Color implementation into the same compile unit).

    2. MorpgOs Opengl imlpementation needs to call glDisableClientState after every glDrawArrays
    Do not know why, but without it does not render anything.

    So the init code looks like that:
    Code:

    // vertices
    glGenBuffers(1, &o.vertexId);
    glBindBuffer(GL_ARRAY_BUFFER, o.vertexId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * o.vertices.size(), o.vertices.data(), GL_STATIC_DRAW);
    // normals
    glGenBuffers(1, &o.normalId);
    glBindBuffer(GL_ARRAY_BUFFER, o.normalId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * o.normals.size(), o.normals.data(), GL_STATIC_DRAW);


    and the rendering code:
    Code:

    glPushMatrix();

    glTranslated(t.translation.x, t.translation.y, t.translation.z);
    glRotated(t.rotation.x, 1, 0, 0);
    glRotated(t.rotation.y, 0, 1, 0);
    glRotated(t.rotation.z, 0, 0, 1);

    setMaterial(m);

    glBindBuffer(GL_ARRAY_BUFFER, o.vertexId);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, o.normalId);
    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, 0, NULL);

    glDrawArrays(GL_TRIANGLES, 0, o.vertices.size());

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);

    glPopMatrix();


    These things will be done next:
    1. obj loader (import objects from blender)
    2. hight maps (based on pgms)
    3. flight controller
    4. throw away glut and use x11/mui directly (needs really to be done for better mouse/keyboard input)
    regards
    eliot
  • »02.01.17 - 14:45
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Ok,

    wavefront object loader was simplier than I expected.
    I am now able to import objects from Blender.

    torus.png

    Height Maps will be the next.
    regards
    eliot
  • »03.01.17 - 14:07
    Profile
  • Paladin of the Pegasos
    Paladin of the Pegasos
    Jupp3
    Posts: 1193 from 2003/2/24
    From: Helsinki, Finland
    Quote:

    2. MorpgOs Opengl imlpementation needs to call glDisableClientState after every glDrawArrays
    Do not know why, but without it does not render anything.

    That shouldn't be needed...

    For most drawing, I simply enable arrays that need to be enabled, and disable everything else, but then again, my drawing functions are way more complex than what you have...

    As for .obj, I assume you already realized it's rather crappy format, and not very well suited for OpenGL. Personally, I decided to do my own format instead, with .obj converter.

    Assuming you wrote a simple importer, here's where it might likely fail: The format supports >3 vertices per face (quads etc.), and if the model has any (and your code doesn't triangulate the faces properly), it will look broken.

    Easiest "fix" is to check the "triangulate faces" checkbox from blender exporter.
  • »06.01.17 - 21:24
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    eliot
    Posts: 564 from 2004/4/15
    Ok,

    I just implemented building height maps based on pgm files.
    On linux everythings is looking good: heightmap_linux.png
    But on MorphOs it's looking quite bad: heightmap_mos.png

    Currently i do not know what is going wrong on MorphOs, I am too tired to debug it this evening.

    Are there any limitations like memoy size when using glBufferData which I should care about?


    EDIT:
    Hmm, the first 5 rows are rendered, the rest is missing?
    heightmap2_mos.png
    It's certainly somewhere in my code (wrong size), but it does no show up on Mac or Linux.

    [ Edited by eliot 07.01.2017 - 20:08 ]
    regards
    eliot
  • »07.01.17 - 20:02
    Profile