`
nsxd15nsxd
  • 浏览: 13932 次
社区版块
存档分类
最新评论

OpenGL编程设置

阅读更多

OpenGL编程设置
13小时前
  一.环境配置
  由于微软公司为了推销自己的产品DirectX,击败OpenGL,因此现在的windows操作系统只支持OpenGL1.1版本,而现在的OpengGL版本已经发展到了3.1,并且只有2.0以上的版本才支持GLSL语言,所以我们必须对操作系统上的OpenGL进行升级,那么应该如何升级呢?实际上,下载OpenGL2.0以上的开发库是没用的,因为windows只支持1.1版本。所以,要想解决这个问题,只能使用OpenGL扩展。这里我建议(也是许多人建议的)大家使用GLEW扩展库,因为它使用起来较为简单。
  第一步:下载GLEW库。网址:
  http://glew.sourceforge.net/index.html
  第二步:解压缩文件,将include文件夹内的所有头文件添加到VC98/INCLUDE/GL中,将lib文件夹内的所有文件添加到VC98/LIB中,再将bin文件夹内的所有dll文件添加到C盘windows/system32中,OK了,其他文件就不要管了。
  第三步:新建工程,在工程-》设置-》link中添加opengl32.lib glu32.lib glew32s.lib
  第四步:在stdAfx.h中添加如下语句:
  #define GLEW_STATIC 1
  #include      (由于glew头文件中已经包含了对gl.h和glu.h的包含,因此这里没有必要include。
  第五步:配置OpenGL基本环境,详见上一篇文章《基于MFC的opengl编程》。
  第六步:在InitOpenGL函数中添加如下代码:
  GLenum err=glewInit();//初始化glew
  if(err!=GLEW_OK)
  MessageBox("failed to init glew!");
  第七步:完成。
  二、建立并导入shader文件。
  分别建立两个文本文件,将shader源码写入其中,并将名字分别设置为temp.vert和temp.frag。然后将这两个文件复制到工程所在的目录下。
  temp.vert的内容如下:
  uniform float CoolestTemp;
  uniform float TempRange;
  attribute float VertexTemp;
  varying float Temperature;
  void main(void)
  {
  Temperature=(VertexTemp-CoolestTemp)/TempRange;
  gl_Position=gl_ModelViewProjectionMatrix*gl_Vertex;
  }
  temp.frag的内容如下:
  uniform vec3 CoolestColor;
  uniform vec3 HottestColor;
  varying float Temperature;
  void main(void)
  {
  vec3 color=mix(CoolestColor,HottestColor,Temperature);
  gl_FragColor=vec4(color,1.0);
  }
  这两个shader的作用是定义三角形三个顶点的温度,并根据温度对颜色进行插值。
  三、编写连接shader与opengl的函数 。
  //获得shader文件中字符的个数。
  int ShaderSize(char *filename)
  {
  FILE *fp;
  int count;
  fp=fopen(filename,"rt");
  if(!fp)
  MessageBox("error");
  rewind(fp);
  fseek(fp,0,SEEK_END);
  count=ftell(fp);
  rewind(fp);
  fclose(fp);
  return count;
  }
  //将shader文件中的代码读取到字符串中,并返回该字符串的指针。
  GLchar *ReadShaderSource(char *filename, int len)
  {
  GLchar *shader;
  shader=(GLchar*)malloc(sizeof(char)*(len+1));
  FILE *fp;
  memset(shader,0,len+1);
  fp=fopen(filename,"rt+");
  if(!fp)
  MessageBox("error");
  fseek(fp,0,SEEK_SET);
  fread(shader,sizeof(char),len,fp);
  fclose(fp);
  return shader;
  }
  int InstallShaders( GLchar *Vertex, GLchar *Fragment)
  {
  GLint vertCompiled, fragCompiled;    // status values
  GLint linked;
  // Create a vertex shader object and a fragment shader object
  vertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
  fragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
  // Load source code strings into shaders
  glShaderSource(vertexShaderObject, 1, (const char **)&Vertex, NULL);
  glShaderSource(fragmentShaderObject, 1, (const char **)&Fragment, NULL);
  // Compile the brick vertex shader, and print out
  // the compiler log file.
  glCompileShader(vertexShaderObject);
  glGetShaderiv(vertexShaderObject, GL_COMPILE_STATUS, &vertCompiled);
  // Compile the brick vertex shader, and print out
  // the compiler log file.
  glCompileShader(fragmentShaderObject);
  glGetShaderiv(fragmentShaderObject, GL_COMPILE_STATUS, &fragCompiled);
  if (!vertCompiled || !fragCompiled)
  MessageBox("error");
  // Create a program object and attach the two compiled shaders
  programObject = glCreateProgram();
  glAttachShader(programObject, vertexShaderObject);
  glAttachShader(programObject, fragmentShaderObject);
  // Link the program object and print out the info log
  glLinkProgram(programObject);
  glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
  if (!linked)
  MessageBox("error");
  /* int infologlength;
  int charswrriten;
  char *infolog;
  // Install program object as part of current state
  glGetShaderiv(vertexShaderObject,GL_INFO_LOG_LENGTH,&infologlength);
  infolog=(char*)malloc(infologlength);
  glGetShaderInfoLog(vertexShaderObject,infologlength,&charswrriten,infolog);
  MessageBox(infolog);
  glGetShaderiv(fragmentShaderObject,GL_INFO_LOG_LENGTH,&infologlength);
  infolog=(char*)malloc(infologlength);
  glGetShaderInfoLog(fragmentShaderObject,infologlength,&charswrriten,infolog);
  MessageBox(infolog);*/
  //以上的代码被注释起来,作用是获得shader编译后的错误报告,用于调试,由于已经调试成功,这里就不需要这些代码了
  glUseProgram(programObject);
  // Set up initial uniform values
  glUniform1f(glGetUniformLocation(programObject, "CoolestTemp"), 0.0f);
  glUniform1f(glGetUniformLocation(programObject, "TempRange"), 1.0f);
  glUniform3f(glGetUniformLocation(programObject, "CoolestColor"), 0.0, 0.0, 1.0);
  glUniform3f(glGetUniformLocation(programObject, "HottestColor"), 1.0, 0.0, 0.0);
  return 1;
  }
  将这三个函数添加到VIEW类当中。注意,InstallShaer函数中的vertexShaderObject   fragmentShaderObject以及programObject是VIEW类下的成员变量,需要大家手动添加到view类中。这三个变量都是GLuint类型。
  同时,在view类中添加vertexShaderSource和fragmentShaderSource这两个变量,用于接收ReadShaderSource函数返回的指针。这两个变量都是GLchar*型。
  在函数InitializeOpenGL中添加如下代码:
  vertexShaderSource=ReadShaderSource("temp.vert",ShaderSize("temp.vert"));
  fragmentShaderSource=ReadShaderSource("temp.frag",ShaderSize("temp.frag"));
  InstallShaders(vertexShaderSource,fragmentShaderSource);
  这样的话,shader源码就被编译为机器代码,加载到显卡上从而成为了OpenGL状态的一部分。
  四、编写OpenGL绘图函数。
  void RenderScene()
  {
  glTranslatef(0.0,0.0,-3.0);
  GLint tempLoc = glGetAttribLocationARB(programObject, "VertexTemp");
  glBegin(GL_TRIANGLES);
  glVertexAttrib1f(tempLoc, 0.0f);        
  glVertex3f(1.0f,0.0f,0.0f);
  glVertexAttrib1f(tempLoc, 0.5f);
  glVertex3f(-1.0f,0.0f,0.0f);
  glVertexAttrib1f(tempLoc, 1.0f);
  glVertex3f(0.0f,1.0f,0.0f);
  glEnd();
  glLoadIdentity();
  }
  将该函数添加到VIEW类下。
  在Ondraw()函数下写入如下代码:
  ::glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  RenderScene();
  ::glFlush();
  ::SwapBuffers(m_pDC->GetSafeHdc());
  五、运行程序
  这时候,你就会看到一个彩色三角形出现在屏幕上了!
  说明:如果你的显卡为集成显卡或显卡驱动版本太低,则无法运行这段程序。
  MFC背景透明
  BOOL   SetLayeredWindowAttributes( 
  HWND   hwnd,   //   handle   to   the   layered   window 
  COLORREF   crKey,   //   specifies   the   color   key 
  BYTE   bAlpha,   //   value   for   the   blend   function 
  DWORD   dwFlags   //   action 
  ); 
   
  Windows   NT/2000/XP:   Included   in   Windows   2000   and   later. 
  Windows   95/98/Me:   Unsupported. 
  Header:   Declared   in   Winuser.h;   include   Windows.h. 
  Library:   Use   User32.lib. 
  一些常量:   
  WS_EX_LAYERED   =   0x80000; 
  LWA_ALPHA   =   0x2; 
  LWA_COLORKEY=0x1   
  其中dwFlags有LWA_ALPHA和LWA_COLORKEY 
  LWA_ALPHA被设置的话,通过bAlpha决定透明度. 
  LWA_COLORKEY被设置的话,则指定被透明掉的颜色为crKey,其他颜色则正常显示. 
  注:要使使窗体拥有透明效果,首先要有WS_EX_LAYERED扩展属性(旧sdk也没有的).  
  在OnInitDialog()加入: 
  //加入WS_EX_LAYERED扩展属性 
  SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE, 
  GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000); 
  HINSTANCE   hInst   =   LoadLibrary("User32.DLL");   
  if(hInst)   
  {   
  typedef   BOOL   (WINAPI   *MYFUNC)(HWND,COLORREF,BYTE,DWORD);   
  MYFUNC   fun   =   NULL; 
  //取得SetLayeredWindowAttributes函数指针   
  fun=(MYFUNC)GetProcAddress(hInst,   "SetLayeredWindowAttributes"); 
  if(fun)fun(this->GetSafeHwnd(),0,128【设置透明度值在0-255】,2);   
  FreeLibrary(hInst);   
  } 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics