Bug 290979

Summary: Kalgebra 3d plot is (partially) black colored on a black background (video attached)
Product: [Applications] kalgebra Reporter: Nikita Skovoroda <chalkerx>
Component: generalAssignee: Aleix Pol <aleixpol>
Status: RESOLVED FIXED    
Severity: normal CC: aleixpol
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Archlinux   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: The video of the bug. Recoded to fit 1MiB limit.
This is a trivial fix.

Description Nikita Skovoroda 2012-01-08 16:03:11 UTC
Created attachment 67585 [details]
The video of the bug. Recoded to fit 1MiB limit.

Version:           unspecified (using Devel) 
OS:                Linux

See the video.

Reproducible: Didn't try

Steps to Reproduce:
Open Kalgebra, switch to 3d plot mode, plot x*y.

Actual Results:  
A part of the plot is invisible: it is black colored on a black background.

Expected Results:  
The whole plot visible.

It's not missing or invisible, it is black, solid, and can hide other parts of the plot.

Qt: 4.8.0
KDE Development Platform: 4.7.97 (4.8 RC2 (4.7.97)
KAlgebra: 0.11 (not listed in bugzilla).
Comment 1 Nikita Skovoroda 2012-01-08 16:04:09 UTC
> Reproducible: Didn't try

Sorry, it seems that i missed that field. It should state «Reproducable: every time».
Comment 2 Nikita Skovoroda 2012-01-08 16:11:46 UTC
Dots and lines views are ok, only the solid view is affected.
Comment 3 Aleix Pol 2012-01-08 21:34:07 UTC
This code hasn't changed in a while without problems. Sounds like a bug in your OpenGL implementation.

If you think this conclusion is incorrect, please reopen the bug with further information.
Comment 4 Aleix Pol 2012-01-08 21:35:39 UTC
Oops, the video showed me what you meant.

I'll look into it, sorry about the last message.
Comment 5 Nikita Skovoroda 2012-01-09 04:29:03 UTC
Well, it _does_ depend on the videodriver being used.

$ kalgebra
Gives the broken result shown on the video

$ LIBGL_ALWAYS_SOFTWARE=1 kalgebra
Gives a totally nice result. Strangely, it does not even have green and red colors at all (but the above video has).

That's wierd, because things like kwin and openarena work nicely on my videodrivers, and this graph should be rather simple.

OpenGL vendor string: X.Org
OpenGL renderer string: Gallium 0.4 on AMD PALM
OpenGL version string: 2.1 Mesa 7.11.2
OpenGL shading language version string: 1.20

I have an C-50 APU, xf86-video-ati 6.14.3-1, ati-dri 7.11.2-1, mesa 7.11.2-1.
Comment 6 Nikita Skovoroda 2012-01-09 07:43:52 UTC
Mmm. OpenGL trace says that you have a buch of calls like 
«glColor4d(red = -0.955, green = -0.13, blue = nan, alpha = 0.8)»

Looks like nan values are treated differently by various drivers.

This is not a bug in the drivers, they are perfectly fine when giving junk for «nan» colors.

This is a bug in kalgebra, which produces «nan» and negative colors.
Comment 7 Nikita Skovoroda 2012-01-09 07:53:04 UTC
> This code hasn't changed in a while without problems.

That's strange. It produces negative and nan colors for the half of the x*y plot. That's not normal.
Comment 8 Nikita Skovoroda 2012-01-10 06:07:16 UTC
https://projects.kde.org/projects/kde/kdeedu/kalgebra/repository/revisions/master/entry/src/graph3d.cpp

lines 256 and 261.

«red» and «green» are negative there, and «1./fabs(log10(5.+z))» is nan.
Comment 9 Nikita Skovoroda 2012-01-10 06:13:38 UTC
When z = 4.001:

blue = 1./abs(log10(5-4.001)) = 2301,4336

When z = 10:

blue = 1./abs(log10(5-10)) = 1./abs(0,69897 + 1,3643764i) = 1./abs(nan) = nan

That's not good.
Comment 10 Nikita Skovoroda 2012-01-10 06:19:52 UTC
lines 248, 249 and 252.

>const double mida=default_size*zoom, step=default_step*zoom;
>uint bound=(2*mida/step)-1;
>for(uint i=0; i<bound-1; i++) {
>  double red=(i*step-mida)/mida;
>  double nextRed=((i+1)*step-mida)/mida;
>  for(uint j=0; j<bound; j++) {
>    double green=(j*step-mida)/mida;
>  }
>}

This can't work, too.
Comment 11 Aleix Pol 2012-01-11 14:59:18 UTC
Very well reported :) thanks Nikita! Reports like this help us a lot!!

Would you be interested in finding a solution? You're half-way there :)

Feel free to propose one anyway.

Cheers!
Comment 12 Nikita Skovoroda 2012-01-14 22:16:36 UTC
I think that several (mathematically good) variants should be tested, and the most good-looking one picked.

1) Minor modifications of the current formulas.

For blue, «1./fabs(log10(5.+z))» could be replaced by «1./fabs(log10(10.+fabs(something)))», that function would always give a value between 0 and 1. For example, «1./fabs(log10(10.+fabs(z)))», «1./fabs(log10(10.+fabs(z + 10)))», «1 - 1./fabs(log10(10.+fabs(z + mida)))», or something like that.

Red and green parts are calculated using function that takes values from -1 to 1. Some simple solutions to bring them to [0 … 1]: fabs(…), 0.5*fabs(1 + …), or 0.5*fabs(1 - …).

If you do not want totally black or too bright colors, you can bring [0…1] functions to, for example, [0.2 … 0.8] by doing 0.2 + 0.6 * function(…).

2) Constant brightness.
You could make the brightness constant by compensating colors.
For example, let's suppose that you have two [0 … 1] functions, f1 and f2 (see part one). But it would be better if they will not depend only on x and y (i and j), but also on z coordinate. Like f1 = 0.5 * (r0 + b0), f1 = 0.5 * (g0 + b0), where r0, b0, and g0 are good [0…1] functions for red, green, and blue from the fist part.

That's make the brightness (ok, i know, that's not brightness, but anyway) constant (r + b + g = 1):
red0 = f1 * f2
blue0 = (1 - f1) * (1 - f2)
green0 = f1* (1 - f2) + f2 * (1 - f1) = f1 + f2 -  2 * f1 * f2 = f1 + f2 - 2 * red

That's make the brightness constant, but bigger (r + g + b = 1.4):
red1 = 0.2 + 0.8 * red0 = 0.2 + 0.8 * (f1 * f2)
blue1 = 0.2 + 0.8 * blue0
green1 = 0.2 + 0.8 * green0

3) Solid color with a light source.

Another (totally different) solution would be to paint everything with a single color and to add a light source (fixed to the camera, not in the scene).

4) Combine methods 2 and 3.

You could add light to colored scene.
I like this solution the most.
Comment 13 Nikita Skovoroda 2012-01-14 22:38:25 UTC
By the way, can i talk to you in irc (ChALkeR on freenode) or jabber (chalker@jabber.ru)?

I have some issues with 2d plot, too. I think that i should better describe them in irc/jabber before creating another bugreport.
Comment 14 Aleix Pol 2012-01-16 02:06:08 UTC
Feel free to contact me at aleixpol@gmail.com (jabber) or apol (irc, freenode), I tried to but I couldn't find you.
Comment 15 Nikita Skovoroda 2012-01-16 16:13:19 UTC
Created attachment 67894 [details]
This is a trivial fix.

This is a trivial fix (see method 1).
Comment 16 Nikita Skovoroda 2012-01-16 16:13:36 UTC
I will probably try to add light sources when I will have some spare time.
Also there should be a way to turn texturing on and off (to hide the lines).
Comment 17 Aleix Pol 2012-01-16 16:49:55 UTC
Git commit f1277634a1ba25549e84e8bc74cd77ddacc6a402 by Aleix Pol.
Committed on 16/01/2012 at 17:47.
Pushed by apol into branch 'KDE/4.8'.

Fix colors on graph3d

In some occasions the colors used in 3D graphs were NaN and some
opengl implementations drew it differently than others. Find a
common place where it always works.

Patch contributed by Nikita Skovoroda.

M  +7    -5    src/graph3d.cpp

http://commits.kde.org/kalgebra/f1277634a1ba25549e84e8bc74cd77ddacc6a402
Comment 18 Aleix Pol 2012-01-16 16:49:56 UTC
Git commit 55e6fbcd78a34b051b90ef33e3af2661d5beebe8 by Aleix Pol.
Committed on 16/01/2012 at 17:47.
Pushed by apol into branch 'master'.

Fix colors on graph3d

In some occasions the colors used in 3D graphs were NaN and some
opengl implementations drew it differently than others. Find a
common place where it always works.

Patch contributed by Nikita Skovoroda.

M  +7    -5    src/graph3d.cpp

http://commits.kde.org/kalgebra/55e6fbcd78a34b051b90ef33e3af2661d5beebe8