Initial Commit
This commit is contained in:
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