CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - C++Builder blokuje rysowanie pikseli na niektórych obszarach

C++Builder blokuje rysowanie pikseli na niektórych obszarach

dział ogólny

C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez lukagrom » czwartek, 9 sierpnia 2018, 11:43

Do rzeczy. Od dłuższego czasu "dziergam" różne graficzne przekształcenia, polegające na wkomponowaniu matematyki, geometrii do metod graficznych środowiska. Najczęściej korzystam, z książek Andrzeja Stasiewicza, gdzie autor pokazuje jak można wdrożyć powyższe środowisko do badań przyrodniczo-naukowych. Od pewnego czasu, coś z moimi Builderami (C++ Builder 6, 10.1 Berlin), stało się dziwnego, po prostu przestały nagle wykreślać piksele na niektórych powierzchniach formy (w mietodzie OnPaint), jak i na komponentach typu - PaintBox. Może przedstawię prosty przykład książkowy. Za pomocą równań liniowych, poprzez odpowiednie współczynniki, można wykreślić miła dla oka figurę - smoka.
W tym celu wykorzystuje się przez napisaną przez autora klasę, służąca skalowaniu obrazu, na wymiar z realnego na komputerowy i na odwrót:
KOD cpp:     UKRYJ  
class TSkalowanie
{
        private:
        double A,B,C,D;
        double E,F,G,H;
        public:
        TSkalowanie(int xe0, int ye0,int eszer,int ewys,double xr0,double yr0,
        double rszer, double rwys);
        int daj_ekr_x(double xr);
        int daj_ekr_y(double yr);
        double daj_real_x(int xe);
    double daj_real_y(int ye);
};


TSkalowanie::TSkalowanie(int xe0, int ye0, int eszer, int ewys, double xr0,
double yr0, double rszer, double rwys)
{
        A=(double) eszer/rszer;
        B=(double) xe0-A*(xr0-rszer/2.);
        C=-(double) ewys/rwys;
        D=(double)ye0-C*(yr0+rwys/2.);
        E=rszer/(double)eszer;
        F=xr0-rszer/2.-E*(double)xe0;
        G=-rwys/(double)ewys;
        H=yr0+rwys/2.-G*(double)ye0;
}
int TSkalowanie::daj_ekr_x(double x)
{
        return (int)(A*x+B);
}
int TSkalowanie::daj_ekr_y(double y)
{
        return (int)(C*y+D);

}
double TSkalowanie::daj_real_x(int xe)
{
        return E*xe+F;
}
double TSkalowanie::daj_real_y(int ye)
{
    return G*ye+H;
}
 

I teraz w C++ Builder, po uprzednim dodaniu bibliotek -
Kod: Zaznacz cały
#include <math.h> , #include <stdlib.h> i #include "skala.h"
korzystając z iteracyjnych przekształceń wg treści książki, przystępuję do wykreślania smoka:
KOD cpp:     UKRYJ  
void __fastcall TForm1::FormPaint(TObject *Sender)
{
 const int max_iter=100000,max_il_przekszt=2;
                                 const double
                                         A[]={0.824074,0.088272},
                                         B[]={0.281482,0.520988},
                                         C[]={-0.212346,-0.463889},
                                         D[]={0.864198,-0.377778},
                                         E[]={-1.88229,0.785360},
                                         F[]={-0.110607,8.095795};

                                 TSkalowanie skal(0,0,ClientWidth,ClientWidth,0,5,15,15);
                                 int i,nr_przekszt,xe,ye;
                                 double x,y,x1;
                                 x=0,y=0;
                                 for(i=0;i<max_iter;i++)
                                 {
                                         ;
                                         nr_przekszt=random(max_il_przekszt);
                                         x1=A[nr_przekszt]*x+B[nr_przekszt]*y+E[nr_przekszt];
                                         y=C[nr_przekszt]*x+D[nr_przekszt]*y+F[nr_przekszt];
                                         x=x1;
                                         xe=skal.daj_ekr_x(x);
                                         ye=skal.daj_ekr_y(y);

                                         Canvas->Pixels[xe][ye]=clBlack;
                                 }
}
 

To samo mogę uczynić dla PaintBoxa i rezultat jest analogiczny. "Smok" jest przecięty w pionie obszarem, gdzie piksele nie są wpuszczane.
https://www.fotosik.pl/zdjecie/d8af104665423ef8

Wcześniej, wszystko bywało OK, a obecnie tnie mi C++ Builder, każdą strukturę jako wykreślam począwszy, od wykresu funkcji czy fraktala i zawsze w obszarach pasów pionowych. Sprawdzałem kod wielokrotnie, klasę także, aż w końcu spróbowałem poprzenosić przykłady na Visual C++, wykorzystując tą samą skalującą klasę.
KOD cpp:     UKRYJ  
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
                                 System::Drawing::Color kolor;
                                 Graphics^ g1=panel1->CreateGraphics();
                                 Bitmap^ bitmapa=gcnew Bitmap(panel1->Width,panel1->Height);
                                 kolor=System::Drawing::Color::Black;
                                 const int max_iter=100000,max_il_przekszt=2;
                                 const double
                                         A[]={0.824074,0.088272},
                                         B[]={0.281482,0.520988},
                                         C[]={-0.212346,-0.463889},
                                         D[]={0.864198,-0.377778},
                                         E[]={-1.88229,0.785360},
                                         F[]={-0.110607,8.095795};

                                 TSkalowanie skal(0,0,panel1->Width,panel1->Height,0,5,15,15);
                                 int i,nr_przekszt,xe,ye;
                                 double x,y,x1;
                                 x=0,y=0;
                                 for(i=0;i<max_iter;i++)
                                 {
                                         ;
                                         nr_przekszt=rand()%max_il_przekszt;
                                         x1=A[nr_przekszt]*x+B[nr_przekszt]*y+E[nr_przekszt];
                                         y=C[nr_przekszt]*x+D[nr_przekszt]*y+F[nr_przekszt];
                                         x=x1;
                                         xe=skal.daj_ekr_x(x);
                                         ye=skal.daj_ekr_y(y);
                                         bitmapa->SetPixel(xe,ye,kolor);
                                 }

                                 g1->DrawImage(dynamic_cast<Image^>(bitmapa),10,10);
                         }
 

Rezultat o dziwo prawidłowy:
https://www.fotosik.pl/zdjecie/df0ea3da9b5d1feb
Podobnie inne przekształcenia graficzne, na Visualu wykręslają się poprawnie, a na C++ Buildera-ch częściowo są zamazywane w pionowych pasach. Czy przyczyną może być jakaś zmiana ustawień środowiska? Jakieś buforowanie grafiki, dla określonej rozdzielczości? Dziwne, że programy dedykowane na C++ Builder, po korektach płynnie pracują na Visual C++, a na macierzystym środowisku, następują przeszkody w postaci obszarów, których nie obejmuje wykreślanie punktów.
PS. Zastosowałem znacznik URL, ponieważ Img - pokazywał błąd - "Określenie wymiarów obrazka nie było mozliwe"
Avatar użytkownika
lukagrom
Homos antropiczny
Homos antropiczny
 
Posty: 73
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 7
Otrzymał podziękowań: 4
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez polymorphism » czwartek, 9 sierpnia 2018, 19:17

To TForm1::FormPaint to obsługa zdarzenia OnPaint? Jeśli tak, to niewykluczone, że ustawiony jest clipping region na obszar okna i dlatego nie rysuje wszystkiego.

Wersja VC jest, jak by nie patrzeć, inna od tej z CppB. Podejrzewam, że jak byś napisał analogiczny kod, czyli malował w onclicku po bitmapie, którą później wrzucasz na okno, to też by działał.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2177
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 203
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    UbuntuFirefox

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez lukagrom » czwartek, 9 sierpnia 2018, 20:41

To jakaś kpina. Nigdy, żadnego syfu typu, nie mogę wpisywać pikseli w jakiś obszar ekranu nie miałem. Co to jest owe cliping region? Narzędzie Microsoftu bym zakupił kolejną wersję Windy, czy może Embarcadero dopominaina się, aby kupić pełną wersję środowiska? Dlaczego ten shift mam dopiero od nie dawna?!? Wcześniej kreśliłem w Builderach najbardziej złożone grafiki, teraz nie mogę, bo jakieś pionowe pasy "smierci" nie pozwalają mi na to. Żeby było śmiesznej, po przekształceniu kodu Visual C++ (Ekspress Edition 2006) nie ma żadnych problemów, z kreśleniem w formie graficznej tych samych danych.
W C++ Builder, nie ma, żadnych bitmap. Są metody "klasy Canvas". a one wcześniej sprawowały się poprawnie, i mogłem skalować i kreślić symulacje najbardziej złożonego zjawiska wpisując w formę grafiki. Zakładam, że pobrałem jakieś "cudowne" aktualizację, które mi to poblokowały.
Avatar użytkownika
lukagrom
Homos antropiczny
Homos antropiczny
 
Posty: 73
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 7
Otrzymał podziękowań: 4
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez polymorphism » czwartek, 9 sierpnia 2018, 21:30

Co to jest owe cliping region?

Heh, widać, że nigdy nie pisałeś własnej kontrolki :) Clipping.


Żeby było śmiesznej, po przekształceniu kodu Visual C++ (Ekspress Edition 2006) nie ma żadnych problemów

Jak już pisałem, te kody różnią się sposobem rysowania...

W C++ Builder, nie ma, żadnych bitmap.

Jak nie ma, jak ma? TBitmap
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2177
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 203
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    UbuntuFirefox

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez lukagrom » sobota, 11 sierpnia 2018, 10:08

Chodzi prawdopodobnie o jakieś ustawienia "lokalne" Windowsa. Na innych maszynach owych pasów nie ma. Te same programy śmigają kreśląc piksele na całości obszaru formy i komponentów.
Avatar użytkownika
lukagrom
Homos antropiczny
Homos antropiczny
 
Posty: 73
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 7
Otrzymał podziękowań: 4
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez lukagrom » sobota, 11 sierpnia 2018, 16:57

Jeszcze dla upewnienia prosty program z 3 PaintBoxami, który ma wypikselować całą powierzchnie tych kompentów w różnych kolorach:
KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TColor kolor1,kolor2,kolor3,kolor4,kolor5,kolor6;
 kolor1=clWhite;
 kolor2=clBlack;
 kolor3=clBlue;
 kolor4=clRed;
 kolor5=clGreen;
 kolor6=clPurple;
 int i,j;
 for(i=0;i<PaintBox1->Width;i+=3)
  for(j=0;j<PaintBox1->Height;j++)
   if(i+j%3==0)
    PaintBox1->Canvas->Pixels[i][j]=kolor1;
   else
    PaintBox1->Canvas->Pixels[i][j]=kolor2;

 for(i=0;i<PaintBox2->Width;i++)
  for(j=0;j<PaintBox2->Height;j++)
   if(i+j%3==0)
    PaintBox2->Canvas->Pixels[i][j]=kolor3;
   else
    PaintBox2->Canvas->Pixels[i][j]=kolor4;

  for(i=0;i<PaintBox3->Width;i++)
   for(j=0;j<PaintBox3->Height;j++)
    if(i+j%2==0)
     PaintBox3->Canvas->Pixels[i][j]=kolor5;
    else
     PaintBox3->Canvas->Pixels[i][j]=kolor6;
}

 

I ponownie na moim kompie, zamalowany tylko pewien fragment, PaintBoxów (tradycyjne pasy pionowe w ogóle nie ruszone). Na innym Windowsie, zamalowane całe PaintBoxy. Najdziwniejsze, że mam to od pewnego czasu, wcześniej powierzchnie "zamalowywane" były pełne i dla Form-y i PaintBoxów. Powtórzę, że tego problemu nie mam w Visual C++.
Avatar użytkownika
lukagrom
Homos antropiczny
Homos antropiczny
 
Posty: 73
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 7
Otrzymał podziękowań: 4
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez polymorphism » sobota, 11 sierpnia 2018, 19:39

Dziwne. Spróbuj jeszcze z rysowaniem na bitmapie, którą później wrzucasz na okno/kontrolkę. W sumie TImage możesz użyć.

if(i + j % 3 == 0)
if(i + j % 2 == 0)

Na pewno o takie warunki Ci chodzi? One będą spełnione tylko dla pierwszej pionowej linii, dla i > 0 zawsze będą false.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2177
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 203
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    UbuntuFirefox

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez lukagrom » sobota, 11 sierpnia 2018, 20:03

W tym samym zdarzeniu z komponentem Image.
KOD cpp:     UKRYJ  
 for(i=0;i<Image1->Width;i++)
    for(j=0;j<Image1->Height;j++)
     Image1->Canvas->Pixels[i][j]=clGreen;
 

O dziwo kreśli na całej długości. Tamte warunki rzeczywiście dawały - false, ale wtedy kolor był jednolity (bez kreślenia mozaiki w kratkę), tyle, że piksele nie zajmowały całego komponentu.
Teraz zagwozdka, dlaczego w Image1 działa, dla PaintBoxa i Formy nie?
Avatar użytkownika
lukagrom
Homos antropiczny
Homos antropiczny
 
Posty: 73
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 7
Otrzymał podziękowań: 4
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez lukagrom » sobota, 11 sierpnia 2018, 20:10

KOD cpp:     UKRYJ  
void __fastcall TForm1::FormPaint(TObject *Sender)
{
 int i,j;
 for(i=0;i<Form1->Width;i++)
  for(j=0;j<Form1->Height;j++)
   Canvas->Pixels[i][j]=clBlue;
}
 

"Zmaksylizowałem" Formę i patrząc przez pryzmat całego ekranu/formy. To mam 3 równoległe "pasy śmierci" i stałej szerokości. Analogicznie w PaintBoxach. W Image tego nie ma.
Avatar użytkownika
lukagrom
Homos antropiczny
Homos antropiczny
 
Posty: 73
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 7
Otrzymał podziękowań: 4
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez polymorphism » sobota, 11 sierpnia 2018, 20:54

No to używaj TImage, jeśli użycie jej rozwiązuje problem.


Co Ty masz z tym definiowaniem "liczników" pętli poza pętlami?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2177
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 203
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    UbuntuFirefox

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez lukagrom » sobota, 11 sierpnia 2018, 21:09

Ja mam podręczniki od czasów C++ Builder 3 i tam zawsze się najpierw zmienną definiowało,dopiero pózniej uzywało. Borland szedł po linii Turbo Pascala i Delphi, gdzie były sekcje definiowania zmiennych.
Avatar użytkownika
lukagrom
Homos antropiczny
Homos antropiczny
 
Posty: 73
Dołączył(a): wtorek, 1 stycznia 2013, 14:54
Podziękował : 7
Otrzymał podziękowań: 4
System operacyjny: Windows Vista
Kompilator: C++ Builder 10.1 Starter
Gadu Gadu: 0
    Windows VistaChrome

Re: C++Builder blokuje rysowanie pikseli na niektórych obszarach

Nowy postprzez polymorphism » sobota, 11 sierpnia 2018, 21:24

Tak to się robiło w starym C, w C++, szczególnie współczesnym, to niepotrzebnie zaciemnia kod, bo na pewno nic nie daje w kwestii optymalizacji. Wyrzuć te podręczniki i załatw sobie współczesne, dotyczące przynajmniej standardu C++11.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2177
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 203
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    UbuntuFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości

cron