Unix build

This commit is contained in:
2025-12-22 16:07:05 +04:00
parent 6cde4a2a9a
commit 947ad09430
12 changed files with 195 additions and 23 deletions

View File

@@ -2,7 +2,8 @@
CC = gcc
CFLAGS = -std=gnu23 -Wall -Wextra -O2
CXXFLAGS = -std=gnu++17 -Wall -Wextra -O2 -fno-exceptions -fno-rtti
LIBS = -lgdi32
WIN_LIBS = -lgdi32
UNIX_LIBS = -lX11 -lm
# Micro options
MCU = atmega328p
@@ -25,7 +26,7 @@ WIN_SOURCES = $(BASE_SOURCES) platforms/win/win.c
WIN_OBJECTS = $(WIN_SOURCES:.c=.wo)
WIN_TARGET = $(TARGET).exe
UNIX_SOURCES = $(BASE_SOURCES) platforms/unix.c
UNIX_SOURCES = $(BASE_SOURCES) platforms/unix/unix.c
UNIX_OBJECTS = $(UNIX_SOURCES:.c=.uo)
UNIX_TARGET = $(TARGET)
@@ -39,7 +40,12 @@ HEX = $(TARGET).hex
win: $(WIN_TARGET)
$(WIN_TARGET): $(WIN_OBJECTS)
$(CC) -o $@ $^ $(LIBS)
$(CC) -o $@ $^ $(WIN_LIBS)
unix: $(UNIX_TARGET)
$(UNIX_TARGET): $(UNIX_OBJECTS)
$(CC) -o $@ $^ $(UNIX_LIBS)
micro: $(HEX)
@@ -68,7 +74,7 @@ run_win: $(WIN_TARGET)
.\$(WIN_TARGET)
run_unix: $(UNIX_TARGET)
.\$(UNIX_TARGET)
./$(UNIX_TARGET)
upload_micro: $(HEX)
$(AVRDUDE) -p $(MCU) -c $(PROGRAMMER) -P $(PORT) -b 57600 -U flash:w:$(HEX):i

View File

@@ -27,7 +27,7 @@ Point object_get_centroid(const Object *const object) {
return centroid;
}
void object_draw(const Object *object, const Screen *const screen,
void object_draw(const Object *object, const EngineScreen *const screen,
const float *render_matrix, const Camera *const camera,
const Color *const color) {
// Массив для отслеживания, какие рёбра нужно нарисовать

View File

@@ -20,7 +20,7 @@ typedef struct Object {
void object_transform(Object *const object, int size, float *translate_matrix);
Point object_get_centroid(const Object *const object);
void object_draw(const Object *object, const Screen *const screen,
void object_draw(const Object *object, const EngineScreen *const screen,
const float *render_matrix, const Camera *const camera,
const Color *const color);

View File

@@ -39,7 +39,8 @@ void point_create_translate_matrix(const Point *const position,
}
}
ScreenPoint point_to_screen_point(Point *point, const Screen *const screen,
ScreenPoint point_to_screen_point(Point *point,
const EngineScreen *const screen,
const float *render_matrix) {
float tmp[] = {point->coordinates[0], point->coordinates[1],
point->coordinates[2], 1.0f};

View File

@@ -14,7 +14,8 @@ void point_transform(Point *const point, int size,
const float *translate_matrix);
void point_create_translate_matrix(const Point *const position,
float *translate_matrix, int k);
ScreenPoint point_to_screen_point(Point *point, const Screen *const screen,
ScreenPoint point_to_screen_point(Point *point,
const EngineScreen *const screen,
const float *render_matrix);
#endif

View File

@@ -45,7 +45,7 @@ void init_engine() {
logff(BLUE BOLD UNDERLINE, "Engine init complete!");
}
void render(const Screen *const screen, const Color *const color) {
void render(const EngineScreen *const screen, const Color *const color) {
for (int i = 0; i < number_of_objects; i++) {
object_draw(&(objects[i]), screen, render_matrix, &camera, color);
}

View File

@@ -13,7 +13,7 @@ void draw_line(const ScreenPoint *const sp1, const ScreenPoint *const sp2,
TV.drawLine(sp1->coordinates[0], sp1->coordinates[1], sp2->coordinates[0],
sp2->coordinates[1], 1);
}
Screen screen = {.width = 128, .height = 64, .draw_line = &draw_line};
EngineScreen screen = {.width = 128, .height = 64, .draw_line = &draw_line};
Color white = {.red = (char)255, .green = (char)255, .blue = (char)255};
float gx, gy, gz;

View File

@@ -11,7 +11,7 @@
#endif
EXTERNC void init_engine();
EXTERNC void render(const Screen *const screen, const Color *const color);
EXTERNC void render(const EngineScreen *const screen, const Color *const color);
EXTERNC void tic();
EXTERNC void rotate(const float angles_speed[3]);
EXTERNC void destroy();
@@ -27,6 +27,15 @@ EXTERNC void destroy();
#endif // WIN
#ifdef UNIX
#include "unix/unix.h"
#define FPS 25
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#endif // WIN
#ifdef MICRO
#define FPS 20

141
src/platforms/unix/unix.c Normal file
View File

@@ -0,0 +1,141 @@
#include "../platform.h"
#include "unix.h"
const Color white = {255, 255, 255};
const Color black = {0, 0, 0};
Display *display = NULL;
Window window;
GC gc;
int screen_num;
int running = 1;
void draw_line_x11(const ScreenPoint *sp1, const ScreenPoint *sp2,
const Color *const color) {
if (!display || !gc)
return;
XSetForeground(display, gc,
(color->red << 16) | (color->green << 8) | color->blue);
XDrawLine(display, window, gc, sp1->coordinates[0], sp1->coordinates[1],
sp2->coordinates[0], sp2->coordinates[1]);
}
void redraw_window(void) {
if (!display || !window)
return;
XWindowAttributes window_attrs;
XGetWindowAttributes(display, window, &window_attrs);
XSetForeground(display, gc,
(black.red << 16) | (black.green << 8) | black.blue);
XFillRectangle(display, window, gc, 0, 0, window_attrs.width,
window_attrs.height);
EngineScreen screen = {.width = window_attrs.width,
.height = window_attrs.height,
.draw_line = &draw_line_x11};
render(&screen, &white);
XFlush(display);
}
int main() {
struct timeval last_time, current_time;
long frame_delay = 1000000 / FPS; // микросекунды на кадр
display = XOpenDisplay(NULL);
if (display == NULL) {
fprintf(stderr, "Cannot open display\n");
return 1;
}
screen_num = DefaultScreen(display);
window = XCreateSimpleWindow(display, RootWindow(display, screen_num), 0, 0,
WINDOW_WIDTH, WINDOW_HEIGHT, 1,
BlackPixel(display, screen_num),
BlackPixel(display, screen_num));
XStoreName(display, window, "C3DGraphicEngine");
XSelectInput(display, window,
ExposureMask | KeyPressMask | StructureNotifyMask |
KeyReleaseMask);
Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &wm_delete_window, 1);
gc = XCreateGC(display, window, 0, NULL);
XSetGraphicsExposures(display, gc, False);
XMapWindow(display, window);
XFlush(display);
XEvent ev;
do {
XNextEvent(display, &ev);
} while (ev.type != Expose);
init_engine();
redraw_window();
gettimeofday(&last_time, NULL);
while (running) {
while (XPending(display) > 0) {
XNextEvent(display, &ev);
switch (ev.type) {
case Expose:
if (ev.xexpose.count == 0) {
redraw_window();
}
break;
case ConfigureNotify:
redraw_window();
break;
case KeyPress:
if (XLookupKeysym(&ev.xkey, 0) == XK_Escape) {
running = 0;
}
break;
case ClientMessage:
if (ev.xclient.message_type ==
XInternAtom(display, "WM_PROTOCOLS", True) &&
(Atom)ev.xclient.data.l[0] ==
XInternAtom(display, "WM_DELETE_WINDOW", False)) {
running = 0;
}
break;
}
}
gettimeofday(&current_time, NULL);
long elapsed = (current_time.tv_sec - last_time.tv_sec) * 1000000 +
(current_time.tv_usec - last_time.tv_usec);
if (elapsed >= frame_delay) {
tic();
redraw_window();
last_time = current_time;
} else {
usleep(1000);
}
}
XFreeGC(display, gc);
XDestroyWindow(display, window);
XCloseDisplay(display);
return 0;
}

13
src/platforms/unix/unix.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef UNIX_H
#define UNIX_H
#include "../platform.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#endif

View File

@@ -32,7 +32,8 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
DeleteObject(hPen);
};
Screen screen = {.width = width, .height = height, .draw_line = &draw_line};
EngineScreen screen = {
.width = width, .height = height, .draw_line = &draw_line};
render(&screen, &white);

View File

@@ -11,11 +11,11 @@ typedef struct Color {
char blue;
} Color;
typedef struct Screen {
typedef struct EngineScreen {
int width;
int height;
void (*draw_line)(const ScreenPoint *sp1, const ScreenPoint *sp2,
const Color *const color);
} Screen;
} EngineScreen;
#endif