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

View File

@@ -27,7 +27,7 @@ Point object_get_centroid(const Object *const object) {
return centroid; 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 float *render_matrix, const Camera *const camera,
const Color *const color) { const Color *const color) {
// Массив для отслеживания, какие рёбра нужно нарисовать // Массив для отслеживания, какие рёбра нужно нарисовать
@@ -108,4 +108,4 @@ void object_draw(const Object *object, const Screen *const screen,
screen->draw_line(&p1, &p2, color); screen->draw_line(&p1, &p2, color);
} }
} }
} }

View File

@@ -20,8 +20,8 @@ typedef struct Object {
void object_transform(Object *const object, int size, float *translate_matrix); void object_transform(Object *const object, int size, float *translate_matrix);
Point object_get_centroid(const Object *const object); 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 float *render_matrix, const Camera *const camera,
const Color *const color); const Color *const color);
#endif #endif

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) { const float *render_matrix) {
float tmp[] = {point->coordinates[0], point->coordinates[1], float tmp[] = {point->coordinates[0], point->coordinates[1],
point->coordinates[2], 1.0f}; point->coordinates[2], 1.0f};
@@ -57,4 +58,4 @@ ScreenPoint point_to_screen_point(Point *point, const Screen *const screen,
((perspective_coordinates[1] + 1.0f) / 2.0f) * ((perspective_coordinates[1] + 1.0f) / 2.0f) *
(float)screen->height}}; (float)screen->height}};
return spoint; return spoint;
} }

View File

@@ -14,7 +14,8 @@ void point_transform(Point *const point, int size,
const float *translate_matrix); const float *translate_matrix);
void point_create_translate_matrix(const Point *const position, void point_create_translate_matrix(const Point *const position,
float *translate_matrix, int k); 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); const float *render_matrix);
#endif #endif

View File

@@ -45,7 +45,7 @@ void init_engine() {
logff(BLUE BOLD UNDERLINE, "Engine init complete!"); 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++) { for (int i = 0; i < number_of_objects; i++) {
object_draw(&(objects[i]), screen, render_matrix, &camera, color); object_draw(&(objects[i]), screen, render_matrix, &camera, color);
} }
@@ -80,4 +80,4 @@ void tic() {
} }
} }
void destroy() { free(render_matrix); } void destroy() { free(render_matrix); }

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], TV.drawLine(sp1->coordinates[0], sp1->coordinates[1], sp2->coordinates[0],
sp2->coordinates[1], 1); 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}; Color white = {.red = (char)255, .green = (char)255, .blue = (char)255};
float gx, gy, gz; float gx, gy, gz;
@@ -36,4 +36,4 @@ int main(void) {
// _delay_ms(1000 / FPS); // _delay_ms(1000 / FPS);
} }
return 0; return 0;
} }

View File

@@ -11,7 +11,7 @@
#endif #endif
EXTERNC void init_engine(); 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 tic();
EXTERNC void rotate(const float angles_speed[3]); EXTERNC void rotate(const float angles_speed[3]);
EXTERNC void destroy(); EXTERNC void destroy();
@@ -27,6 +27,15 @@ EXTERNC void destroy();
#endif // WIN #endif // WIN
#ifdef UNIX
#include "unix/unix.h"
#define FPS 25
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#endif // WIN
#ifdef MICRO #ifdef MICRO
#define FPS 20 #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); 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); render(&screen, &white);
@@ -86,4 +87,4 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
} }
return 0; return 0;
} }

View File

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