in emulation mode, the program works without emulation error why? ERROR: 0xC0000005: Access violatio

Hello everyone,

someone tell me why my program in CUDA only works in emulation mode?

this is the kernel’s code:

[codebox]#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <cuda.h>

#include <cutil_math.h>

#include <cutil_inline.h>

#include <cuda_runtime.h>

#include “DrawScreen.h”

#include “geometry.h”

#define EPSILON 0.00001

#define M_PI 3.1415926535897932384626433832795

static double *dvertex = NULL;

static int *dface = NULL;

static int *dfaceIndex = NULL;

static int dfaceNum;

static Pixel *da_d = NULL;

static Pixel *ha_d = NULL;

device float RayTriangleInc(float3 d,float3 o, float3 p0, float3 p1, float3 p2)

{

float3 e1, e2;

normalize(d);

e1=p1-p0;

e2=p2-p0;

float3 q=cross(d,e2);

float a=dot(e1,q);   

if (a>-EPSILON && a<EPSILON){

    return 0;

    }

float f = 1/a;

float3 s=o-p0;

float u=f*(dot(s,q));

if (u<0){

    return 0;

    }

float3 r=cross(s,e1);

float v=f*(dot(d,r));

if (v<0 || u+v>1){

    return 0;

    }

float t=f*(dot(e2,r));

return 1;

}

device host float3 CalcolaVettorePunto(float3 xdir, float3 ydir, float3 LLdir, int tdx, int tdy)

{

float3 dir;

dir.x=LLdir.x + (xdir.x*tdx); 

dir.y=LLdir.y + (ydir.y*tdy);

dir.z=LLdir.z;

normalize(dir);	

return dir;

}

global void DrawScreen(float *da_d, int w, int h, int ch,float3 eye, float3 xdir, float3 ydir, float3 LLdir,

					   double *dvertex, int *dface, int *dfaceIndex, int dfaceNum) 

{

int n =w*h*ch; 

int tdx = (threadIdx.x+blockIdx.x*blockDim.x);

int tdy = (threadIdx.y+blockIdx.y*blockDim.y);

int idarray = (tdx+tdy*w)*ch;



float3 dir= CalcolaVettorePunto(xdir, ydir, LLdir, tdx, tdy);

float3 p0,p1,p2;

int inc=0;

	

for (int i=0; i<dfaceNum; i++){

		

	p0.x = dvertex[(dface[dfaceIndex[i]+1]-1)*4];

	p0.y = dvertex[((dface[dfaceIndex[i]+1]-1)*4)+1];

	p0.z = dvertex[((dface[dfaceIndex[i]+1]-1)*4)+2];

	p1.x = dvertex[(dface[dfaceIndex[i]+4]-1)*4];

	p1.y = dvertex[((dface[dfaceIndex[i]+4]-1)*4)+1];

	p1.z = dvertex[((dface[dfaceIndex[i]+4]-1)*4)+2];

	p2.x = dvertex[(dface[dfaceIndex[i]+7]-1)*4];

	p2.y = dvertex[((dface[dfaceIndex[i]+7]-1)*4)+1];

	p2.z = dvertex[((dface[dfaceIndex[i]+7]-1)*4)+2];

	

	inc = inc || (RayTriangleInc (dir,eye, p0 , p1, p2)==1.0);

	

}



if(idarray<n){

	if(inc==1){

	da_d[idarray]=1.0f;

	da_d[idarray+1]=1.0f;

	da_d[idarray+2]=1.0f;

	da_d[idarray+3]=1.0f;

	}else{da_d[idarray]=0.0f;

		da_d[idarray+1]=0.0f;

		da_d[idarray+2]=0.0f;

		da_d[idarray+3]=1.0f;

		}		

}

}

host void callCuda(Pixel *a_d, int w, int h, int ch, float x, float y, float z, scene *hScene)

{

if(dvertex==NULL && dface==NULL && dfaceIndex==NULL && da_d == NULL){

	//Alloco memoria su device

	cutilSafeCall(cudaMalloc((void**) &dvertex, hScene->vertexSize * sizeof(double)));

	cutilSafeCall(cudaMalloc((void**) &dface, hScene->faceSize * sizeof(int)));

	cutilSafeCall(cudaMalloc((void**) &dfaceIndex, hScene->faceIndexSize * sizeof(int)));

	cutilSafeCall(cudaMalloc((void**) &da_d, (w*h*ch) * sizeof(Pixel)));

		

	//Copio Dati dalla scena agli array su device

	cutilSafeCall(cudaMemcpy(dvertex, hScene->vertex, hScene->vertexSize * sizeof(double),cudaMemcpyHostToDevice));    

	cutilSafeCall(cudaMemcpy(dface, hScene->face, hScene->faceSize * sizeof(int),cudaMemcpyHostToDevice));    

	cutilSafeCall(cudaMemcpy(dfaceIndex, hScene->faceIndex, hScene->faceIndexSize * sizeof(int),cudaMemcpyHostToDevice));



}	



//Copio Dati dalla scena alle variabili su device

dfaceNum = hScene->faceNum;



float3 Eye;

Eye.x =x;

Eye.y =y;

Eye.z =z;



float distanza=2.00;

float vFov=60.00;

float hFov=vFov*((float)w/(float)h);



vFov = vFov * M_PI / 180;

hFov = hFov * M_PI / 180;



float3 At;

At.x= Eye.x;

At.y= Eye.y;

At.z=Eye.z-distanza;

float3 vettoreCam = At-Eye;

float3 vettore_up = {0.0,1.0,0.0};

float3 vettore_v = cross(vettoreCam,vettore_up);



float3 ydir= -vettore_up;

float3 xdir= cross(ydir,vettoreCam);



xdir= normalize(xdir)*((2.0*distanza*tan(hFov/2.0))/(float)w);

ydir= normalize(ydir)*((2.0*distanza*tan(vFov/2.0))/(float)h);



float3 LLdir;

LLdir.x=vettoreCam.x-(xdir.x*w)/2;

LLdir.y=vettoreCam.y-(ydir.y*h)/2;

LLdir.z=vettoreCam.z;



dim3 dimGrid (80,60);

dim3 dimBlock (8,8);

DrawScreen <<< dimGrid, dimBlock >>> (da_d,w,h,ch,Eye,xdir,ydir,LLdir, dvertex, dface, dfaceIndex, dfaceNum);





//ha_d = (Pixel *) malloc((w*h*ch) * sizeof(Pixel));





cutilSafeCall(cudaMemcpy(a_d, da_d, (w*h*ch) * sizeof(Pixel),cudaMemcpyDeviceToHost));	



for(int i=0; i<(w*h*ch); i++){

	if(a_d[i]!= 0)                              //<b>ERROR: 0xC0000005: Access violation reading location 0x03020000. only without emulation mode </b>

	printf("a_d[%d] %f\n ",i,a_d[i]);

}





// cleanup memory

//free(a_d);

//cutilSafeCall(cudaFree(da_d));

}

[/codebox]

Help me this program is part of my thesis … : '(

a_d looks like a device pointer. How it gets to be a device pointer is a question only you can answer because you don’t show the code where the function call is made. It works in emulation only because device pointers and host pointers are the same.

thanks for your reply.

This is the code where I call:

[codebox]#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <GL/glew.h>

#include <GL/glut.h>

#include <cuda.h>

#include <cuda_runtime.h>

#include <cuda_gl_interop.h>

#include <cutil_inline.h>

#include “DrawScreen.h”

#define OFFSET(i) ((char *)NULL + (i))

Pixel *data = NULL; //declare pointer

int imWidth=640;

int imHeight=480;

int Ch=4;

static GLuint pbo_buffer = 0;

static GLuint texid = 0;

unsigned int timer;

//prova

float cameraX=0.0;

float cameraY=0.0;

float cameraZ=6.0;

scene myScene;

void reshape(int x, int y)

{

glViewport(0, 0, x, y);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(0, 1, 0, 1, 0, 1); 

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glutPostRedisplay();

}

void display(void)

{

glClear(GL_COLOR_BUFFER_BIT);

cutilSafeCall(cudaGLMapBufferObject((void**)&data, pbo_buffer));

callCuda(data, imWidth, imHeight, Ch, cameraX, cameraY, cameraZ, &myScene); //<b>pass the poiter</b>

cutilSafeCall(cudaGLUnmapBufferObject(pbo_buffer));  



glBindTexture(GL_TEXTURE_2D, texid);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_buffer);

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imWidth, imHeight, GL_RGBA, GL_FLOAT, OFFSET(0) );

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

glDisable(GL_DEPTH_TEST);

glEnable(GL_TEXTURE_2D);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glLoadIdentity();

glBegin(GL_QUADS);

glVertex2f(0, 0); glTexCoord2f(0, 0);

glVertex2f(0, 1); glTexCoord2f(1, 0);

glVertex2f(1, 1); glTexCoord2f(1, 1);

glVertex2f(1, 0); glTexCoord2f(0, 1);

glEnd();

glBindTexture(GL_TEXTURE_2D, 0);

glutSwapBuffers();

}

void inizializza (int w, int h, int ch)

{

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glewInit();

data = (Pixel*)malloc( sizeof(float) * ch * w * h );

memset(data, 0, sizeof(float) * ch * w * h);

glGenBuffers(1, &pbo_buffer);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_buffer); 

glBufferData(GL_PIXEL_UNPACK_BUFFER, 

                ch * sizeof(Pixel) * w * h, 

                data, GL_STREAM_DRAW);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

cutilSafeCall(cudaGLRegisterBufferObject(pbo_buffer));



glGenTextures(1, &texid);

glBindTexture(GL_TEXTURE_2D, texid);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imWidth, imHeight,  0, GL_RGBA, GL_FLOAT, NULL);

glBindTexture(GL_TEXTURE_2D, 0);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glPixelStorei(GL_PACK_ALIGNMENT, 1);

memset(&myScene, 0, sizeof(scene));

readObj("cube.obj", &myScene);

}

void keyb (unsigned char key, int x, int y)

{

switch (key)

{

	case '+': cameraX = cameraX + 0.25;

		break;

	case '-': cameraX = cameraX - 0.25;

		break;

	case '*': cameraY = cameraY + 0.25;

		break;

	case '/': cameraY = cameraY - 0.25;

		break;

	case '9': cameraZ = cameraZ + 0.25;

		break;

	case '8': cameraZ = cameraZ - 0.25;

		break;

}

glutPostRedisplay();

}

int main(int argc, char** argv)

{

glutInit( &argc, argv);    

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

glutInitWindowSize(imWidth, imHeight);

glutCreateWindow("Draw Screen");

inizializza(imWidth,imHeight,Ch);

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyb);

glutMainLoop();

}

[/codebox]

Right, so data is a device pointer. You cannot use it the way you are using it in your callCuda function. This code is illegal:

cutilSafeCall(cudaMemcpy(a_d, da_d, (w*h*ch) * sizeof(Pixel),cudaMemcpyDeviceToHost));

for(int i=0; i<(w*h*ch); i++){

if(a_d[i]!= 0) //ERROR: 0xC0000005: Access violation reading location 0x03020000. only without emulation mode

printf("a_d[%d] %f\n ",i,a_d[i]);

}

I removed the code illegal, but it still does not work without emulation. Why? it now comes back to me with a black screen instead of drawing a cube.

I can’t help you with OpenGL interop problems, I am afraid.

I went back again asking for help, I discovered that I have problems accessing the array on the device.

This is the code:

[codebox]#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <cuda.h>

#include <cutil_math.h>

#include <cutil_inline.h>

#include <cuda_runtime.h>

#include “DrawScreen.h”

#include “geometry.h”

#define EPSILON 0.00001

#define M_PI 3.1415926535897932384626433832795

static double *dvertex = NULL;

static int *dface = NULL;

static int *dfaceIndex = NULL;

static int dfaceNum = NULL;

static double *ha_d = NULL;

static double *dProva = NULL;

void checkCUDAError(const char *msg)

{

cudaError_t err = cudaGetLastError();

if( cudaSuccess != err) 

{

    fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString( err) );

    exit(-1);

}                         

}

device float RayTriangleInc(float3 d,float3 o, float3 p0, float3 p1, float3 p2)

{

float3 e1, e2;

normalize(d);

e1=p1-p0;

e2=p2-p0;

float3 q=cross(d,e2);

float a=dot(e1,q);   

if (a>-EPSILON && a<EPSILON){

    return 0;

    }

float f = 1/a;

float3 s=o-p0;

float u=f*(dot(s,q));

if (u<0){

    return 0;

    }

float3 r=cross(s,e1);

float v=f*(dot(d,r));

if (v<0 || u+v>1){

    return 0;

    }

float t=f*(dot(e2,r));

return 1;

}

device host float3 CalcolaVettorePunto(float3 xdir, float3 ydir, float3 LLdir, int tdx, int tdy)

{

float3 dir;

dir.x=LLdir.x + (xdir.x*tdx); 

dir.y=LLdir.y + (ydir.y*tdy);

dir.z=LLdir.z;

normalize(dir);	

return dir;

}

global void DrawScreen(float *a_d, int w, int h, int ch,float3 eye, float3 xdir, float3 ydir, float3 LLdir,

					   double *dvertex, int *dface, int *dfaceIndex, int dfaceNum,double *dProva) 

{

int n =w*h*ch; 

int tdx = (threadIdx.x+blockIdx.x*blockDim.x);

int tdy = (threadIdx.y+blockIdx.y*blockDim.y);

int idarray = (tdx+tdy*w)*ch;



float3 dir= CalcolaVettorePunto(xdir, ydir, LLdir, tdx, tdy);

float3 p0,p1,p2;

int inc=0;

	

for (int i=0; i<dfaceNum; i++){

	/* <b>CASE 1</b>

	p0.x = 0;

	p0.y = 0;

	p0.z = 0;

	p1.x = 0;

	p1.y = 1;

	p1.z = 0;

	p2.x = 1;

	p2.y = 1;

	p2.z = 0;

	*/

	

	// <b>CASE 2</b>

	p0.x = dProva[0];

	p0.y = dProva[1];

	p0.z = dProva[2];

	p1.x = dProva[3];

	p1.y = dProva[4];

	p1.z = dProva[5];

	p2.x = dProva[6];

	p2.y = dProva[7];

	p2.z = dProva[8];

	

	/*

	p0.x = dvertex[0];

	p0.y = dvertex[1];

	p0.z = dvertex[2];

	p1.x = dvertex[24];

	p1.y = dvertex[25];

	p1.z = dvertex[26];

	p2.x = dvertex[16];

	p2.y = dvertex[17];

	p2.z = dvertex[18];

	*/

	/*

	p0.x = dvertex[((dface[dfaceIndex[0]+1]-1)*4)];

	p0.y = dvertex[((dface[dfaceIndex[0]+1]-1)*4)+1];

	p0.z = dvertex[((dface[dfaceIndex[0]+1]-1)*4)+2];

	p1.x = dvertex[((dface[dfaceIndex[0]+4]-1)*4)];

	p1.y = dvertex[((dface[dfaceIndex[0]+4]-1)*4)+1];

	p1.z = dvertex[((dface[dfaceIndex[0]+4]-1)*4)+2];

	p2.x = dvertex[((dface[dfaceIndex[0]+7]-1)*4)];

	p2.y = dvertex[((dface[dfaceIndex[0]+7]-1)*4)+1];

	p2.z = dvertex[((dface[dfaceIndex[0]+7]-1)*4)+2];

	*/

	inc = inc || (RayTriangleInc (dir,eye, p0 , p1, p2)==1.0);

	

}



if(idarray<n){

	if(inc==1){

	a_d[idarray]=1.0f;

	a_d[idarray+1]=1.0f;

	a_d[idarray+2]=1.0f;

	a_d[idarray+3]=1.0f;

	}else{a_d[idarray]=0.0f;

		a_d[idarray+1]=0.0f;

		a_d[idarray+2]=0.0f;

		a_d[idarray+3]=0.0f;

		}		

}

}

host void callCuda(Pixel *a_d, int w, int h, int ch, float x, float y, float z, scene *hScene, double *hProva)

{

if(dvertex==NULL && dface==NULL && dfaceIndex==NULL){

	

	//Alloco memoria su device

	cutilSafeCall(cudaMalloc((void**) &dvertex, 32 * sizeof(double)));

	cutilSafeCall(cudaMalloc((void**) &dface, 120 * sizeof(int)));

	cutilSafeCall(cudaMalloc((void**) &dfaceIndex, 12 * sizeof(int)));

	

	cutilSafeCall(cudaMalloc((void**) &dProva, 9 * sizeof(double)));

			

	//Copio Dati dalla scena agli array su device

	cutilSafeCall(cudaMemcpy(dvertex, hScene->vertex, 32 * sizeof(double),cudaMemcpyHostToDevice));    

	cutilSafeCall(cudaMemcpy(dface, hScene->face, 120* sizeof(int),cudaMemcpyHostToDevice));    

	cutilSafeCall(cudaMemcpy(dfaceIndex, hScene->faceIndex, 12 * sizeof(int),cudaMemcpyHostToDevice));

	

	cutilSafeCall(cudaMemcpy(dProva, hProva, 9 * sizeof(double),cudaMemcpyHostToDevice)); 

}	



//Copio Dati dalla scena alle variabili su device

dfaceNum = hScene->faceNum;



float3 Eye;

Eye.x =x;

Eye.y =y;

Eye.z =z;



float distanza=2.00;

float vFov=60.00;

float hFov=vFov*((float)w/(float)h);



vFov = vFov * M_PI / 180;

hFov = hFov * M_PI / 180;



float3 At;

At.x= Eye.x;

At.y= Eye.y;

At.z=Eye.z-distanza;

float3 vettoreCam = At-Eye;

float3 vettore_up = {0.0,1.0,0.0};

float3 vettore_v = cross(vettoreCam,vettore_up);



float3 ydir= -vettore_up;

float3 xdir= cross(ydir,vettoreCam);



xdir= normalize(xdir)*((2.0*distanza*tan(hFov/2.0))/(float)w);

ydir= normalize(ydir)*((2.0*distanza*tan(vFov/2.0))/(float)h);



float3 LLdir;

LLdir.x=vettoreCam.x-(xdir.x*w)/2;

LLdir.y=vettoreCam.y-(ydir.y*h)/2;

LLdir.z=vettoreCam.z;



dim3 dimGrid (80,60);

dim3 dimBlock (8,8);

DrawScreen <<< dimGrid, dimBlock >>> (a_d,w,h,ch,Eye,xdir,ydir,LLdir, dvertex, dface, dfaceIndex, dfaceNum,dProva);



checkCUDAError("kernel execution");

}

[/codebox]

[codebox]#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <GL/glew.h>

#include <GL/glut.h>

#include <cuda.h>

#include <cuda_runtime.h>

#include <cuda_gl_interop.h>

#include <cutil_inline.h>

#include “DrawScreen.h”

#define OFFSET(i) ((char *)NULL + (i))

Pixel *data = NULL;

int imWidth=640;

int imHeight=480;

int Ch=4;

static GLuint pbo_buffer = 0;

static GLuint texid = 0;

unsigned int timer;

float cameraX=0.0;

float cameraY=0.0;

float cameraZ=6.0;

scene myScene;

static double *hProva= NULL;

void reshape(int x, int y)

{

glViewport(0, 0, x, y);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(0, 1, 0, 1, 0, 1); 

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

glutPostRedisplay();

}

void display(void)

{

// initialize hProva

hProva=(double *) malloc(9 * sizeof(double));

hProva[0]=0;

hProva[1]=0;

hProva[2]=0;

hProva[3]=1;

hProva[4]=1;

hProva[5]=0;

hProva[6]=1;

hProva[7]=0;

hProva[8]=0;





glClear(GL_COLOR_BUFFER_BIT);

cutilSafeCall(cudaGLMapBufferObject((void**)&data, pbo_buffer));

//PASS hProva

callCuda(data, imWidth, imHeight, Ch, cameraX, cameraY, cameraZ, &myScene, hProva);

cutilSafeCall(cudaGLUnmapBufferObject(pbo_buffer));  



glBindTexture(GL_TEXTURE_2D, texid);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_buffer);

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imWidth, imHeight, GL_RGBA, GL_FLOAT, OFFSET(0) );

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

glDisable(GL_DEPTH_TEST);

glEnable(GL_TEXTURE_2D);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glLoadIdentity();

glBegin(GL_QUADS);

glVertex2f(0, 0); glTexCoord2f(0, 0);

glVertex2f(0, 1); glTexCoord2f(1, 0);

glVertex2f(1, 1); glTexCoord2f(1, 1);

glVertex2f(1, 0); glTexCoord2f(0, 1);

glEnd();

glBindTexture(GL_TEXTURE_2D, 0);

glutSwapBuffers();

}

void inizializza (int w, int h, int ch)

{

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glewInit();

data = (Pixel*)malloc( sizeof(float) * ch * w * h );

memset(data, 0, sizeof(float) * ch * w * h);

glGenBuffers(1, &pbo_buffer);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_buffer); 

glBufferData(GL_PIXEL_UNPACK_BUFFER, 

                ch * sizeof(Pixel) * w * h, 

                data, GL_STREAM_DRAW);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

cutilSafeCall(cudaGLRegisterBufferObject(pbo_buffer));



glGenTextures(1, &texid);

glBindTexture(GL_TEXTURE_2D, texid);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imWidth, imHeight,  0, GL_RGBA, GL_FLOAT, NULL);

glBindTexture(GL_TEXTURE_2D, 0);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glPixelStorei(GL_PACK_ALIGNMENT, 1);

memset(&myScene, 0, sizeof(scene));

readObj("cube.obj", &myScene);

}

void keyb (unsigned char key, int x, int y)

{

switch (key)

{

	case '+': cameraX = cameraX + 0.25;

		break;

	case '-': cameraX = cameraX - 0.25;

		break;

	case '*': cameraY = cameraY + 0.25;

		break;

	case '/': cameraY = cameraY - 0.25;

		break;

	case '9': cameraZ = cameraZ + 0.25;

		break;

	case '8': cameraZ = cameraZ - 0.25;

		break;

}

glutPostRedisplay();

}

int main(int argc, char** argv)

{

glutInit( &argc, argv);    

glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);

glutInitWindowSize(imWidth, imHeight);

glutCreateWindow("Draw Screen");

inizializza(imWidth,imHeight,Ch);

glutDisplayFunc(display);

glutReshapeFunc(reshape);

glutKeyboardFunc(keyb);

glutMainLoop();

return 1;

}

[/codebox]

if I set the vertices manually (case 1), the triangle appears on the screen, if I’m going to read the vertices from an array allocated on the device (case 2) the screen stays black …

Why?