6
$\begingroup$

for better accuracy, instead of GLfloat, I bound double data and tried to use the data in shader as follow: (I just tested to draw single triangle.)

cpp.

// xyzw three vertices
double points[] = { 0.0, 0.0, 0.0, 1.0 , 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0 };

glGenVertexArrays(1, VAO);
glBindVertexArray(VAO);

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 96, points, GL_STATIC_DRAW);


int data = 0;
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_DOUBLE, GL_FALSE, 0, (void*)data);

shader.

#version 460 core
layout(location = 0) in dvec4 vPos;


void main() {
    gl_Position = vec4(vPos);
}

What's worng with me?

(If I changed the dvec4 in the above shader to vec4, the triangle was drawn, but maybe it's not double anymore. I want to use double in shader.)

$\endgroup$
  • $\begingroup$ you need to keep in mind that doubles on GPUs, unlike on CPUs, actually significantly tank performance unless you are using compute cards like quadros or Teslas. On the Nvidia side, up until recently you had a 1:32 ration between fp throughput and double precision throughput. compute 7.0 I believe that ratio is down to 1:2, but I wouldn't count on that getting any better any time soon, as Quadros are sold based on their inclusion of double to float precision tradeoff, and teslas have equal performance on both, whilst not having really any other advantages over consumer gaming GPUs. $\endgroup$ – opa Mar 13 '18 at 16:09
13
$\begingroup$

The problem is, glVertexAttribPointer(0, 4, GL_DOUBLE... doesn't do what you think it does.

Using actual double-precision vertex attributes and performing double precision computations is a very modern hardware feature (GL4/DX12) and is different from specifying the type GL_DOUBLE in the good old glVertexAttribPointer call. This always worked and does nothing else than specify the input type, i.e. the type of your vertex data in memory. All it does is make the GL convert your doubles into singles and feeding them into a normal single-precision attribute (and failing when there is none), same with other input types like GL_SHORT or GL_UNSIGNED_BYTE.

When specifying data for genuine double-precision attributes, you have to use glVertexAttribLPointer (note the L) instead. The same holds for genuine integer attributes (ivecX/uvecX), which use glVertexAttribIPointer.


Of course the answer isn't complete without some general advise, that you should really make sure you actually need double precision vertex attributes, or even double precision computation. Even on modern hardware that's still significantly slower and not what those GPUs are really made for, not to speak of the doubled memory consumption for the vertex data. More precision is not always better if it isn't actually necessary and you might be surprised what a lousy little float is able to accomplish when used well.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.