Initial Commit
This commit is contained in:
3
clock/README.md
Normal file
3
clock/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# clock Project
|
||||||
|
|
||||||
|
This is a C project generated with the setup tool.
|
||||||
24
clock/build/Makefile
Normal file
24
clock/build/Makefile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# build/Makefile
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Wall -I../include
|
||||||
|
SRCDIR = ../src
|
||||||
|
OBJDIR = ../obj
|
||||||
|
BINDIR = ../build
|
||||||
|
TARGET = clock
|
||||||
|
|
||||||
|
# Gather all source files in src directory
|
||||||
|
SOURCES = $(wildcard $(SRCDIR)/*.c)
|
||||||
|
OBJECTS = $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SOURCES))
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJECTS)
|
||||||
|
$(CC) $(CFLAGS) -o $(BINDIR)/$(TARGET) $(OBJECTS) -lm
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
BIN
clock/build/clock
Executable file
BIN
clock/build/clock
Executable file
Binary file not shown.
37
clock/include/clock.h
Normal file
37
clock/include/clock.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// include/clock.h
|
||||||
|
#ifndef CLOCK_H
|
||||||
|
#define CLOCK_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define SCREEN_WIDTH 800
|
||||||
|
#define SCREEN_HEIGHT 600
|
||||||
|
#define CENTER_X (SCREEN_WIDTH / 2)
|
||||||
|
#define CENTER_Y (SCREEN_HEIGHT / 2)
|
||||||
|
#define RADIUS 200
|
||||||
|
#define HOUR_HAND_LENGTH 100
|
||||||
|
#define MINUTE_HAND_LENGTH 150
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} Point;
|
||||||
|
|
||||||
|
void draw_circle(int *framebuffer, struct fb_var_screeninfo vinfo);
|
||||||
|
void draw_hand(int *framebuffer, struct fb_var_screeninfo vinfo, float angle, int length, int color);
|
||||||
|
void draw_clock_face(int *framebuffer, struct fb_var_screeninfo vinfo);
|
||||||
|
void update_time(int *framebuffer, struct fb_var_screeninfo vinfo);
|
||||||
|
void draw_text(int *framebuffer, struct fb_var_screeninfo vinfo, const char *text, int x, int y, int size, int color);
|
||||||
|
|
||||||
|
#endif
|
||||||
BIN
clock/obj/clock.o
Normal file
BIN
clock/obj/clock.o
Normal file
Binary file not shown.
168
clock/src/clock.c
Normal file
168
clock/src/clock.c
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
// src/clock.c
|
||||||
|
#include "../include/clock.h"
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// Set a pixel at (x, y) with color in the framebuffer
|
||||||
|
void set_pixel(int *framebuffer, struct fb_var_screeninfo vinfo, int x, int y, int color) {
|
||||||
|
if (x >= 0 && x < vinfo.xres_virtual && y >= 0 && y < vinfo.yres_virtual) {
|
||||||
|
framebuffer[y * vinfo.xres_virtual + x] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bresenham's line algorithm for drawing lines
|
||||||
|
void draw_line(int *framebuffer, struct fb_var_screeninfo vinfo, int x0, int y0, int x1, int y1, int color) {
|
||||||
|
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||||
|
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||||
|
int err = dx + dy, e2;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
set_pixel(framebuffer, vinfo, x0, y0, color);
|
||||||
|
if (x0 == x1 && y0 == y1) break;
|
||||||
|
e2 = 2 * err;
|
||||||
|
if (e2 >= dy) { err += dy; x0 += sx; }
|
||||||
|
if (e2 <= dx) { err += dx; y0 += sy; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a simple filled rectangle to represent text characters
|
||||||
|
void draw_char(int *framebuffer, struct fb_var_screeninfo vinfo, char c, int x, int y, int size, int color) {
|
||||||
|
static const char font[10][5][3] = {
|
||||||
|
{ "111", "101", "101", "101", "111" }, // '0'
|
||||||
|
{ "110", "010", "010", "010", "111" }, // '1'
|
||||||
|
{ "111", "001", "111", "100", "111" }, // '2'
|
||||||
|
{ "111", "001", "111", "001", "111" }, // '3'
|
||||||
|
{ "101", "101", "111", "001", "001" }, // '4'
|
||||||
|
{ "111", "100", "111", "001", "111" }, // '5'
|
||||||
|
{ "111", "100", "111", "101", "111" }, // '6'
|
||||||
|
{ "111", "001", "001", "001", "001" }, // '7'
|
||||||
|
{ "111", "101", "111", "101", "111" }, // '8'
|
||||||
|
{ "111", "101", "111", "001", "111" } // '9'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
int index = c - '0';
|
||||||
|
for (int row = 0; row < 5; ++row) {
|
||||||
|
for (int col = 0; col < 3; ++col) {
|
||||||
|
if (font[index][row][col] == '1') {
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
for (int j = 0; j < size; ++j) {
|
||||||
|
set_pixel(framebuffer, vinfo, x + col * size + i, y + row * size + j, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a string of characters
|
||||||
|
void draw_text(int *framebuffer, struct fb_var_screeninfo vinfo, const char *text, int x, int y, int size, int color) {
|
||||||
|
for (const char *p = text; *p; ++p) {
|
||||||
|
draw_char(framebuffer, vinfo, *p, x, y, size, color);
|
||||||
|
x += size * 4; // Move to the next character position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw numbers around the clock face
|
||||||
|
void draw_circle(int *framebuffer, struct fb_var_screeninfo vinfo) {
|
||||||
|
for (int i = 1; i <= 12; ++i) {
|
||||||
|
float angle = (i * 30 - 90) * M_PI / 180.0;
|
||||||
|
int x = CENTER_X + (int)(RADIUS * cos(angle));
|
||||||
|
int y = CENTER_Y + (int)(RADIUS * sin(angle));
|
||||||
|
|
||||||
|
char buffer[3];
|
||||||
|
sprintf(buffer, "%d", i);
|
||||||
|
draw_text(framebuffer, vinfo, buffer, x - 10, y - 10, 3, 0xFFFFFF); // Increased the size to '3' for visibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw clock hands
|
||||||
|
void draw_hand(int *framebuffer, struct fb_var_screeninfo vinfo, float angle, int length, int color) {
|
||||||
|
int x_end = CENTER_X + length * cos(angle);
|
||||||
|
int y_end = CENTER_Y - length * sin(angle);
|
||||||
|
draw_line(framebuffer, vinfo, CENTER_X, CENTER_Y, x_end, y_end, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the clock face with numbers
|
||||||
|
void draw_clock_face(int *framebuffer, struct fb_var_screeninfo vinfo) {
|
||||||
|
memset(framebuffer, 0, vinfo.yres_virtual * vinfo.xres_virtual * sizeof(int)); // Clear screen
|
||||||
|
draw_circle(framebuffer, vinfo); // Draw the numbers
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the clock hands and date/time display
|
||||||
|
void update_time(int *framebuffer, struct fb_var_screeninfo vinfo) {
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm *timeinfo;
|
||||||
|
char date_buffer[80];
|
||||||
|
char time_buffer[80];
|
||||||
|
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
|
||||||
|
// Calculate the angle for the hour hand
|
||||||
|
float hour_angle_degrees = (30 * timeinfo->tm_hour) + (timeinfo->tm_min * 0.5);
|
||||||
|
float hour_angle = - hour_angle_degrees * M_PI / 180.0 + M_PI / 2; // Convert to radians and adjust to 12 o'clock start
|
||||||
|
|
||||||
|
// Calculate the angle for the minute hand
|
||||||
|
float minute_angle_degrees = 6 * timeinfo->tm_min;
|
||||||
|
float minute_angle = - minute_angle_degrees * M_PI / 180.0 + M_PI / 2; // Convert to radians and adjust to 12 o'clock start
|
||||||
|
|
||||||
|
// Draw both hands in white (0xFFFFFF)
|
||||||
|
draw_hand(framebuffer, vinfo, hour_angle, HOUR_HAND_LENGTH, 0xFFFFFF); // Hour hand is shorter
|
||||||
|
draw_hand(framebuffer, vinfo, minute_angle, MINUTE_HAND_LENGTH, 0xFFFFFF); // Minute hand is longer
|
||||||
|
|
||||||
|
// Display the date
|
||||||
|
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", timeinfo);
|
||||||
|
draw_text(framebuffer, vinfo, date_buffer, CENTER_X - 100, CENTER_Y + 300, 3, 0xFFFFFF); // Moved lower and increased size
|
||||||
|
|
||||||
|
// Display the time
|
||||||
|
strftime(time_buffer, sizeof(time_buffer), "%H:%M:%S", timeinfo);
|
||||||
|
draw_text(framebuffer, vinfo, time_buffer, CENTER_X - 80, CENTER_Y + 350, 3, 0xFFFFFF); // Moved lower and increased size
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Open the framebuffer device
|
||||||
|
int fbfd = open("/dev/fb0", O_RDWR);
|
||||||
|
if (fbfd == -1) {
|
||||||
|
perror("Error: cannot open framebuffer device");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get variable screen information
|
||||||
|
struct fb_var_screeninfo vinfo;
|
||||||
|
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
|
||||||
|
perror("Error reading variable information");
|
||||||
|
close(fbfd);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map the framebuffer to user memory
|
||||||
|
size_t screensize = vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8;
|
||||||
|
int *framebuffer = (int *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
|
||||||
|
if (framebuffer == MAP_FAILED) {
|
||||||
|
perror("Error mapping framebuffer device to memory");
|
||||||
|
close(fbfd);
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continuously update the clock
|
||||||
|
while (1) {
|
||||||
|
draw_clock_face(framebuffer, vinfo);
|
||||||
|
update_time(framebuffer, vinfo);
|
||||||
|
sleep(1); // Sleep for 1 second to update the clock every second
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
munmap(framebuffer, screensize);
|
||||||
|
close(fbfd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
165
clock/src/clock.c.bak
Normal file
165
clock/src/clock.c.bak
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
// src/clock.c
|
||||||
|
#include "../include/clock.h"
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// Set a pixel at (x, y) with color in the framebuffer
|
||||||
|
void set_pixel(int *framebuffer, struct fb_var_screeninfo vinfo, int x, int y, int color) {
|
||||||
|
if (x >= 0 && x < vinfo.xres_virtual && y >= 0 && y < vinfo.yres_virtual) {
|
||||||
|
framebuffer[y * vinfo.xres_virtual + x] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bresenham's line algorithm for drawing lines
|
||||||
|
void draw_line(int *framebuffer, struct fb_var_screeninfo vinfo, int x0, int y0, int x1, int y1, int color) {
|
||||||
|
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||||
|
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||||
|
int err = dx + dy, e2;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
set_pixel(framebuffer, vinfo, x0, y0, color);
|
||||||
|
if (x0 == x1 && y0 == y1) break;
|
||||||
|
e2 = 2 * err;
|
||||||
|
if (e2 >= dy) { err += dy; x0 += sx; }
|
||||||
|
if (e2 <= dx) { err += dx; y0 += sy; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a simple filled rectangle to represent text characters
|
||||||
|
void draw_char(int *framebuffer, struct fb_var_screeninfo vinfo, char c, int x, int y, int size, int color) {
|
||||||
|
static const char font[10][5][3] = {
|
||||||
|
{ "111", "101", "101", "101", "111" }, // '0'
|
||||||
|
{ "110", "010", "010", "010", "111" }, // '1'
|
||||||
|
{ "111", "001", "111", "100", "111" }, // '2'
|
||||||
|
{ "111", "001", "111", "001", "111" }, // '3'
|
||||||
|
{ "101", "101", "111", "001", "001" }, // '4'
|
||||||
|
{ "111", "100", "111", "001", "111" }, // '5'
|
||||||
|
{ "111", "100", "111", "101", "111" }, // '6'
|
||||||
|
{ "111", "001", "001", "001", "001" }, // '7'
|
||||||
|
{ "111", "101", "111", "101", "111" }, // '8'
|
||||||
|
{ "111", "101", "111", "001", "111" } // '9'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
int index = c - '0';
|
||||||
|
for (int row = 0; row < 5; ++row) {
|
||||||
|
for (int col = 0; col < 3; ++col) {
|
||||||
|
if (font[index][row][col] == '1') {
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
for (int j = 0; j < size; ++j) {
|
||||||
|
set_pixel(framebuffer, vinfo, x + col * size + i, y + row * size + j, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a string of characters
|
||||||
|
void draw_text(int *framebuffer, struct fb_var_screeninfo vinfo, const char *text, int x, int y, int size, int color) {
|
||||||
|
for (const char *p = text; *p; ++p) {
|
||||||
|
draw_char(framebuffer, vinfo, *p, x, y, size, color);
|
||||||
|
x += size * 4; // Move to the next character position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw numbers around the clock face
|
||||||
|
void draw_circle(int *framebuffer, struct fb_var_screeninfo vinfo) {
|
||||||
|
for (int i = 1; i <= 12; ++i) {
|
||||||
|
float angle = (i * 30 - 90) * M_PI / 180.0;
|
||||||
|
int x = CENTER_X + (int)(RADIUS * cos(angle));
|
||||||
|
int y = CENTER_Y + (int)(RADIUS * sin(angle));
|
||||||
|
|
||||||
|
char buffer[3];
|
||||||
|
sprintf(buffer, "%d", i);
|
||||||
|
draw_text(framebuffer, vinfo, buffer, x - 10, y - 10, 3, 0xFFFFFF); // Increased the size to '3' for visibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw clock hands
|
||||||
|
void draw_hand(int *framebuffer, struct fb_var_screeninfo vinfo, float angle, int length, int color) {
|
||||||
|
int x_end = CENTER_X + length * cos(angle);
|
||||||
|
int y_end = CENTER_Y - length * sin(angle);
|
||||||
|
draw_line(framebuffer, vinfo, CENTER_X, CENTER_Y, x_end, y_end, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the clock face with numbers
|
||||||
|
void draw_clock_face(int *framebuffer, struct fb_var_screeninfo vinfo) {
|
||||||
|
memset(framebuffer, 0, vinfo.yres_virtual * vinfo.xres_virtual * sizeof(int)); // Clear screen
|
||||||
|
draw_circle(framebuffer, vinfo); // Draw the numbers
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the clock hands and date/time display
|
||||||
|
void update_time(int *framebuffer, struct fb_var_screeninfo vinfo) {
|
||||||
|
time_t rawtime;
|
||||||
|
struct tm *timeinfo;
|
||||||
|
char date_buffer[80];
|
||||||
|
char time_buffer[80];
|
||||||
|
|
||||||
|
time(&rawtime);
|
||||||
|
timeinfo = localtime(&rawtime);
|
||||||
|
|
||||||
|
// Correcting hour and minute hand angles
|
||||||
|
float hour_angle = ((timeinfo->tm_hour % 12) * 30 + timeinfo->tm_min * 0.5) * (M_PI / 180.0) - M_PI / 2;
|
||||||
|
float minute_angle = (timeinfo->tm_min * 6 + timeinfo->tm_sec * 0.1) * (M_PI / 180.0) - M_PI / 2;
|
||||||
|
|
||||||
|
// Draw both hands in black color
|
||||||
|
draw_hand(framebuffer, vinfo, hour_angle, HOUR_HAND_LENGTH, 0x000000); // Hour hand in black
|
||||||
|
draw_hand(framebuffer, vinfo, minute_angle, MINUTE_HAND_LENGTH, 0x000000); // Minute hand in black
|
||||||
|
|
||||||
|
// Display the date
|
||||||
|
strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", timeinfo);
|
||||||
|
draw_text(framebuffer, vinfo, date_buffer, CENTER_X - 100, CENTER_Y + 300, 3, 0xFFFFFF); // Moved lower and increased size
|
||||||
|
|
||||||
|
// Display the time
|
||||||
|
strftime(time_buffer, sizeof(time_buffer), "%H:%M:%S", timeinfo);
|
||||||
|
draw_text(framebuffer, vinfo, time_buffer, CENTER_X - 80, CENTER_Y + 350, 3, 0xFFFFFF); // Moved lower and increased size
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function
|
||||||
|
int main() {
|
||||||
|
// Open the framebuffer device
|
||||||
|
int fbfd = open("/dev/fb0", O_RDWR);
|
||||||
|
if (fbfd == -1) {
|
||||||
|
perror("Error: cannot open framebuffer device");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get variable screen information
|
||||||
|
struct fb_var_screeninfo vinfo;
|
||||||
|
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
|
||||||
|
perror("Error reading variable information");
|
||||||
|
close(fbfd);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map the framebuffer to user memory
|
||||||
|
size_t screensize = vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8;
|
||||||
|
int *framebuffer = (int *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
|
||||||
|
if (framebuffer == MAP_FAILED) {
|
||||||
|
perror("Error mapping framebuffer device to memory");
|
||||||
|
close(fbfd);
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continuously update the clock
|
||||||
|
while (1) {
|
||||||
|
draw_clock_face(framebuffer, vinfo);
|
||||||
|
update_time(framebuffer, vinfo);
|
||||||
|
sleep(1); // Sleep for 1 second to update the clock every second
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
munmap(framebuffer, screensize);
|
||||||
|
close(fbfd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
3
render/README.md
Normal file
3
render/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# render Project
|
||||||
|
|
||||||
|
This is a C project generated with the setup tool.
|
||||||
26
render/build/Makefile
Normal file
26
render/build/Makefile
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
CC = gcc
|
||||||
|
CFLAGS = -Wall -O2
|
||||||
|
|
||||||
|
SRC_DIR = ../src
|
||||||
|
OBJ_DIR = ../obj
|
||||||
|
BUILD_DIR = .
|
||||||
|
|
||||||
|
TARGET = $(BUILD_DIR)/cube_render
|
||||||
|
|
||||||
|
SRCS = $(wildcard $(SRC_DIR)/*.c)
|
||||||
|
OBJS = $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) -o $@ $^ -lm
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
||||||
|
@mkdir -p $(OBJ_DIR)
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(OBJ_DIR)/*.o $(TARGET)
|
||||||
|
|
||||||
|
rebuild: clean all
|
||||||
|
|
||||||
BIN
render/build/cube_render
Executable file
BIN
render/build/cube_render
Executable file
Binary file not shown.
BIN
render/obj/main.o
Normal file
BIN
render/obj/main.o
Normal file
Binary file not shown.
189
render/src/cube.c.bak
Normal file
189
render/src/cube.c.bak
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Cube parameters
|
||||||
|
#define CUBE_SIZE 200.0
|
||||||
|
#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit
|
||||||
|
#define FRAME_DELAY 16000 // Microseconds (about 60fps)
|
||||||
|
#define ROTATION_SPEED 0.02
|
||||||
|
|
||||||
|
// Structure for framebuffer info
|
||||||
|
struct framebuffer_info {
|
||||||
|
int fb_fd;
|
||||||
|
uint8_t* fb_ptr;
|
||||||
|
struct fb_var_screeninfo vinfo;
|
||||||
|
struct fb_fix_screeninfo finfo;
|
||||||
|
long int screensize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Structure for 3D point
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
|
} Point3D;
|
||||||
|
|
||||||
|
// Cube vertices
|
||||||
|
Point3D cube[8] = {
|
||||||
|
{-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cube edges
|
||||||
|
int edges[12][2] = {
|
||||||
|
{0, 1}, {1, 2}, {2, 3}, {3, 0}, // Bottom face
|
||||||
|
{4, 5}, {5, 6}, {6, 7}, {7, 4}, // Top face
|
||||||
|
{0, 4}, {1, 5}, {2, 6}, {3, 7} // Connecting edges
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to initialize framebuffer
|
||||||
|
struct framebuffer_info init_framebuffer(const char* fb_path) {
|
||||||
|
struct framebuffer_info fb_info;
|
||||||
|
|
||||||
|
fb_info.fb_fd = open(fb_path, O_RDWR);
|
||||||
|
if (fb_info.fb_fd == -1) {
|
||||||
|
perror("Error opening framebuffer device");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fixed screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) {
|
||||||
|
perror("Error reading fixed information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get variable screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) {
|
||||||
|
perror("Error reading variable information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the screen size in bytes
|
||||||
|
fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length;
|
||||||
|
|
||||||
|
// Map framebuffer to memory
|
||||||
|
fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0);
|
||||||
|
if ((intptr_t)fb_info.fb_ptr == -1) {
|
||||||
|
perror("Error mapping framebuffer to memory");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fb_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to clear the screen
|
||||||
|
void clear_screen(struct framebuffer_info* fb_info) {
|
||||||
|
for (int i = 0; i < fb_info->screensize; i++) {
|
||||||
|
fb_info->fb_ptr[i] = 0; // Set each pixel to black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to set a pixel in the framebuffer
|
||||||
|
void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) {
|
||||||
|
if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) {
|
||||||
|
long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) +
|
||||||
|
(y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length;
|
||||||
|
|
||||||
|
// Handle different bits per pixel
|
||||||
|
if (fb_info->vinfo.bits_per_pixel == 32) {
|
||||||
|
*((uint32_t*)(fb_info->fb_ptr + location)) = color;
|
||||||
|
} else if (fb_info->vinfo.bits_per_pixel == 16) {
|
||||||
|
uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3);
|
||||||
|
*((uint16_t*)(fb_info->fb_ptr + location)) = rgb565;
|
||||||
|
} else {
|
||||||
|
printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bresenham's Line Algorithm
|
||||||
|
void draw_line(struct framebuffer_info* fb_info, int x0, int y0, int x1, int y1, uint32_t color) {
|
||||||
|
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||||
|
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||||
|
int err = dx + dy, e2;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
set_pixel(fb_info, x0, y0, color);
|
||||||
|
if (x0 == x1 && y0 == y1) break;
|
||||||
|
e2 = 2 * err;
|
||||||
|
if (e2 >= dy) { err += dy; x0 += sx; }
|
||||||
|
if (e2 <= dx) { err += dx; y0 += sy; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to rotate 3D point
|
||||||
|
void rotate(Point3D* p, float angleX, float angleY, float angleZ) {
|
||||||
|
// Rotation around X-axis
|
||||||
|
float y = p->y * cos(angleX) - p->z * sin(angleX);
|
||||||
|
float z = p->y * sin(angleX) + p->z * cos(angleX);
|
||||||
|
p->y = y;
|
||||||
|
p->z = z;
|
||||||
|
|
||||||
|
// Rotation around Y-axis
|
||||||
|
float x = p->x * cos(angleY) + p->z * sin(angleY);
|
||||||
|
z = -p->x * sin(angleY) + p->z * cos(angleY);
|
||||||
|
p->x = x;
|
||||||
|
p->z = z;
|
||||||
|
|
||||||
|
// Rotation around Z-axis
|
||||||
|
x = p->x * cos(angleZ) - p->y * sin(angleZ);
|
||||||
|
y = p->x * sin(angleZ) + p->y * cos(angleZ);
|
||||||
|
p->x = x;
|
||||||
|
p->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to project 3D point onto 2D screen
|
||||||
|
void project(Point3D p, int* x2D, int* y2D, int screenWidth, int screenHeight, float dist) {
|
||||||
|
*x2D = (int)(screenWidth / 2 + p.x * (dist / (p.z + dist)));
|
||||||
|
*y2D = (int)(screenHeight / 2 + p.y * (dist / (p.z + dist)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function
|
||||||
|
int main() {
|
||||||
|
struct framebuffer_info fb_info = init_framebuffer("/dev/fb0");
|
||||||
|
|
||||||
|
float angleX = 0, angleY = 0, angleZ = 0;
|
||||||
|
float dist = 400.0f;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
clear_screen(&fb_info);
|
||||||
|
|
||||||
|
Point3D transformed[8];
|
||||||
|
int projected[8][2];
|
||||||
|
|
||||||
|
// Rotate and project each vertex
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
transformed[i] = cube[i];
|
||||||
|
rotate(&transformed[i], angleX, angleY, angleZ);
|
||||||
|
project(transformed[i], &projected[i][0], &projected[i][1], fb_info.vinfo.xres, fb_info.vinfo.yres, dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the cube edges
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
draw_line(&fb_info, projected[edges[i][0]][0], projected[edges[i][0]][1],
|
||||||
|
projected[edges[i][1]][0], projected[edges[i][1]][1], COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment angles for rotation
|
||||||
|
angleX += ROTATION_SPEED;
|
||||||
|
angleY += ROTATION_SPEED * 0.5;
|
||||||
|
angleZ += ROTATION_SPEED * 0.25;
|
||||||
|
|
||||||
|
usleep(FRAME_DELAY); // Sleep for ~60fps
|
||||||
|
}
|
||||||
|
|
||||||
|
munmap(fb_info.fb_ptr, fb_info.screensize);
|
||||||
|
close(fb_info.fb_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
196
render/src/main.c
Normal file
196
render/src/main.c
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define CUBE_SIZE 200.0
|
||||||
|
#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit
|
||||||
|
#define FRAME_DELAY 50000 // Slower: Microseconds (~20fps)
|
||||||
|
#define ROTATION_SPEED 0.003 // Slower rotation speed
|
||||||
|
|
||||||
|
// Structure for framebuffer info
|
||||||
|
struct framebuffer_info {
|
||||||
|
int fb_fd;
|
||||||
|
uint8_t* fb_ptr;
|
||||||
|
struct fb_var_screeninfo vinfo;
|
||||||
|
struct fb_fix_screeninfo finfo;
|
||||||
|
long int screensize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Structure for 3D point
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
|
} Point3D;
|
||||||
|
|
||||||
|
// Cube vertices
|
||||||
|
Point3D cube[8] = {
|
||||||
|
{-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cube edges
|
||||||
|
int edges[12][2] = {
|
||||||
|
{0, 1}, {1, 2}, {2, 3}, {3, 0}, // Bottom face
|
||||||
|
{4, 5}, {5, 6}, {6, 7}, {7, 4}, // Top face
|
||||||
|
{0, 4}, {1, 5}, {2, 6}, {3, 7} // Connecting edges
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to initialize framebuffer
|
||||||
|
struct framebuffer_info init_framebuffer(const char* fb_path) {
|
||||||
|
struct framebuffer_info fb_info;
|
||||||
|
|
||||||
|
fb_info.fb_fd = open(fb_path, O_RDWR);
|
||||||
|
if (fb_info.fb_fd == -1) {
|
||||||
|
perror("Error opening framebuffer device");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fixed screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) {
|
||||||
|
perror("Error reading fixed information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get variable screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) {
|
||||||
|
perror("Error reading variable information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the screen size in bytes
|
||||||
|
fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length;
|
||||||
|
|
||||||
|
// Map framebuffer to memory
|
||||||
|
fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0);
|
||||||
|
if ((intptr_t)fb_info.fb_ptr == -1) {
|
||||||
|
perror("Error mapping framebuffer to memory");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fb_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to clear the screen
|
||||||
|
void clear_screen(struct framebuffer_info* fb_info) {
|
||||||
|
for (int i = 0; i < fb_info->screensize; i++) {
|
||||||
|
fb_info->fb_ptr[i] = 0; // Set each pixel to black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to set a pixel in the framebuffer
|
||||||
|
void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) {
|
||||||
|
if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) {
|
||||||
|
long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) +
|
||||||
|
(y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length;
|
||||||
|
|
||||||
|
// Handle different bits per pixel
|
||||||
|
if (fb_info->vinfo.bits_per_pixel == 32) {
|
||||||
|
*((uint32_t*)(fb_info->fb_ptr + location)) = color;
|
||||||
|
} else if (fb_info->vinfo.bits_per_pixel == 16) {
|
||||||
|
uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3);
|
||||||
|
*((uint16_t*)(fb_info->fb_ptr + location)) = rgb565;
|
||||||
|
} else {
|
||||||
|
printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Improved Bresenham's Line Algorithm with edge cases handling
|
||||||
|
void draw_line(struct framebuffer_info* fb_info, int x0, int y0, int x1, int y1, uint32_t color) {
|
||||||
|
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||||
|
int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||||
|
int err = dx + dy, e2;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
set_pixel(fb_info, x0, y0, color);
|
||||||
|
if (x0 == x1 && y0 == y1) break;
|
||||||
|
|
||||||
|
e2 = 2 * err;
|
||||||
|
if (e2 >= dy) { err += dy; x0 += sx; }
|
||||||
|
if (e2 <= dx) { err += dx; y0 += sy; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to rotate 3D point
|
||||||
|
void rotate(Point3D* p, float angleX, float angleY, float angleZ) {
|
||||||
|
// Rotation around X-axis
|
||||||
|
float y = p->y * cos(angleX) - p->z * sin(angleX);
|
||||||
|
float z = p->y * sin(angleX) + p->z * cos(angleX);
|
||||||
|
p->y = y;
|
||||||
|
p->z = z;
|
||||||
|
|
||||||
|
// Rotation around Y-axis
|
||||||
|
float x = p->x * cos(angleY) + p->z * sin(angleY);
|
||||||
|
z = -p->x * sin(angleY) + p->z * cos(angleY);
|
||||||
|
p->x = x;
|
||||||
|
p->z = z;
|
||||||
|
|
||||||
|
// Rotation around Z-axis
|
||||||
|
x = p->x * cos(angleZ) - p->y * sin(angleZ);
|
||||||
|
y = p->x * sin(angleZ) + p->y * cos(angleZ);
|
||||||
|
p->x = x;
|
||||||
|
p->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to project 3D point onto 2D screen
|
||||||
|
void project(Point3D p, int* x2D, int* y2D, int screenWidth, int screenHeight, float dist) {
|
||||||
|
float scale = dist / (p.z + dist); // Perspective scaling
|
||||||
|
*x2D = (int)(screenWidth / 2 + p.x * scale);
|
||||||
|
*y2D = (int)(screenHeight / 2 + p.y * scale);
|
||||||
|
|
||||||
|
// Ensure the projected point remains within screen bounds
|
||||||
|
if (*x2D < 0) *x2D = 0;
|
||||||
|
if (*x2D >= screenWidth) *x2D = screenWidth - 1;
|
||||||
|
if (*y2D < 0) *y2D = 0;
|
||||||
|
if (*y2D >= screenHeight) *y2D = screenHeight - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function
|
||||||
|
int main() {
|
||||||
|
struct framebuffer_info fb_info = init_framebuffer("/dev/fb0");
|
||||||
|
|
||||||
|
float angleX = 0, angleY = 0, angleZ = 0;
|
||||||
|
float dist = 400.0f;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
clear_screen(&fb_info);
|
||||||
|
|
||||||
|
Point3D transformed[8];
|
||||||
|
int projected[8][2];
|
||||||
|
|
||||||
|
// Rotate and project each vertex
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
transformed[i] = cube[i];
|
||||||
|
rotate(&transformed[i], angleX, angleY, angleZ);
|
||||||
|
project(transformed[i], &projected[i][0], &projected[i][1], fb_info.vinfo.xres, fb_info.vinfo.yres, dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the cube edges
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
draw_line(&fb_info, projected[edges[i][0]][0], projected[edges[i][0]][1],
|
||||||
|
projected[edges[i][1]][0], projected[edges[i][1]][1], COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment angles for slower rotation
|
||||||
|
angleX += ROTATION_SPEED;
|
||||||
|
angleY += ROTATION_SPEED * 0.5;
|
||||||
|
angleZ += ROTATION_SPEED * 0.25;
|
||||||
|
|
||||||
|
usleep(FRAME_DELAY); // Slower frame rate for smoother rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
munmap(fb_info.fb_ptr, fb_info.screensize);
|
||||||
|
close(fb_info.fb_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
114
render/src/pixeltest.c.bak
Normal file
114
render/src/pixeltest.c.bak
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Cube parameters
|
||||||
|
#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit
|
||||||
|
|
||||||
|
// Structure for framebuffer info
|
||||||
|
struct framebuffer_info {
|
||||||
|
int fb_fd;
|
||||||
|
uint8_t* fb_ptr;
|
||||||
|
struct fb_var_screeninfo vinfo;
|
||||||
|
struct fb_fix_screeninfo finfo;
|
||||||
|
long int screensize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to initialize framebuffer
|
||||||
|
struct framebuffer_info init_framebuffer(const char* fb_path) {
|
||||||
|
struct framebuffer_info fb_info;
|
||||||
|
|
||||||
|
fb_info.fb_fd = open(fb_path, O_RDWR);
|
||||||
|
if (fb_info.fb_fd == -1) {
|
||||||
|
perror("Error opening framebuffer device");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fixed screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) {
|
||||||
|
perror("Error reading fixed information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get variable screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) {
|
||||||
|
perror("Error reading variable information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the screen size in bytes
|
||||||
|
fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length;
|
||||||
|
|
||||||
|
// Map framebuffer to memory
|
||||||
|
fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0);
|
||||||
|
if ((intptr_t)fb_info.fb_ptr == -1) {
|
||||||
|
perror("Error mapping framebuffer to memory");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugging: print framebuffer info
|
||||||
|
printf("Framebuffer resolution: %dx%d, %d bpp\n", fb_info.vinfo.xres, fb_info.vinfo.yres, fb_info.vinfo.bits_per_pixel);
|
||||||
|
printf("Framebuffer screensize: %ld bytes\n", fb_info.screensize);
|
||||||
|
|
||||||
|
return fb_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to clear the screen
|
||||||
|
void clear_screen(struct framebuffer_info* fb_info) {
|
||||||
|
for (int i = 0; i < fb_info->screensize; i++) {
|
||||||
|
fb_info->fb_ptr[i] = 0; // Set each pixel to black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to set a pixel in the framebuffer
|
||||||
|
void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) {
|
||||||
|
if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) {
|
||||||
|
long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) +
|
||||||
|
(y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length;
|
||||||
|
|
||||||
|
// Handle different bits per pixel
|
||||||
|
if (fb_info->vinfo.bits_per_pixel == 32) {
|
||||||
|
// 32-bit color (ARGB or XRGB)
|
||||||
|
*((uint32_t*)(fb_info->fb_ptr + location)) = color;
|
||||||
|
} else if (fb_info->vinfo.bits_per_pixel == 16) {
|
||||||
|
// 16-bit color (RGB565)
|
||||||
|
uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3);
|
||||||
|
*((uint16_t*)(fb_info->fb_ptr + location)) = rgb565;
|
||||||
|
} else {
|
||||||
|
printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function
|
||||||
|
int main() {
|
||||||
|
// Initialize framebuffer
|
||||||
|
struct framebuffer_info fb_info = init_framebuffer("/dev/fb0");
|
||||||
|
|
||||||
|
// Clear the screen first
|
||||||
|
clear_screen(&fb_info);
|
||||||
|
|
||||||
|
// Draw a pixel at the center of the screen to test framebuffer access
|
||||||
|
int center_x = fb_info.vinfo.xres / 2;
|
||||||
|
int center_y = fb_info.vinfo.yres / 2;
|
||||||
|
printf("Drawing pixel at center: (%d, %d)\n", center_x, center_y);
|
||||||
|
|
||||||
|
// Use appropriate color depth
|
||||||
|
set_pixel(&fb_info, center_x, center_y, COLOR); // Draw white pixel at the center
|
||||||
|
|
||||||
|
// Hold for a while to inspect
|
||||||
|
printf("Framebuffer test complete. Pixel drawn at the center.\n");
|
||||||
|
sleep(10); // Wait for 10 seconds to allow visual inspection
|
||||||
|
|
||||||
|
// Unmap and close the framebuffer
|
||||||
|
munmap(fb_info.fb_ptr, fb_info.screensize);
|
||||||
|
close(fb_info.fb_fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
189
render/src/slow_cube.c.bak
Normal file
189
render/src/slow_cube.c.bak
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define CUBE_SIZE 200.0
|
||||||
|
#define COLOR 0xFFFFFF // White for 32-bit or RGB565 for 16-bit
|
||||||
|
#define FRAME_DELAY 50000 // Slower: Microseconds (~20fps)
|
||||||
|
#define ROTATION_SPEED 0.005 // Slower rotation speed
|
||||||
|
|
||||||
|
// Structure for framebuffer info
|
||||||
|
struct framebuffer_info {
|
||||||
|
int fb_fd;
|
||||||
|
uint8_t* fb_ptr;
|
||||||
|
struct fb_var_screeninfo vinfo;
|
||||||
|
struct fb_fix_screeninfo finfo;
|
||||||
|
long int screensize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Structure for 3D point
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
|
} Point3D;
|
||||||
|
|
||||||
|
// Cube vertices
|
||||||
|
Point3D cube[8] = {
|
||||||
|
{-CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, -CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, CUBE_SIZE, -CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, -CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{ CUBE_SIZE, CUBE_SIZE, CUBE_SIZE},
|
||||||
|
{-CUBE_SIZE, CUBE_SIZE, CUBE_SIZE}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Cube edges
|
||||||
|
int edges[12][2] = {
|
||||||
|
{0, 1}, {1, 2}, {2, 3}, {3, 0}, // Bottom face
|
||||||
|
{4, 5}, {5, 6}, {6, 7}, {7, 4}, // Top face
|
||||||
|
{0, 4}, {1, 5}, {2, 6}, {3, 7} // Connecting edges
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to initialize framebuffer
|
||||||
|
struct framebuffer_info init_framebuffer(const char* fb_path) {
|
||||||
|
struct framebuffer_info fb_info;
|
||||||
|
|
||||||
|
fb_info.fb_fd = open(fb_path, O_RDWR);
|
||||||
|
if (fb_info.fb_fd == -1) {
|
||||||
|
perror("Error opening framebuffer device");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fixed screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_FSCREENINFO, &fb_info.finfo)) {
|
||||||
|
perror("Error reading fixed information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get variable screen information
|
||||||
|
if (ioctl(fb_info.fb_fd, FBIOGET_VSCREENINFO, &fb_info.vinfo)) {
|
||||||
|
perror("Error reading variable information");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the screen size in bytes
|
||||||
|
fb_info.screensize = fb_info.vinfo.yres_virtual * fb_info.finfo.line_length;
|
||||||
|
|
||||||
|
// Map framebuffer to memory
|
||||||
|
fb_info.fb_ptr = (uint8_t*)mmap(0, fb_info.screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_info.fb_fd, 0);
|
||||||
|
if ((intptr_t)fb_info.fb_ptr == -1) {
|
||||||
|
perror("Error mapping framebuffer to memory");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fb_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to clear the screen
|
||||||
|
void clear_screen(struct framebuffer_info* fb_info) {
|
||||||
|
for (int i = 0; i < fb_info->screensize; i++) {
|
||||||
|
fb_info->fb_ptr[i] = 0; // Set each pixel to black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to set a pixel in the framebuffer
|
||||||
|
void set_pixel(struct framebuffer_info* fb_info, int x, int y, uint32_t color) {
|
||||||
|
if (x >= 0 && x < fb_info->vinfo.xres && y >= 0 && y < fb_info->vinfo.yres) {
|
||||||
|
long location = (x + fb_info->vinfo.xoffset) * (fb_info->vinfo.bits_per_pixel / 8) +
|
||||||
|
(y + fb_info->vinfo.yoffset) * fb_info->finfo.line_length;
|
||||||
|
|
||||||
|
// Handle different bits per pixel
|
||||||
|
if (fb_info->vinfo.bits_per_pixel == 32) {
|
||||||
|
*((uint32_t*)(fb_info->fb_ptr + location)) = color;
|
||||||
|
} else if (fb_info->vinfo.bits_per_pixel == 16) {
|
||||||
|
uint16_t rgb565 = ((color & 0xF80000) >> 8) | ((color & 0x00FC00) >> 5) | ((color & 0x0000F8) >> 3);
|
||||||
|
*((uint16_t*)(fb_info->fb_ptr + location)) = rgb565;
|
||||||
|
} else {
|
||||||
|
printf("Unsupported bits per pixel: %d\n", fb_info->vinfo.bits_per_pixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Improved Bresenham's Line Algorithm with edge cases handling
|
||||||
|
void draw_line(struct framebuffer_info* fb_info, int x0, int y0, int x1, int y1, uint32_t color) {
|
||||||
|
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||||
|
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||||
|
int err = (dx > dy ? dx : -dy) / 2, e2;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
set_pixel(fb_info, x0, y0, color);
|
||||||
|
if (x0 == x1 && y0 == y1) break;
|
||||||
|
e2 = err;
|
||||||
|
if (e2 > -dx) { err -= dy; x0 += sx; }
|
||||||
|
if (e2 < dy) { err += dx; y0 += sy; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to rotate 3D point
|
||||||
|
void rotate(Point3D* p, float angleX, float angleY, float angleZ) {
|
||||||
|
// Rotation around X-axis
|
||||||
|
float y = p->y * cos(angleX) - p->z * sin(angleX);
|
||||||
|
float z = p->y * sin(angleX) + p->z * cos(angleX);
|
||||||
|
p->y = y;
|
||||||
|
p->z = z;
|
||||||
|
|
||||||
|
// Rotation around Y-axis
|
||||||
|
float x = p->x * cos(angleY) + p->z * sin(angleY);
|
||||||
|
z = -p->x * sin(angleY) + p->z * cos(angleY);
|
||||||
|
p->x = x;
|
||||||
|
p->z = z;
|
||||||
|
|
||||||
|
// Rotation around Z-axis
|
||||||
|
x = p->x * cos(angleZ) - p->y * sin(angleZ);
|
||||||
|
y = p->x * sin(angleZ) + p->y * cos(angleZ);
|
||||||
|
p->x = x;
|
||||||
|
p->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to project 3D point onto 2D screen
|
||||||
|
void project(Point3D p, int* x2D, int* y2D, int screenWidth, int screenHeight, float dist) {
|
||||||
|
float scale = dist / (p.z + dist); // Perspective scaling
|
||||||
|
*x2D = (int)(screenWidth / 2 + p.x * scale);
|
||||||
|
*y2D = (int)(screenHeight / 2 + p.y * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function
|
||||||
|
int main() {
|
||||||
|
struct framebuffer_info fb_info = init_framebuffer("/dev/fb0");
|
||||||
|
|
||||||
|
float angleX = 0, angleY = 0, angleZ = 0;
|
||||||
|
float dist = 400.0f;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
clear_screen(&fb_info);
|
||||||
|
|
||||||
|
Point3D transformed[8];
|
||||||
|
int projected[8][2];
|
||||||
|
|
||||||
|
// Rotate and project each vertex
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
transformed[i] = cube[i];
|
||||||
|
rotate(&transformed[i], angleX, angleY, angleZ);
|
||||||
|
project(transformed[i], &projected[i][0], &projected[i][1], fb_info.vinfo.xres, fb_info.vinfo.yres, dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the cube edges
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
draw_line(&fb_info, projected[edges[i][0]][0], projected[edges[i][0]][1],
|
||||||
|
projected[edges[i][1]][0], projected[edges[i][1]][1], COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment angles for slower rotation
|
||||||
|
angleX += ROTATION_SPEED;
|
||||||
|
angleY += ROTATION_SPEED * 0.5;
|
||||||
|
angleZ += ROTATION_SPEED * 0.25;
|
||||||
|
|
||||||
|
usleep(FRAME_DELAY); // Slower frame rate for smoother rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
munmap(fb_info.fb_ptr, fb_info.screensize);
|
||||||
|
close(fb_info.fb_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
3
riceapp/README.md
Normal file
3
riceapp/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# riceapp Project
|
||||||
|
|
||||||
|
This is a C project generated with the setup tool.
|
||||||
24
riceapp/build/Makefile
Normal file
24
riceapp/build/Makefile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
CC = gcc
|
||||||
|
CFLAGS = -I../include -Wall -O2
|
||||||
|
LDFLAGS = -lm
|
||||||
|
SRCDIR = ../src
|
||||||
|
OBJDIR = ../obj
|
||||||
|
BUILDDIR = ../build
|
||||||
|
TARGET = cube_app
|
||||||
|
|
||||||
|
SOURCES = $(wildcard $(SRCDIR)/*.c)
|
||||||
|
OBJECTS = $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJECTS)
|
||||||
|
$(CC) $(OBJECTS) $(LDFLAGS) -o $(BUILDDIR)/$(TARGET)
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJDIR)/*.o $(BUILDDIR)/$(TARGET)
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
BIN
riceapp/build/cube_app
Executable file
BIN
riceapp/build/cube_app
Executable file
Binary file not shown.
21
riceapp/include/cube.h
Normal file
21
riceapp/include/cube.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef CUBE_H
|
||||||
|
#define CUBE_H
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x, y, z;
|
||||||
|
} Vertex;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int width, height;
|
||||||
|
} Screen;
|
||||||
|
|
||||||
|
// Function declarations
|
||||||
|
void init_framebuffer();
|
||||||
|
void draw_cube(Vertex vertices[8], Screen *screen);
|
||||||
|
void translate(Vertex *v, float dx, float dy, float dz);
|
||||||
|
void rotate_cube(Vertex vertices[8], float angleX, float angleY);
|
||||||
|
void update_screen(Screen *screen);
|
||||||
|
void handle_collision(Vertex *v, Screen *screen);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
BIN
riceapp/obj/cube.o
Normal file
BIN
riceapp/obj/cube.o
Normal file
Binary file not shown.
178
riceapp/src/cube.c
Normal file
178
riceapp/src/cube.c
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <linux/fb.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include "cube.h"
|
||||||
|
|
||||||
|
// Framebuffer and screen parameters
|
||||||
|
int fbfd = 0;
|
||||||
|
struct fb_var_screeninfo vinfo;
|
||||||
|
struct fb_fix_screeninfo finfo;
|
||||||
|
long int screensize = 0;
|
||||||
|
char *fbp = 0;
|
||||||
|
|
||||||
|
// Cube vertex data
|
||||||
|
Vertex vertices[8] = {
|
||||||
|
{-50, -50, -50}, {50, -50, -50}, {50, 50, -50}, {-50, 50, -50},
|
||||||
|
{-50, -50, 50}, {50, -50, 50}, {50, 50, 50}, {-50, 50, 50}
|
||||||
|
};
|
||||||
|
|
||||||
|
float velocityX = 2.0, velocityY = 1.5;
|
||||||
|
float rotationSpeed = 0.02;
|
||||||
|
float cubeX = 300, cubeY = 200;
|
||||||
|
Screen screen = {800, 600}; // Screen resolution
|
||||||
|
|
||||||
|
// Initialize framebuffer
|
||||||
|
void init_framebuffer() {
|
||||||
|
fbfd = open("/dev/fb0", O_RDWR);
|
||||||
|
if (fbfd == -1) {
|
||||||
|
perror("Error opening framebuffer device");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
|
||||||
|
perror("Error reading fixed information");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
|
||||||
|
perror("Error reading variable information");
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
screensize = vinfo.yres_virtual * finfo.line_length;
|
||||||
|
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
|
||||||
|
if ((int)fbp == -1) {
|
||||||
|
perror("Error mapping framebuffer device to memory");
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear screen
|
||||||
|
void clear_screen() {
|
||||||
|
for (int y = 0; y < screen.height; y++) {
|
||||||
|
for (int x = 0; x < screen.width; x++) {
|
||||||
|
long int location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) + (y + vinfo.yoffset) * finfo.line_length;
|
||||||
|
*((unsigned int*)(fbp + location)) = 0x000000; // Black color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put pixel on screen
|
||||||
|
void put_pixel(int x, int y, unsigned int color) {
|
||||||
|
if (x >= 0 && x < screen.width && y >= 0 && y < screen.height) {
|
||||||
|
long int location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) + (y + vinfo.yoffset) * finfo.line_length;
|
||||||
|
*((unsigned int*)(fbp + location)) = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw line between two points (Bresenham's line algorithm)
|
||||||
|
void draw_line(int x1, int y1, int x2, int y2, unsigned int color) {
|
||||||
|
int dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
|
||||||
|
int dy = -abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
|
||||||
|
int err = dx + dy, e2;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
put_pixel(x1, y1, color);
|
||||||
|
if (x1 == x2 && y1 == y2) break;
|
||||||
|
e2 = 2 * err;
|
||||||
|
if (e2 >= dy) { err += dy; x1 += sx; }
|
||||||
|
if (e2 <= dx) { err += dx; y1 += sy; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Project 3D coordinates to 2D
|
||||||
|
void project(Vertex v, int *x, int *y) {
|
||||||
|
float scale = 200 / (v.z + 200); // Perspective projection scaling
|
||||||
|
*x = (int)(v.x * scale + cubeX);
|
||||||
|
*y = (int)(v.y * scale + cubeY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the 3D cube
|
||||||
|
void draw_cube(Vertex vertices[8]) {
|
||||||
|
int projectedX[8], projectedY[8];
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
project(vertices[i], &projectedX[i], &projectedY[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw front face
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
draw_line(projectedX[i], projectedY[i], projectedX[(i+1)%4], projectedY[(i+1)%4], 0xFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw back face
|
||||||
|
for (int i = 4; i < 8; i++) {
|
||||||
|
draw_line(projectedX[i], projectedY[i], projectedX[((i+1)%4)+4], projectedY[((i+1)%4)+4], 0x00FF00);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw edges between front and back faces
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
draw_line(projectedX[i], projectedY[i], projectedX[i+4], projectedY[i+4], 0xFF0000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate vertices
|
||||||
|
void translate(Vertex *v, float dx, float dy, float dz) {
|
||||||
|
v->x += dx;
|
||||||
|
v->y += dy;
|
||||||
|
v->z += dz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate cube vertices around X and Y axes
|
||||||
|
void rotate_cube(Vertex vertices[8], float angleX, float angleY) {
|
||||||
|
float cosX = cos(angleX), sinX = sin(angleX);
|
||||||
|
float cosY = cos(angleY), sinY = sin(angleY);
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
float x = vertices[i].x, y = vertices[i].y, z = vertices[i].z;
|
||||||
|
|
||||||
|
// Rotation around X-axis
|
||||||
|
vertices[i].y = y * cosX - z * sinX;
|
||||||
|
vertices[i].z = y * sinX + z * cosX;
|
||||||
|
|
||||||
|
// Rotation around Y-axis
|
||||||
|
vertices[i].x = x * cosY - z * sinY;
|
||||||
|
vertices[i].z = x * sinY + z * cosY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle screen edge collision
|
||||||
|
void handle_collision() {
|
||||||
|
if (cubeX >= screen.width - 100 || cubeX <= 100) velocityX = -velocityX;
|
||||||
|
if (cubeY >= screen.height - 100 || cubeY <= 100) velocityY = -velocityY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init_framebuffer();
|
||||||
|
|
||||||
|
float angleX = 0.0, angleY = 0.0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// Clear the screen
|
||||||
|
clear_screen();
|
||||||
|
|
||||||
|
// Translate the cube across the screen
|
||||||
|
cubeX += velocityX;
|
||||||
|
cubeY += velocityY;
|
||||||
|
handle_collision();
|
||||||
|
|
||||||
|
// Rotate the cube
|
||||||
|
rotate_cube(vertices, angleX, angleY);
|
||||||
|
|
||||||
|
// Draw the cube on the screen
|
||||||
|
draw_cube(vertices);
|
||||||
|
|
||||||
|
// Update rotation angles for the next iteration
|
||||||
|
angleX += rotationSpeed;
|
||||||
|
angleY += rotationSpeed;
|
||||||
|
|
||||||
|
// Add delay to control frame rate (~60 FPS)
|
||||||
|
usleep(16000);
|
||||||
|
}
|
||||||
|
|
||||||
|
munmap(fbp, screensize);
|
||||||
|
close(fbfd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user