Beta Prboom Es Style


Pickle

Mega GP Mania
Joined
May 30, 2006
Messages
5,518
Location
Detroit, Michigan
Website
Visit site
edit sorry not working yet thought it was :-(

Edit: ive got it working enough where the walls are showing up, but the floors and skybox are not....

Edit 2:
ok im not sure whats wrong, im putting up the source if anyone wants to review.
Ive tried with USE_VERTEX_ARRAYS and without, same result.

pickle.gp2x.de/prboom-2.5.0.zip
 
hey Pickle. i glanced quickly.

in gl_main.c::gld_DrawFlat, the non- USE_VERTEX_ARRAYS version says:

Code:
#if defined(OPENGLES)
      int v = -1;
      int t = -1;
      GLfloat vtx[sectorloops[flat->sectornum].loopcount][currentloop->vertexcount*3];
      GLfloat tex[sectorloops[flat->sectornum].loopcount][currentloop->vertexcount*2];
#else
      glBegin(currentloop->mode);
#endif
      // go through all vertexes of this loop
      for (vertexnum=currentloop->vertexindex; vertexnum<(currentloop->vertexindex+currentloop->vertexcount); vertexnum++)
      {
#if defined(OPENGLES)
        tex[loopnum][t++] = gld_texcoords[(vertexnum*2)].u;
        tex[loopnum][t++] = gld_texcoords[(vertexnum*2)].v;

        vtx[loopnum][v++] = gld_vertexes[(vertexnum*3)].x;
        vtx[loopnum][v++] = gld_vertexes[(vertexnum*3)].y;
        vtx[loopnum][v++] = gld_vertexes[(vertexnum*3)].z;
#else
        // set texture coordinate of this vertex
        glTexCoord2fv(&gld_texcoords[vertexnum*2]);
        // set vertex coordinate
        glVertex3fv(&gld_vertexes[vertexnum*3]);
#endif      
      }
      // end of loop

you're out-of-bounds for both tex[] and vtx[] on the first vertex. either init v and t to zero, or use pre-increment for them during the indexation later.

then, at the end of that sector loop you have :
Code:
#if defined(OPENGLES)
      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);

      glVertexPointer(3, GL_FLOAT, 0, vtx[loopnum]);
      glTexCoordPointer(2, GL_FLOAT, 0, tex[loopnum]);

      glDrawArrays(currentloop->mode, 0, currentloop->vertexcount);

      glDisableClientState(GL_VERTEX_ARRAY);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#else
      glEnd();
#endif

you can drop the first dimension of the vtx and tex arrays - as they're declared inside the sector loop, and you use only the loopnum-th index from their first dimension, you really don't need them as two-dimensional. just declare them as:

Code:
GLfloat vtx[currentloop->vertexcount*3];
GLfloat tex[currentloop->vertexcount*2];

and use them without the outer-most indexation.

ok, that's at first glance. will check more tomorrow. good luck!
 
Yeah i didnt have have the second dimension to start, good catch on the increments. Also a little guess on the index and the flats work :)
Code:
         tex[++t] = gld_texcoords[vertexnum].u;
         tex[++t] = gld_texcoords[vertexnum].v;
         
         vtx[++v] = gld_vertexes[vertexnum].x;
         vtx[++v] = gld_vertexes[vertexnum].y;
         vtx[++v] = gld_vertexes[vertexnum].z;

Skybox's are still broke and theres still a nuge hit on some of the more detailed views (more geometry)

Edit: fixed a typo with the map line drawing, the other things still have me stumped.
 
Pickle said:
Yeah i didnt have have the second dimension to start, good catch on the increments. Also a little guess on the index and the flats work :)
Code:
        tex[++t] = gld_texcoords[vertexnum].u;
        tex[++t] = gld_texcoords[vertexnum].v;
        
        vtx[++v] = gld_vertexes[vertexnum].x;
        vtx[++v] = gld_vertexes[vertexnum].y;
        vtx[++v] = gld_vertexes[vertexnum].z;
heh, they screwed up their indexing, but you caught it. my guess is their non-USE_VERTEX_ARRAYS code simply does not work in the current codebase.

Skybox's are still broke and theres still a nuge hit on some of the more detailed views (more geometry)
skybox is broken since it's a special case of wall segments using autogenerated environmental uv-mapping, that much is obvious in the drawing code. i'll go check what kind of envmapping they actually set up next time i go through the codebase.

in the meantime, about the performance hiccups with more geometry - that could be from the fact that vertex data is copied one more time on the way to the GL pipeline. so let's try to fix the USE_VERTEX_ARRAYS version in our familiar gld_DrawFlat routine:

Code:
#ifndef USE_VERTEX_ARRAYS
    // not interested in this version this time
#else
    for (loopnum=0; loopnum<sectorloops[flat->sectornum].loopcount; loopnum++)
    {
      // set the current loop
      currentloop=&sectorloops[flat->sectornum].loops[loopnum];

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);

      glTexCoordPointer(2, GL_FLOAT, 0, gld_texcoords);
      glVertexPointer(3, GL_FLOAT, 0, gld_vertexes);

      glDrawArrays(currentloop->mode,currentloop->vertexindex,currentloop->vertexcount);

      glDisableClientState(GL_VERTEX_ARRAY);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    }
#endif

(the reason why the original USE_VERTEX_ARRAYS code does not work is that it expects that the gl*Pointer routines are set up once per frame, which is not the case anymore)
 
Last edited by a moderator:
The USE_VERTEX_ARRAYS works now, but there are still very slow parts, not sure if its the level geometry or special lighting with some textures.


Edit:
Scratch that :)

Code:
  if (gltexture->glTexID[cm]!=0)
  {
    glBindTexture(GL_TEXTURE_2D, gltexture->glTexID[cm]);
#if !defined(OPENGLES)    
    glGetTexParameteriv(GL_TEXTURE_2D,GL_TEXTURE_RESIDENT,&i);
#endif    
#ifdef _DEBUG
    if (i!=GL_TRUE)
      lprintf(LO_INFO, "glGetTexParam: %in", i);
#endif
#if !defined(OPENGLES)    
    if (i==GL_TRUE)
#endif      
      return;
  }

I forced the return on the check above and the slowdown is done, guess it was causing the textures to be reuploaded every frame.

Now those sky textures....
 
Pickle, try the following patch to gl_main.c::gld_DrawWall(). keep in mind it's a prima-vista code - has not even been passed through a compiler, so you may need to fix a typo or two.

Code:
--- gl_main.c.bak       2010-08-14 19:55:08.000000000 -0400
+++ gl_main.c   2010-08-14 21:33:10.000000000 -0400
@@ -2147,12 +2147,40 @@
  *               *
  *****************/
 
+static void tfm(
+       GLfloat out[3],
+       const GLfloat mtx[16],
+       const GLfloat x,
+       const GLfloat y,
+       const GLfloat z)
+{
+       out[0] = mtx[0]   * x;
+       out[1] = mtx[1]   * x;
+       out[2] = mtx[2]   * x;
+
+       out[0] += mtx[4]  * y;
+       out[1] += mtx[5]  * y;
+       out[2] += mtx[6]  * y;
+
+       out[0] += mtx[8]  * z;
+       out[1] += mtx[9]  * z;
+       out[2] += mtx[10] * z;
+
+       out[0] += mtx[12];
+       out[1] += mtx[13];
+       out[2] += mtx[14];
+}
+
+
 static void gld_DrawWall(GLWall *wall)
 {
 #if defined(OPENGLES)
   GLfloat vtx[12];
-  GLfloat tex[8];  
+  GLfloat tex[16];  
+  GLfloat mv[16];
+  GLfloat vtx_e[3];
 #endif
+
   if ( (!gl_drawskys) && (wall->flag>=GLDWF_SKY) )
     wall->gltexture=NULL;
   gld_BindTexture(wall->gltexture);
@@ -2175,26 +2203,44 @@
       glTranslatef(wall->skyyaw,wall->skyymid,0.0f);
     }
 #if defined(OPENGLES)
     vtx[0] = wall->glseg->x1;   vtx[1] = wall->ytop;    vtx[2] = wall->glseg->z1;
     vtx[3] = wall->glseg->x1;   vtx[4] = wall->ybottom; vtx[5] = wall->glseg->z1;
     vtx[6] = wall->glseg->x2;   vtx[7] = wall->ytop;    vtx[8] = wall->glseg->z2;
     vtx[9] = wall->glseg->x2;   vtx[10] = wall->ybottom; vtx[11] = wall->glseg->z2;
+
+    glGetFloatv(GL_MODELVIEW_MATRIX, mv);
+
+    tfm(vtx_e, mv, vtx[0], vtx[1], vtx[2]);
+    tex[0] = vtx_e[0];      tex[1] = vtx_e[1];      tex[2] = 0.f;   tex[3] = vtx_e[2];
+
+    tfm(vtx_e, mv, vtx[3], vtx[4], vtx[5]);
+    tex[4] = vtx_e[0];      tex[5] = vtx_e[1];      tex[6] = 0.f;   tex[7] = vtx_e[2];
+
+    tfm(vtx_e, mv, vtx[6], vtx[7], vtx[8]);
+    tex[8] = vtx_e[0];      tex[9] = vtx_e[1];      tex[10] = 0.f;  tex[11] = vtx_e[2];
+
+    tfm(vtx_e, mv, vtx[9], vtx[10], vtx[11]);
+    tex[12] = vtx_e[0];     tex[13] = vtx_e[1];     tex[14] = 0.f;  tex[15] = vtx_e[2];
+
     glEnableClientState(GL_VERTEX_ARRAY);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
     glVertexPointer(3, GL_FLOAT, 0, vtx);
+    glTexCoordPointer(4, GL_FLOAT, 0, tex);
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
     glDisableClientState(GL_VERTEX_ARRAY);
-#else    
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+#else
     glBegin(GL_TRIANGLE_STRIP);
       glVertex3f(wall->glseg->x1,wall->ytop,wall->glseg->z1);
       glVertex3f(wall->glseg->x1,wall->ybottom,wall->glseg->z1);
       glVertex3f(wall->glseg->x2,wall->ytop,wall->glseg->z2);
       glVertex3f(wall->glseg->x2,wall->ybottom,wall->glseg->z2);
     glEnd();
#endif
     if ( wall->gltexture )
     {
       glPopMatrix();

(don't read too much into diff's line references - better find the lines yourself)
 
brilliant it works, thanks
can you explain what going on with this. I guess your taking the model matix and transforming the texture coords based on it?
 
generally yes, and it's quite simple, really. as you know the wall segments of sky type use a special planar projective texture mapping. now, the final, homogeneous projection stage of that mapping, namely (s, t, r) /q, is done automatically by the ES 1.x pipeline, the same way it's been done in all GL incarnations before. what's missing in the ES case is the initial feeding stage of the mapping coordinates - desktop GL has the glTexGen* family of routines which is absent form ES. so what we do above is manually implement that part. the original TexGen used in prboom is using the EYE_LINEAR projection, which basically takes vertex coordinates in eye space (post model-view transform), and then does a distance-to-plane computation to obtain each individual texture coordinate prior to texture matrix transform & projection. since it's a two-dimensional mapping case (a sky background), the computation is carried on the first two texcoords, and a homogeneous part (in GL terms: s, t and q, from the full set of (s, t, r, q)). so what we pass to glTexcoordPointer is:

Code:
s = p1 * Xe + p2 * Ye + p3 * Ze + p4 * We, for a plane equation (p1, p2, p3, p4) = (1, 0, 0, 0), yielding Xe
t = p1 * Xe + p2 * Ye + p3 * Ze + p4 * We, for a plane equation (p1, p2, p3, p4) = (0, 1, 0, 0), yielding Ye
r = 0
q = p1 * Xe + p2 * Ye + p3 * Ze + p4 * We, for a plane equation (p1, p2, p3, p4) = (0, 0, 1, 0), yielding Ze

supplied for each of the four vertices of the wall-segment trapezoid, and where (Xe, Ye, Ze, We) is the vertex's image in eye/camera/view space, i.e. post model-view transform.
 
Back
Top