zoukankan      html  css  js  c++  java
  • OpenGL第五节:纹理贴图和像素操作

    LOpengGL.h不变

    LTexture.h

    #include "LOpenGL.h"
    #include <stdio.h>

    class LTexture
    {
    public:
    LTexture();

    ~LTexture();

    bool loadTextureFromPixels32( GLuint* pixels, GLuint width, GLuint height );//根据像素创建或者说加载纹理

    void freeTexture();//释放

    void render( GLfloat x, GLfloat y );//渲染

    GLuint getTextureID();

    GLuint textureWidth();

    GLuint textureHeight();

    private:
    GLuint mTextureID;//纹理ID

    GLuint mTextureWidth;//纹理宽
    GLuint mTextureHeight;//纹理高
    };

    LUtil.h

    bool loadMedia();//添加加载资源的方法

    LTexture.cpp

    LTexture::LTexture()//构造函数
    {
      mTextureID = 0;
      mTextureWidth = 0;
      mTextureHeight = 0;
    }

    LTexture::~LTexture()//析构函数
    {
      freeTexture();
    }

    void LTexture::freeTexture()
    {
      if( mTextureID != 0 )//删除纹理
      {
        glDeleteTextures( 1, &mTextureID );
        mTextureID = 0;
      }

      mTextureWidth = 0;
      mTextureHeight = 0;
    }

    bool LTexture::loadTextureFromPixels32( GLuint* pixels, GLuint width, GLuint height )
    {
      freeTexture();//如果存在了就先释放

      mTextureWidth = width;
      mTextureHeight = height;

      glGenTextures( 1, &mTextureID );//生成一个纹理ID

      glBindTexture( GL_TEXTURE_2D, mTextureID );//然后绑定到TEXTURE_2D

      glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels );//生成纹理,参数:纹理类型,映射级别,纹理存储像素格式,宽度,高度,边框宽度,传进来的像素格式,传进来的像素的数据类型,传进来的像素

      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );//设置参数,magnify放大时按线性放大
      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );//设置参数,minify缩小时按线性缩小

      glBindTexture( GL_TEXTURE_2D, NULL );//解除绑定

      GLenum error = glGetError();
      if( error != GL_NO_ERROR )
      {
        printf( "Error loading texture from %p pixels! %s ", pixels, gluErrorString( error ) );
        return false;
      }

      return true;
    }

    void LTexture::render( GLfloat x, GLfloat y )
    {
      if( mTextureID != 0 )
      {
        glLoadIdentity();//重置为单位矩阵,去掉之前的移动等操作

        glTranslatef( x, y, 0.f );

        glBindTexture( GL_TEXTURE_2D, mTextureID );

        glBegin( GL_QUADS );
          glTexCoord2f( 0.f, 0.f ); glVertex2f( 0.f, 0.f );//glTexCoord2f方法的参数分别是s,t,取值0~1 。s代表水平方向,t代表竖直方向,(0,0)代表左上角,(1,0)代表右上角,(1,1)代表右下角,(0,0)代表左下角
          glTexCoord2f( 1.f, 0.f ); glVertex2f( mTextureWidth, 0.f );
          glTexCoord2f( 1.f, 1.f ); glVertex2f( mTextureWidth, mTextureHeight );
          glTexCoord2f( 0.f, 1.f ); glVertex2f( 0.f, mTextureHeight );
        glEnd();
      }
    }

    纹理坐标如下图所示:

      

    GLuint LTexture::getTextureID()
    {
      return mTextureID;
    }

    GLuint LTexture::textureWidth()
    {
      return mTextureWidth;
    }

    GLuint LTexture::textureHeight()
    {
      return mTextureHeight;
    }

    LUtil.cpp

    LTexture gCheckerBoardTexture;

    bool loadMedia()
    {
      const int CHECKERBOARD_WIDTH = 128;//棋盘的宽,需要是2的幂次方
      const int CHECKERBOARD_HEIGHT = 128;//期盼的高
      const int CHECKERBOARD_PIXEL_COUNT = CHECKERBOARD_WIDTH * CHECKERBOARD_HEIGHT;//总的像素数
      GLuint checkerBoard[ CHECKERBOARD_PIXEL_COUNT ];

      for( int i = 0; i < CHECKERBOARD_PIXEL_COUNT; ++i )//遍历每个像素,然后复制
      {
        GLubyte* colors = (GLubyte*)&checkerBoard[ i ];//一个像素是32位,rgba各8位,强制转化为一个8位的指针指向它,这样可以分别操作r,g,b,a每种颜色

        if(i / 128 & 16   ^   i % 128 & 16 )//间隔
        {//设置为白色
          colors[ 0 ] = 0xFF;//r
          colors[ 1 ] = 0xFF;//g
          colors[ 2 ] = 0xFF;//b
          colors[ 3 ] = 0xFF;//a
        }
        else
        {//设置为红色
          colors[ 0 ] = 0xFF;
          colors[ 1 ] = 0x00;
          colors[ 2 ] = 0x00;
          colors[ 3 ] = 0xFF;
        }
      }

      if( !gCheckerBoardTexture.loadTextureFromPixels32( checkerBoard, CHECKERBOARD_WIDTH, CHECKERBOARD_HEIGHT ) )//创建纹理
      {
        printf( "Unable to load checkerboard texture! " );
        return false;
      }

      return true;
      }

    void render()
    {
      glClear( GL_COLOR_BUFFER_BIT );

      GLfloat x = ( SCREEN_WIDTH - gCheckerBoardTexture.textureWidth() ) / 2.f;//中心点
      GLfloat y = ( SCREEN_HEIGHT - gCheckerBoardTexture.textureHeight() ) / 2.f;

      gCheckerBoardTexture.render( x, y );//绘制

      glutSwapBuffers();//更新屏幕
    }

    main.cpp

    int main( int argc, char* args[] )
    {
      glutInit( &argc, args );

      glutInitContextVersion( 2, 1 );

      glutInitDisplayMode( GLUT_DOUBLE );
      glutInitWindowSize( SCREEN_WIDTH, SCREEN_HEIGHT );
      glutCreateWindow( "OpenGL" );

      if( !initGL() )//初始化OpenGL
      {
        printf( "Unable to initialize graphics library! " );
        return 1;
      }

      if( !loadMedia() )//加载媒体,该方法根据像素创建纹理
      {
        printf( "Unable to load media! " );
        return 2;
      }

      glutDisplayFunc( render );

      glutTimerFunc( 1000 / SCREEN_FPS, runMainLoop, 0 );

      glutMainLoop();

      return 0;
    }

  • 相关阅读:
    1137 Final Grading (25 分)
    1136 A Delayed Palindrome (20 分)
    1135 Is It A Red-Black Tree (30 分)
    1134 Vertex Cover (25 分)
    1133 Splitting A Linked List (25 分)
    1074 Reversing Linked List (25 分)
    1132 Cut Integer (20 分)
    HDU 3342 Legal or Not
    IDEA解决JSP页面无法使用EL表达式问题
    25. Bootstreap 下拉菜单
  • 原文地址:https://www.cnblogs.com/yongfengnice/p/7885269.html
Copyright © 2011-2022 走看看