-
-
Notifications
You must be signed in to change notification settings - Fork 183
Description
Hi, I successfully used GL4ES for Glide emulation in DOSBox-X. However, there's an issue where glVertexAttrib does not store values per vertex. Here's a visual example:
The screenshot shows fog emulation. It works like this: each triangle has a fogBlend value assigned to each vertex. In the case of this screenshot, vertex 2 has fogBlend = 0, and vertex 1 has fogBlend ≈ 0.7. In normal OpenGL, fogBlend values are interpolated between vertices, resulting in a smooth fog effect. However, in GL4ES, each call to glVertexAttrib1fARB overrides the previous value, so interpolation doesn't work as expected.
void APIENTRY_GL4ES gl4es_glVertexAttrib4fv(GLuint index, const GLfloat *v) {
DBG(printf("glVertexAttrib4fv(%d, %p)\n", index, v);)
FLUSH_BEGINEND;
// sanity test
if(index<0 || index>=hardext.maxvattrib) {
errorShim(GL_INVALID_VALUE);
return;
}
// test if changed
if(memcmp(glstate->vavalue[index], v, 4*sizeof(GLfloat))==0) {
noerrorShim();
return;
}
memcpy(glstate->vavalue[index], v, 4*sizeof(GLfloat)); <--- HERE
}Here we overwrite previous value:
memcpy(glstate->vavalue[index], v, 4*sizeof(GLfloat));
The fog emulation rendered with this list:
glBegin(GL_TRIANGLES);
for (unsigned int i=0;i<3;i++) {
glColor4fv(&vd[i].r);
for (unsigned int t=0;t<2;t++)
if (td[t].enable) {
glMultiTexCoord4fv(GL_TEXTURE0_ARB+t,&vd[i].m[t].sw);
if (extra->info->shader_ready && extra->info->shader_ulocations[10u+t] >= 0)
db_glVertexAttrib1fARB((GLuint)extra->info->shader_ulocations[10u+t],vd[i].m[t].lodblend);
}
if (extra->info->shader_ready && extra->info->shader_ulocations[9] >= 0)
db_glVertexAttrib1fARB((GLuint)extra->info->shader_ulocations[9],vd[i].fogblend);
glVertex3fv(&vd[i].x);
}
glEnd();If i change vd[i].fogblend with vd[2].fogblend, here:
if (extra->info->shader_ready && extra->info->shader_ulocations[9] >= 0)
db_glVertexAttrib1fARB((GLuint)extra->info->shader_ulocations[9],vd[i].fogblend);
^ - i -> 2then output for OpenGL is exactly same as in GL4ES.
The same issue applies to all other attributes as well. What would be the best way to address this? I think I can try to fix it if you point me to where to start or suggest a good approach.
Off-topic: Why are we doing a comparison here? Is memcpy really slower than memcmp + memcpy?
// test if changed
if(memcmp(glstate->vavalue[index], v, 4*sizeof(GLfloat))==0) {
noerrorShim();
return;
}
memcpy(glstate->vavalue[index], v, 4*sizeof(GLfloat));