Ir ao conteúdo
  • Cadastre-se

V!OLADOR

Membro Pleno
  • Posts

    435
  • Cadastrado em

  • Última visita

posts postados por V!OLADOR

  1. Em 07/12/2023 às 12:07, Beatriz Yakamura disse:
    glTranslatef(-centerX, -centerY, 0.0); // Translada para centralizar o polígono vermelho
    
    glTranslatef(4.0, 4.0, 0.0); // Translada o sistema de coordenadas para o centro do polígono azul
    glRotatef(45.0, 0.0, 0.0, 1.0); // Rotaciona o sistema de coordenadas em 45 graus no eixo z
    glTranslatef(-4.0, -4.0, 0.0); // Translada o sistema de coordenadas de volta para a origem

     

    Bom, mas esta parte não tá claramente errada? O que eu tô lendo ai acima: transladamos o objeto pro ponto (-centerX, -centerY), em seguida transladamos novamente pra posição inicial (4, 4), aplicamos uma rotação e então transladamos novamente pra posição aleatória (-4, -4).

     

    De qualquer maneira, assumindo que o polígono já esteja inicialmente centrado na posição (4, 4), pelos valores dos próprios vértices, faça uma translação pra origem do sistema de coordenadas, ou seja (0, 0), aplique a rotação ali e translada o objeto novamente pra posição inicial (4, 4). Talvez funcione.

    • Amei 1
  2. Em 17/11/2023 às 14:54, Cambalinho disse:

    porque o ciclo 'for' é executado 1 única vez e o 'v' é zero?

     

    Bom, por que foi exatamente isso que você pediu pro programa executar. Ou seja, se Y0 + 0 for maior ou igual a Y0, o que é verdade (y=Y0 e Y1=Y0 se Radians=0), então o loop deve ser terminado.

     

    Em 17/11/2023 às 14:54, Cambalinho disse:

    deveria somar '32' no 'x' e 1 vez seria '132', ou seja inferior ao comprimento....

     

    32 + 100 parece-me suficientemente maior que 100, supondo que você se refere a width como um comprimento.

     

    Em 17/11/2023 às 14:54, Cambalinho disse:

    o que estou a fazer errado no código?

     

    Off-topic: Aparentemente, muitas coisas, mas o mais importante seria ter um pouco mais de cuidado na hora das operações aritméticas misturando int, float e double. Sempre converta tudo pra float ou double, dependendo do nível de precisão que deseja, antes das operações. O compilador tá realizando várias conversões implícitas e o código executado não é exatamente o código escrito. Portanto, ele é péssimo pra ler, pra debugar e provavelmente vai ter erros durante o runtime também.

    • Curtir 1
    • Amei 1
  3. Essa linha,

     

    Em 14/11/2023 às 13:05, Cambalinho disse:
    if(&Hello==NULL) Hello();

     

    não faz o menor sentido. Talvez, o que busca seja um ponteiro pra uma função como membro de test2. Ou seja,

     

    class test2 {
        public:
        test2(): Hello(NULL) {}
    
        void (*Hello)();
    
        void hey() {
            if (this->Hello != NULL) this->Hello();
        }
    };

     

    Agora, basta associar uma função com a mesma assinatura de Hello pro membro this->Hello. P/ex:

     

    void Hi() {
        cout << "hello world!!!\n";
    }
    
    test2 a;
    int main() {
        a.Hello = Hi;
        a.hey();
    
        return 0;
    }

     

    • Curtir 1
    • Amei 1
  4. 2 horas atrás, Cambalinho disse:

    main.cpp:9:14: error: redefinition of 'std::__cxx11::wstring towstring(const string&)'

     

    2 horas atrás, Cambalinho disse:

    cambalinho.h:359:14: note: 'std::__cxx11::wstring towstring(const string&)' previously defined here

     

    O compilador está sendo bem claro sobre o problema: Você definiu a função towstring() duas vezes; aparentemente na linha 9 do main.cpp e na linha 359 do cabeçalho cambalinho.h.

    • Curtir 2
  5. 3 horas atrás, Cambalinho disse:

    why CodeBlocks can't  find the file if there on that folder?

     

    Explicado anteriormente.

     

    56 minutos atrás, Cambalinho disse:

    qual são as suas flags nas opções do compilador?

     

    Se eu quero linkar uma biblioteca chamada libfoo.a localizada no endereço /home/mylibs, eu usaria:

     

    -L/home/mylibs -lfoo
    • Curtir 1
  6. Bom, o primeiro detalhe é notar que você não está providenciando o endereço do local onde a biblioteca vive mas o endereço da biblioteca propriamente dita (ou seja, do arquivo). O linker poderia tentar procurar no diretório ..\libbgi.a e, obviamente, não encontrar nenhum arquivo libbgi.a ali. O endereço deveria terminar em ..\lib a não ser que seja uma notação própria do Code::Blocks.

     

    O segundo detalhe é o fato de que você está tentando utilizar uma biblioteca estática. São essas com extensão .a. Você pode simplesmente utilizar o endereço completo do arquivo (não do local) na flag -l, p/ex.:
     

    -l[PATH]\libbgi.a -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32

     

    Lembre-se que a ordem das bibliotecas importa. Salvo enganos, as que dependam da libbgi.a devem estar posicionadas a direita dela na linha de comando.

     

    6 horas atrás, Cambalinho disse:

    mas acredito que não devo ter a libraria correcta...

     

    Você só pode concluir isso depois de linkar a libbgi.a corretamente e obter o próximo erro. Até o momento você não usou a biblioteca.

    • Curtir 1
  7. 18 horas atrás, Cambalinho disse:

    porque este erro?

     

    O linker utilizado pelo Code::Blocks, ou seja ld.exe, não foi capaz de encontrar a biblioteca libbgi no sistema e, portanto, não consegue montar o executável. Ele procurou em alguns lugares predefinidos (onde normalmente as bibliotecas ficam armazenadas) e noutros especificados por você.

     

    18 horas atrás, Cambalinho disse:

    como o corrigir?

     

    Você poderia fornecer o endereço da biblioteca pro linker utilizando a flag -L, p/ex.:

     

    -L[PATH] -lbgi -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32

     

    Onde [PATH] seria o endereço pro diretório no qual a biblioteca vive (um arquivo .a ou .so ou .dll etc).

     

    Ou você poderia procurar na documentação do Code::Blocks onde ele prefere guardar as bibliotecas e, então, copiar a libbgi pra esse local. Nunca usei Code::Blocks, portanto não posso ajudar muito nessa parte.

    • Curtir 2
  8. 18 horas atrás, Midori disse:

    Outra questão, como faco para incluir um diretorio de headers para que os fontes *.c encontrem ele com #define <header.h> em vez de #include "header.h"? Tentei passar o diretorio para INCDIR e não deu certo, p.ex: -I./xg/include.

     

    Eu acho que usar a flag -I é exatamente a forma (mais) correta. Tentou usar o endereço absoluto ao invés do relativo? Talvez com $PWD/xg/include ou algo do tipo.

     

    18 horas atrás, Midori disse:

    Se eu colocar p.ex #define __NetBSD__ em xplore.h resolvo esse erro, mas tem outros arquivos com essas macros. Como posso fazer isso no Makefile para não ter que editar cada arquivo?

     

    Eu diria que, a não ser que você saiba exatamente quais serão as consequências de modificar o código, nesse caso, a opção de editar o próprio código pra fazê-lo compilar não é uma boa ideia. Quase sempre indica problemas. O processo de compilação não deveria necessitar modificar o código alvo.

     

    18 horas atrás, Midori disse:

    Vi que daria para para fazer algo com -D. Mas tentei -D__NetBSD__ e não deu certo, Qual e a forma correta?

     

    Porque não deu certo? Por quê os demais arquivos que usavam __NetBSD__ agora precisavam de outras dependências que você não tinha ou algo do tipo? Se sim, então talvez a macro __NetBSD__ definida apenas na xplore.h não faça sentido.

     

    Aqui novamente eu acho que a flag -D é a solução mais correta. Seria possível que alloca.h seja parte de outro pacote e que você tenha que instalar essa dependência primeiro antes de compilar?

    • Obrigado 1
  9. 1 hora atrás, Cambalinho disse:

    porque o centro da rotação está sempre a variar se eu nem estou a alterar as coordenadas intPlayerPosX e intPlayerPosY?


    Aparentemente as equações estão corretas. Você sempre pode checar o comprimento do vetor, ou a distância entre o ponto e a origem (x0, y0), pra garantir que a rotação foi feita corretamente. O comprimento deve ser o mesmo antes e depois da operação. Assim o erro deve ser noutra parte do código que você não mostrou.

    Por sinal, não misture números inteiros e números reais nos cálculos pra não perder precisão. Use double (float) pra todas as variáveis envolvidas além de constantes literais também como reais, i.e. "1.0", "180.0" ("1.0f", "180.0f"). Se estiver usando um compilador de C, ao invés de C++, conversões inesperadas podem alterar o cálculo.

    • Amei 1
  10. 8 horas atrás, Cambalinho disse:

    O que ainda estou com dificuldade em entender é: como posso rodar um ponto a partir de outro ponto?


    Da mesma forma mas, ao invés de medir a distância a partir do ponto (0, 0), meça a partir de um ponto (x0, y0). Então, x' = (x - x0)*cos(alpha) - (y - y0)*sin(alpha). Alternativamente, você sempre pode mover um vetor de onde quer que ele esteja pra origem (0, 0) aplicar a rotação e então movê-lo novamente pra posição original (agora devidamente rotacionado). Lembre-se de movê-lo sem alterar o comprimento ou a direção.

    • Curtir 1
  11. O problema pode ocorrer em vários lugares porque você não está sendo cuidadoso na hora checar se as coisas são válidas antes de usá-las. Por exemplo, você recebe ponteiros de duas funções, create_bitmap() e load_bitmap(), e não testa se eles não são, pelo menos, NULL antes de já ir usando por ai. Caso sejam NULL, em algum momento, alguma parte do programa vai tentar dereferenciar esses ponteiros e o programa (o SO por detrás) vai emitir um seg fault.

    Bom, tudo isso pra dizer que você deve ser mais cuidadoso. Por hora, o problema parece ser aqui:

     

    1 hora atrás, W0xer disse:
    for(int j = 0; j < 10; j++)


    Note que o tamanho máximo de invader é 5x10 e não 10x10.

    • Obrigado 1
  12. O compilador deve tá bem confuso porque você prometeu que media seria do tipo float e em seguida inicializou com um inteiro (0) e, se não bastasse, dividiu por outro inteiro (10). Bom, assumindo que alguém não possa ter uma idade de 22.7 anos, utilize int como o tipo de media.

     

    33 minutos atrás, Robs156 disse:
    int media=0;

     


    Se há algo pra melhorar? bom, eu diria exatamente ter mais cuidado na hora de associar valores aos tipos corretos porque um compilador de C é bem permissivo e não vai checar muitas coisas por você. Na duvida, e quando possível, eles farão conversões automáticas dos valores envolvidos e que frequentemente não funcionam.

    • Curtir 1
  13. Suponho que o membro v de s1 represente uma velocidade utilizada pelo método move() pra atualizar as posições x e y. Bom, ocorre que quando você resolve que houve uma colisão, zera a velocidade aqui:

     

    2 horas atrás, dev9 disse:
    s1.v = 0;


    E ela não volta a receber um valor não nulo e, portanto, não é mais possível atualizar a posição. 

    Ao invés de zerar a velocidade, você poderia tentar o seguinte: no inicio de cada passo, depois de receber o evento event, testar se haverá colisão pra cada uma das direções (cima, baixo, esquerda e direita) e apenas atualizar a posição naquela direção se não houver colisão. Então são quatro chamadas da função collide() primeiro pra determinar qual direção não há colisão e apenas depois dessa etapa uma chamada de move() pra cada direção sem obstaculo. Seria melhor redefinir collide() pra facilitar o trabalho.

    A velocidade não deve ser alterada.

    • Curtir 1
  14. Ah, são pixels pretos no meio da região vermelha. Não deve tratar-se de aliasing e tampouco anti-aliasing.

    Se eles tivessem posições irregulares, e dependo do algoritmo que está a usar, tipo ray-tracing, talvez fosse um problema de noise/denoise. Tampouco parece ser o caso, dada a regularidade dos pontos pretos. Parece ser algo muito mais simples, precisamente na forma como você desenha a imagem.

    Mais tarde darei uma olhadela no código.

    • Amei 1
  15. A resolução da imagem é muito baixa então não consigo ver bem o problema. Ele ocorre na borda do retângulo ou no centro?

    De qualquer maneira, como é uma imagem com apenas duas cores (vermelho e preto), e além do objeto vermelho possuir segmentos pontudos (intersecção dos dois lados do retângulo), a mim me parece completamente natural que você venha a observar pixelamento. Um AA certamente ajudaria mas, devido a pobreza da imagem (apenas duas cores), o máximo que vai conseguir é um efeito borrado na borda pra esconder o pixelamento. Não há muita mágica possível na média entre apenas duas coisas 😅.

    • Curtir 1
  16. Essa não parece ser uma pergunta de programação e tampouco de C++. É sobre computação gráfica e você pode encontrar a resposta buscando pela palavra-chave processamento de sinais (signal processing).

    Uma imagem aliased foi resterizada, ou seja, transformada da sua forma vetorial numa malha de pixels. Obviamente, os pixels na fronteira entre os vários objetos que formam a imagem mudam de cor de forma brusca. Por exemplo, numa foto de um céu ensolarado, os últimos pixels na borda das nuvens são brancos enquanto os pixels seguintes, do fundo, são azuis. Isso causa um efeito artificial de (escada) pixelamento. Uma imagem anti-aliased (AA) corrige esse problema determinando um valor médio da cor na fronteira entre objetos utilizando vários pixels ao redor (sampling). Assim, no caso da foto do céu ensolarado, e com AA, ao invés de um pixel branco seguido de um pixel azul, teríamos um pixel azul claro (parcialmente branco e azul).

    Devido a minha ignorância no tema, eu seria incapaz de dar qualquer dica minimamente inteligente pra resolver o seu problema especificamente, muito embora pareça obvio que, sim, utilizando AA você vai conseguir linhas mais definidas. Caso esteja afiado no inglês, recomendo a fantástica aula abaixo sobre esse tema. Na verdade, não recomendo apenas a aula 22 mas toda a série de aulas do Cem Yuksel.

    Intro to Graphics 22 - Signal Processing

    • Curtir 2
    • Amei 1
  17.  

    3 horas atrás, b.0463 disse:

    já aprendi uma boa base e ate mesmo já fiz um jogo da velha CLI ( https://github.com/B0463/TickTackToe_CLI_C ).

     

    Além das dicas dos colegas você pode já ter ouvido falar da ótima biblioteca Dear ImGui, né? bom, o projeto cimgui disponibiliza wrappers pra outros projetos escritos em C.

    Dear ImGuihttps://github.com/ocornut/imgui
    cimguihttps://github.com/cimgui/cimgui

    Dear ImGui (e portanto cimgui) é famosa por GUIs rápidas e interativas sem (muita) retenção do estado da UI (dai o nome Im de imediato). Basicamente, ela é a primeira ferramenta de qualquer vídeo game feito nos dias de hoje.

    • Curtir 1
    • Obrigado 1
  18. Talvez devêssemos considerar outro aspecto também.

    C tem tornado-se num padrão da industria mais além do que qualquer outra linguagem conhecida. Se uma nova biblioteca ou dispositivo é criado, cria-se também uma API seguindo o padrão do C de forma que todo o resto possa ter compatibilidade. C é fundamental pra OS, pra outras linguagens, pra compiladores, pra frameworks, pra servidores (backend), pra drivers etc. E C++ ainda é muito utilizada na área de gráficos, o que movimenta muito dinheiro como vídeo games.

    Então, mesmo que novos projetos não mais sejam feitos em C e C++ nativo hoje em dia, o fato é que sempre haverá a necessidade de gente capacitada nas duas pra fazer manutenção e manter o mundo girando. Então, talvez, sempre haja possibilidade de emprego pra esses indivíduos embora, certamente, não tanto quanto pra outras linguagens.

    E pro futuro seria bom citar também Rust, que muitos consideram como a sucessora do C e tem sido considerada, recentemente, como substituta do C no desenvolvimento do kernel do Linux (🤯).

    • Curtir 2
    • Amei 1
  19. Em 14/02/2022 às 13:55, Cambalinho disse:

    Otimizar,  penso, é evitar duplicar o código e tentar evitar muito consumo do CPU.

     

    Bem, depende. Primeiro você deveria especificar o aspecto que gostaria de otimizar e a performance não é o único dos tantos que existem.

    Mas considerando que seja isto, otimizar performance, definitivamente, não é sobre evitar o consumo da CPU, pelo contrário, é garantir que a CPU esteja sempre cheia de serviço útil a ser feito. A CPU tá sempre executando algo mesmo que a instrução seja fazer nada. Por exemplo, se ela precisa acessar a memória RAM pra ler um determinado valor, pelo fato da RAM funcionar numa frequência muito inferior, a CPU precisa ficar centenas, talvez milhares, de ciclos fazendo nada até que o valor tenha sido carregado da RAM pra memória cache. Caso ela precise fazer isso frequentemente, temos então uma CPU que passa boa parte do tempo fazendo nada, esperando uma resposta da memória RAM, ou seja, baixa performance.

    Você não deve otimizar às cegas supondo o que seria o problema. Primeiro você deve executar o programa num profiler e o relatório vai apontar as partes do código que estão engasgando. Apenas então você pode montar uma estratégia de otimização. Depois dessa etapa, sabendo qual é o problema especifico, geralmente, e no caso de C++, algumas práticas pra extrair performance são:

    - Evite alocar memória frequentemente com new e delete. São operações muito custosas e que, por vezes, podem ser substituídas pela stack. Ou, alternativamente, faça uma alocação grande no inicio, gerencie esse recurso durante o curso do programa e libere apenas ao final.

    - Quanto mais alocação dinâmica fizer mais fragmentada ficará a memória e, portanto, mais custosas serão as próximas alocações.

    - Favoreça malloc (ou calloc e realloc) ao invés de new. Chamar new implica alocar memória na heap mais uma chamada do construtor enquanto malloc & cia apenas alocam memória (ainda assim custosamente).

    - Favoreça free ao invés de delete pela mesma razão: delete implica uma chamada do destrutor antes de liberar a memória enquanto free apenas libera (ainda assim custosamente também).

    - Evite uso exagerado de classes por que você vai findar criando "bolhas" na memória nas quais os dados, que deveriam estar alinhados pra acesso sequencial e rápido, ficam isolados e a CPU perde boa parte do tempo pulando de um local pro outro (cache miss é extremamente custoso).
    - Favoreça uma struct de arrays ao invés de um array de structs. E favoreça também acessar dados sequencialmente de maneira que a CPU possa predizer os próximos elementos que ela vai precisar.

    - Evite dereferenciar ponteiros por que o próximo local apontado pelo ponteiro certamente não será aquele que já estaria disponível na cache da CPU, forçando-a a voltar a acessar a memória RAM (muito lento).

    - Evite todas as situações que possam estar induzido o compilador a criar objetos temporários, principalmente, se são instâncias de classes com construtores e destrutores pesados.

    - Tente determinar (com o profiler) quais as funções mais quentes e então, se possível, redesenhá-las pra versões inline.

    - Considere desenhar a manipulação dos dados em sequências de blocos de, digamos, 64 Kb, ou qualquer que seja o tamanho da cache da maquina que está a usar, e assim você pode usufruir de registros mais largos com SIMD pra operações aritméticas. Dependendo do nível de otimização do compilador, ele pode já estar a fazer isto por você mas você pode programar assim pra impor um comportamento ideal independente do compilador.

     

    Há muitas dicas mais mas o importante mesmo é, antes de tudo, fazer um benchmark com um bom profiler pra determinar a causa da lentidão do programa.
     

    • Curtir 2
    • Obrigado 1
    • Amei 1
  20. Bom, como meu conhecimento básico de OpenGL é da versão 3.0 em diante, as chances de dar algum pitaco minimamente útil são pequenas mas vou tentar mesmo assim.
     

    Talvez fosse interessante dar uma olhada em todas as chamadas de funções entre updateCamera() e a função que redesenha a imagem, chamada por glutPostRedisplay(). A primeira coisa a investigar é se a matriz criada por gluLookAt() não está sendo modificada sem querer antes da imagem ser atualizada. Por exemplo, um erro muito comum é uma chamada inapropriada da função glLoadIdentity() entre gluLookAt() e a imagem a ser redesenhada na tela. Ou seja, você cria a matriz de projeção e em seguida, sem querer, substitui por uma matriz identidade. Dependendo de como o código estiver organizado pode não ser óbvio que há uma chamada de função modificando a matriz criada por gluLookAt() antes da imagem ser redesenhada.

    Então, seria bom ter o código inteiro como bem disse @devair1010.

    • Obrigado 2
  21. 1 hora atrás, arfneto disse:

    Eu só queria deixar isso claro.


    Entendi. Tudo clarificado.

     

    1 hora atrás, arfneto disse:

    Tem uma cara séria e até a struct chama string :)


    Sim, tem uma cara séria mas só a cara mesmo. Não foi planejada pra se transformar numa biblioteca propriamente dita muito embora eu tenha querido deixar isto implícito, de maneira que o leitor pudesse imaginar que, possivelmente, struct string vem acompanhada de uma API pra manipulá-la em vários cenários distintos. Mas nesse tópico o intuito era apenas um cenário: concatenação.

    Fun fact: aquela struct realmente faz parte de uma biblioteca que eu escrevi anos atrás pra um projeto de um compilador. E ela realmente tem uma longa API com várias funções pra fazer todo tipo de coisa (tokens, concatenar, inserir, cortar, trocar etc.). Talvez a unica diferença seja que o código cliente tem acesso a um ponteiro opaco, através do header .h, e a struct é mantida apenas dentro da implementação .c, de maneira que não é possível acessar diretamente o array, length e max_length. Ah, a struct original tem também um outro membro, chamado use_omp do tipo bool, pra ligar (ou desligar) o uso de threads que aceleram o funcionamento interno. 

    • Curtir 1

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!