OpenGL 4.3 程序 Ubuntu 14.04 x64 中的时间变量冲突问题

Posted

技术标签:

【中文标题】OpenGL 4.3 程序 Ubuntu 14.04 x64 中的时间变量冲突问题【英文标题】:Issue with time variable conflict in OpenGL 4.3 program Ubuntu 14.04 x64 【发布时间】:2014-08-22 07:42:29 【问题描述】:

所以我在编译 OpenGL 4.3 程序时遇到了一个奇怪的错误,希望有人能提供帮助。我一直在为 RippleDeformer 编写 OpenGL Development Cookbook 中的一个食谱。我遇到了编译错误,不知道如何修复它。

似乎 main.cpp 程序中有一个名为 time 的变量,而且其中一个 OpenGL 库也涉及 time.h 标头,因此导致声明出现问题。我试图在程序中更改变量的名称并编译它,但是当我运行可执行文件时它给了我一个不同的错误。

我尝试使用以下命令进行编译:

g++ -o mycc main.cpp GLSLShader.cpp -lglut -lGLEW -lGL -lm -lglm                 

所以让我给你消息,然后是实际的 main.cpp 和着色器程序:

错误信息

    ^
main.cpp: At global scope:
main.cpp:62:7: error: ‘float time’ redeclared as different kind of symbol
float time = 0;
      ^
In file included from /usr/include/pthread.h:24:0,
             from /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h:35,
             from /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h:148,
             from /usr/include/c++/4.8/ext/atomicity.h:35,
             from /usr/include/c++/4.8/bits/ios_base.h:39,
             from /usr/include/c++/4.8/ios:42,
             from /usr/include/c++/4.8/ostream:38,
             from /usr/include/c++/4.8/iostream:39,
             from main.cpp:3:
/usr/include/time.h:192:15: error: previous declaration of ‘time_t time(time_t*)’
extern time_t time (time_t *__timer) __THROW;
          ^
main.cpp: In function ‘void OnRender()’:
main.cpp:198:7: error: assignment of function ‘time_t time(time_t*)’
time = glutGet(GLUT_ELAPSED_TIME)/1000.0f * SPEED;
     ^
main.cpp:198:7: error: cannot convert ‘float’ to ‘time_t(time_t*)throw () aka long int(long int*)throw     
()’ in assignment
main.cpp:213:35: error: cannot convert ‘time_t (*)(time_t*)throw () aka long int (*)(long int*)throw ()’ to ‘GLfloat aka float’ in argument passing
glUniform1f(shader("time"), time);
                               ^

main.cpp

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include "GLSLShader.h"

#define GL_CHECK_ERRORS assert(glGetError()== GL_NO_ERROR);

#ifdef _DEBUG 
#pragma comment(lib, "glew_static_x86_d.lib")
#pragma comment(lib, "freeglut_static_x86_d.lib")
#pragma comment(lib, "SOIL_static_x86_d.lib")
#else
#pragma comment(lib, "glew_static_x86.lib")
#pragma comment(lib, "freeglut_static_x86.lib")
#pragma comment(lib, "SOIL_static_x86.lib")
#endif

using namespace std;

//screen size
const int WIDTH  = 1280;
const int HEIGHT = 960;

//shader reference
GLSLShader shader;

//vertex array and vertex buffer object IDs
GLuint vaoID;
GLuint vboVerticesID;
GLuint vboIndicesID;

const int NUM_X = 40; //total quads on X axis
const int NUM_Z = 40; //total quads on Z axis

const float SIZE_X = 4; //size of plane in world space
const float SIZE_Z = 4;
const float HALF_SIZE_X = SIZE_X/2.0f;
const float HALF_SIZE_Z = SIZE_Z/2.0f;

//ripple displacement speed
const float SPEED = 2;

//ripple mesh vertices and indices
glm::vec3 vertices[(NUM_X+1)*(NUM_Z+1)];
const int TOTAL_INDICES = NUM_X*NUM_Z*2*3;
GLushort indices[TOTAL_INDICES];

//projection and modelview matrices
glm::mat4  P = glm::mat4(1);
glm::mat4 MV = glm::mat4(1);

//camera transformation variables
int state = 0, oldX=0, oldY=0;
float rX=25, rY=-40, dist = -7;

//current time
float time = 0;

//mouse click handler
void OnMouseDown(int button, int s, int x, int y)

if (s == GLUT_DOWN)

    oldX = x;
    oldY = y;


if(button == GLUT_MIDDLE_BUTTON)
    state = 0;
else
    state = 1;


//mosue move handler
void OnMouseMove(int x, int y)

if (state == 0)
    dist *= (1 + (y - oldY)/60.0f);
else

    rY += (x - oldX)/5.0f;
    rX += (y - oldY)/5.0f;

oldX = x;
oldY = y;

glutPostRedisplay();


//OpenGL initialization
void OnInit() 
//set the polygon mode to render lines
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

GL_CHECK_ERRORS
//load shader
shader.LoadFromFile(GL_VERTEX_SHADER, "shaders/shader.vert");
shader.LoadFromFile(GL_FRAGMENT_SHADER, "shaders/shader.frag");
//compile and link shader
shader.CreateAndLinkProgram();
shader.Use();
    //add shader attribute and uniforms
    shader.AddAttribute("vVertex");
    shader.AddUniform("MVP");
    shader.AddUniform("time");
shader.UnUse();

GL_CHECK_ERRORS

//setup plane geometry
//setup plane vertices
int count = 0;
int i=0, j=0;
for( j=0;j<=NUM_Z;j++) 
    for( i=0;i<=NUM_X;i++) 
        vertices[count++] = glm::vec3( ((float(i)/(NUM_X-1)) *2-1)* HALF_SIZE_X, 0, ((float(j)/(NUM_Z-1))*2-1)*HALF_SIZE_Z);
    


//fill plane indices array
GLushort* id=&indices[0];
for (i = 0; i < NUM_Z; i++) 
    for (j = 0; j < NUM_X; j++) 
        int i0 = i * (NUM_X+1) + j;
        int i1 = i0 + 1;
        int i2 = i0 + (NUM_X+1);
        int i3 = i2 + 1;
        if ((j+i)%2) 
            *id++ = i0; *id++ = i2; *id++ = i1;
            *id++ = i1; *id++ = i2; *id++ = i3;
         else 
            *id++ = i0; *id++ = i2; *id++ = i3;
            *id++ = i0; *id++ = i3; *id++ = i1;
        
    


GL_CHECK_ERRORS

//setup plane vao and vbo stuff
glGenVertexArrays(1, &vaoID);
glGenBuffers(1, &vboVerticesID);
glGenBuffers(1, &vboIndicesID);

glBindVertexArray(vaoID);

    glBindBuffer (GL_ARRAY_BUFFER, vboVerticesID);
    //pass plane vertices to array buffer object
    glBufferData (GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);
    GL_CHECK_ERRORS
    //enable vertex attrib array for position
    glEnableVertexAttribArray(shader["vVertex"]);
    glVertexAttribPointer(shader["vVertex"], 3, GL_FLOAT, GL_FALSE,0,0);
    GL_CHECK_ERRORS
    //pass the plane indices to element array buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndicesID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW);
    GL_CHECK_ERRORS
          
 cout<<"Initialization successfull"<<endl;



//release all allocated resources
void OnShutdown() 
//Destroy shader
shader.DeleteShaderProgram();

//Destroy vao and vbo
glDeleteBuffers(1, &vboVerticesID);
glDeleteBuffers(1, &vboIndicesID);
glDeleteVertexArrays(1, &vaoID);

cout<<"Shutdown successfull"<<endl;


//resize event handler
void OnResize(int w, int h) 
//set the viewport size
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
//setup the projection matrix
P = glm::perspective(45.0f, (GLfloat)w/h, 1.f, 1000.f);


//idle event callback
void OnIdle() 
    glutPostRedisplay();


//display callback 
void OnRender() 
//get the elapse time
time = glutGet(GLUT_ELAPSED_TIME)/1000.0f * SPEED;

//clear the colour and depth buffers
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

//set teh camera viewing transformation
glm::mat4 T     = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f, 0.0f, dist));
glm::mat4 Rx    = glm::rotate(T,  rX, glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 MV    = glm::rotate(Rx, rY, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 MVP   = P*MV;

//bind the shader 
shader.Use();
    //set the shader uniforms
    glUniformMatrix4fv(shader("MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
    glUniform1f(shader("time"), time);
        //draw the mesh triangles
        glDrawElements(GL_TRIANGLES, TOTAL_INDICES, GL_UNSIGNED_SHORT, 0);

//unbind the shader
shader.UnUse();

//swap front and back buffers to show the rendered result
glutSwapBuffers();


int main(int argc, char** argv) 
//freeglut initialization calls
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitContextVersion (3, 3);
glutInitContextFlags (GLUT_CORE_PROFILE | GLUT_DEBUG);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Ripple deformer - OpenGL 3.3");
    
//glew initialization   
glewExperimental = GL_TRUE;

GLenum err = glewInit();
if (GLEW_OK != err) 
    cerr<<"Error: "<<glewGetErrorString(err)<<endl;
 else 
    if (GLEW_VERSION_3_3)
    
        cout<<"Driver supports OpenGL 3.3\nDetails:"<<endl;
    

err = glGetError(); //this is to ignore INVALID ENUM error 1282
GL_CHECK_ERRORS
            
//print information on screen
cout<<"\tUsing GLEW "<<glewGetString(GLEW_VERSION)<<endl;
cout<<"\tVendor: "<<glGetString (GL_VENDOR)<<endl;
cout<<"\tRenderer: "<<glGetString (GL_RENDERER)<<endl;
cout<<"\tVersion: "<<glGetString (GL_VERSION)<<endl;
cout<<"\tGLSL: "<<glGetString (GL_SHADING_LANGUAGE_VERSION)<<endl;

GL_CHECK_ERRORS

//opengl initialization
OnInit();

//callback hooks
glutCloseFunc(OnShutdown);
glutDisplayFunc(OnRender);
glutReshapeFunc(OnResize);
glutMouseFunc(OnMouseDown);
glutMotionFunc(OnMouseMove);
glutIdleFunc(OnIdle);

//main loop call
glutMainLoop();

return 0;

最后是着色器代码:

GLSLShader.cpp

#include "GLSLShader.h"
#include <iostream>


GLSLShader::GLSLShader(void)

_totalShaders=0;
_shaders[VERTEX_SHADER]=0;
_shaders[FRAGMENT_SHADER]=0;
_shaders[GEOMETRY_SHADER]=0;
_attributeList.clear();
_uniformLocationList.clear();


GLSLShader::~GLSLShader(void)

_attributeList.clear(); 
_uniformLocationList.clear();


void GLSLShader::DeleteShaderProgram()     
glDeleteProgram(_program);


void GLSLShader::LoadFromString(GLenum type, const string& source)     
GLuint shader = glCreateShader (type);

const char * ptmp = source.c_str();
glShaderSource (shader, 1, &ptmp, NULL);

//check whether the shader loads fine
GLint status;
glCompileShader (shader);
glGetShaderiv (shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) 
    GLint infoLogLength;        
    glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLogLength);
    GLchar *infoLog= new GLchar[infoLogLength];
    glGetShaderInfoLog (shader, infoLogLength, NULL, infoLog);
    cerr<<"Compile log: "<<infoLog<<endl;
    delete [] infoLog;

_shaders[_totalShaders++]=shader;



void GLSLShader::CreateAndLinkProgram() 
_program = glCreateProgram ();
if (_shaders[VERTEX_SHADER] != 0) 
    glAttachShader (_program, _shaders[VERTEX_SHADER]);

if (_shaders[FRAGMENT_SHADER] != 0) 
    glAttachShader (_program, _shaders[FRAGMENT_SHADER]);

if (_shaders[GEOMETRY_SHADER] != 0) 
    glAttachShader (_program, _shaders[GEOMETRY_SHADER]);


//link and check whether the program links fine
GLint status;
glLinkProgram (_program);
glGetProgramiv (_program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) 
    GLint infoLogLength;
    
    glGetProgramiv (_program, GL_INFO_LOG_LENGTH, &infoLogLength);
    GLchar *infoLog= new GLchar[infoLogLength];
    glGetProgramInfoLog (_program, infoLogLength, NULL, infoLog);
    cerr<<"Link log: "<<infoLog<<endl;
    delete [] infoLog;


glDeleteShader(_shaders[VERTEX_SHADER]);
glDeleteShader(_shaders[FRAGMENT_SHADER]);
glDeleteShader(_shaders[GEOMETRY_SHADER]);


void GLSLShader::Use() 
glUseProgram(_program);


void GLSLShader::UnUse() 
glUseProgram(0);


void GLSLShader::AddAttribute(const string& attribute) 
_attributeList[attribute]= glGetAttribLocation(_program, attribute.c_str());    


//An indexer that returns the location of the attribute
GLuint GLSLShader::operator [](const string& attribute) 
return _attributeList[attribute];


void GLSLShader::AddUniform(const string& uniform) 
_uniformLocationList[uniform] = glGetUniformLocation(_program, uniform.c_str());


GLuint GLSLShader::operator()(const string& uniform)
return _uniformLocationList[uniform];


#include <fstream>
void GLSLShader::LoadFromFile(GLenum whichShader, const string& filename)
ifstream fp;
fp.open(filename.c_str(), ios_base::in);
if(fp)          
    string line, buffer;
    while(getline(fp, line)) 
        buffer.append(line);
        buffer.append("\r\n");
            
    //copy to source
    LoadFromString(whichShader, buffer);        
 else 
    cerr<<"Error loading shader: "<<filename<<endl;


调试 1 [已解决]

啊,所以我按照@KimKulling 的建议做了,并将变量变为elapsedTime 而不仅仅是time。所以该文件确实编译为可执行文件mycc,但是当我运行它时,我收到以下错误:

Inconsistency detected by ld.so: dl-version.c: 224: _dl_check_map_versions: Assertion `needed != ((void *)0)' failed!

它所指向的行:224只是主函数int main() . . .的第一行。

我对其进行了更多研究,发现此问题与与 OpenGL/C++ 的动态库不一致相关的现有错误有关。在这个问题上存在一个现有的错误。

https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-319/+bug/1248642

好消息是有人找到了解决方法。

error running a compiled C++ file (uses OpenGL). Error: “Inconsistency detected by ld.so: dl-version.c: 224”

我所要做的就是使用不同的编译设置。这真的很不直观。

我必须向视频驱动程序添加目录链接。这是有效的:

 g++ -L/usr/lib/nvidia-340/ main.cpp GLSLShader.cpp -lglut -lGLEW -lGL 

【问题讨论】:

【参考方案1】:

编译器似乎是正确的。已经有一个名为 time 的符号,因此您必须将名称更改为

float elapsedTime = 0.0f;

当之后发生其他错误时,您当然也必须修复它们。但我觉得他们的原因有点不同,所以试着调查原因并逐步解决它们。

也许发布下一个错误可能是一个开始:-)。

【讨论】:

是的,感谢您对此的帮助。我确实更改了time 变量的名称,然后得到了一个不同的错误——我在上面发布了。似乎我得到的新错误与一些现有的关于链接动态库的 OpenGL/C++ 错误有关。所以我更新了编译器设置并且它起作用了。感谢您的帮助。

以上是关于OpenGL 4.3 程序 Ubuntu 14.04 x64 中的时间变量冲突问题的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 GPU Grid 驱动程序在 Google Compute Engine 上将 OpenGL 升级到 4.3 版?

Nvidia Nsight 4.0 无法在 OpenGL 4.3 中分析代码

Linux(Ubuntu 14.0)

迁移基于 Qt QGL 的项目以使用 OpenGL 4.3

OpenGL 4.3错误地将第4个纹理坐标映射到与第3个纹理坐标相同的位置

Ubuntu 14.0 升级内核到指定版本