Problems with glew library and glewinit() function

Hello everyone.
I need your help, I’m new to this.
I am currently studying a code to create articulas using CUDA programming platform use Visual Studio 2012. I have already configured the system to be able to program with CUDA libraries.
But I make a mistake I do not know. :
articles.cu.obj: error LNK2019: unresolved external symbol __ imp__glewInit @ 0 referenced in function “void __ cdecl initGL (int, char **)” (? initGL YAXHPAPAD @ @ @ Z)
1> particles.cu.obj: error LNK2019: unresolved external symbol __ imp__glewIsSupported @ 4 referenced in function “void __ cdecl initGL (int, char **)” (? InitGL YAXHPAPAD @ @ @ Z)
1> particles.cu.obj: error LNK2001: unresolved external symbol __ imp____glewBindBuffer
1> particles.cu.obj: error LNK2001: unresolved external symbol __ imp____glewBufferData
1> particles.cu.obj: error LNK2001: unresolved external symbol __ imp____glewGenBuffers

  • ------------------------------------------------- ------ *
    In my opinion is a bug in the function glewInit (). I read many forums already and nobody told me a dimensioned or at least a similar problem.

If someone could direct me I would appreciate.

This is the code I’m studying.:

#define _USE_MATH_DEFINES
#include <cuda.h>
#include <iostream>
#include <math.h>
#include <ctime>
#include <gl\glew.h>
#include <gl\glut.h>
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>
#include <vector_types.h>

//Constants
const unsigned int window_width = 768;
const unsigned int window_height = 768;

const unsigned int mesh_width = 1024;
const unsigned int mesh_height = 1024;

float rnd1[mesh_width*mesh_height];
float rnd2[mesh_width*mesh_height];

//Mouse controls
int mouse_x, mouse_y;
int buttons = 0;
float translate_z = -3.0;

//VBO variables
GLuint vbo;
void *d_vbo_buffer = NULL;

//float time = 0.0;
float anim = 0.0;

//Device pointers
float4 *d_array;
float *d_rnd1, *d_rnd2;

void keyboard(unsigned char key, int, int)
{
    switch(key) {
    case(27) :
        exit(0);
        break;
	case('a'):
		if (buttons!=10)
			buttons=10;
		else
			buttons=0;
		break;
    }
}

void mouse(int button, int state, int x, int y)
{
    if (state == GLUT_DOWN) {
        buttons |= 1<<button;
    } else if (state == GLUT_UP) {
        buttons = 0;
    }

    mouse_x = x;
    mouse_y = y;
    glutPostRedisplay();
}

void motion(int x, int y)
{
    float dx, dy;
    dx = x - mouse_x;
    dy = y - mouse_y;

	if (buttons & 4)
        translate_z += dy * 0.01;

    mouse_x = x;
    mouse_y = y;
}

union Color
{
	float c;
	uchar4 components;
};

__global__ void initialize_kernel(float4* pos, unsigned int width, unsigned int height, float anim, float4* vel, float* rnd1, float* rnd2)
{
    unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;

	//Calculate the initial coordinates
    float u = x / (float) width + rnd1[y*width+x];
    float v = y / (float) height + rnd2[y*width+x];

    //Calculate a simple sine wave pattern
    float freq = 2.0f;
    float w = sinf(u*freq + anim) * cosf(v*freq + anim) * 0.2f;

	//Set the initial color
	Color temp;
	temp.components = make_uchar4(0,255,255,1);

	//Set initial position, color and velocity
	pos[y*width+x] = make_float4(u, w, v, temp.c);
	vel[y*width+x] = make_float4(0.0, 0.0, 0.0, 1.0f);
}

__global__ void particles_kernel(float4* pos, unsigned int width, unsigned int height, float anim, float X, float Y, float4* vel, int buttons)
{
	const float speed = 0.0005f;
	const float threshold = 0.1f;
    unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;

    float u = x / (float) width;
    float v = y / (float) height;

	float xX = (X - width/2 + 128)/(float)width*4.5f;
	float yY = (Y - height/2 + 128)/(float)height*4.5f;
	float dx = -pos[y*width+x].x + xX;
	float dz = -pos[y*width+x].z + yY;
	float length = sqrtf(dx*dx+dz*dz);
	if (buttons==10)
	{
		vel[y*width+x].x=0;
		vel[y*width+x].z=0;
		dx = -pos[y*width+x].x + u;
		dz = -pos[y*width+x].z + v;
		length = sqrtf(dx*dx+dz*dz);
		pos[y*width+x].x+=dx/length*speed*10;
		pos[y*width+x].z+=dz/length*speed*10;
	}
	else if (!(buttons & 4) && !(buttons & 6))
	{
		float2 normalized = make_float2(dx/length*speed, dz/length*speed);
		vel[y*width+x].x+=normalized.x;
		vel[y*width+x].z+=normalized.y;
		dx = vel[y*width+x].x;
		dz = vel[y*width+x].z;
		float velocity = sqrtf(dx*dx+dz*dz);
		if (velocity>threshold)
		{
			vel[y*width+x].x=dx/velocity*threshold;
			vel[y*width+x].z=dz/velocity*threshold;
		}
		Color temp;
		temp.components = make_uchar4(128/length,(int)(255/(velocity*51)),255,10);
		if (pos[y*width+x].x<-5.0f && vel[y*width+x].x<0.0)
			vel[y*width+x].x=-vel[y*width+x].x;
		if (pos[y*width+x].x>5.0f && vel[y*width+x].x>0.0)
			vel[y*width+x].x=-vel[y*width+x].x;
		pos[y*width+x].x+=vel[y*width+x].x;
		pos[y*width+x].z+=vel[y*width+x].z;
		pos[y*width+x].w = temp.c;
	}
	else if (!(buttons & 4))
	{
		vel[y*width+x].x=0;
		vel[y*width+x].z=0;
		pos[y*width+x].x+=dx/length*speed*10;
		pos[y*width+x].z+=dz/length*speed*10;
		Color temp;
		temp.components = make_uchar4(255/length,255/length, 255, 10);
		pos[y*width+x].w = temp.c;
	}

    float freq = 2.0f;
    float w = sinf(u*freq + anim) * cosf(v*freq + anim) * 0.2f;

	pos[y*width+x].y=w;
}

void particles(GLuint vbo)
{
    //Map OpenGL buffer object for writing from CUDA
    float4 *dptr;
    cudaGLMapBufferObject((void**)&dptr, vbo);

    //Run the particles kernel
    dim3 block(8, 8, 1);
    dim3 grid(mesh_width / block.x, mesh_height / block.y, 1);
	particles_kernel<<< grid, block>>>(dptr, mesh_width, mesh_height, anim, mouse_x, mouse_y, d_array, buttons);

    //Unmap buffer object
    cudaGLUnmapBufferObject(vbo);
}

void initialize(GLuint vbo)
{
    //Map OpenGL buffer object for writing from CUDA
    float4 *dptr;
    cudaGLMapBufferObject((void**)&dptr, vbo);

    //Run the initialization kernel
    dim3 block(8, 8, 1);
    dim3 grid(mesh_width / block.x, mesh_height / block.y, 1);
	initialize_kernel<<< grid, block>>>(dptr, mesh_width, mesh_height, anim, d_array, d_rnd1, d_rnd2);

    //Unmap buffer object
    cudaGLUnmapBufferObject(vbo);
}

static void display(void)
{
    //Process particles using CUDA kernel
    particles(vbo);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //View matrix
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

	glTranslatef(0.0, 0.0, translate_z);
    glRotatef(90.0, 1.0, 0.0, 0.0);

    //Render from VBO
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexPointer(3, GL_FLOAT, 16, 0);
	glColorPointer(4,GL_UNSIGNED_BYTE,16,(GLvoid*)12);

    glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
    glDrawArrays(GL_POINTS, 0, mesh_width * mesh_height);
    glDisableClientState(GL_VERTEX_ARRAY);

    glutSwapBuffers();
    glutPostRedisplay();

    anim += 0.01;
}

void createVBO(GLuint* vbo)
{
	//Create vertex buffer object
	glGenBuffers(1, vbo);
	glBindBuffer(GL_ARRAY_BUFFER, *vbo);

	//Initialize VBO
	unsigned int size = mesh_width * mesh_height * 4 * sizeof(float);
	glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	//Register VBO with CUDA
	cudaGLRegisterBufferObject(*vbo);
}

void initGL(int argc, char **argv)
{
    glutInit(&argc, argv);

	//Setup window
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(window_width, window_height);
    glutCreateWindow("Million particles");

	//Register callbacks
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	glutMouseFunc(mouse);
	glutMotionFunc(motion);

	//GLEW initialization
    glewInit();
    if (!glewIsSupported("GL_VERSION_2_0 ")) {
        fprintf(stderr, "ERROR: Support for necessary OpenGL extensions missing.");
        fflush(stderr);
		exit(0);
    }

    //Clear
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glDisable(GL_DEPTH_TEST);

    //Viewport
    glViewport(0, 0, window_width, window_height);

    //Projection
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, (GLfloat)window_width / (GLfloat) window_height, 0.1, 10.0);
}

int main(int argc, char** argv)
{
	initGL(argc, argv);

	//Create VBO
	createVBO(&vbo);

	//Initialize random arrays
	for (int i=0;i<mesh_height*mesh_width;++i)
		rnd1[i]=(rand()%100-100)/2000.0f;
	for (int i=0;i<mesh_height*mesh_width;++i)
		rnd2[i]=(rand()%100-100)/2000.0f;

	//CUDA allocation and copying
	cudaMalloc(&d_array, mesh_width*mesh_height*sizeof(float4));
	cudaMalloc(&d_rnd1, mesh_width*mesh_height*sizeof(float));
	cudaMemcpy(d_rnd1, rnd1, mesh_height*mesh_width*sizeof(float), cudaMemcpyHostToDevice);
	cudaMalloc(&d_rnd2, mesh_width*mesh_height*sizeof(float));
	cudaMemcpy(d_rnd2, rnd2, mesh_height*mesh_width*sizeof(float), cudaMemcpyHostToDevice);

	initialize(vbo);

	glutMainLoop();

	//Free CUDA variables
	cudaFree(d_array);
	cudaFree(d_rnd1);
	cudaFree(d_rnd2);
	return 0;
}

Thks

LNK are linker errors.
That the linker complains about “unresolved external symbol” means it didn’t find a library which exported that symbol.
In your case it would be one of the glew32.lib files missing on the linker command line.
Change your project’s properties so that it can find that file on your development system.

If that doesn’t help, maybe try building the GLEW libraries yourself.

Just in case, another way to clean up behind a glutMainLoop() is to use a glutCloseFunc(closeFunc); callback and set the GLUT_ACTION_CONTINUE_EXECUTION.

glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

and move the cleanup code from after the glutMainLoop() call into the closeFunc() callback.
That way OpenGL is still active when cleaning resources which might be become important when sharing resources.

Sorry but I need to ask more. Tell me if this form of the code is correct:
void initGL(int argc, char **argv)
{
glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
.
.
.

}

int main(int argc, char** argv)
{
initGL(argc, argv);

    .
    . 
    .

initialize(vbo);

glutCloseFunc(closeFunc);
glutMainLoop();

    .
    .
    .
return 0;

}

First, did you solve the glew linking error?
If yes, what was the problem?
Because the glutCloseFunc recommendation is unrelated.

Your new code layout looks ok from GLUT perspective. I’m assuming you’re using FreeGLUT. I would put the glutCloseFunc() call in line 262 where the other callbacks are set in your original code above. Simply single-step through the code in the debugger to see how the calls work.

make sure you set the window context.

glutInit(&argc, argv);
glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);

I got the exact same error until created the window context, also to note, you need to set the window context before you call glewInit();

I use SDL2 + GLEW, so I’ve not used glut but that solved the issue for me, seems like similar issue providing you have everything linked correctly.