我正在尝试使用SDL2库在C中编写自己的绘画。目前我正在试图弄清楚如何绘制一条直线。到目前为止,我可以“画它”,但我必须解决问题......“直线”是实际绘制线条的函数。但是,当我在
期间调用该函数时case SDL_MOUSEBUTTONUP:
它绘制了一条正确的线条,但我没有任何预览。相反,如果我在
中调用该函数case SDL_MOUSEMOTION:
我有“太多的预览/行”
这是我的整个代码:
#include <SDL2/SDL.h>
void putpixel(SDL_Surface *canvas, int x, int y, Uint32 pixel)
{
int byteperpixel = canvas->format->BytesPerPixel;
Uint8 *p = (Uint8*)canvas->pixels + y * canvas->pitch + x * byteperpixel;
// Adress to pixel
*(Uint32 *)p = pixel;
}
typedef struct RGBcolour
{
Uint8 r;
Uint8 g;
Uint8 b;
} RGBcolour; /* easier than handling 3 separate values */
void straightline(SDL_Surface *canvas,int wdth,int hght,int x0,int y0,int xn,int yn,RGBcolour c,int preview,SDL_Renderer *renderer)
{
int dx = abs(xn-x0), sx = x0<xn ? 1 : -1;
int dy = abs(yn-y0), sy = y0<yn ? 1 : -1;
int error = (dx>dy ? dx : -dy)/2, e2;
SDL_SetRenderDrawColor(renderer,c.r,c.g,c.b,255);
while(1)
{
/* draw point only if coordinate is valid */
if(preview==0)
{
if(x0>=0 && x0<wdth && y0>=0 && y0<hght) putpixel(canvas,x0,y0, SDL_MapRGB(canvas->format, c.r, c.g, c.b));
}
else
{
if(x0>=0 && x0<wdth && y0>=0 && y0<hght) SDL_RenderDrawPoint(renderer,x0,y0);
}
if(x0==xn && y0==yn) break;
e2 = error;
if(e2 >-dx) { error -= dy; x0 += sx; }
if(e2 < dy) { error += dx; y0 += sy; }
}
}
int main(int argc, char ** argv)
{
// variables
int width=640;
int height=480;
int quit = 0;
SDL_Event event;
// init SDL
SDL_Init(SDL_INIT_VIDEO);
SDL_Window * window = SDL_CreateWindow("Paint Program", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
SDL_Surface *canvas = NULL;
canvas = SDL_GetWindowSurface(window);
SDL_FillRect(canvas, NULL, SDL_MapRGB(canvas->format, 255, 255, 255));
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
// handle events
//we need an integer variable for each coordinate, and a boolean that indicates whether a line is being drawn (i.e. whether the left mouse button is pressed):
int x1 = 0;
int y1 = 0;
int x2 = 0;
int y2 = 0;
int drawing = 0;
RGBcolour color;
color.r= 0;
color.g= 255;
color.b= 0;
while (!quit)
{
SDL_PollEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = 1;
break;
// TODO input handling code goes here
//Handlers for when the left mouse button is pressed and released. This involves switching the drawing flag. However, when the left mouse button is pressed (i.e. when a new line is started), we also need to record the current cursor position as (x1, y1), and reset the value of (x2, y2).
case SDL_MOUSEBUTTONDOWN:
switch (event.button.button)
{
case SDL_BUTTON_LEFT:
x1 = event.motion.x;
y1 = event.motion.y;
x2 = event.motion.x;
y2 = event.motion.y;
drawing = 1;
break;
}
break;
case SDL_MOUSEBUTTONUP:
switch (event.button.button)
{
case SDL_BUTTON_LEFT:
straightline(canvas,width, height, x1, y1, x2, y2,color,0,renderer);
drawing = 0;
break;
}
break;
//Mouse movement handler. Updates the value of (x2,y2) while the left mouse button is pressed, giving a feel that the line is being dragged.
case SDL_MOUSEMOTION:
if (drawing)
{
x2 = event.motion.x;
y2 = event.motion.y;
//SDL_SetRenderDrawColor( renderer, 0xFF, 0xFF, 0xFF, 0xFF );
/* Clear the entire screen to our selected colour */
straightline(canvas,width, height, x1, y1, x2, y2,color,1,renderer);
}
break;
}
// clear window
//SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
//SDL_RenderClear(renderer);
// render window
SDL_UpdateWindowSurface(window);
SDL_RenderPresent(renderer);
}
// cleanup SDL
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}