OpenGL编程设置

OpenGL编程设置
11小时前
  一.环境配置
  由于微软公司为了推销自己的产品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);
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值