擦除线条的SDL2功能?
SDL2 function that erases lines?
我正在制作一个创建线条的程序,如何删除线条?有它的功能吗?
我已经尝试使用 SDL_RenderClear()
但它没有用。
(请注意,我是初学者,我不是美国本土人,而且我只有 10 岁,所以请用简单的方式解释。)
这是我的行创建代码:
#include <iostream>
#include <SDL.h>
using namespace std;
int main( int argc, char * argv[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *janela = NULL;
SDL_Renderer *renderer = NULL;
bool roda = true;
SDL_Event evento;
int x;
int y;
int x2;
int y2;
janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);
while (roda) {
SDL_Event evento;
while (SDL_PollEvent(&evento)) {
switch(evento.type){
case SDL_QUIT:
roda = false;
break;
case SDL_MOUSEBUTTONDOWN:{
x = evento.motion.x;
y = evento.motion.y;
break;}
case SDL_MOUSEBUTTONUP:
while(roda){
x2 = evento.motion.x;
y2 = evento.motion.y;
SDL_SetRenderDrawColor(renderer , 255 , 0 , 0 , 255);
SDL_SetRenderDrawColor(renderer , 125 , 234 , 253 , 255);
SDL_RenderDrawLine(renderer , x , y , x2 , y2);
SDL_RenderPresent(renderer);
break;}
case SDL_KEYDOWN:{
switch(evento.key.keysym.sym){
case SDLK_b:{
SDL_RenderClear(renderer);
}
}
}
}
}
}
SDL_DestroyWindow(janela);
janela = NULL;
SDL_DestroyRenderer(renderer);
renderer = NULL;
SDL_Quit();
return 1;
}
我期望的是线条被擦除,但它并没有发生。
典型的主循环基本上是这样的:
while(!quit) {
while(pool_event()) {
// change state to react to event
}
clear_previous_frame();
for each line {
draw_line();
}
present();
}
因此,您应该始终清除并重新绘制线条,如果事件如此,则添加新的线条状态(但还没有绘制它 - 事件处理不应该这样做,否则它会变得非常 复杂)。保留前一帧的内容并添加更多行是有问题的;简短的解释是因为 SDL_RenderPresent documentation 说 The backbuffer should be considered invalidated after each present
(而长的解释基本上是一个列表,说明为什么这样说)。
要跟踪要绘制的线条,您需要将它们保存在某个地方。 std::vector
可能是一个简单的选择,如果您的要求不反对的话。
总而言之,您的问题修改后的代码加上一些注释:
#include <vector>
#include <SDL.h>
struct line {
int x0, y0, x1, y1;
};
int main( int argc, char * argv[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *janela = NULL;
SDL_Renderer *renderer = NULL;
bool roda = true;
int x;
int y;
janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);
std::vector<line> lines;
while (roda) {
SDL_Event evento;
while (SDL_PollEvent(&evento)) {
switch(evento.type){
case SDL_QUIT:
roda = false;
break;
case SDL_MOUSEBUTTONDOWN:
// save starting coordinates
x = evento.motion.x;
y = evento.motion.y;
break;
case SDL_MOUSEBUTTONUP: {
// add new line to draw
line l = { x, y, evento.motion.x, evento.motion.y };
lines.push_back(l);
} break;
case SDL_KEYDOWN:
if(evento.key.keysym.sym == SDLK_b) {
// drop lines
lines.resize(0);
}
break;
}
}
// clear previous contents - in most cases, screen content is
// invalidated after RenderPresent and you need to draw again
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // your 'clear' colour
SDL_RenderClear(renderer);
// draw all accumulated lines
SDL_SetRenderDrawColor(renderer, 125, 234, 253, 255); // your lines colour
for(const line &l : lines) {
SDL_RenderDrawLine(renderer, l.x0, l.y0, l.x1, l.y1);
}
// all drawn - present
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(janela);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0; // 0 is 'success' return code, non-0 is failure
}
我正在制作一个创建线条的程序,如何删除线条?有它的功能吗?
我已经尝试使用 SDL_RenderClear()
但它没有用。
(请注意,我是初学者,我不是美国本土人,而且我只有 10 岁,所以请用简单的方式解释。)
这是我的行创建代码:
#include <iostream>
#include <SDL.h>
using namespace std;
int main( int argc, char * argv[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *janela = NULL;
SDL_Renderer *renderer = NULL;
bool roda = true;
SDL_Event evento;
int x;
int y;
int x2;
int y2;
janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);
while (roda) {
SDL_Event evento;
while (SDL_PollEvent(&evento)) {
switch(evento.type){
case SDL_QUIT:
roda = false;
break;
case SDL_MOUSEBUTTONDOWN:{
x = evento.motion.x;
y = evento.motion.y;
break;}
case SDL_MOUSEBUTTONUP:
while(roda){
x2 = evento.motion.x;
y2 = evento.motion.y;
SDL_SetRenderDrawColor(renderer , 255 , 0 , 0 , 255);
SDL_SetRenderDrawColor(renderer , 125 , 234 , 253 , 255);
SDL_RenderDrawLine(renderer , x , y , x2 , y2);
SDL_RenderPresent(renderer);
break;}
case SDL_KEYDOWN:{
switch(evento.key.keysym.sym){
case SDLK_b:{
SDL_RenderClear(renderer);
}
}
}
}
}
}
SDL_DestroyWindow(janela);
janela = NULL;
SDL_DestroyRenderer(renderer);
renderer = NULL;
SDL_Quit();
return 1;
}
我期望的是线条被擦除,但它并没有发生。
典型的主循环基本上是这样的:
while(!quit) {
while(pool_event()) {
// change state to react to event
}
clear_previous_frame();
for each line {
draw_line();
}
present();
}
因此,您应该始终清除并重新绘制线条,如果事件如此,则添加新的线条状态(但还没有绘制它 - 事件处理不应该这样做,否则它会变得非常 复杂)。保留前一帧的内容并添加更多行是有问题的;简短的解释是因为 SDL_RenderPresent documentation 说 The backbuffer should be considered invalidated after each present
(而长的解释基本上是一个列表,说明为什么这样说)。
要跟踪要绘制的线条,您需要将它们保存在某个地方。 std::vector
可能是一个简单的选择,如果您的要求不反对的话。
总而言之,您的问题修改后的代码加上一些注释:
#include <vector>
#include <SDL.h>
struct line {
int x0, y0, x1, y1;
};
int main( int argc, char * argv[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *janela = NULL;
SDL_Renderer *renderer = NULL;
bool roda = true;
int x;
int y;
janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);
std::vector<line> lines;
while (roda) {
SDL_Event evento;
while (SDL_PollEvent(&evento)) {
switch(evento.type){
case SDL_QUIT:
roda = false;
break;
case SDL_MOUSEBUTTONDOWN:
// save starting coordinates
x = evento.motion.x;
y = evento.motion.y;
break;
case SDL_MOUSEBUTTONUP: {
// add new line to draw
line l = { x, y, evento.motion.x, evento.motion.y };
lines.push_back(l);
} break;
case SDL_KEYDOWN:
if(evento.key.keysym.sym == SDLK_b) {
// drop lines
lines.resize(0);
}
break;
}
}
// clear previous contents - in most cases, screen content is
// invalidated after RenderPresent and you need to draw again
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); // your 'clear' colour
SDL_RenderClear(renderer);
// draw all accumulated lines
SDL_SetRenderDrawColor(renderer, 125, 234, 253, 255); // your lines colour
for(const line &l : lines) {
SDL_RenderDrawLine(renderer, l.x0, l.y0, l.x1, l.y1);
}
// all drawn - present
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(janela);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0; // 0 is 'success' return code, non-0 is failure
}