照明在opengl中不起作用 [英] Lighting not working in opengl

查看:61
本文介绍了照明在opengl中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MFC中的opengl纹理中使用了一些灯光代码,但它不起作用



我尝试过:



我的代码是

i used some lighting codes in opengl texture in MFC, but it does not work

What I have tried:

My code is

GLuint glTexture ; 

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glEnable( GL_TEXTURE_2D );
 //   glEnable(GL_BLEND);
 //   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable( GL_LIGHTING );
   glEnable(GL_LIGHT1);
 //   glEnable(GL_ALPHA_TEST);
 //   glAlphaFunc(GL_GREATER,0.01);;
     glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
        //Light
    GLfloat lightColor0[] = {0.9f, 0.9f, 0.9f, 1.0f};
    GLfloat lightPos0[] = {0.0f, 30.0f, 0.0f, 1};
    glLightfv(GL_LIGHT1, GL_SPECULAR, lightColor0);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor0);
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos0);
 
    glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0);
    GLfloat spot_direction[] = { 0.0, -1.0, 0.0 };
    glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
    glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 2.0);
    glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0);
 
    //Material
    GLfloat mcolor[] = {0.1, 0.9, 0.4, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolor);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mcolor);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
    glEnable(GL_COLOR_MATERIAL);
    glGenTextures( 1, &glTexture );
    glBindTexture( GL_TEXTURE_2D, glTexture );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );    // Select modulate to mix texture with color for shading
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );   // When texture area is small, bilinear filter the closest mipmap
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );        // When texture area is large, bilinear filter the original
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );       // The texture wraps over at the edges (repeat)
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
//    GLfloat globalAmbient[] = { g_nRedSlider, g_nGreenSlider, g_nBlueSlider, g_nAlphaSlider };
//    glLightModelfv( GL_LIGHT_MODEL_AMBIENT, globalAmbient );
    glColor4f( float( ( float )g_nRedSlider / 10 ), float( ( float )g_nGreenSlider/ 10 ), float( ( float )g_nBlueSlider / 10 ), float( ( float )g_nAlphaSlider / 10 ));
    glTexImage2D( GL_TEXTURE_2D, 0, GL_INTENSITY, WIDTH, HEIGHT, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_pbyImageData ); 
    glEnable( GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, glTexture );
    glBegin( GL_QUADS );
    glTexCoord2d(0.0,0.0); 
    glVertex2f(-0.8f, -0.8f); 
    glTexCoord2d(1.0,0.0);
    glVertex2f( 0.8f, -0.8f);
    glTexCoord2d(1.0,1.0);
    glVertex2f( 0.8f,  0.8f);
    glTexCoord2d(0.0,1.0);
    glVertex2f(-0.8f,  0.8f);
    glEnd();
    SwapBuffers( m_hDeviceContextDC );
    glDisable( GL_TEXTURE_2D );
    glDisable( GL_COLOR_MATERIAL );





它不会产生任何光照效果只显示纹理图像。



it does not produce any lighting effects just shows the texture image.

推荐答案

我用你的光和材料代码



这是我的本能化代码...光是一个bool并开始是的,所以glEnable被称为在那里打开它

I used your code for light and material

This is my inintialization code ... light is a bool and starts true so glEnable is called turning it on in there
int InitGL(GLvoid)										// All Setup For OpenGL Goes Here
{
	if (!BMP2GLTexture("Bitmaps/Crate.bmp", &glTexture[0]))				// Jump To Texture Loading Routine
	{
		return FALSE;							        // If Texture Didn't Load Return FALSE
	}

	glEnable(GL_TEXTURE_2D);							// Enable Texture Mapping
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);				// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations

	//Light
	GLfloat lightColor0 [] = { 0.9f, 0.9f, 0.9f, 1.0f };
	GLfloat lightPos0 [] = { 0.0f, 30.0f, 0.0f, 1 };
	glLightfv(GL_LIGHT1, GL_SPECULAR, lightColor0);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor0);
	glLightfv(GL_LIGHT1, GL_POSITION, lightPos0);
	glEnable(GL_LIGHT1);

	glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0);
	GLfloat spot_direction [] = { 0.0, -1.0, 0.0 };
	glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
	glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 2.0);
	glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0);
	glEnable(GL_LIGHT1);

	// Material
	GLfloat mcolor [] = { 0.1f, 0.9f, 0.4f, 1.0f };
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolor);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mcolor);
	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
	glEnable(GL_COLOR_MATERIAL);

	if (light) glEnable(GL_LIGHTING);

	return TRUE;										// Initialization Went OK
}





接下来会有一个例程来设置场景到窗口大小...你目前没有的代码,不知道你做了什么。宽度和高度是我的OpenGL窗口大小。



Next will come a routine to set the scene to the window size ... code you don't currently have and not sure what you do. Width and Height are my OpenGL window size.

GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		// Resize And Initialize The GL Window
{
	if (height==0)										// Prevent A Divide By Zero By
	{
		height=1;										// Making Height Equal One
	}

	glViewport(0,0,width,height);						// Reset The Current Viewport

	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	glLoadIdentity();									// Reset The Projection Matrix

	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
	glLoadIdentity();									// Reset The Modelview Matrix
}





最后我绘制了一个场景,它将是你MFC窗口的绘图调用..有几个位所以我可以旋转纹理你可以忽略它们





Finally I draw the scene which will be the draw call of your MFC window .. there are a couple of bits so I can rotate the texture you can ignore them

int DrawGLScene(GLvoid)									// Here's Where We Do All The Drawing
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	// Translate some Depth Into The Screen in this case -5.0
	glTranslatef(0.0f, 0.0f, -5.0f);

	// these just rotate the texture my addition you can leave out
        glRotatef(xrot, 1.0f, 0.0f, 0.0f);
	glRotatef(yrot, 0.0f, 1.0f, 0.0f);

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, glTexture[0]);

	glBegin(GL_QUADS);
	glNormal3f(0.0f, 0.0f, 1.0f);
	glTexCoord2d(0.0, 0.0); glVertex2f(-0.8f, -0.8f);
	glTexCoord2d(1.0, 0.0);	glVertex2f(0.8f, -0.8f);
	glTexCoord2d(1.0, 1.0);	glVertex2f(0.8f, 0.8f);
	glTexCoord2d(0.0, 1.0);	glVertex2f(-0.8f, 0.8f);
	glEnd();

     // These are the rotations being added ... again you can ignore
	xrot+=xspeed;
	yrot+=yspeed;
	return TRUE;										// Keep Going
}





在消息循环中,swapbuffers就像你一样。



这是运行序列的伪代码



1.)InitGL ...被称为opengl窗口是创建并运行一次

2.)ReSizeGLScene ...作为opengl创建调用一次任何时候窗口调整大小都会运行..我把它挂钩到windows resize事件

3.)DrawGLScene ....绘制场景

4.)交换缓冲区

5.)循环回3 ...只会在程序退出时停止循环



In the message loop the swapbuffers happens just like you.

This is the Pseudocode for the running sequence

1.) InitGL ... Called as opengl window is create and runs just the once
2.) ReSizeGLScene ... Called once as opengl create and runs anytime the window is resized .. I hook it to windows resize event
3.) DrawGLScene .... draws the scence
4.) Swap the buffers
5.) Loop back to 3 ... will only stop looping when program quits


你的代码实际上不能以你应该拥有的那种形式使用至少2个部分,你有两个混合组件



1.)一个初始设置部分(在开始时调用一次)

2。 )一个叫做每帧画的部分



当我把这个代码放在骨架OpenGL代码中时ng有效,但有一个我无法测试并且有问题的元素,我必须为我的应用程序定位视图位置。你的代码给我一个黑屏,因为视图位置没有设置。



我关心的是这条线的纹理文件实际是什么

glTexImage2D(GL_TEXTURE_2D,0,GL_INTENSITY,WIDTH,HEIGHT,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,m_pbyImageData);



你的图像纹理是否真的在GL_LUMINANCE中保存在m_pbyImageData中格式?



我的等效代码,因为我正在加载一个标准的Windows位图是

glTexImage2D(GL_TEXTURE_2D,0,3,BMP.bmWidth, BMP.bmHeight,0,GL_BGR_EXT,GL_UNSIGNED_BYTE,m_pbyImageData);



普通的Windows DIB格式是GL_BGR_EXT,但你没有在m_pbyImageData中显示创建纹理的代码/>


我已经上传了VS2013格式的粗略检查代码..按L打开和关闭灯光,箭头键旋转纹理,这样你就可以找到方向灯了。 />
TinyUpload.com - 最佳文件托管解决方案,无限制,完全免费 [ ^ ]



骨架代码有3个部分BTW

1.)初始设置部分(在开始时调用一次)

2.)一个部分称为每个帧绘制

3.)在调整窗口大小时运行的一段代码
Your code can't really be used in that form you are supposed to have a minimum 2 sections and you have mixed components of both

1.) An intial setup section (called once at start)
2.) A section called each frame draw

When I put that code in a skeleton OpenGL code the lighting works but there is one element I can not test and and have concerns with, and I have to position the view position for my application. You code for me gives me a black screen because the view position is not setup.

My concern is what the texture file actually is with this line
glTexImage2D( GL_TEXTURE_2D, 0, GL_INTENSITY, WIDTH, HEIGHT, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_pbyImageData );

Is your image texture held in m_pbyImageData really in GL_LUMINANCE format?

My equivalent code because I am loading a standard windows bitmap is
glTexImage2D(GL_TEXTURE_2D, 0, 3, BMP.bmWidth, BMP.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, m_pbyImageData);

The normal windows DIB format is GL_BGR_EXT but you havent shown the code that creates your texture in m_pbyImageData

I have uploaded the roughcheck code in VS2013 format .. press L to turn the lights on and off and arrow keys rotates the texture so you can look for direction lights.
TinyUpload.com - best file hosting solution, with no limits, totaly free[^]

The skeleton code has 3 sections BTW
1.) An intial setup section (called once at start)
2.) A section called each frame draw
3.) A section of code that runs when you resize the window


当然我的代码是更通用的代码,只使用Win32 api加载位图



Sure my code is more generic code that loads a bitmap using just the Win32 api

bool BMP2GLTexture(LPCSTR bmpFilename, GLuint* glTexture) { // Load Bitmaps And Convert To a texture
	HBITMAP hBMP;                                           // Handle Of The Bitmap
	BITMAP  BMP;                                            // Bitmap Structure

	if (glTexture == NULL) return false;					// Return texture pointer invalid so fail out
	hBMP = (HBITMAP) LoadImage(GetModuleHandle(NULL), bmpFilename, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
	if (!hBMP) return FALSE;								// If bitmap does not exist return false
	GetObject(hBMP, sizeof(BMP), &BMP);						// Get The bitmap details
	int P2Width = (BMP.bmWidth) >> 2;						// Divid width by 4
	if ((P2Width << 2) < (BMP.bmWidth)) P2Width++;			// Inc by 1 if width x 4 is less than original
	P2Width = P2Width << 2;									// Power of two width
	long imageSize = (long) P2Width * (long) BMP.bmHeight * (long)sizeof(RGBQUAD);

	// Create the pixel buffer
	BYTE* m_pbyImageData = (BYTE*) malloc(imageSize);

	// Fetch desktop DC to use
	HDC Dc = GetDC(GetDesktopWindow());

	// Create and fill BITMAPINFO structure to pass to GetDIBits
	BITMAPINFO bmi;
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth = BMP.bmWidth;
	bmi.bmiHeader.biHeight = BMP.bmHeight;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = 24;
	bmi.bmiHeader.biCompression = 0;
	bmi.bmiHeader.biSizeImage = imageSize;
	bmi.bmiHeader.biXPelsPerMeter = 0;
	bmi.bmiHeader.biYPelsPerMeter = 0;
	bmi.bmiHeader.biClrUsed = 0;
	bmi.bmiHeader.biClrImportant = 0;

	// Load m_pbyImageData with the pixels in DIB format
	GetDIBits(Dc, hBMP, 0, BMP.bmHeight, m_pbyImageData, &bmi, DIB_RGB_COLORS);

	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);								// Pixel Storage Mode (Word Alignment / 4 Bytes)

	glGenTextures(1, glTexture);										// Create a texture
	glBindTexture(GL_TEXTURE_2D, glTexture[0]);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);		// Select modulate to mix texture with color for shading
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	// When texture area is small, bilinear filter the closest mipmap
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);	// When texture area is large, bilinear filter the original
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);		// The texture wraps over at the edges (repeat)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, BMP.bmWidth, BMP.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, m_pbyImageData);

	free(m_pbyImageData);												// Free allocated pixel memory
	ReleaseDC(GetDesktopWindow(), Dc);									// Release the desktop DC
	DeleteObject(hBMP);													// Delete The Object
	return TRUE;														// Return true Status
}





我的加载纹理调用直接只是filname和指向GLUint的指针来存储结果



My load texture call is straight forward just the filname and a pointer to the GLUint to store the result

BMP2GLTexture("somepath/xyz.bmp", &glTexture[0]);


这篇关于照明在opengl中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆