【计算机图形学】1-1 Windows下准备工作 1

一、准备工作

编程语言:C

IDECode::Blocks10.05

工程类型:Consoleapplication

代码文件中重复部分不会重复贴出。

1.Windows环境

编译目标配置:

链接库:

gdi32

user32

kernel32

Win_Debug

加入宏定义

DEBUG

SYSTEM_WIN

Win_Release

加入宏定义:

SYSTEM_WIN

1)基本定义和main函数

文件:define.h

#ifndef DEFINE_H_INCLUDED
#define DEFINE_H_INCLUDED

typedef short        int16;
typedef int         int32;
typedef long long      int64;
typedef unsigned short   uint16;
typedef unsigned int    uint32;
typedef unsigned long long uint64;

#endif // DEFINE_H_INCLUDED

在该文件中目前定义了最基本的几个数据类型。基本上工程中所有文件都要包含这个头文件。


文件:gui.h

#ifndef GUI_H_INCLUDED
#define GUI_H_INCLUDED

#if defined(SYSTEM_WIN)
#include "gui_windows.h"
#endif

#endif // GUI_H_INCLUDED

图形界面实现的选择,在定义了SYSTEM_WIN的情况下直接用WindowsAPI编程。


文件:gui_windows.h

#ifndef GUI_WINDOWS_H_INCLUDED
#define GUI_WINDOWS_H_INCLUDED

#include <windows.h>
#include "define.h"

#define main fake_main

int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

#endif // GUI_WINDOWS_H_INCLUDED

因为windows的程序入口是WinMain(...),这里使用了宏定义,当写main函数的时候会被改名为fake_main,而在WinMain中调用fake_main函数,这样就可以像平常一样写main函数,而不用管GUI的实现了。


文件:gui_windows.c

#include "gui_windows.h"

int WINAPI WinMain(HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          PSTR szCmdLine,
          int iCmdShow)
{
  fake_main();
  return 0;
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
}

目前还没写实际的东西。


2)主窗口的创建

文件:gui_windows.h

#ifndef GUI_WINDOWS_H_INCLUDED
#define GUI_WINDOWS_H_INCLUDED

#include <windows.h>
#include "define.h"

#define main fake_main

int fake_main();
int WINAPI WinMain(HINSTANCE, HINSTANCE, PSTR, int);
LRESULT CALLBACK gui_mainProcess(HWND, UINT, WPARAM, LPARAM);
void gui_createMainWindow(const char *);
void gui_mainLoop();

#endif // GUI_WINDOWS_H_INCLUDED

文件:gui_windows.c

#include "gui_windows.h"

static HINSTANCE mainInstance;

int WINAPI WinMain(HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          PSTR szCmdLine,
          int iCmdShow)
{
  mainInstance = hInstance;
  return fake_main();
}

void gui_createMainWindow(const char *title)
{
  WNDCLASS mainWindow;
  mainWindow.style      = CS_HREDRAW | CS_VREDRAW;
  mainWindow.lpfnWndProc   = gui_mainProcess;
  mainWindow.cbClsExtra    = 0;
  mainWindow.cbWndExtra    = 0;
  mainWindow.hInstance    = mainInstance;
  mainWindow.hIcon      = LoadIcon(NULL, IDI_APPLICATION);
  mainWindow.hCursor     = LoadCursor(NULL, IDC_ARROW);
  mainWindow.hbrBackground  = (HBRUSH)GetStockObject(BLACK_BRUSH);
  mainWindow.lpszMenuName   = NULL;
  mainWindow.lpszClassName  = "mainWindow";
  if(!RegisterClass(&mainWindow))
  {
    MessageBox(NULL, TEXT("Cannot register class for main window."), TEXT(title), MB_ICONERROR);
    exit(0);
  }
  HWND handleMainWindow;
  handleMainWindow = CreateWindow("mainWindow",
                  title,
                  WS_OVERLAPPEDWINDOW,
                  CW_USEDEFAULT,
                  CW_USEDEFAULT,
                  CW_USEDEFAULT,
                  CW_USEDEFAULT,
                  NULL,
                  NULL,
                  mainInstance,
                  NULL);
  ShowWindow(handleMainWindow, 1);
  UpdateWindow(handleMainWindow);
}

void gui_mainLoop()
{
  MSG message;
  while(GetMessage(&message, NULL, 0, 0))
  {
    TranslateMessage(&message);
    DispatchMessage(&message);
  }
}

LRESULT CALLBACK gui_mainProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  HDC hdc ;
  PAINTSTRUCT ps ;
  RECT rect ;
  switch (message)
  {
  case WM_PAINT:
    hdc = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rect);
    EndPaint(hwnd, &ps) ;
    break;
  case WM_DESTROY:
    PostQuitMessage(0) ;
    break;
  }
  return DefWindowProc (hwnd, message, wParam, lParam) ;
}

文件:main.c

#include <stdio.h>
#include <stdlib.h>
#include "gui.h"

int main()
{
  gui_createMainWindow("ZPIC");
  gui_mainLoop();
  return 0;
}

由于与图形学无关,这里只需知道在main函数中使用这两个函数就可以创建主窗口了。

3)主窗口的基本参数设置

文件:gui_windows.h

#ifndef GUI_WINDOWS_H_INCLUDED
#define GUI_WINDOWS_H_INCLUDED

#include <assert.h>
#include <windows.h>
#include "define.h"

#define main fake_main

void gui_setMainWindowPosition(int32 x, int32 y);
void gui_setMainWindowSize(int32 w, int32 h);
void gui_setMainWindowToCenter();
void gui_setMainWindowMinimize();
void gui_setMainWindowMaximize();
void gui_setMainWindowRestore();

#endif // GUI_WINDOWS_H_INCLUDED

文件:gui_windows.c

#include "gui_windows.h"

static HINSTANCE mainInstance;
static HWND handleMainWindow;
static int32 systemWidth, systemHeight;

int WINAPI WinMain(HINSTANCE hInstance,
          HINSTANCE hPrevInstance,
          PSTR szCmdLine,
          int iCmdShow)
{
  mainInstance = hInstance;
  systemWidth = GetSystemMetrics(SM_CXSCREEN);
  systemHeight = GetSystemMetrics(SM_CYSCREEN);
  return fake_main();
}

void gui_setMainWindowPosition(int32 x, int32 y)
{
  assert(handleMainWindow != NULL);
  SetWindowPos(handleMainWindow, NULL, x, y, 0, 0, SWP_NOSIZE);
}

void gui_setMainWindowSize(int32 w, int32 h)
{
  assert(handleMainWindow != NULL);
  SetWindowPos(handleMainWindow, NULL, 0, 0, w, h, SWP_NOMOVE);
}

void gui_setMainWindowToCenter()
{
  assert(handleMainWindow != NULL);
  RECT rect;
  GetWindowRect(handleMainWindow, &rect);
  int32 w = rect.right - rect.left;
  int32 h = rect.bottom - rect.top;
  gui_setMainWindowPosition((systemWidth - w) >> 1, (systemHeight - h) >> 1);
}

void gui_setMainWindowMinimize()
{
  assert(handleMainWindow != NULL);
  SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_MINIMIZE, (LPARAM)NULL);
}

void gui_setMainWindowMaximize()
{
  assert(handleMainWindow != NULL);
  SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_MAXIMIZE, (LPARAM)NULL);
}

void gui_setMainWindowRestore()
{
  assert(handleMainWindow != NULL);
  SendMessage(handleMainWindow, WM_SYSCOMMAND, SC_RESTORE, (LPARAM)NULL);
}


文件:main.c

#include <stdio.h>
#include <stdlib.h>
#include "gui.h"

int main()
{
  #ifndef DEBUG
    freopen("log.txt", "w", stdout);
  #endif
  freopen("error.txt", "w", stderr);
  gui_createMainWindow("ZPIC");
  gui_setMainWindowSize(800, 600);
  gui_setMainWindowToCenter();
  gui_setMainWindowMaximize();
  gui_mainLoop();
  return 0;
}

由于与图形学无关,这里只需知道函数名及相应功能即可。

4基本消息获取结构

文件:gui_windows.h

void gui_setDisplayFunction(void (*func)(void));
void gui_setReshapeFunction(void (*func)(int32 w, int32 h));
void gui_setKeyboardFunction(void (*func)(unsigned char key, int32 x, int32 y));
void gui_setMouseFunction(void (*func)(int32 button, int32 state, int32 x, int32 y));
void gui_setMotionFunction(void (*func)(int32 x, int32 y));

文件:gui_windows.c

static void (*mainWindowDisplayFunction)();
static void (*mainWindowReshapeFunction)(int32, int32);
static void (*mainWindowKeyboardFunction)(unsigned char, int32, int32);
static void (*mainWindowMouseFunction)(int32, int32, int32, int32);
static void (*mainWindowMotionFunction)(int32, int32);

void gui_setDisplayFunction(void (*func)(void))
{
  mainWindowDisplayFunction = func;
}

void gui_setReshapeFunction(void (*func)(int32 w, int32 h))
{
  mainWindowReshapeFunction = func;
}

void gui_setKeyboardFunction(void (*func)(unsigned char key, int32 x, int32 y))
{
  mainWindowKeyboardFunction = func;
}

void gui_setMouseFunction(void (*func)(int32 button, int32 state, int32 x, int32 y))
{
  mainWindowMouseFunction = func;
}

void gui_setMotionFunction(void (*func)(int32 x, int32 y))
{
  mainWindowMotionFunction = func;
}


文件:main.c

#include <stdio.h>
#include <stdlib.h>
#include "define.h"
#include "gui.h"

void displayFunction(void)
{
  //TODO
}

void reshapeFunction(int32 w, int32 h)
{
  //TODO
}

void keyboardFunction(unsigned char key, int32 x, int32 y)
{
  //TODO
}

void mouseFunction(int32 button, int32 state, int32 x, int32 y)
{
  //TODO
}

void motionFunction(int32 x, int32 y)
{
  //TODO
}

int main()
{
  #ifndef DEBUG
    freopen("log.txt", "w", stdout);
  #endif
  freopen("error.txt", "w", stderr);

  gui_createMainWindow("ZPIC");
  gui_setMainWindowSize(800, 600);
  gui_setMainWindowToCenter();

  gui_setDisplayFunction(displayFunction);
  gui_setReshapeFunction(reshapeFunction);
  gui_setKeyboardFunction(keyboardFunction);
  gui_setMouseFunction(mouseFunction);
  gui_setMotionFunction(motionFunction);

  gui_mainLoop();
  return 0;
}

5)基本绘制条件

添加上鼠标事件的监控和像素点的绘制后,就满足了基本的学习条件。

文件:define.h

typedef uint16 z_color;

static const int32 MOUSE_LEFT   = 0;
static const int32 MOUSE_MIDDLE  = 1;
static const int32 MOUSE_RIGHT  = 2;
static const int32 MOUSE_DOWN   = 3;
static const int32 MOUSE_UP    = 4;

文件:gui_windows.h

void gui_repaint(void);
void gui_setPixel(int x, int y, int r, int g, int b);
z_color gui_getPixel(int x, int y);

文件:gui_windows.c

void gui_repaint(void)
{
  InvalidateRect(handleMainWindow, NULL, TRUE);
  UpdateWindow(handleMainWindow);
}

void gui_setPixel(int x, int y, int r, int g, int b)
{
  COLORREF color = RGB(r, g, b);
  SetPixel(handleMainWindowDeviceContext, x, y, color);
}

z_color gui_getPixel(int x, int y)
{
  return GetPixel(handleMainWindowDeviceContext, x, y);
}

LRESULT CALLBACK gui_mainProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  PAINTSTRUCT ps;
  RECT rect;
  switch (message)
  {
  case WM_PAINT:
    handleMainWindowDeviceContext = BeginPaint(hwnd, &ps);
    GetClientRect(hwnd, &rect);
    if(mainWindowDisplayFunction)
    {
      mainWindowDisplayFunction();
    }
    EndPaint(hwnd, &ps) ;
    break;
  case WM_MOUSEMOVE:
    if(mainWindowMotionFunction)
    {
      mainWindowMotionFunction(LOWORD(lParam), HIWORD(lParam));
    }
    break;
  case WM_LBUTTONDOWN:
    if(mainWindowMouseFunction)
    {
      mainWindowMouseFunction(MOUSE_LEFT, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
    }
    break;
  case WM_LBUTTONUP:
    if(mainWindowMouseFunction)
    {
      mainWindowMouseFunction(MOUSE_LEFT, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
    }
    break;
  case WM_RBUTTONDOWN:
    if(mainWindowMouseFunction)
    {
      mainWindowMouseFunction(MOUSE_RIGHT, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
    }
    break;
  case WM_RBUTTONUP:
    if(mainWindowMouseFunction)
    {
      mainWindowMouseFunction(MOUSE_RIGHT, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
    }
    break;
  case WM_MBUTTONDOWN:
    if(mainWindowMouseFunction)
    {
      mainWindowMouseFunction(MOUSE_MIDDLE, MOUSE_DOWN, LOWORD(lParam), HIWORD(lParam));
    }
    break;
  case WM_MBUTTONUP:
    if(mainWindowMouseFunction)
    {
      mainWindowMouseFunction(MOUSE_MIDDLE, MOUSE_UP, LOWORD(lParam), HIWORD(lParam));
    }
    break;
  case WM_KEYDOWN:
    break;
  case WM_KEYUP:
    break;
  case WM_MOUSEWHEEL:
    break;
  case WM_DESTROY:
    PostQuitMessage(0) ;
    break;
  }
  return DefWindowProc (hwnd, message, wParam, lParam) ;
}


查看完整代码:http://blog.csdn.net/cyberzhg/article/details/7720282

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值