一个OPENGL的简单程序,其中DrawCircle函数无法绘制出圆,请大神们帮忙修改下,谢谢!

lyflyflee 2015-04-13 10:53:10

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <gl/glut.h>

const int kWindowLeft = 50,
kWindowTop = 50,
kWindowRight = 960,
kWindowBottom = 535;

const int kWindowHeight = kWindowBottom - kWindowTop,
kWindowWidth = kWindowRight - kWindowLeft;


bool gDone; // set to true when the program is finished
HINSTANCE thisAppInstance; // a handle for this application instance
HWND gMainWindowHandle = NULL; // handle to main window
HDC gWindowDC; // handle to main window drawing context (all drawing operations use this)

int gTestCase;
POINT gStartPt, gEndPt;

int EventLoop(void);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void HandleUpdate ();
void HandleKeyPress(WPARAM theChar);
void PlotPixel(int x, int y);
void myDDALine(int x1, int y1, int x2, int y2);
void myBresLine(int x1, int y1, int x2, int y2);
void testLine(int index, POINT start, POINT end);
void DrawContent();
void DrawCircle(int cx, int cy, int radius);

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
thisAppInstance = hInstance;
WNDCLASSEX win_class;
// Fill in the Window class fields
win_class.cbSize = sizeof(WNDCLASSEX);
win_class.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
win_class.lpfnWndProc = (WNDPROC)WndProc;
win_class.cbClsExtra = 0;
win_class.cbWndExtra = 0;
win_class.hInstance = hInstance;
win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
win_class.lpszMenuName = NULL;
win_class.lpszClassName = TEXT("MAIN");
win_class.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if (!RegisterClassEx(&win_class))
{
MessageBox(NULL, TEXT("Window registration failed."), TEXT("ERROR"),
MB_ICONEXCLAMATION | MB_OK);
return(0);
}

gMainWindowHandle = CreateWindowEx(0,
TEXT("MAIN"),
TEXT("Computer Assig2"),
WS_OVERLAPPED | WS_SYSMENU,
kWindowLeft,
kWindowTop,
kWindowWidth,
kWindowHeight,
NULL,
NULL,
hInstance,
NULL);

if (NULL == gMainWindowHandle)
{
MessageBox(NULL, TEXT("Window creation failed."), TEXT("ERROR"),
MB_ICONEXCLAMATION | MB_OK);
return(0);
}


// Display the main window
ShowWindow(gMainWindowHandle, nCmdShow);
UpdateWindow(gMainWindowHandle);

// call the application event loop - when this terminates, the program terminates
return EventLoop();

}

int EventLoop (void)
{
MSG msg; // Windows message

// event loop - stay in this loop (processing events) until the user quits the program
// by closing the window
while (!gDone)
{
// check message queue
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// if it is a Windows quit message, stop
if (WM_QUIT == msg.message)
break;

// translate and dispatch message
TranslateMessage(&msg);
DispatchMessage(&msg);
}

// Do application-specific stuff here
}
return(msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
// Process the message
switch (msg)
{
// Check for window closing
case WM_CLOSE:
case WM_DESTROY:
{
// Post a quit message on the queue
PostQuitMessage(0);
break;
}

// Check for a keypress - any key press means quit
case WM_CHAR:
{
gDone = true;
break;
}

case WM_PAINT:
{
HandleUpdate();
break;
}

default:
{
// Handle any unprocessed message
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}

return(0);
}

void HandleUpdate ()
{
PAINTSTRUCT ps;
gWindowDC = BeginPaint(gMainWindowHandle, &ps);
DrawContent(); // Draw the picture
EndPaint(gMainWindowHandle, &ps);
}

void PlotPixel(int x, int y)
{
SetPixelV(gWindowDC, x, y, RGB(0, 0, 0));
}

void SetPt(POINT *thePoint, int px, int py)
{
thePoint->x = px;
thePoint->y = py;
}

void testLine(int index, POINT start, POINT end)
{
RECT r;

// calculate the offsets so that each line case is drawn in a different part of the window
int xoffset = ((index % 6) * 150) + 4;
int yoffset = ((index / 6) * 150) + 4;


// draw a small red square at the "start" of the line
SetRect (&r, start.x+xoffset-2, start.y+yoffset-2, start.x+xoffset+3, start.y+yoffset+3);
HBRUSH theBrush = CreateSolidBrush(RGB(255, 0, 0));
HBRUSH oldBrush = (HBRUSH) SelectObject(gWindowDC, theBrush);
FillRect(gWindowDC, &r, theBrush);


// draw a small cyan square at the "end" of the line
SetRect (&r, end.x+xoffset-2, end.y+yoffset-2, end.x+xoffset+3, end.y+yoffset+3);
theBrush = CreateSolidBrush(RGB(0, 255, 0));
FillRect(gWindowDC, &r, theBrush);


// draw a black frame around the test area
SetRect (&r, xoffset, yoffset, xoffset+145, yoffset+145);
theBrush = CreateSolidBrush(RGB(0, 0, 0));
FrameRect(gWindowDC, &r, theBrush);


// now call the actual line drawing function
//作业1:
myDDALine(start.x+xoffset, start.y+yoffset, end.x+xoffset, end.y+yoffset);
//作业2:
//myBresLine (start.x+xoffset, start.y+yoffset, end.x+xoffset, end.y+yoffset);


// delete the windows brush we created
SelectObject(gWindowDC, oldBrush);
DeleteObject(theBrush);

}

void DrawContent()
{
int i = 0;


// case 0 - left-to-right horizontal line
// --------------------------------------------------------------------
SetPt(&gStartPt, 10, 75);
SetPt(&gEndPt, 135, 75);
testLine(i++, gStartPt, gEndPt);


// case 1 - right-to-left horizontal line
// --------------------------------------------------------------------
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 75, 10);
SetPt(&gEndPt, 75, 135);
testLine(i++, gStartPt, gEndPt);
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 10, 100);
SetPt(&gEndPt, 135, 50);
testLine(i++, gStartPt, gEndPt);
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 10, 50);
SetPt(&gEndPt, 135, 100);
testLine(i++, gStartPt, gEndPt);
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 50, 135);
SetPt(&gEndPt, 100, 10);
testLine(i++, gStartPt, gEndPt);
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 50, 10);
SetPt(&gEndPt, 100, 135);
testLine(i++, gStartPt, gEndPt);
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 10, 135);
SetPt(&gEndPt, 135, 10);
testLine(i++, gStartPt, gEndPt);
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 10, 10);
SetPt(&gEndPt, 135, 135);
testLine(i++, gStartPt, gEndPt);
testLine(i++, gEndPt, gStartPt);
SetPt(&gStartPt, 75, 75);
SetPt(&gEndPt, 75, 75);
testLine(i++, gStartPt, gEndPt);

DrawCircle(kWindowWidth-75,kWindowHeight-100, 50);
}

void myDDALine (int x1, int y1, int x2, int y2)
{
int dx=x2-x1,dy=y2-y1,steps,k;
float xIncrement,yIncrement,x=x1,y=y1;
if(abs(dx)>abs(dy))
steps=abs(dx);
else
steps=abs(dy);
xIncrement=float(dx)/float(steps);
yIncrement=float(dy)/float(steps);
for(k=0;k<steps;k++)
{
x+=xIncrement;
y+=yIncrement;
PlotPixel(int(x+0.5), int(y+0.5));
}
}

void myBresLine (int x1, int y1, int x2, int y2)
{
int xa = x1; // make copies of the end-points that you can modify
int ya = y1;
int xb = x2;
int yb = y2;

int dx = xb - xa, dy = yb - ya;
int p = 2 * dy - dx;
int twoDy = 2 * dy, twoDyDx = 2 * (dy - dx);
int x, y, xEnd;

x = xa;
y = ya;
// plot the first pixel
PlotPixel(x, y);

while (x < xb)
{
x++;
if (p < 0)
p += twoDy;
else
{
y++;
p += twoDyDx;
}
PlotPixel(x, y);
}
}

class screenPt
{
private:
GLint x,y;
public:
screenPt(){
x = y =0;
}
void setCoords(GLint xCoordValue,GLint yCoordValue){
x = xCoordValue;
y = yCoordValue;
}

GLint getx() const
{
return x;
}
GLint gety() const
{
return y;
}
void incrementx()
{
x++;
}
void decrementy()
{
y--;
}
};

void setPixel(GLint xCoord,GLint yCoord)
{
glBegin(GL_POINTS);
glVertex2i(xCoord,yCoord);
glEnd();
glFlush();
}

void DrawCircle(GLint xc,GLint yc,GLint radius)
{
glColor3f(1.0,0.0,0.0);
screenPt circPt;
GLint p = 1 - radius;
circPt.setCoords(0,radius)
void circlePlotPoints(GLint,GLint,screenPt);
circlePlotPoints(xc,yc,circPt);
while(circPt.getx()< circPt.gety())
{
circPt.incrementx();
if (p<0){
p += 2*circPt.getx() + 1;
}
else{
circPt.decrementy();
p += 2*(circPt.getx() - circPt.gety()) + 1;
}
circlePlotPoints(xc,yc,circPt);
}
}

void circlePlotPoints(GLint xc,GLint yc,screenPt circPt)
{
setPixel(xc + circPt.getx(),yc + circPt.gety());
setPixel(xc - circPt.getx(),yc + circPt.gety());
setPixel(xc + circPt.getx(),yc - circPt.gety());
setPixel(xc - circPt.getx(),yc - circPt.gety());
setPixel(xc + circPt.gety(),yc + circPt.getx());
setPixel(xc - circPt.gety(),yc + circPt.getx());
setPixel(xc + circPt.gety(),yc - circPt.getx());
setPixel(xc - circPt.gety(),yc - circPt.getx());
}


其他部分均可正常显示,但圆画不出
...全文
313 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-04-15
  • 打赏
  • 举报
回复
有时不将“调用函数名字+各参数值,进入函数后各参数值,中间变量值,退出函数前准备返回的值,返回函数到调用处后函数名字+各参数值+返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的,包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行! 写日志到文件参考下面:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
    #include <windows.h>
    #include <io.h>
#else
    #include <unistd.h>
    #include <sys/time.h>
    #include <pthread.h>
    #define  CRITICAL_SECTION   pthread_mutex_t
    #define  _vsnprintf         vsnprintf
#endif
//Log{
#define MAXLOGSIZE 20000000
#define MAXLINSIZE 16000
#include <time.h>
#include <sys/timeb.h>
#include <stdarg.h>
char logfilename1[]="MyLog1.log";
char logfilename2[]="MyLog2.log";
static char logstr[MAXLINSIZE+1];
char datestr[16];
char timestr[16];
char mss[4];
CRITICAL_SECTION cs_log;
FILE *flog;
#ifdef WIN32
void Lock(CRITICAL_SECTION *l) {
    EnterCriticalSection(l);
}
void Unlock(CRITICAL_SECTION *l) {
    LeaveCriticalSection(l);
}
#else
void Lock(CRITICAL_SECTION *l) {
    pthread_mutex_lock(l);
}
void Unlock(CRITICAL_SECTION *l) {
    pthread_mutex_unlock(l);
}
#endif
void LogV(const char *pszFmt,va_list argp) {
    struct tm *now;
    struct timeb tb;

    if (NULL==pszFmt||0==pszFmt[0]) return;
    _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);
    ftime(&tb);
    now=localtime(&tb.time);
    sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);
    sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );
    sprintf(mss,"%03d",tb.millitm);
    printf("%s %s.%s %s",datestr,timestr,mss,logstr);
    flog=fopen(logfilename1,"a");
    if (NULL!=flog) {
        fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);
        if (ftell(flog)>MAXLOGSIZE) {
            fclose(flog);
            if (rename(logfilename1,logfilename2)) {
                remove(logfilename2);
                rename(logfilename1,logfilename2);
            }
        } else {
            fclose(flog);
        }
    }
}
void Log(const char *pszFmt,...) {
    va_list argp;

    Lock(&cs_log);
    va_start(argp,pszFmt);
    LogV(pszFmt,argp);
    va_end(argp);
    Unlock(&cs_log);
}
//Log}
int main(int argc,char * argv[]) {
    int i;
#ifdef WIN32
    InitializeCriticalSection(&cs_log);
#else
    pthread_mutex_init(&cs_log,NULL);
#endif
    for (i=0;i<10000;i++) {
        Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);
    }
#ifdef WIN32
    DeleteCriticalSection(&cs_log);
#else
    pthread_mutex_destroy(&cs_log);
#endif
    return 0;
}
//1-78行添加到你带main的.c或.cpp的那个文件的最前面
//81-85行添加到你的main函数开头
//89-93行添加到你的main函数结束前
//在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中
lyflyflee 2015-04-14
  • 打赏
  • 举报
回复
没有人吗?真心解决不了。。
lyflyflee 2015-04-13
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
搜网络教程“学OpenGL编3D游戏”。
这个可以直接粘贴进去运行,大神能否帮忙看下到底是什么问题?
lyflyflee 2015-04-13
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
搜网络教程“学OpenGL编3D游戏”。
这是教科书上的一个例子,但我敲进去以后这个圆就是出不来。我也在网上找了半天,但没有一点头绪啊
赵4老师 2015-04-13
  • 打赏
  • 举报
回复
搜网络教程“学OpenGL编3D游戏”。
lyflyflee 2015-04-13
  • 打赏
  • 举报
回复
只需要看DrawCircle一个函数。
lyflyflee 2015-04-13
  • 打赏
  • 举报
回复
求大神们给点修改意见,实在不知道圆为什么画不出

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧