VOGONS


3dfx voodoo chip emulation

Topic actions

Reply 300 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

well, I can't see anything clearly wrong. glide sets its depth function to LESS (equivalent of GL_LESS).

here's my opengl initialization routine

void ogl_init(voodoo_state *v) {
std::map<const Bit32u, GLuint>::iterator t;

// SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

if (SDL_SetVideoMode(v->fbi.width, v->fbi.height, 32, SDL_OPENGL) == 0)
E_Exit("opengl init error");

for (t=textures.begin(); t!=textures.end(); t++)
glDeleteTextures(1,&t->second);
if (!textures.empty()) textures.clear();

ogl_set_window(v);
}

and here's the window adjust routine. I added a call to it during "fbzmode" register write, in order to adjust the depth function

void ogl_set_window(voodoo_state *v) {

if (FBZMODE_ENABLE_DEPTHBUF(v->reg[fbzMode].u)) {
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
// glDepthFunc(GL_LEQUAL);
glDepthFunc(GL_NEVER+FBZMODE_DEPTH_FUNCTION(v->reg[fbzMode].u));
// printf("%d\n",FBZMODE_DEPTH_FUNCTION(v->reg[fbzMode].u));
}
else
glDisable(GL_DEPTH_TEST);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

// glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,GL_FASTEST);

// glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
if (FBZMODE_Y_ORIGIN(v->reg[fbzMode].u))
glOrtho( 0, v->fbi.width, 0, v->fbi.height, 0.0f, -1.0f );
else
glOrtho( 0, v->fbi.width, v->fbi.height, 0, 0.0f, -1.0f );
glViewport( 0, 0, v->fbi.width, v->fbi.height );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
}

I also can't be sure that the calculation and the precision of the depth value is correct, even if I didn't change the code very much starting from the software renderer, which works perfectly of course.

Reply 301 of 386, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Are there any voodoo functions that resemble those depth test related functions (like glDepthTest)?

Reply 302 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

I found in the documentation that bit(10) of fbzMode register toggles writes to depth/alpha buffer; in fact, this bit changes to 0 when drawing background.
how do I mix triangles with depth enabled and disabled in the same scene?!?

Reply 303 of 386, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Maybe that's too simple (though possibly expensive to implement) but try checking if that bit is toggled and use glDepthMask according to its new value.

Reply 304 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

thanks. I tried glDepthMask and it seem to fix the menus, but for some reason breaks the first few frames when going ingame. Probably there's also some other error.
Meanwhile I just disabled gl_depth_test instead and use glVertex2f instead of glVertex3f when bit10 is high; it's working, with some little depth bugs left to fix.
here's the new sourcecode; don't remember all the changes but nothing major.
EDIT: opengl extensions should be loaded after video init. 😀

Reply 305 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

I found a better explanation of how texture combine works, in the glide programming guide, p.88 (p.97 of the pdf).

At higher level, the texture combine is handled through a single function, grTexCombine;

void grTexCombine( GrChipID_t tmu,
GrCombineFunction_t rgbFunction,
GrCombineFactor_t rgbFactor,
GrCombineFunction_t alphaFunction,
GrCombineFactor_t alphaFactor,
FxBool rgbInvert,
FxBool alphaInvert
)

The guide also provides some Examples of Configuring the Texture Pipeline.
I guess I have to find some opengl equivalent function(s). Any help is appreciated 😀

Reply 308 of 386, by mudlord

User metadata
Rank Newbie
Rank
Newbie

kekko: yes, that code uses ALL fragment shaders.

imo, the best way to go, since some Glide combiner/blend modes don't really have OpenGL analogues.

Reply 309 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

hi, actually I already switched to GLSL shaders, but I'm writing everything from scratch.
The shaders seem to work just fine. I also added a shader caching mechanism, in order to compile a new shader and store it every time one of the main registers changes.
The code framework should be ok, now there's the pipeline itself that needs to be written.
Main challenges are to translate texture combine and color path, from the software rasterizer.
I'm not very skilled with shader language, so any help is welcome 😀
Thanks to gulikoza for the help.

new code is in the attachment. enjoy!

Reply 310 of 386, by mudlord

User metadata
Rank Newbie
Rank
Newbie

If you use shaders from the Glide64 project, be sure to credit us at least...
Nice to see your doing the shaders from scratch though. 😀

Reply 311 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

I decided to do everything from scratch because there are substantial differences among the wrappers and low-level emulation.
The former emulates glide calls from an higher level, while the latter operates on pixel processing, based on the chip registers.
There are actually some things in common, but I'll be faster in rewriting everything, instead of understanding what I'd need or not from that code.
Anyway I would appreciate if some glide expert would help with this. Just let me know.
Also, have a look at this post Re: 3dfx voodoo chip emulation

Reply 312 of 386, by mudlord

User metadata
Rank Newbie
Rank
Newbie

Looks like what you posted from those pastebins is very easily done as a chained shader, sampling from the allocated textures.

At least thats from what you say in that first paragraph in what happens on the Glide level. I say on the OGL level, you just do it in shaders instead, by sampling the source textures, and then processing depending in the blend mode your operations use. In our code, we go through each combiner stage/operations and dynamically build the fragment shaders according to what blend modes are called.

I have no idea how the Voodoo HW does this on a low level (selecting blend modes), but I guess the same principles apply.

Reply 313 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

I'm writing the texture combine pipeline, but I'm having some troubles with some of the instructions, like reversing a channel :

	if (!TEXMODE_TC_REVERSE_BLEND(TEXMODE))
{
blendr ^= 0xff;
blendg ^= 0xff;
blendb ^= 0xff;
}
	if (!TEXMODE_TC_REVERSE_BLEND(TEXMODE))
*strFShader += "blend.rgb = vec3(1) - blend.rgb;";

or the blending of t and blend:

	/* do the blend */
tr = (tr * (blendr + 1)) >> 8;
tg = (tg * (blendg + 1)) >> 8;
tb = (tb * (blendb + 1)) >> 8;
ta = (ta * (blenda + 1)) >> 8;
*strFShader += "tt *= blend;";

this last one is probably totally wrong, actually I didn't know how to translate it.
can you help me with this? new code in the attachment (edit:i fixed a bug, uploaded new file)

Reply 314 of 386, by mudlord

User metadata
Rank Newbie
Rank
Newbie

*strFShader += "blend.rgb = vec3(1) - blend.rgb;";

Why the vec3? You could do it *without* that.

From one of my color invert shaders in HLSL (same idea).....

float4 color = 1-tex2D( s0, Tex.xy);

tex2D is just a texture lookup.
I hate to sound like a ass, but it seems like some basic GLSL knowledge would work wonders here...I really don't want to babysit people.

Reply 315 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

actually, the request was not specifically directed at you, it was for anyone with glsl skills that wants to help, and I got a big help from people on this forum.
I already stated my low ogl/glsl knowledge in the past.
Thank you for the help.

Reply 316 of 386, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I really don't want to babysit people.

Then don't do it. Keeps the thread clean.

Reply 317 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

here's a new version, I added most of the color combine pipeline and fixed few bugs. Some games fixed, while some other break (see tomb raider).
Please give me some comments/critiques on it.

left to do:
- detail texturing in the texture pipeline
- chroma keying
- alpha test
- alpha mask
- fogging
- alpha blending
- few other things
there are also few things I'm not going to add, i.e. dither.

a couple questions to the experts:
- how could I perform alpha blending as in the software renderer, if I'm not able to access frame and depth buffer from the shader?
- for some reason, textured triangles with transparency like smoke, water, clouds, often appear in front of anything else; any idea why?
thanks.

Reply 318 of 386, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

for some reason, textured triangles with transparency like smoke, water, clouds, often appear in front of anything else; any idea why?

From the layout perspective you usually draw everything non-transparent first
(with full depth write/testing enabled), then perform a second run where you
draw all transparent elements which is usually done with depth writing *disabled*
(means you get volumetric effects for things like smoke, but if the smoke is behind
a wall it's still hidden since depth testing against the previously-drawn solid
geometry removes the smoke elements).
So maybe check when those elements are drawn relative to other geometry
and keep an eye on the projections that may reverse drawing, on things that
affect evaluation of depth information and things like that.

Reply 319 of 386, by bored

User metadata
Rank Newbie
Rank
Newbie

The 3D part of EF2000 is looking really good now. The two remaining problems as far as I can see are the 2D overlays which come out blank, and switching to full screen doesn't work.
...but I don't want to dwell on the negative since this is great work!

ef_ogl_12_04.jpg