well what I am seen is that Display List are about 5 time faster that Vertex array, but that may be because in Alchemedia editor I have to do lot of work to extract the geometry for rendering in the four viewports.
I am using display List as Geometry cache and what I like about it is that they do not need Maintenance, just an integer that I can keep track and regenerate each time part of the mesh changes.
However I am having lot of problem having OpenGL to render in multiples viewports.
When I use Vertex array, the textures only show up in one of the view ports, the other three come in white color.
When I use Display List then it only renders in the first viewport but the textures do not show up.
It is like everything that is in the GPU memory is only associated with one viewport.
I though that the function wglMakeCurrent is what associate the device wit the corrent viewport but aparentlly not.
The is what I do at the beginning of rendering on one view port
- Code: Select all
void alchemediaView::OnDraw(CDC* dc)
{
alchemediaDoc* doc = GetDocument();
ASSERT_VALID(doc);
if (!(doc && doc->GetCurWorld()))
return;
BOOL state = wglMakeCurrent(dc->GetSafeHdc(), m_renderContext);
_ASSERTE (state);
And this is the change from Vertex Array to display List.
- Code: Select all
void alchemediaStaticMesh::UpdateDisplayList(dScene* const world, dScene::dTreeNode* const myNode) const
{
if (!m_dipalyList) {
m_dipalyList = glGenLists(1);
glNewList(m_dipalyList, GL_COMPILE);
int stride = NewtonMeshGetPointStrideInByte(m_mesh) / sizeof (dFloat);
float* const vertexArray = NewtonMeshGetPointArray(m_mesh);
float* const normalArray = NewtonMeshGetNormalArray(m_mesh);
float* const uv0Array = NewtonMeshGetUV0Array(m_mesh);
for (void* ptr = world->GetFirstChild(myNode); ptr; ptr = world->GetNextChild(myNode, ptr)) {
dScene::dTreeNode* const materialNode = world->GetNodeFromLink (ptr);
dNodeInfo* const info = world->GetInfoFromNode(materialNode);
if (info->IsType(dMaterialNodeInfo::GetRttiType())) {
dMaterialNodeInfo* const material = (dMaterialNodeInfo*) info;
glMaterialfv(GL_FRONT, GL_SPECULAR, &material->GetSpecularColor().m_x);
glMaterialfv(GL_FRONT, GL_AMBIENT, &material->GetAmbientColor().m_x);
glMaterialfv(GL_FRONT, GL_DIFFUSE, &material->GetDiffuseColor().m_x);
glMaterialfv(GL_FRONT, GL_EMISSION, &material->GetEmissiveColor().m_x);
glMaterialf(GL_FRONT, GL_SHININESS, material->GetShininess());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
dTextureNodeInfo* diffuseTex = NULL;
dScene::dTreeNode* diffTexNode = world->FindTextureByTextId (materialNode, material->GetDiffuseTextId());
if (diffTexNode){
diffuseTex = (dTextureNodeInfo*) world->GetInfoFromNode(diffTexNode);
}
if (diffuseTex && (diffuseTex->GetInternalId() != -1)) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, GLuint (diffuseTex->GetInternalId()));
} else {
glDisable(GL_TEXTURE_2D);
}
glBegin(GL_TRIANGLES);
int id = material->GetId();
for (void* face = NewtonMeshGetFirstFace (m_mesh); face; face = NewtonMeshGetNextFace (m_mesh, face)) {
if (!NewtonMeshIsFaceOpen (m_mesh, face)) {
int materialID = NewtonMeshGetFaceMaterial (m_mesh, face);
if (materialID == id) {
int vertexCount = NewtonMeshGetFaceIndexCount (m_mesh, face);
int indices[1024];
NewtonMeshGetFacePointIndices (m_mesh, face, indices);
int index = indices[0] * stride;
dVector uv0 (uv0Array[index], uv0Array[index + 1], 0.0f, 0.0f);
dVector normal0 (normalArray[index], normalArray[index + 1], normalArray[index + 2], 0.0f);
dVector point0 (vertexArray[index], vertexArray[index + 1], vertexArray[index + 2], 0.0f);
index = indices[1] * stride;
dVector uv1 (uv0Array[index], uv0Array[index + 1], 0.0f, 0.0f);
dVector normal1 (normalArray[index], normalArray[index + 1], normalArray[index + 2], 0.0f);
dVector point1 (vertexArray[index], vertexArray[index + 1], vertexArray[index + 2], 0.0f);
for (int i = 2; i < vertexCount; i ++) {
int index = indices[i] * stride;
dVector uv2 (uv0Array[index], uv0Array[index + 1], 0.0f, 0.0f);
dVector normal2 (normalArray[index], normalArray[index + 1], normalArray[index + 2], 0.0f);
dVector point2 (vertexArray[index], vertexArray[index + 1], vertexArray[index + 2], 0.0f);
glTexCoord2f(uv0.m_x, uv0.m_y);
glNormal3f (normal0.m_x, normal0.m_y, normal0.m_z);
glVertex3f(point0.m_x, point0.m_y, point0.m_z);
glTexCoord2f(uv1.m_x, uv1.m_y);
glNormal3f (normal1.m_x, normal1.m_y, normal1.m_z);
glVertex3f(point1.m_x, point1.m_y, point1.m_z);
glTexCoord2f(uv2.m_x, uv2.m_y);
glNormal3f (normal2.m_x, normal2.m_y, normal2.m_z);
glVertex3f(point2.m_x, point2.m_y, point2.m_z);
uv1 = uv2;
normal1 = normal2;
point1 = point2;
}
}
}
}
glEnd();
}
}
glEndList();
}
}
// draw scene in Gouraud shaded normal textured mode
void alchemediaStaticMesh::DrawGouraudShaded(dScene* world, dScene::dTreeNode* myNode, const dVector& color, int* const workBuffer, int worlfBufferInBytes) const
{
_ASSERTE (world->GetInfoFromNode(myNode) == this);
#if 1
// this uses Vertex arrays but it is slow and only show the textures in one viewport
int bufferSize = (worlfBufferInBytes / sizeof (int)) / 2;
int* buffer0 = &workBuffer[0];
int* buffer1 = &workBuffer[bufferSize];
int* doubleBufferPtr[2];
doubleBufferPtr[0] = buffer0;
doubleBufferPtr[1] = buffer1;
// int vertexCount = NewtonMeshGetPointCount(m_mesh);
int stride = NewtonMeshGetPointStrideInByte(m_mesh);
// float* vertexList = NewtonMeshGetPointArray(m_mesh);
float* const vertexArray = NewtonMeshGetPointArray(m_mesh);
float* const normalArray = NewtonMeshGetNormalArray(m_mesh);
float* const uv0Array = NewtonMeshGetUV0Array(m_mesh);
glPushMatrix();
glMultMatrix(&m_matrix[0][0]);
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_NORMAL_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glVertexPointer (4, GL_FLOAT, stride, vertexArray);
glNormalPointer (GL_FLOAT, stride, normalArray);
glTexCoordPointer (2, GL_FLOAT, stride, uv0Array);
int pointCount = 0;
int bufferIndex = 0;
int* buffer = doubleBufferPtr[bufferIndex];
for (void* ptr = world->GetFirstChild(myNode); ptr; ptr = world->GetNextChild(myNode, ptr)) {
dScene::dTreeNode* materialNode = world->GetNodeFromLink (ptr);
dNodeInfo* info = world->GetInfoFromNode(materialNode);
if (info->IsType(dMaterialNodeInfo::GetRttiType())) {
dMaterialNodeInfo* material = (dMaterialNodeInfo*) info;
glMaterialfv(GL_FRONT, GL_SPECULAR, &material->GetSpecularColor().m_x);
glMaterialfv(GL_FRONT, GL_AMBIENT, &material->GetAmbientColor().m_x);
glMaterialfv(GL_FRONT, GL_DIFFUSE, &material->GetDiffuseColor().m_x);
glMaterialfv(GL_FRONT, GL_EMISSION, &material->GetEmissiveColor().m_x);
glMaterialf(GL_FRONT, GL_SHININESS, material->GetShininess());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
dTextureNodeInfo* diffuseTex = NULL;
dScene::dTreeNode* diffTexNode = world->FindTextureByTextId (materialNode, material->GetDiffuseTextId());
if (diffTexNode){
diffuseTex = (dTextureNodeInfo*) world->GetInfoFromNode(diffTexNode);
}
if (diffuseTex && (diffuseTex->GetInternalId() != -1)) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, GLuint (diffuseTex->GetInternalId()));
} else {
glDisable(GL_TEXTURE_2D);
}
int id = material->GetId();
for (void* face = NewtonMeshGetFirstFace (m_mesh); face; face = NewtonMeshGetNextFace (m_mesh, face)) {
if (!NewtonMeshIsFaceOpen (m_mesh, face)) {
int materialID = NewtonMeshGetFaceMaterial (m_mesh, face);
if (materialID == id) {
int vertexCount = NewtonMeshGetFaceIndexCount (m_mesh, face);
if ((pointCount + 3 * (vertexCount - 2)) >= bufferSize) {
glDrawElements (GL_TRIANGLES, pointCount, GL_UNSIGNED_INT, buffer);
bufferIndex = (bufferIndex + 1) & 1;
buffer = doubleBufferPtr[bufferIndex];
pointCount = 0;
}
int indices[1024];
NewtonMeshGetFacePointIndices (m_mesh, face, indices);
for (int i = 2; i < vertexCount; i ++) {
buffer[pointCount + 0] = indices[0];
buffer[pointCount + 1] = indices[i - 1];
buffer[pointCount + 2] = indices[i];
pointCount += 3;
}
}
}
}
if (pointCount) {
glDrawElements (GL_TRIANGLES, pointCount, GL_UNSIGNED_INT, buffer);
bufferIndex = (bufferIndex + 1) & 1;
buffer = doubleBufferPtr[bufferIndex];
pointCount = 0;
}
}
}
glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays
glDisableClientState(GL_NORMAL_ARRAY); // disable normal arrays
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // disable normal arrays
glPopMatrix();
#else
// this uses Display list it is extremely fast, about 5 time faster than VA and VBO, however
// it only render on view port without textures. It look like anythonmg stored on teh device memory only renders i one viewport
// does anyone know what is wrong? I cannot figure it out
UpdateDisplayList(world, myNode);
glPushMatrix();
glMultMatrix(&m_matrix[0][0]);
glCallList(m_dipalyList);
glPopMatrix();
#endif
}
does anyone had made an application using Open GL and rendering to different view ports?
if so can you tell my what I am doing wrong?