LINUX.ORG.RU

На каком яп можно так же легко и просто манипулировать пикселями?

 , ,


1

2

В процессе поисков яп для некоторых задач узнал про https://processing.org/, вопрос в заголовке. Нужно примерно такое https://i.imgur.com/Yy6BNwC.png то есть короткий, легкий для понимания код. В принципе processing устраивает, но вдруг есть какой-то искомый яп, с заданными хотелками, без vm java, достаточно производительный и такой же простой? Можно и не очень простой, если выбора совсем нет.Желательно без адовых портянок инициализации графики. Пример на скриншоте запущен на intel q6600. Сори за виндовс. Если накидаете аналог моего примера на предложенном вами яп, то вообще будет здорово!

void setup() {
  size(640, 480);
  //frameRate(60);
  background(0); 
}

void draw() {
  int stMillis = millis();
  
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      if((int)random(2)==1) set(x, y, color(255,255,255));
      else set(x, y, color(0,0,0));
    }
  }
  
  float fps = 1000.0/float((millis() - stMillis));
  fill(0, 0, 0);
  rect(2, 2, 140, 35);
  fill(255, 50, 50);
  textSize(32);
  text(fps, 5, 30);
}

Кому интересно, вот что транслируется из примера выше в *.java:

import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class noise extends PApplet {

public void setup() {
  
  //frameRate(60);
  background(0); 
}

public void draw() {
  int stMillis = millis();
  
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      if((int)random(2)==1) set(x, y, color(255,255,255));
      else set(x, y, color(0,0,0));
    }
  }
  
  float fps = 1000.0f/PApplet.parseFloat((millis() - stMillis));
  fill(0, 0, 0);
  rect(2, 2, 140, 35);
  fill(255, 50, 50);
  textSize(32);
  text(fps, 5, 30);
}
  public void settings() {  size(640, 480); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "noise" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

Это же трындец сколько импортов всяких писать! Ну и если бы писал на чисто java без import processing думаю было бы все не так просто.

Ответ на: комментарий от Lorovec

другой разговор

по описанию похоже на запрос игрового движка для начинающих с возможностью отрисовки через видеокарту

Kokonavtuz
()
Ответ на: комментарий от Kokonavtuz

игрового движка для начинающих

Вот, для начинающих — это в самую точку. Потому у меня такие трудности. Этим мне и понравился Processing. Он для начинающих. Пока смотрю еще raylib который тут посоветовали. Но там С, указатели.

Lorovec
() автор топика
Ответ на: комментарий от Lorovec

Я в движках не разбираюсь, но по идее они должны решить вопросы отрисовки чего, как, в какой последовательности, вопрос по перемещению фигур и дать забыть о фпс - много не надо. Их сотни https://www.slant.co/search?query=game engine

LOVE, raylib советовали - можно уточнять 2д/3д что нужно. Скорее это вопрос типа какой яп учить первым. Как-нибудь сами. К тому же raylib биндинги есть на го, луа, питоне, и т.д. Сводится к выбору.

Процессинг это псевдоязык, лучше не надо трогать. Рисовать исключительно на цпу это для определенных задач. И можно было бы, но это не язык. Только как трамплин куда-нибудь.

Ну или не учить ничего, купить/украсть готовое или поспрашивать по инкспейсу и настройке

Kokonavtuz
()
Ответ на: комментарий от LINUX-ORG-RU

Примерно 3000 fps (2800 в среднем) (Radeon hd 6850) https://imgur.com/a/4Phyaem , пустой шейдер выдаёт около 3100 fps так что это по сути предел видеокарты в принципе, генерация шума из интернетов я не стал парится, она чёть кривая видно внизсходящие линии как на делеке старом =)

Код страшный ну да ладно

noise.c

#include "corange.h"

static float shader_time = 0.0;
GLuint vertexbuffer;
material* noise_mat;

typedef SDL_Event event;
static bool  running = true;
static event event_common_event = { 0 };
static bool  event_common_state = false;

inline static event event_get(){
    return  event_common_event;
}
bool event_update(){
    event_common_state = SDL_PollEvent(&event_common_event);
    return event_common_state;
}

static const GLfloat g_vertex_buffer_data[] = 
{
 1, 1, 1, -1, 1, 1, -1,-1, 1,   1,-1, 1,
 1, 1, 1,  1,-1, 1,  1,-1,-1,   1, 1,-1,
 1, 1, 1,  1, 1,-1, -1, 1,-1,  -1, 1, 1,
-1,-1,-1, -1, 1,-1,  1, 1,-1,   1,-1,-1,
-1,-1,-1, -1,-1, 1, -1, 1, 1,  -1, 1,-1,
-1,-1,-1,  1,-1,-1,  1,-1, 1,  -1,-1, 1
};




static float data;
static void noise_render() 
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(-1.0, 0.0, 1.0, -1.0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    shader * sh =  material_first_program(noise_mat);
    shader_program_enable(sh);
    shader_program_set_float(sh,"data",data+=(randf_scale(2)*1));

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(0, 3,GL_FLOAT,GL_FALSE,0,(void*)0);

    glDrawArrays(GL_QUADS, 0, 16); 
    glDisableVertexAttribArray(0);

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glActiveTexture(GL_TEXTURE0 + 0 );
    glDisable(GL_TEXTURE_2D);

    glUseProgram(0);

}


int main(int argc, char **argv) 
{
  corange_init("../../assets_core");

  graphics_viewport_title("Noise");

  folder_load(P("./"));

  noise_mat = asset_get(P("./noise.mat"));

  ui_button* fps = ui_elem_new("fps", ui_button);
  ui_button_resize(fps, vec2_new(64, 32));
  ui_button_move(fps, vec2_new(0, 0));

  glGenBuffers(1, &vertexbuffer);
  glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
  glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

  while(running) 
  {
     while(event_update())
     {
        if(event_get().key.keysym.sym == SDLK_ESCAPE)
        {
            running = false;
        }
     }


    frame_begin();
    ui_button_set_label(fps, frame_rate_string());
    noise_render();
    ui_render();
    graphics_swap();
    frame_end();
  };
    corange_finish();
  return 0;
}

noise.fs

#version 120

uniform float data;
//https://thebookofshaders.com/11/
float random (in vec2 st) {
    return fract(sin(dot(st.xy,
                         vec2(12.9898,78.233)))
                 * 43758.5453123);
}

float noise (in vec2 st) {
    vec2 i = floor(st);
    vec2 f = fract(st);
    float a = random(i);
    float b = random(i + vec2(1.0, 0.0));
    float c = random(i + vec2(0.0, 1.0));
    float d = random(i + vec2(1.0, 1.0));
    vec2 u = f*f*(3.0-2.0*f);
    return mix(a, b, u.x) +
            (c - a)* u.y * (1.0 - u.x) +
            (d - b) * u.x * u.y;
}

void main() {
    vec2 st = gl_FragCoord.xy  / vec2(800,600) ;
    vec2 pos = vec2(st ) * data;
    float n = noise(pos);

    gl_FragColor = vec4(vec3(n), 1.0);
}


noise.vs


void main() {

  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

noise.mat

shader vert = ./noise.vs 
shader frag = ./noise.fs

Makefile

DEMO=shader
CC=gcc

CFLAGS= -I../../include -std=gnu99 -Wall -Werror -Wno-unused -O3 -g

PLATFORM = $(shell uname)

ifeq ($(findstring Linux,$(PLATFORM)),Linux)
	OUT=$(DEMO)
	LFLAGS=-L../../ -lcorange -lGL -lSDL2 -lSDL2_net -lSDL2_mixer -lm
endif

ifeq ($(findstring Darwin,$(PLATFORM)),Darwin)
	OUT=$(DEMO)
	LFLAGS= -lcorange -lGL -lSDL2main -lSDL2 -lSDL2_net -lSDL2_mixer
endif

ifeq ($(findstring MINGW,$(PLATFORM)),MINGW)
	OUT=$(DEMO).exe
	LFLAGS=-L../../ -lcorange -lmingw32 -lSDL2main -lSDL2 -lSDL2_net -lSDL2_mixer -lopengl32
endif

$(OUT): shader-test.c
	$(CC) $< $(CFLAGS) $(LFLAGS) -o $@
	
clean:
	rm $(OUT)


Файлы положить в Corange/demos/noise-test и make;./shader

LINUX-ORG-RU ★★★★★
()

Без матриц, обрабатывающихся параллельно, а только с циклами это адовое говно всё. Медленное и некрасивое, хоть и понятное. Годится только для прототипирования. Не вздумайте писать такой код в нормальных приложениях для обработки изображений.

peregrine ★★★★★
()
Ответ на: комментарий от anonymous

Не, я же специально рендер на чисто opengl сделал, оверхеда нет, движок тут чисто что бы fps на экране показать =) Да так по мелочи проинициализировать, падон, мелочи. Я даже не правильно сделал надо было генерировать текстуру биндить её к буферу а потом считать рандом из данных текстуры и записывать в неё же gl_FragData[0] = ... а тут это занимает разовая в кадр на весь фрейм записть юниформы data от того видно что шум такой себе, хреновенький если сравнивать с обычным результатом через for. Та и пофиг вдруг ТС надо будет, а тут пример есть, страшный уродливый, но пример. А если не надо то и хрен с ним с примером этим

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от Lorovec

У меня этот огрызок лежал давно я просто сейчас под шум сделал, а так он был когда я хотел сделать импортёр из shadertoy. Ты уже можешь просто писать всё что надо только в noise.fs и впиндюривать туда нужные тебе вычисления, к примеру вот шейдер моря из shadertoy https://www.youtube.com/watch?v=jkq5VW7iKUI&feature=youtu.be . Если всё облагородить скрыть мусор в функции, задать удобные способы передачи данных в шейдер то вот тебе и игрушка которая будет на gpu всё что угодно дробить. Хотя наверное лучше взять что-то из готового что выше предлагали и получить удобные способы играть с пикселями да будет медленее, но тут как бы тебе решать, упороться и под себя что-то подогнать или взять что-то универсальное и более удобное, а упарываться чисто из интереса как задел на потом =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от Lorovec

Если благородному Дону нужен аналог

CorelDraw, где тонкие линии не исчезают при масштабировании, то он пошел не туда совершенно. Тут скорее нужно придумывать алгоритм масштабирования изображения или принцип его отрисовки. Рисование попиксельного шума - ваще про другое. Что допустим делать, если исходную картинку с шумом захочется сжать перемасштабировать в произвольное число раз?

anonymous
()
Ответ на: Если благородному Дону нужен аналог от anonymous

нужно придумывать алгоритм масштабирования изображения или принцип его отрисовки

Согласен. Но мне нужно сразу же видеть результат работы этого алгоритма. Да, может не с того конца начал. Нужно же с чего-то начать. Может стоило просто продолжить использовать Processing? Я подумал, что потом трудно будет с него перейти на что-то другое, если я уткнусь в какое-либо ограничение java.

Lorovec
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Примерно 3000 fps (2800 в среднем) (Radeon hd 6850) https://imgur.com/a/4Phyaem , пустой шейдер выдаёт около 3100 fps так что это по сути предел видеокарты в принципе

А размер изображения какой?

gag ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

движок тут чисто что бы fps на экране показать =)

Давай как старый добрый glxgears текстом в консольке:

$ vblank_mode=0 glxgears
ATTENTION: default value of option vblank_mode overridden by environment.
34890 frames in 5.0 seconds = 6977.921 FPS
35378 frames in 5.0 seconds = 7075.439 FPS
34421 frames in 5.0 seconds = 6884.196 FPS
36134 frames in 5.0 seconds = 7225.457 FPS
37337 frames in 5.0 seconds = 7467.308 FPS
34795 frames in 5.0 seconds = 6958.874 FPS
37123 frames in 5.0 seconds = 7424.444 FPS
Стандартный размер окошка на встроенном видео мобильного sandy bridge.

gag ★★★★★
()
Ответ на: комментарий от gag

640x480 текстура в 800x600 окне как хочет ТС и как тут все тестили ))

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от gag

Да, я сейчас чекнул, у меня тоже самое, видимо в прошлый раз что-то грузило карту хз, блендер мож чё делал, не помню. Сейчас перепроверять лень, спать пора =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от gag

Давай как старый добрый glxgears текстом в консольке:

Лучше GALLIUM_HUD=fps ./run_app, но в прошлый раз я чёт не сообразил

LINUX-ORG-RU ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.