Skip to content

glVertexAttrib does not work per vertex #486

@caiiiycuk

Description

@caiiiycuk

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:

Image

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 -> 2

then 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));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions