I have configured the OpenGL environment under windows, I use VS2010.
When I wrote this code: glLightfv(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5), I got a warning type mismatch message.
I also got this informations:
IntelliSense, "double type" real participation "const GLfloat *" type
parameter is not compatible with f: \ lirui \ project \ opengltest \
opengltest \ opengltest 22 50 opengltest CPP
The parameter 1.5 is of type double while glLightfv needs a const GLfloat *.
When you specify pname to be GL_CONSTANT_ATTENUATION, the documentation says:
params is a single integer or floating-point value...
So you should use glLightf (or glLighti) instead of glLightfv.
You may give it a float (or an integer) instead of a double to avoid unnecessary cast:
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5); // what you want
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5f); // what you want (avoid a cast)
glLighti(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1); // what you may want
Related
I'm working on a piece of code in OpenGL.
I'm getting the following error message while trying to compile:
MyGLWidget.cpp: In member function ‘virtual void MyGLWidget::initializeGL()’:
MyGLWidget.cpp:30:38: error: cannot convert ‘glm::vec3 {aka glm::tvec3<float, (glm::precision)0u>}’ to ‘const GLfloat* {aka const float*}’ in argument passing
MyGLWidget.cpp:31:39: error: cannot convert ‘glm::vec3 {aka glm::tvec3<float, (glm::precision)0u>}’ to ‘const GLfloat* {aka const float*}’ in argument passing
I have declared these locations in MyGLWidget.h as follows:
GLuint llumLoc, focusLoc;
And have initialize them in MyGLWidget.cpp as:
llumLoc = glGetUniformLocation (program->programId(), "llumAmbient");
focusLoc = glGetUniformLocation (program->programId(), "posFocus");
"llumAmbient" and "posFocus" are uniforms in my vertex shader:
uniform vec3 llumAmbient;
uniform vec3 posFocus;
I get the mentioned error message while trying to call the following code inside of MyGLWidget::initializeGL
glUniform3fv(llumLoc, 1, glm::vec3(0.2));
glUniform3fv(focusLoc, 1, glm::vec3(1.0));
Obviously, I've tried to follow the documentation at www.opengl.org and glm.g-truc.net/0.9.2/api/a00001.html, but I just can't see what's wrong with this code...
Actually, I just found out today that there's a cleaner and more straight forward way. Simply:
glUniform3fv(focusLoc, 1, &v[0]);
No need to import value_ptr.
You need to give a pointer to the vector, not the vector itself. For example:
glm::vec3 v(1.0f);
glUniform3fv(focusLoc, 1, glm::value_ptr(&v[0]));
I've moved a Visual Studio project to a different computer and now GLSL won't compile shaders which previously worked fine. It's getting stuck implicitly converting vec4s to vec3s and it tells me the 'dot' function is undefined, for example.
I'm using the GLSDK and the project builds correctly, and glGetString(GL_SHADING_LANGUAGE_VERSION) tells me 4.40. It's obviously something I don't have installed but used to, but I've searched around and cannot work out what.
Sorry, it sounds like your old drivers were being a bit too permissive. Your new drivers are correct in rejecting the shaders.
vec4 a = vec4(1.0, 2.0, 3.0, 4.0);
vec3 x = vec3(a); // Ok
// vec3 y = a; error
Indeed, if I run the implicit conversion through the reference compiler, I get the following error message:
ERROR: 0:4: '=' : cannot convert from '4-component vector of float' to '3-component vector of float'
ERROR: 1 compilation errors. No code generated.
Try validating your scripts with the reference compiler, it may catch some portability issues like these. Your only real option here is to fix the broken shaders.
What about dot()?
Try this:
#version 330
void main() {
vec4 x = vec4(1.0);
vec3 y = vec3(2.0);
float z = dot(x, y);
}
When I run the validator, I get:
ERROR: 0:5: 'dot' : no matching overloaded function found
ERROR: 1 compilation errors. No code generated.
The error here is that my arguments to dot() are the wrong type. Again, the problem is in my shader.
I'm trying to apply the log2 onto a __m128 variable. Like this:
#include <immintrin.h>
int main (void) {
__m128 two_v = {2.0, 2.0, 2.0, 2.0};
__m128 log2_v = _mm_log2_ps(two_v); // log_2 := log(2)
return 0;
}
Trying to compile this returns this error:
error: initializing '__m128' with an expression of
incompatible type 'int'
__m128 log2_v = _mm_log2_ps(two_v); // log_2 := log(2)
^ ~~~~~~~~~~~~~~~~~~
How can I fix it?
The immintrin.h you look into and immintrin.h used for compilation are different.
Likely, you're looking into Intel-specific header (somewhere like /opt/intel/include/immintrin.h), while your compiler uses default immintrin.h
As it was correctly said, extern __m128 _mm_log2_ps(__m128 v1) is SVML routine, so
the very first solution I see is to use Intel Compiler. For non-commercial development its free for Linux.
Although you can specify the include path to your custom immintrin.h file as a very first argument during compilation using different compiler, but I think you'll get just way too many errors - just because this header is Intel-specific.
I've just started learning openGL a couple of hours ago for my work and have been tasked with rendering a concave polygon using tessellation. I'm trying to compile the following code:
#ifndef CALLBACK
#define CALLBACK
#endif
#include "GL/gl.h"
#include "GL/glu.h"
void CALLBACK beginCallback(GLenum which);
void drawHook()
{
GLUtesselator* tessObj = gluNewTess();
gluTessCallback(tessObj, GLU_TESS_BEGIN, beginCallback);
}
void CALLBACK beginCallback(GLenum which)
{
glBegin(which);
}
which I've gotten from the OpenGL Programming Guide, Seventh Edition, with the relevant chapter also being available online. But the following error is being returned:
hook.cc:28: error: invalid conversion from ‘void (*)(GLenum)’ to ‘void (*)()’
hook.cc:28: error: initializing argument 3 of ‘void gluTessCallback(GLUtesselator*, GLenum, void (*)())’
This error leads me to believe that the third argument of gluTessCallback should be a function that takes no arguments, yet the 'official' openGL reference states otherwise.
Am I missing something here or is the book incorrect?
The book is correct. You just have to cast the function pointer to void(*)(). It's needed because the type is not (and cannot be) precise.
gluTessCallback(tessObj, GLU_TESS_BEGIN, (void(*)())&beginCallback);
The documentation you linked states that the third argument of gluTessCallback is a parameterless function. (right after the heading Tessellation Callback Routines)
However, Example 11-1 casts the actual function pointer to a parameterless one:
gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (*) ()) &errorCallback);
^^^^^^^^^^^^^^^
Initializer lists should be supported since gcc 4.4 (and I could also use them in other places without problems), yet when I try to compile this with MinGW 4.5.2 I get a "bad array initializer" error. I do compile with -std=c++0x. "points" is just a Vector2D[4].
What am I doing wrong?
BoundingBox::BoundingBox(float width, float height, float posX, float posY) :
points{
Vector2D{posX,posY},
Vector2D{posX+width, posY},
Vector2D{posX+width, posY+height},
Vector2D{posX, posY+height}
} //error: bad array initializer
{
}
Try adding parens:
points({Vector2D{posX, posY}, ...})
instead of
points{Vector2D{posX, posY}, ...}
I don't have a compiler at hand to check it.
Your code compiles with gcc 4.6.1 (linux).
So if there was a bug it has been fixed.