//-------------------------------------------------------------------------------------------------- /// Do immediate mode rendering //-------------------------------------------------------------------------------------------------- void DrawableGeo::renderImmediateMode(OpenGLContext* oglContext, const MatrixState&) { #ifdef CVF_OPENGL_ES CVF_FAIL_MSG("Not supported on OpenGL ES"); #else CVF_ASSERT(oglContext); const Vec3fArray* vertexArr = m_vertexBundle->vertexArray(); const Vec3fArray* normalArr = m_vertexBundle->normalArray(); const Vec2fArray* texCoordArr = m_vertexBundle->textureCoordArray(); const Color3ubArray* colorArr = m_vertexBundle->colorArray(); size_t numPrimitiveSets = m_primitiveSets.size(); size_t ip; for (ip = 0; ip < numPrimitiveSets; ip++) { const PrimitiveSet* primitiveSet = m_primitiveSets.at(ip); CVF_TIGHT_ASSERT(primitiveSet); glBegin(primitiveSet->primitiveTypeOpenGL()); size_t numIndices = primitiveSet->indexCount(); size_t i; for (i = 0; i < numIndices; i++) { uint index = primitiveSet->index(i); if (normalArr) { glNormal3fv((const float*)&normalArr->get(index)); } if (colorArr) { glColor3ubv((const ubyte*)&colorArr->get(index)); } if (texCoordArr) { glTexCoord2fv((const float*)&texCoordArr->get(index)); } glVertex3fv((float*)&vertexArr->get(index)); } glEnd(); } #endif // CVF_OPENGL_ES }
void Renderer::DrawTiles (int tiles[], int w, int h, float tileW, float tileH, ClipRecti &clip) { Tileset *tset = GetTileset (mTileset); int t; Vec2f offset ((float)clip.x1*tileW, -(float)clip.y1*tileH); int tris,numTris; int endx = clip.x2, endy = clip.y2; Vec2f tran(0.,0.); glTranslatef (offset.x, offset.y, 0.); for (int y=clip.y1; y < endy; y++) { float trX=0.; for (int x=clip.x1; x < endx; x++) { t = y*w+x; Tile &tile = tset->tiles[tiles[t]]; tris = tile.tris[mRenderPass]; numTris = tile.tris[mRenderPass+1] - tris; if (numTris) { glTranslatef (trX, 0., 0.); tran.x += trX; trX = 0.; glBegin (GL_TRIANGLES); for (int i = 0; i < numTris; i++) { TsetTri &tri = tset->tris[tris+i]; for (int j = 0; j < 3; j++) { glTexCoord2fv (tset->verts[tri.p[j]].tco.V); glVertex3fv (tset->verts[tri.p[j]].co.V); } } glEnd (); } trX += tileW; } glTranslatef(-tran.x, -tileH, 0.0); tran.y += -tileH; tran.x = 0.; } glTranslatef (-tran.x - offset.x,-tran.y - offset.y, 0.); }
void CGeoTri::Draw() { glBegin( GL_TRIANGLES ); glNormal3fv( m_oNormal ); unsigned int i = 0; do { glTexCoord2fv( m_aoTex[i] ); glVertex3fv( m_aoPos[i] ); ++i; } while( i < 3 ); glEnd(); }
/* ============================== R_FS_RasterizeLMap1Bfr static specular light map ============================== */ void R_FS_RasterizeTMapsBfr_lmap1( void ) { int i, j, num; glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer( 4, GL_FLOAT, 0, fs_vertex_array ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glTexCoordPointer( 2, GL_FLOAT, 0, fs_lmap1_texcoord_array ); glEnable( GL_TEXTURE_2D ); glEnable(GL_BLEND); glTexEnvi( GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glBlendFunc( GL_ONE, GL_ONE ); for ( i = 0; i < MAX_LIGHTPAGES; i++ ) { num = fs_lmap1num[i]; if ( !num ) continue; glBindTexture( GL_TEXTURE_2D, r_lightpages[i].texobj ); for( j = 0; j < num; j++ ) { int *faceptr; int pointnum; int k, elmt; faceptr = fs_lmap1facebfr[i][j]; if ( !faceptr ) break; pointnum = *faceptr++; // maps flag faceptr++; elmt = *faceptr++; glBegin( GL_TRIANGLE_FAN ); for ( k = 0; k < pointnum; k++, elmt++ ) { glTexCoord2fv( fs_lmap1_texcoord_array[elmt] ); glVertex4fv( fs_vertex_array[elmt] ); } glEnd(); } } }
void Brush_Draw( brush_t *b ) { face_t *face; int i, order; qtexture_t *prev = 0; winding_t *w; if (b->owner->eclass->fixedsize && camera.draw_mode == cd_texture) glDisable (GL_TEXTURE_2D); // guarantee the texture will be set first prev = NULL; for(face = b->brush_faces,order = 0; face; face = face->next,order++) { w = face->face_winding; if (!w) continue; // freed face if ( face->d_texture != prev && camera.draw_mode == cd_texture) { // set the texture for this face prev = face->d_texture; glBindTexture( GL_TEXTURE_2D, face->d_texture->texture_number ); } if(camera.draw_mode == cd_solid) { srand(order); glColor3ub(rand()%256,rand()%256,rand()%256); } else glColor3fv( face->d_color ); // draw the polygon glBegin(GL_POLYGON); for (i=0 ; i<w->numpoints ; i++) { if (camera.draw_mode == cd_texture) glTexCoord2fv( &w->points[i][3] ); glVertex3fv(w->points[i]); } glEnd(); } if (b->owner->eclass->fixedsize && camera.draw_mode == cd_texture) glEnable (GL_TEXTURE_2D); glBindTexture( GL_TEXTURE_2D, 0 ); }
void draw_quads(GLfloat vertices[121][121][4], GLfloat normals[121][121][4], GLfloat tex[121][121][2], int iv1a, int iv1b, int iv2a, int iv2b, int iv3a, int iv3b, int iv4a, int iv4b, int ic) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(-1.0, 1.0, 1.0); glMatrixMode(GL_MODELVIEW); glBegin(crt_render_mode); { // glColor3fv(colors[ic]); glNormal3fv(normals[iv1a][iv1b]); glTexCoord2fv(tex[iv1a][iv1b]); glVertex4fv(vertices[iv1a][iv1b]); glTexCoord2fv(tex[iv2a][iv2b]); glVertex4fv(vertices[iv2a][iv2b]); glTexCoord2fv(tex[iv3a][iv3b]); glVertex4fv(vertices[iv3a][iv3b]); glTexCoord2fv(tex[iv4a][iv4b]); glVertex4fv(vertices[iv4a][iv4b]); } glEnd(); }
void drawWithTexture(GLuint texName) { glActiveTexture(GL_TEXTURE0); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glBindTexture(GL_TEXTURE_2D, texName); glBegin(GL_QUADS); glNormal3fv(this->n); glTexCoord2fv(t1); glVertex3fv(this->v1); glNormal3fv(this->n); glTexCoord2fv(t2); glVertex3fv(this->v2); glNormal3fv(this->n); glTexCoord2fv(t3); glVertex3fv(this->v3); glNormal3fv(this->n); glTexCoord2fv(t4); glVertex3fv(this->v4); glEnd(); glFlush(); glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); }
void WP_TriangleFan::drawOpenGL(const WP_Vertex *verticesFrameA) const { unsigned int i, j; glBegin(GL_TRIANGLE_FAN); for(i = 0, j = 0; i < numberIndices; i++, j += 2) { const WP_Vertex *v = verticesFrameA + indices[i]; glColor4f(1.0, 1.0, 1.0, 1.0); glNormal3fv(v->normal.data); glTexCoord2fv(texCoords + j); glVertex3fv(v->point.data); } glEnd(); }
//--------------------------------------------------------------------------------------- // モデル表示(非α部のみ) //--------------------------------------------------------------------------------------- void DrawMeshNoAlpha(MATRIX *matWorld, MESH *mesh) { int i, j; int nVtx, nMat; MATERIAL *pMat; // ワールドマトリックス設定 glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMultMatrixf(matWorld->f); // 描画 nVtx = -1; nMat = -1; for (i = 0; i < mesh->fnum; i++) { if (nVtx != mesh->face[i * 5] || nMat != mesh->midx[i]) { if (nVtx > 0) glEnd(); nVtx = mesh->face[i * 5]; if (nMat != mesh->midx[i]) { nMat = mesh->midx[i]; pMat = &mesh->material[mesh->midx[i]]; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pMat->diffuse.f); glMaterialf(GL_FRONT, GL_SHININESS, pMat->power); glMaterialfv(GL_FRONT, GL_SPECULAR, pMat->specular.f); glMaterialfv(GL_FRONT, GL_EMISSION, pMat->emissive.f); if (mesh->uv && pMat->textureID) { glBindTexture(GL_TEXTURE_2D, pMat->textureID); glEnable(GL_TEXTURE_2D); } else glDisable(GL_TEXTURE_2D); } glBegin((nVtx > 3) ? GL_QUADS : GL_TRIANGLES); } if (pMat->diffuse.a >= 1.0f) { for (j = 1; j <= nVtx; j++) { if (mesh->uv) glTexCoord2fv(mesh->uv[mesh->face[i * 5 + j]].f); if (mesh->normal && mesh->index) glNormal3fv(mesh->normal[mesh->index[i * 5 + j]].f); glVertex3fv(mesh->vertex[mesh->face[i * 5 + j]].f); } } } if (nVtx > 0) glEnd(); // ビューマトリックス復帰 glPopMatrix(); }
void FMD3Model::RenderTriangles(MD3Surface * surf, MD3Vertex * vert) { gl_RenderState.Apply(); glBegin(GL_TRIANGLES); for(int i=0; i<surf->numTriangles;i++) { for(int j=0;j<3;j++) { int x = surf->tris[i].VertIndex[j]; glTexCoord2fv(&surf->texcoords[x].s); glVertex3f(vert[x].x, vert[x].z, vert[x].y); } } glEnd(); }
void WP_TriangleStrip::drawOpenGL(const WP_Vertex *verticesFrameA, const WP_Vertex *verticesFrameB, scalar interpolation) const { unsigned int i, j; glBegin(GL_TRIANGLE_STRIP); for(i = 0, j =0; i < numberIndices; i++, j += 2) { WP_Vertex v = verticesFrameA[indices[i]]; glColor4f(1.0, 1.0, 1.0, 1.0); glNormal3fv(v.normal.data); glTexCoord2fv(texCoords + j); v.lerp3D(verticesFrameB + indices[i], interpolation); glVertex3fv(v.point.data); } glEnd(); }
static void DrawCube(void) { static const GLfloat texcoords[4][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; static const GLfloat vertices[4][2] = { { -1, -1 }, { 1, -1 }, { 1, 1 }, { -1, 1 } }; static const GLfloat xforms[6][4] = { { 0, 0, 1, 0 }, { 90, 0, 1, 0 }, { 180, 0, 1, 0 }, { 270, 0, 1, 0 }, { 90, 1, 0, 0 }, { -90, 1, 0, 0 } }; static const GLfloat mat[4] = { 1.0, 1.0, 0.5, 1.0 }; GLint i, j; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); glEnable(GL_TEXTURE_2D); glPushMatrix(); glRotatef(ViewRotX, 1.0, 0.0, 0.0); glRotatef(15, 1, 0, 0); glRotatef(CubeRot, 0, 1, 0); glScalef(4, 4, 4); for (i = 0; i < 6; i++) { glPushMatrix(); glRotatef(xforms[i][0], xforms[i][1], xforms[i][2], xforms[i][3]); glTranslatef(0, 0, 1.1); glBegin(GL_POLYGON); glNormal3f(0, 0, 1); for (j = 0; j < 4; j++) { glTexCoord2fv(texcoords[j]); glVertex2fv(vertices[j]); } glEnd(); glPopMatrix(); } glPopMatrix(); glDisable(GL_TEXTURE_2D); }
void DrawGLTriangle( triangle *thisTriangle ) { int i; glNormal3f( thisTriangle->PNor->nx, thisTriangle->PNor->ny, thisTriangle->PNor->nz ); glBegin( GL_TRIANGLES); for(i=0; i<3; ++i) { if (thisTriangle->type & MG_TR_NORMAL) { glNormal3fv(&thisTriangle->normals[3*i]); } if (thisTriangle->type & MG_TR_TEX) { glTexCoord2fv(&thisTriangle->tex_coords[2*i]); } glVertex3fv(&thisTriangle->vertices[3*i]); } glEnd(); }
////////////////////////////////////////////////////////// // Draw the Thunderbird's canopy void DrawGlass(void) { int iFace, iPoint; glBegin(GL_TRIANGLES); for(iFace = 0; iFace < 352; iFace++) // Each new triangle starts here for(iPoint = 0; iPoint < 3; iPoint++) // Each vertex specified here { // Lookup the texture value glTexCoord2fv(texturesGlass[face_indiciesGlass[iFace][iPoint+6]]); // Lookup the normal value glNormal3fv(normalsGlass[face_indiciesGlass[iFace][iPoint+3]]); // Lookup the vertex value glVertex3fv(verticesGlass[face_indiciesGlass[iFace][iPoint]]); } glEnd(); }
void RenderHardGlare (fVector *sprite, fVector *vCenter, int nTexture, float fLight, float fIntensity, tIntervalf *zRangeP, int bAdditive) { tTexCoord2f tcGlare [4] = {{{0,0}},{{1,0}},{{1,1}},{{0,1}}}; tFaceColor *pf; grsBitmap *bmP; float a; int i; fLight /= 4; if (fLight < 0.01f) return; a = VmVecMagf (vCenter); if (a < zRangeP->fRad) fIntensity *= a / zRangeP->fRad; pf = gameData.render.color.textures + nTexture; a = (float) (pf->color.red * 3 + pf->color.green * 5 + pf->color.blue * 2) / 30 * 2; a *= fIntensity; if (a < 0.01f) return; glEnable (GL_TEXTURE_2D); bmP = bAdditive ? bmpGlare : bmpCorona; if (OglBindBmTex (bmP, 1, -1)) return; OglTexWrap (bmP->glTexture, GL_CLAMP); glDisable (GL_CULL_FACE); if (bAdditive) { fLight *= a; glBlendFunc (GL_ONE, GL_ONE); } glColor4f (pf->color.red * fLight, pf->color.green * fLight, pf->color.blue * fLight, a); glBegin (GL_QUADS); for (i = 0; i < 4; i++) { glTexCoord2fv ((GLfloat *) (tcGlare + i)); glVertex3fv ((GLfloat *) (sprite + i)); } glEnd (); if (bAdditive) glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_CULL_FACE); RenderCoronaOutline (sprite, vCenter); }
void ComplexAppearance::assembleAppearances() const { glPushMatrix(); glMultMatrixf(transformation); size_t verticesSize = vertices->vertices.size(); if(verticesSize > 0) { surface->set(!texCoords); const Vertex* vertexLibrary = &vertices->vertices[0]; const Normal* vertexNormals = &normals->normals[0]; for(std::list<PrimitiveGroup*>::const_iterator iter = primitiveGroups.begin(), end = primitiveGroups.end(); iter != end; ++iter) { const PrimitiveGroup& primitiveGroup = *(*iter); glBegin(primitiveGroup.mode); for(std::list<unsigned int>::const_iterator iter = primitiveGroup.vertices.begin(), end = primitiveGroup.vertices.end(); iter != end; ++iter) { const unsigned int i = *iter; if(texCoords && i < texCoords->coords.size()) glTexCoord2fv(&texCoords->coords[i].x); if(normalsDefined) { if(++iter != end) glNormal3fv(&vertexNormals[*iter].x); else break; } else glNormal3fv(&vertexNormals[i].x); glVertex3fv(&vertexLibrary[i].x); } glEnd(); } surface->unset(!texCoords); } GraphicalObject::assembleAppearances(); glPopMatrix(); }
void Modelo::desenha() { unsigned numVerts = m_indices.size() / 3; //Tem que ser múltiplo de três pra formar triângulos assert(m_indices.size() % 3 == 0); glBegin(GL_TRIANGLES); for (unsigned i=0 ; i<numVerts ; ++i) { for (unsigned j=0 ; j<3 ; ++j) { Vertice &v = m_vertices[m_indices[i*3 + j]]; glTexCoord2fv(v.texCoord.data()); glNormal3fv(v.normal.data()); glVertex3fv(v.posicao.data()); } } glEnd(); }
void TScreenItem::drawGL(){ printf("%d drawgl cen@(%f,%f),size(%f,%f)",this,cen[0],cen[1],hwid,hhei); cor[0][0]=hwid*cos(ang)-hhei*sin(ang)+cen[0]; cor[1][0]=cen[0]-hwid*cos(ang)-hhei*sin(ang); cor[2][0]=cen[0]-hwid*cos(ang)+hhei*sin(ang); cor[3][0]=hwid*cos(ang)+hhei*sin(ang)+cen[0]; cor[0][1]=hwid*sin(ang)+hhei*cos(ang)+cen[1]; cor[1][1]=cen[1]-hwid*sin(ang)+hhei*cos(ang); cor[2][1]=cen[1]-hwid*sin(ang)-hhei*cos(ang); cor[3][1]=hwid*sinf(ang)-hhei*cosf(ang)+cen[1]; glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_BLEND); glBindTexture(GL_TEXTURE_2D,Now->content); glBegin(GL_POLYGON); for(int i=0;i<4;++i){ glTexCoord2fv(texpos[i]); glVertex2fv(cor[i]); } glEnd(); if(autoplay) Now=Now->next; }
void CWorldGeometry::Draw() { unsigned int i; unsigned int a; for(i = 0; i < m_surfaces.size(); i++) { CWorldGeometrySurface* surface = &(m_surfaces[i]); glBindTexture(GL_TEXTURE_2D, surface->GetTexture()); glNormal3fv(surface->GetPolygon().GetNormal().GetArrayPtr()); glBegin(GL_POLYGON); for(a = 0; a < surface->GetPolygon().GetNumVertices(); a++) { glTexCoord2fv(surface->GetPolygon().GetTexCoord(i)); glVertex3fv(surface->GetPolygon().GetVertex(i).GetArrayPtr()); } glEnd(); } }
inline void RenderSphereRing (fVector *vertexP, tTexCoord2f *texCoordP, int nItems, int bTextured, int nPrimitive) { if (G3EnableClientStates (bTextured, 0, 0, GL_TEXTURE0)) { if (bTextured) glTexCoordPointer (2, GL_FLOAT, 0, texCoordP); glVertexPointer (3, GL_FLOAT, sizeof (fVector), vertexP); glDrawArrays (nPrimitive, 0, nItems); G3DisableClientStates (bTextured, 0, 0, GL_TEXTURE0); } else { int i; glBegin (nPrimitive); for (i = 0; i < nItems; i++) { if (bTextured) glTexCoord2fv ((GLfloat *) (texCoordP + i)); glVertex3fv ((GLfloat *) (vertexP + i)); } glEnd (); } }
//描画 void sankakOBJ::Render() { //UV float uv[3][2] = { {0.0,0.0}, {1.0,0.0}, {0.0,1.0} }; glPushMatrix(); glTranslatef(pos.x, pos.y, pos.z); //移動 setDefaultMaterial(); glBindTexture(GL_TEXTURE_2D, texturePNG); glNormal3fv( (GLfloat*)&(colliOBJ.GetNormal().x) ); glBegin(GL_TRIANGLES); for(int i=0; i<3; i++){ glTexCoord2fv( uv[i] ); glVertex3fv( vertex[i] ); } glEnd(); glBindTexture(GL_TEXTURE_2D, 0);//バインドしたのをもとに戻す //glCallList(DisplayList); //描画 glPopMatrix(); }
void ssgVtxTableShadow::draw_geometry () { int num_colours = getNumColours () ; int num_normals = getNumNormals () ; int num_vertices = getNumVertices () ; int num_texcoords = getNumTexCoords () ; sgVec3 *vx = (sgVec3 *) vertices -> get(0) ; sgVec3 *nm = (sgVec3 *) normals -> get(0) ; sgVec2 *tx = (sgVec2 *) texcoords -> get(0) ; sgVec4 *cl = (sgVec4 *) colours -> get(0) ; glDepthMask(GL_FALSE); glPolygonOffset(-15.0f, -20.0f); glEnable(GL_POLYGON_OFFSET_FILL); //glEnable(GL_CULL_FACE); glBegin ( gltype ) ; if ( num_colours == 0 ) glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f ) ; if ( num_colours == 1 ) glColor4fv ( cl [ 0 ] ) ; if ( num_normals == 1 ) glNormal3fv ( nm [ 0 ] ) ; for ( int i = 0 ; i < num_vertices ; i++ ) { if ( num_colours > 1 ) glColor4fv ( cl [ i ] ) ; if ( num_normals > 1 ) glNormal3fv ( nm [ i ] ) ; if ( num_texcoords > 1 ) glTexCoord2fv ( tx [ i ] ) ; glVertex3fv ( vx [ i ] ) ; } glEnd () ; glDisable(GL_POLYGON_OFFSET_FILL); glDepthMask(GL_TRUE); }
void glArrayElement(GLint i) { GLfloat *v; pointer_state_t *p; p = &state.pointers.color; if (state.enable.color_array && p->pointer) { v = gl_pointer_index(p, i); GLuint scale = gl_max_value(p->type); // color[3] defaults to 1.0f if (p->size < 4) v[3] = 1.0f; // scale color coordinates to a 0 - 1.0 range for (int i = 0; i < p->size; i++) { v[i] /= scale; } glColor4fv(v); } p = &state.pointers.normal; if (state.enable.normal_array && p->pointer) { v = gl_pointer_index(p, i); glNormal3fv(v); } p = &state.pointers.tex_coord; if (state.enable.tex_coord_array && p->pointer) { v = gl_pointer_index(p, i); glTexCoord2fv(v); } p = &state.pointers.vertex; if (state.enable.vertex_array && p->pointer) { v = gl_pointer_index(p, i); if (p->size == 4) { glVertex4fv(v); } else { glVertex3fv(v); } } }
void glcolorbox(const float3 &r, const Pose &p) // p = { { 0, 0, 0 }, { 0, 0, 0, 1 } }) { glPushMatrix(); glMultMatrixf(p.Matrix()); glBegin(GL_QUADS); for (int m : {0, 1}) for (int i : {0, 1, 2}) { int i1 = (i + 1 + m) % 3; int i2 = (i + 2 - m) % 3; float3 u, v, w; u[i1] = r[i1]; v[i2] = r[i2]; w[i] = (m) ? -1.0f : 1.0f; float3 a((float)m, (float)m, (float)m); a[i] = 1-a[i]; glColor3fv(a); glNormal3fv(w); float2 corners[] = { { -1.0f, -1.0f }, { 1.0f, -1.0f }, { 1.0f, 1.0f }, { -1.0f, 1.0f } }; // ccw order for (float2 t : corners) glTexCoord2fv(t), glVertex3fv(w*r[i] + u*t.x + v*t.y); } glEnd(); glPopMatrix(); }
// // Load OBJ file // int LoadOBJ(const char* file) { int k; int Nv,Nn,Nt; // Number of vertex, normal and textures int Mv,Mn,Mt; // Maximum vertex, normal and textures float* V; // Array of vertexes float* N; // Array of normals float* T; // Array if textures coordinates char* line; // Line pointer char* str; // String pointer // Open file FILE* f = fopen(file,"r"); if (!f) Fatal("Cannot open file %s\n",file); // Reset materials mtl = NULL; Nmtl = 0; // Start new displaylist int list = glGenLists(1); glNewList(list,GL_COMPILE); // Push attributes for textures glPushAttrib(GL_TEXTURE_BIT); // Read vertexes and facets V = N = T = NULL; Nv = Nn = Nt = 0; Mv = Mn = Mt = 0; while ((line = readline(f))) { // Vertex coordinates (always 3) if (line[0]=='v' && line[1]==' ') readcoord(line+2,3,&V,&Nv,&Mv); // Normal coordinates (always 3) else if (line[0]=='v' && line[1] == 'n') readcoord(line+2,3,&N,&Nn,&Mn); // Texture coordinates (always 2) else if (line[0]=='v' && line[1] == 't') readcoord(line+2,2,&T,&Nt,&Mt); // Read and draw facets else if (line[0]=='f') { line++; // Read Vertex/Texture/Normal triplets glBegin(GL_POLYGON); while ((str = getword(&line))) { int Kv,Kt,Kn; // Try Vertex/Texture/Normal triplet if (sscanf(str,"%d/%d/%d",&Kv,&Kt,&Kn)==3) { if (Kv<0 || Kv>Nv/3) Fatal("Vertex %d out of range 1-%d\n",Kv,Nv/3); if (Kn<0 || Kn>Nn/3) Fatal("Normal %d out of range 1-%d\n",Kn,Nn/3); if (Kt<0 || Kt>Nt/2) Fatal("Texture %d out of range 1-%d\n",Kt,Nt/2); } // Try Vertex//Normal pairs else if (sscanf(str,"%d//%d",&Kv,&Kn)==2) { if (Kv<0 || Kv>Nv/3) Fatal("Vertex %d out of range 1-%d\n",Kv,Nv/3); if (Kn<0 || Kn>Nn/3) Fatal("Normal %d out of range 1-%d\n",Kn,Nn/3); Kt = 0; } // Try Vertex index else if (sscanf(str,"%d",&Kv)==1) { if (Kv<0 || Kv>Nv/3) Fatal("Vertex %d out of range 1-%d\n",Kv,Nv/3); Kn = 0; Kt = 0; } // This is an error else Fatal("Invalid facet %s\n",str); // Draw vectors if (Kt) glTexCoord2fv(T+2*(Kt-1)); if (Kn) glNormal3fv(N+3*(Kn-1)); if (Kv) glVertex3fv(V+3*(Kv-1)); } glEnd(); } // Use material else if ((str = readstr(line,"usemtl"))) SetMaterial(str); // Load materials else if ((str = readstr(line,"mtllib"))) LoadMaterial(str); // Skip this line } fclose(f); // Pop attributes (textures) glPopAttrib(); glEndList(); // Free materials for (k=0;k<Nmtl;k++) free(mtl[k].name); free(mtl); // Free arrays free(V); free(T); free(N); return list; }
void ccGenericMesh::drawMeOnly(CC_DRAW_CONTEXT& context) { ccGenericPointCloud* vertices = getAssociatedCloud(); if (!vertices) return; handleColorRamp(context); //3D pass if (MACRO_Draw3D(context)) { //any triangle? unsigned triNum = size(); if (triNum == 0) return; //L.O.D. bool lodEnabled = (triNum > GET_MAX_LOD_FACES_NUMBER() && context.decimateMeshOnMove && MACRO_LODActivated(context)); unsigned decimStep = (lodEnabled ? (unsigned)ceil((float)triNum*3 / (float)GET_MAX_LOD_FACES_NUMBER()) : 1); unsigned displayedTriNum = triNum / decimStep; //display parameters glDrawParams glParams; getDrawingParameters(glParams); glParams.showNorms &= bool(MACRO_LightIsEnabled(context)); //vertices visibility const ccGenericPointCloud::VisibilityTableType* verticesVisibility = vertices->getTheVisibilityArray(); bool visFiltering = (verticesVisibility && verticesVisibility->isAllocated()); //wireframe ? (not compatible with LOD) bool showWired = isShownAsWire() && !lodEnabled; //per-triangle normals? bool showTriNormals = (hasTriNormals() && triNormsShown()); //fix 'showNorms' glParams.showNorms = showTriNormals || (vertices->hasNormals() && m_normalsDisplayed); //materials & textures bool applyMaterials = (hasMaterials() && materialsShown()); bool showTextures = (hasTextures() && materialsShown() && !lodEnabled); //GL name pushing bool pushName = MACRO_DrawEntityNames(context); //special case: triangle names pushing (for picking) bool pushTriangleNames = MACRO_DrawTriangleNames(context); pushName |= pushTriangleNames; if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); //minimal display for picking mode! glParams.showNorms = false; glParams.showColors = false; //glParams.showSF --> we keep it only if SF 'NaN' values are hidden showTriNormals = false; applyMaterials = false; showTextures = false; } //in the case we need to display scalar field colors ccScalarField* currentDisplayedScalarField = 0; bool greyForNanScalarValues = true; unsigned colorRampSteps = 0; ccColorScale::Shared colorScale(0); if (glParams.showSF) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); ccPointCloud* cloud = static_cast<ccPointCloud*>(vertices); greyForNanScalarValues = (cloud->getCurrentDisplayedScalarField() && cloud->getCurrentDisplayedScalarField()->areNaNValuesShownInGrey()); if (greyForNanScalarValues && pushName) { //in picking mode, no need to take SF into account if we don't hide any points! glParams.showSF = false; } else { currentDisplayedScalarField = cloud->getCurrentDisplayedScalarField(); colorScale = currentDisplayedScalarField->getColorScale(); colorRampSteps = currentDisplayedScalarField->getColorRampSteps(); assert(colorScale); //get default color ramp if cloud has no scale associated?! if (!colorScale) colorScale = ccColorScalesManager::GetUniqueInstance()->getDefaultScale(ccColorScalesManager::BGYR); } } //materials or color? bool colorMaterial = false; if (glParams.showSF || glParams.showColors) { applyMaterials = false; colorMaterial = true; glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); } //in the case we need to display vertex colors ColorsTableType* rgbColorsTable = 0; if (glParams.showColors) { if (isColorOverriden()) { glColor3ubv(m_tempColor); glParams.showColors = false; } else { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); rgbColorsTable = static_cast<ccPointCloud*>(vertices)->rgbColors(); } } else { glColor3fv(context.defaultMat.diffuseFront); } if (glParams.showNorms) { //DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version can fall to 1.0! glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); glEnable(GL_LIGHTING); context.defaultMat.applyGL(true,colorMaterial); } //in the case we need normals (i.e. lighting) NormsIndexesTableType* normalsIndexesTable = 0; ccNormalVectors* compressedNormals = 0; if (glParams.showNorms) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); normalsIndexesTable = static_cast<ccPointCloud*>(vertices)->normals(); compressedNormals = ccNormalVectors::GetUniqueInstance(); } //stipple mask if (stipplingEnabled()) EnableGLStippleMask(true); if (!pushTriangleNames && !visFiltering && !(applyMaterials || showTextures) && (!glParams.showSF || greyForNanScalarValues)) { //the GL type depends on the PointCoordinateType 'size' (float or double) GLenum GL_COORD_TYPE = sizeof(PointCoordinateType) == 4 ? GL_FLOAT : GL_DOUBLE; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_COORD_TYPE,0,GetVertexBuffer()); if (glParams.showNorms) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_COORD_TYPE,0,GetNormalsBuffer()); } if (glParams.showSF || glParams.showColors) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3,GL_UNSIGNED_BYTE,0,GetColorsBuffer()); } //we can scan and process each chunk separately in an optimized way //we mimic the way ccMesh beahves by using virtual chunks! unsigned chunks = static_cast<unsigned>(ceil((double)displayedTriNum/(double)MAX_NUMBER_OF_ELEMENTS_PER_CHUNK)); unsigned chunkStart = 0; const colorType* col = 0; for (unsigned k=0; k<chunks; ++k, chunkStart += MAX_NUMBER_OF_ELEMENTS_PER_CHUNK) { //virtual chunk size const unsigned chunkSize = k+1 < chunks ? MAX_NUMBER_OF_ELEMENTS_PER_CHUNK : (displayedTriNum % MAX_NUMBER_OF_ELEMENTS_PER_CHUNK); //vertices PointCoordinateType* _vertices = GetVertexBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_vertices,vertices->getPoint(ti->i1)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i2)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i3)->u,sizeof(PointCoordinateType)*3); _vertices+=3; } //scalar field if (glParams.showSF) { colorType* _rgbColors = GetColorsBuffer(); assert(colorScale); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); col = currentDisplayedScalarField->getValueColor(ti->i1); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i2); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i3); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; } } //colors else if (glParams.showColors) { colorType* _rgbColors = GetColorsBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_rgbColors,rgbColorsTable->getValue(ti->i1),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i2),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i3),sizeof(colorType)*3); _rgbColors += 3; } } //normals if (glParams.showNorms) { PointCoordinateType* _normals = GetNormalsBuffer(); if (showTriNormals) { for (unsigned n=0; n<chunkSize; n+=decimStep) { CCVector3 Na, Nb, Nc; getTriangleNormals(chunkStart + n, Na, Nb, Nc); memcpy(_normals,Na.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nb.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nc.u,sizeof(PointCoordinateType)*3); _normals+=3; } } else { for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_normals,vertices->getPointNormal(ti->i1).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i2).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i3).u,sizeof(PointCoordinateType)*3); _normals+=3; } } } if (!showWired) { glDrawArrays(lodEnabled ? GL_POINTS : GL_TRIANGLES,0,(chunkSize/decimStep)*3); } else { glDrawElements(GL_LINES,(chunkSize/decimStep)*6,GL_UNSIGNED_INT,GetWireVertexIndexes()); } } //disable arrays glDisableClientState(GL_VERTEX_ARRAY); if (glParams.showNorms) glDisableClientState(GL_NORMAL_ARRAY); if (glParams.showSF || glParams.showColors) glDisableClientState(GL_COLOR_ARRAY); } else { //current vertex color const colorType *col1=0,*col2=0,*col3=0; //current vertex normal const PointCoordinateType *N1=0,*N2=0,*N3=0; //current vertex texture coordinates float *Tx1=0,*Tx2=0,*Tx3=0; //loop on all triangles int lasMtlIndex = -1; if (showTextures) { //#define TEST_TEXTURED_BUNDLER_IMPORT #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(context.sourceBlend, context.destBlend); #endif glEnable(GL_TEXTURE_2D); } if (pushTriangleNames) glPushName(0); GLenum triangleDisplayType = lodEnabled ? GL_POINTS : showWired ? GL_LINE_LOOP : GL_TRIANGLES; glBegin(triangleDisplayType); //per-triangle normals const NormsIndexesTableType* triNormals = getTriNormsTable(); //materials const ccMaterialSet* materials = getMaterialSet(); for (unsigned n=0; n<triNum; ++n) { //current triangle vertices const CCLib::TriangleSummitsIndexes* tsi = getTriangleIndexes(n); //LOD: shall we display this triangle? if (n % decimStep) continue; if (visFiltering) { //we skip the triangle if at least one vertex is hidden if ((verticesVisibility->getValue(tsi->i1) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i2) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i3) != POINT_VISIBLE)) continue; } if (glParams.showSF) { assert(colorScale); col1 = currentDisplayedScalarField->getValueColor(tsi->i1); if (!col1) continue; col2 = currentDisplayedScalarField->getValueColor(tsi->i2); if (!col2) continue; col3 = currentDisplayedScalarField->getValueColor(tsi->i3); if (!col3) continue; } else if (glParams.showColors) { col1 = rgbColorsTable->getValue(tsi->i1); col2 = rgbColorsTable->getValue(tsi->i2); col3 = rgbColorsTable->getValue(tsi->i3); } if (glParams.showNorms) { if (showTriNormals) { assert(triNormals); int n1,n2,n3; getTriangleNormalIndexes(n,n1,n2,n3); N1 = (n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n1)).u : 0); N2 = (n1==n2 ? N1 : n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n2)).u : 0); N3 = (n1==n3 ? N1 : n3>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n3)).u : 0); } else { N1 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i1)).u; N2 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i2)).u; N3 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i3)).u; } } if (applyMaterials || showTextures) { assert(materials); int newMatlIndex = this->getTriangleMtlIndex(n); //do we need to change material? if (lasMtlIndex != newMatlIndex) { assert(newMatlIndex<(int)materials->size()); glEnd(); if (showTextures) { GLuint texID = (newMatlIndex>=0 ? (*materials)[newMatlIndex].texID : 0); if (texID>0) assert(glIsTexture(texID)); glBindTexture(GL_TEXTURE_2D, texID); } //if we don't have any current material, we apply default one (newMatlIndex>=0 ? (*materials)[newMatlIndex] : context.defaultMat).applyGL(glParams.showNorms,false); glBegin(triangleDisplayType); lasMtlIndex=newMatlIndex; } if (showTextures) { getTriangleTexCoordinates(n,Tx1,Tx2,Tx3); } } if (pushTriangleNames) { glEnd(); glLoadName(n); glBegin(triangleDisplayType); } else if (showWired) { glEnd(); glBegin(triangleDisplayType); } //vertex 1 if (N1) ccGL::Normal3v(N1); if (col1) glColor3ubv(col1); if (Tx1) glTexCoord2fv(Tx1); ccGL::Vertex3v(vertices->getPoint(tsi->i1)->u); //vertex 2 if (N2) ccGL::Normal3v(N2); if (col2) glColor3ubv(col2); if (Tx2) glTexCoord2fv(Tx2); ccGL::Vertex3v(vertices->getPoint(tsi->i2)->u); //vertex 3 if (N3) ccGL::Normal3v(N3); if (col3) glColor3ubv(col3); if (Tx3) glTexCoord2fv(Tx3); ccGL::Vertex3v(vertices->getPoint(tsi->i3)->u); } glEnd(); if (pushTriangleNames) glPopName(); if (showTextures) { #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPopAttrib(); //GL_COLOR_BUFFER_BIT #endif glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } } if (stipplingEnabled()) EnableGLStippleMask(false); if (colorMaterial) glDisable(GL_COLOR_MATERIAL); if (glParams.showNorms) { glDisable(GL_LIGHTING); glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); } if (pushName) glPopName(); } }
static void Display( void ) { const struct interleave_info * const curr_info = info[ interleave_mode ]; /* 4 floats for 12 verticies for 4 data elements. */ char data[ (sizeof( GLfloat ) * 4) * 12 * 4 ]; unsigned i; unsigned offset; GLenum err; GLenum format; GLsizei stride; glClearColor(0.2, 0.2, 0.8, 0); glClear( GL_COLOR_BUFFER_BIT ); glPushMatrix(); glTranslatef(-1.5, 0, 0); glColor3fv( c_f[0] ); if ( curr_info[0].data != NULL ) { glEnable( GL_TEXTURE_2D ); } else { glDisable( GL_TEXTURE_2D ); } offset = 0; glBegin(GL_TRIANGLES); for ( i = 0 ; i < 12 ; i++ ) { const unsigned index = indicies[i]; /* Handle the vertex texture coordinate. */ if ( curr_info[0].data != NULL ) { if ( curr_info[0].count == 2 ) { glTexCoord2fv( DEREF(0, index) ); } else { glTexCoord4fv( DEREF(0, index) ); } (void) memcpy( & data[ offset ], DEREF(0, index), curr_info[0].size ); offset += curr_info[0].size; } /* Handle the vertex color. */ if ( curr_info[1].data != NULL ) { if ( curr_info[1].type == GL_FLOAT ) { if ( curr_info[1].count == 3 ) { glColor3fv( DEREF(1, index) ); } else { glColor4fv( DEREF(1, index) ); } } else { glColor4ubv( DEREF(1, index) ); } (void) memcpy( & data[ offset ], DEREF(1, index), curr_info[1].size ); offset += curr_info[1].size; } /* Handle the vertex normal. */ if ( curr_info[2].data != NULL ) { glNormal3fv( DEREF(2, index) ); (void) memcpy( & data[ offset ], DEREF(2, index), curr_info[2].size ); offset += curr_info[2].size; } switch( curr_info[3].count ) { case 2: glVertex2fv( DEREF(3, index) ); break; case 3: glVertex3fv( DEREF(3, index) ); break; case 4: glVertex4fv( DEREF(3, index) ); break; } (void) memcpy( & data[ offset ], DEREF(3, index), curr_info[3].size ); offset += curr_info[3].size; } glEnd(); glTranslatef(3.0, 0, 0); /* The masking with ~0x2A00 is a bit of a hack to make sure that format * ends up with an invalid value no matter what rand() returns. */ format = (use_invalid_mode) ? (rand() & ~0x2A00) : GL_V2F + interleave_mode; stride = (use_invalid_stride) ? -abs(rand()) : 0; (void) glGetError(); glInterleavedArrays( format, stride, data ); err = glGetError(); if ( err ) { printf("glInterleavedArrays(0x%04x, %d, %p) generated the error 0x%04x\n", format, stride, data, err ); } else { glDrawArrays( GL_TRIANGLES, 0, 12 ); } glPopMatrix(); glutSwapBuffers(); }
void End(void) { int i; vertex_t *vtx; if(!primType && inSequence) { inSequence = DGL_FALSE; return; } // FIXME: Why not use OpenGL arrays? The data could rather easily // be organized in arrays suitable for this kind of use. Should be // a "tad" faster than making lots of calls to the various color, // vertex and texcoord functions. glBegin(primType == DGL_POINTS ? GL_POINTS : primType == DGL_LINES ? GL_LINES : primType == DGL_TRIANGLES ? GL_TRIANGLES : primType == DGL_TRIANGLE_FAN ? GL_TRIANGLE_FAN : primType == DGL_TRIANGLE_STRIP ? GL_TRIANGLE_STRIP : primType == DGL_QUAD_STRIP ? GL_QUAD_STRIP : GL_QUADS); for(i = 0, vtx = vertexStack; i < stackPos; i++, vtx++) { if(vtx->flags & VTXF_COLOR_3) glColor3fv(vtx->color); else if(vtx->flags & VTXF_COLOR_4) glColor4fv(vtx->color); if(vtx->flags & VTXF_TEX) glTexCoord2fv(vtx->tex); if(vtx->flags & VTXF_POS_2) glVertex2fv(vtx->pos); else glVertex3fv(vtx->pos); } glEnd(); #ifdef DEBUGMODE { int code = glGetError(); dprintf("GL Error: %x", code); //assert(code == GL_NO_ERROR); } #endif primType = DGL_FALSE; stackPos = 0; vertexStack[0].flags = 0; /*if(primMode == DGL_FALSE) { if(inSequence) { // Sequence ends. inSequence = DGL_FALSE; EndScene(); } return; } if(primType != DGL_QUADS) { if(FAILED(hr = IDirect3DDevice3_End(d3dDevice, 0))) gim.Message( "drD3D.End: Failure! Error: %x\n", hr); } if(!inSequence) EndScene(); primMode = primType = DGL_FALSE; */ }
void Mesh::render(int renderMode, int glMode){ int group_name = 0; int currentID = 0; glBindTexture(GL_TEXTURE_2D, currentID); if (glMode == GL_LINE_LOOP) { renderVerts(); if (renderMode == GL_SELECT) return; } for(Group* g : groups){ if(renderMode == GL_SELECT && glMode == GL_POLYGON){ glLoadName(group_name++); } if(!g->getVisible()){ continue; } string mtlName = g->getMtl(); if(!mtlName.empty()){ Material* mtl = getMtl(mtlName); glMaterialfv(GL_FRONT, GL_SPECULAR, mtl->getSpecular()); glMaterialfv(GL_FRONT, GL_AMBIENT, mtl->getAmbient()); glMaterialfv(GL_FRONT, GL_DIFFUSE, mtl->getDiffuse()); glMaterialf(GL_FRONT, GL_SHININESS, mtl->getShininess()); int tID = mtl->getID(); if(tID != currentID){ currentID = tID; glBindTexture(GL_TEXTURE_2D, currentID); } } int face_name = 0; glColor3f(1.0, 1.0, 1.0); for(Face* f : g->getFaces()){ if (f == face_selected.face) glColor3f(0.603922f, 0.803922f, 0.196078f); vector<int> v = f->getVerts(); vector<int> n = f->getNorms(); vector<int> t = f->getTexts(); bool hasNorm = !n.empty(); bool hasText = !t.empty(); int nv = v.size(); if (renderMode == GL_SELECT && glMode == GL_POLYGON) glPushName(face_name++); glBegin(glMode); for(int x = 0; x < nv; ++x){ if(hasNorm) { glNormal3fv(norms[n[x]].getCoords()); } if(hasText){ glTexCoord2fv(texts[t[x]].getCoords()); } glVertex3fv(verts[v[x]].getCoords()); } glEnd(); if (renderMode == GL_SELECT && glMode == GL_POLYGON) glPopName(); if (f == face_selected.face) glColor3f(1.0, 1.0, 1.0); } } }
static void RandomPrimitive(void) { int i; int len = MinVertexCount + RandomInt(MaxVertexCount - MinVertexCount); Vprim = RandomInt(10); glBegin(Vprim); Vbuffer[Vcount].type = BEGIN; Vbuffer[Vcount].v[0] = Vprim; Vcount++; for (i = 0; i < len; i++) { Vbuffer[Vcount].v[0] = RandomFloat(-3, 3); Vbuffer[Vcount].v[1] = RandomFloat(-3, 3); Vbuffer[Vcount].v[2] = RandomFloat(-3, 3); Vbuffer[Vcount].v[3] = RandomFloat(-3, 3); int k = RandomInt(9); switch (k) { case 0: glVertex2fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = VERTEX2; break; case 1: glVertex3fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = VERTEX3; break; case 2: glVertex4fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = VERTEX4; break; case 3: glColor3fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = COLOR3; break; case 4: glColor4fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = COLOR4; break; case 5: glTexCoord2fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = TEX2; break; case 6: glTexCoord3fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = TEX3; break; case 7: glTexCoord4fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = TEX4; break; case 8: glSecondaryColor3fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = SECCOLOR3; break; case 9: glNormal3fv(Vbuffer[Vcount].v); Vbuffer[Vcount].type = NORMAL3; break; default: abort(); } Vcount++; if (Vcount >= BufferSize - 2) { /* reset */ Vcount = 0; } } Vbuffer[Vcount++].type = END; glEnd(); }