VOGONS


3dfx voodoo chip emulation

Topic actions

  • This topic is locked. You cannot reply or edit posts.

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 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. 😀

Attachments

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 😀

Attachments

  • Filename
    texture_combine.PNG
    File size
    152.54 KiB
    Downloads
    296 downloads
    File license
    Fair use/fair dealing exception

Reply 306 of 386, by gulikoza

User metadata
Rank Oldbie
Rank
Oldbie

I guess you can do it through glTexEnvi or shaders:

http://www.opengl.org/wiki/Texture_Combiners

For some reason, the code in OpenGlide does not do much. Perhaps it does not support multitexturing so I guess no help there 🙁

http://www.si-gamer.net/gulikoza

Reply 307 of 386, by kekko

User metadata
Rank Oldbie
Rank
Oldbie

thank you.
Maybe I found something useful, in mupen64plus sources (a plugin for a console emulator)
https://bitbucket.org/wahrhaft/mupen64plus-vi … er/combiner.cpp

it looks like it can use either gltexenv or shaders, but mostly it's rocket science for me 😀

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!

Attachments

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)

Attachments

  • Filename
    voodoo_opengl.h
    File size
    23.96 KiB
    Downloads
    176 downloads
    File license
    Fair use/fair dealing exception

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

Attachments

  • Filename
    voodoo_opengl.h
    File size
    28.46 KiB
    Downloads
    177 downloads
    File license
    Fair use/fair dealing exception

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.