ucosii_win_7 -- 在ucosii-win-使用openGL实现模拟意见显示屏(改进版)

实    现:在屏幕上画点功能。(能够很快显示)
综合实例(使用480*320显示)
已 改 进:画点更快,刷新频率可以控制
编    者:张永辉 2012年11月17日  三文件

/***************************************************************************************************
*                                            INCLUDE FILES
*app.c
****************************************************************************************************/
#include <includes.h>
#include "OpenglLcd.h"

OS_STK  AppStartTaskStk[APP_OS_CFG_START_TASK_STK_SIZE];
static  void  App_TaskStart (void);

/***************************************************************************************************
*                                            INCLUDE FILES
***************************************************************************************************/
int  main (void)
{
    INT8U  err;
    OSInit();
   
 GlInit();           //openGL初始化,必须放在此位置。
 
    OSTaskCreate((void (*)(void *)) App_TaskStart,
                    (void          *) 0,
                    (OS_STK        *)&AppStartTaskStk[APP_OS_CFG_START_TASK_STK_SIZE-1],
                    (INT16U         )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR)
                 );

    #if  (OS_TASK_NAME_SIZE  >= 5)                      //Give a name to tasks
        OSTaskNameSet(OS_TASK_IDLE_PRIO,"Idle",&err);   //默认的Idle任务
    #endif
    OSStart();                                          // Start OS
}

/***************************************************************************************************
*                                       第一个任务 App_TaskStart()
***************************************************************************************************/
void  App_TaskStart (void)
{
    #if OS_TASK_STAT_EN > 0
        OSStatInit();                                   // Determine CPU capacity
    #endif

    while (1)
    {
        printf("Delay 2 second and print\n");
        OSTimeDlyHMSM(0, 0, 1, 0);      //需要任务GL_TaskStart申请空间完成后才能DisTset。
        GlDisTset();
        OSTimeDlyHMSM(0, 0, 1, 0);
        GlDisClear();
    }
}

 

/***************************************************************************************************
                                    OpenGL模拟显示屏
文 件 名: OpenglLcd.h
模块功能:模拟显示器
颜色模式:固定为565模式
编译环境:VS2008
系统环境:ucOS2.86
改    进: 画点函数很快。画面刷新频率可以控制了,可以让出很多CPU。
编    者: 张永辉 2012-11-19
***************************************************************************************************/
#ifndef __OPENGLLCD__H
#define __OPENGLLCD__H
/**************************************************************************************************/
#define u16 unsigned short                      //数据长度。
#define u32 unsigned int

#define GL_TASK_STK_SIZE 256                    //两任务的堆栈
#define GL_TASK_DISBUFFCOPY_STK_SIZE 256

#define GL_TASK_STK_PRIO 10                     //两任务的优先级
#define GL_TASK_DISBUFFCOPY_STK_PRIO 9

#define X_SIZE 800                              //定义屏幕尺寸
#define Y_SIZE 600
#define GL_FREASH_TIME()    OSTimeDly(7)        //屏幕刷新时间间隔 500/7=72Hz

extern  u16 GlDisBuff[Y_SIZE][X_SIZE];          //显存区。向此写入数据即可改变颜色.与显示屏的接口。
/***************************************************************************************************
                                    颜色定义
***************************************************************************************************/
#define COLOUR_CLEAR 0X0000                     //调用GlInit() GlDisClear()后的显示屏颜色

/***************************************************************************************************
                                    功能函数
***************************************************************************************************/
void    GlInit(void);                           //在OSInit()之后,OSStart()之前调用。
void    GlDisTset(void);                        //测试,将显示屏画RBG三个色后返回
void    GlDisPoint(u32 x,u32 y, u16 Color);     //描点函数
void    GlDisClear(void);                       //清屏
/**************************************************************************************************/
#endif

 

/***************************************************************************************************
                                    OpenGL模拟显示屏
文 件 名: OpenglLcd.c
***************************************************************************************************/

#include <GL/glut.h>
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glut32.lib")
#include <includes.h>
#include "OpenglLcd.h"

/**************************************************************************************************/
//静态变量
static u32   FreshFlg = 0;
static const GLint      ImageWidth =X_SIZE;         //使用OpenGL的GLint类型,它是32位的。
static const GLint      ImageHeight=Y_SIZE;
static GLint            ImagelLength;               //图像缓冲占的字节长度
static GLubyte*         ImageDataP;                 //图像缓冲区指针更改该区域的值即可改变图像

static OS_STK  GLTaskStk[GL_TASK_STK_SIZE];         //两个任务的堆栈
static OS_STK  GlTaskDisBuffCopyStk[GL_TASK_DISBUFFCOPY_STK_SIZE];
u16     GlDisBuff[Y_SIZE][X_SIZE];                  //显存区
/**************************************************************************************************/
//两个任务
void static GlTaskStart (void);
void static GlTaskDisBuffCopy(void);

/***************************************************************************************************
                                    初始化函数
在OSInit()之后,OSStart()之前调用
***************************************************************************************************/
void GlInit(void)
{
    u32 x , y;

    //给背景色
    for(y = 0; y < Y_SIZE ; y++)
    {
        for(x = 0; x < X_SIZE ; x++)
        {
            GlDisBuff[y][x] = COLOUR_CLEAR;
        }
    }

    //任务:GL将显存的颜色显示到显示屏
    OSTaskCreate((void (*)(void *)) GlTaskStart,
                (void          *) 0,
                (OS_STK        *)&GLTaskStk[GL_TASK_STK_SIZE-1],
                (INT16U         )GL_TASK_STK_PRIO);

    //任务:将GlDisBuff的颜色刷新到显存
    OSTaskCreate((void (*)(void *)) GlTaskDisBuffCopy,
                (void          *) 0,
                (OS_STK        *)&GlTaskDisBuffCopyStk[GL_TASK_DISBUFFCOPY_STK_SIZE-1],
                (INT16U         )GL_TASK_DISBUFFCOPY_STK_PRIO);
}
/***************************************************************************************************
                                    功能函数集
***************************************************************************************************/
//--------------------------------------------------------------------------------------------------
//函数功能:性能测试 功能测试函数
void GlDisTset(void)
{
    int x = 0;
    int y = 0;

    //绘制红色区域块
    for(x = 0;x < X_SIZE/3; x++)
    {
        for(y = 0;y <= Y_SIZE;y++)
        {
            GlDisPoint(x,y,0x1f<<11);
        }
    }

    //绘制绿色区域块
    for(x = X_SIZE/3; x < 2*X_SIZE/3; x++)
    {
        for(y = 0;y <= Y_SIZE;y++)
        {
            GlDisPoint(x,y,0x3f<<5);
        }
    }

    //绘制蓝色区域块
    for(x = 2*X_SIZE/3; x <= X_SIZE; x++)
    {
        for(y = 0;y <= Y_SIZE;y++)
        {
            GlDisPoint(x,y,0x1f);
        }
    }
}

//--------------------------------------------------------------------------------------------------
//函数功能:清屏
void GlDisClear(void)
{
    u32 x , y;
    for(y = 0; y < Y_SIZE ; y++)
    {
        for(x = 0; x < X_SIZE ; x++)
        {
            GlDisBuff[y][x] = COLOUR_CLEAR;
        }
    }
}

//--------------------------------------------------------------------------------------------------
//函数功能:在屏幕上画点
//      x :    x坐标位置 0... X_SIZE-1
//      y :    y坐标位置 0... Y_SIZE-1
//      C :    点的颜色  0... 65535  RGB565模式
//坐 标 系:左上角(0,0)  右下角(X_SIZE,Y_SIZE)
void    GlDisPoint(u32 x,u32 y, u16 Color)
{
    if(x >= X_SIZE || y >= Y_SIZE)
    {
        return;
    }
    GlDisBuff[y][x] = Color;
}

/***************************************************************************************************
                                任务函数:GlTaskDisBuffCopy
任务:将GlDisBuff的颜色刷新到显存
***************************************************************************************************/
void static GlTaskDisBuffCopy(void)
{
    GLint post,ypost;
    GLubyte fr,fg,fb;

    u32 x , y;
    u16 Color;

    //等待 GlTaskStart() 给ImageDataP分配储存空间后才能对ImageDataP操作。
    GL_FREASH_TIME();
    GL_FREASH_TIME();

    while(1)
    {
        //决定刷新频率
        GL_FREASH_TIME();

        //把颜色从GlDisBuff复制到ImageDataP
        for(y = 0; y < Y_SIZE ; y++)
        {
            ypost = (Y_SIZE-1-y)*X_SIZE;    //计算y坐标
            for(x = 0; x < X_SIZE ; x++)
            {
                //颜色变换 将565变成24位模式
                Color = GlDisBuff[y][x];
                fr = (GLubyte)((Color >> 8)|(0x07));
                fg = (GLubyte)((Color >> 3)|(0x03));
                fb = (GLubyte)((Color << 3));

                //坐标变换 ImageDataP坐标是:按笛卡尔坐标系的第一象限,x=[0 ... X_SIZE-1]  y=[0 ... Y_SIZE-1]
                post = (ypost + x)*3;

                //向缓冲区写入一个点的颜色
                ImageDataP[post]   = fb;    //B
                ImageDataP[post+1] = fg;    //G
                ImageDataP[post+2] = fr;    //R
            }
        }
        FreshFlg = 1;                       //与GlTaskStart()任务保持同步
    }
}

/***************************************************************************************************
                                任务函数:GlTaskStart
任务:GL将内存的颜色显示到显示屏
***************************************************************************************************/
void static GL_Display(void);       //显示处理回调函数
void static GL_Idle(void);          //CPU空闲时自动回调用的函数
//--------------------------------------------------------------------------------------------------
//函数功能:GL任务
void static GlTaskStart (void)
{
    #if OS_TASK_STAT_EN > 0
        OSStatInit();                               // Determine CPU capacity
    #endif

    //计算图像大小
    ImagelLength = ImageWidth *  3;                 //每个像素3字节
    while(  ImagelLength % 4 != 0 )                 //修正LineLength使其为4的倍数
    {
        ++ImagelLength;                             //每一行像素数据的长度若不是4的倍数则填充数据使它是4的倍数
    }
    ImagelLength *=  ImageHeight;                   //PixelLength = ImageWidth*3*ImageHeight

    //申请图像缓冲区
    ImageDataP = (GLubyte*)malloc(ImagelLength);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);    //修改了参数为GLUT_DOUBLE
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(X_SIZE,  Y_SIZE);
    glutCreateWindow("华丽的显示屏");               //窗口标题
    glutDisplayFunc(&GL_Display);
    glutIdleFunc(&GL_Idle);                         //新加入了这句
    FreshFlg = 1;
    glutMainLoop();

    free(ImageDataP);
    while (1)
    {
        printf("err : GL_TaskStart is backup");
        OSTimeDlyHMSM(0, 0, 2, 0);
    }
}

void static GL_Display(void)
{
    //glClear(GL_COLOR_BUFFER_BIT);//可以不要清屏,因为每次绘制时,画面都覆盖整个屏幕
    //绘制像素
    glDrawPixels(ImageWidth, ImageHeight,GL_BGR_EXT,GL_UNSIGNED_BYTE,ImageDataP);
    //完成绘制
    glutSwapBuffers();
}

void static GL_Idle(void)
{
    //在CPU空闲时调用. 在这里可以添加程序,使扫描速度降低。
    if(FreshFlg == 0)
    {
        return;
    }
    FreshFlg = 0;                                   //同步

    GL_Display();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值