Fastest way to draw primitives?

I’m sure this is a FAQ, but I would like some personal guidance to make sure I understand the trade-offs.

I’m coding my first PC 3D engine. My former engines were PSX, meaning they were limited in a number of ways (no Z buffer, affine texture mapping, 3x3M+V transformations, limited blending modes, etc.)

I’m using OpenGL as a rasterizer only, just so you know, although I don’t think it makes a big difference for this question. I’m doing it to better learn things like perspective texture mapping, lighting equations, etc. on my own. After I feel solid on these, I may convert them to OpenGL calls.

What I am asking is the best manner of drawing primitives? Up until now I’ve down glBegin…glVertex, glColor, glTex…glEnd on each of my prims. I figured this was slow, but quick and dirty to get something on the screen. Now I want to start throwing down more polygons, so I would like something more optimised.

Here’s the dilemma, I have frequent texture changes, and not too much texture repetion, although there is some. Not only does this mean frequent glBindTexture calls, but UVs for individual vertices are different for each polygon that vertex shares, so even combining several textures into one, shared coordinates are a problem. (?) From my understanding of glDrawElements, there is no way to have the coordinate of a vertex and the uvs using different indices. Is this correct? If not, how do I indicate differing indices for the uvs compared to the coordinates?

I thought next, I could transform just the coordinates once for each vertex, and then “copy” them when the uvs differ into an array and call glDrawArray. This seemed to alleviate the uv problems and still give me the savings of not having to transform everything more than once. But where to put the texture changes?

This led me to display lists. Is this the best I can do? It’s nice in some ways, because I don’t have to change my glBegin, glEnd calls in the C++ rasteriser class, and only put in a glNewList in the ClearScreen method and a glEndList/glCallList pair in the SwapBuffers method of my rasteriser.

Which begs the next question, “What is the best way to sort the primitives to draw?” I’m guessing to try and minimise the texture changes so I sort them by texture/material. Is this common on the PC world? It’s pretty common in the next gen console world to do this (though I don’t have much experience programming them, just from the docs that I’ve read it seems logical to do it this way to minimise texture cache misses).

Anyhoo, I apologise for the length of this message. I’m hoping to hear something like glDrawElements with GL_TRIANGLES or GL_TRIANGLE_STRIPS is the best method, though I sorely doubt it would be that easy.