cuốn sách gpt4 ai đã làm

c - 卡在交互式 openGL 程序中

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 08:10:43 28 4
mua khóa gpt4 Nike

Tôi gặp sự cố mỗi lần tôi cố gắng nhập hai đỉnh bằng chuột. Gần đây tôi đã thay đổi cách sắp xếp từng hình dạng để đảm bảo các hình dạng mới chồng lên các hình dạng cũ.

Ý tưởng của dự án này là tạo ra một loại Canvas tương tác. Người dùng có thể chọn giữa các đường thẳng, hình tam giác và hình chữ nhật, sau đó chọn màu sắc và một số tính năng khác.

Tôi biết mã dành cho đường thẳng và hình tam giác hoạt động và hình chữ nhật cũng hoạt động nhưng tôi không thể kiểm tra mã do có sự cố.

Tôi nghĩ vấn đề của tôi là ở khu vực nhả nút chuột trái. Cụ thể, thêm ID hình dạng vào từng cấu trúc trong mảng "StructArray". Tôi chắc chắn đó chỉ là điều tôi đã bỏ qua.

Một lưu ý nữa, lớp của tôi đang sử dụng openGL cũ, vì vậy mọi mã openGL đã có trong chương trình cần được giữ lại, tôi không thể sử dụng nội dung mới hoặc nội dung dựa trên shader.

Nếu bạn cần bất kỳ sự làm rõ xin vui lòng cho tôi biết.

Tôi đã bao gồm các tệp C và tệp tiêu đề (CẬP NHẬT V2):

#include 
#include
#include

#include
#include
#include

#include "lineseg.h"
#include "triseg.h"
#include "orthseg.h"
#include "colors.h"

#defineMAXLINES 100

hình dạng cấu trúc typedef {
int id;
} hình dạng;

enum {LINE, TAM GIÁC, HÌNH CHỮ NHẬT};

hình dạng *ShapeArray[MAXLINES];


int currentcolor = ĐEN;
Màu vẽ GLfloat[][3] = {{0,0, 0,0, 0,0},
{1,0, 0,0, 0,0},
{0,0, 1,0, 0,0},
{0,0, 0,0, 1,0}};
char *colorword[] = {"đen", "đỏ", "xanh", "xanh"};

int shapenum = 0; // Số hình được vẽ
int linenum = 0;

Ln *LineSegments[MAXLINES] // LineSegments là một mảng các con trỏ tới Ln
Tri *TriangleSegments[MAXLINES] // TriangleSegments là một mảng các con trỏ tới Tri
Rect *RectangleSegments[MAXLINES] // RectangelSegments là một mảng các con trỏ tới Rect

int NumVertex = 2;

GLint currentx, currenty; // Dùng để lưu trữ tọa độ con trỏ
GLdouble dx, dy; // Được chuyển tới GetCursorPos, cần con trỏ để nhân đôi
GLint winwidth = 700, winheight = 700; // Chiều rộng và chiều cao cửa sổ
V2d *firstvert = NULL, *secondvert = NULL, *thirdvert = NULL, *fourthvert = NULL // Con trỏ tới các đỉnh hiện đang được vẽ;

V2d *make_vertex(int ​​​​x, int y) {
V2d *tmp;

tmp = (V2d *) malloc(sizeof(V2d));
nếu (tmp == NULL) {
printf("Hết bộ nhớ\n");
thoát (0);
}
tmp->x = x;
tmp->y = y;

trả lại tmp;
}

Ln *make_line(V2d v1, V2d v2) {
Ln *tmp;

tmp = (Ln *) malloc(sizeof(Ln));
nếu (tmp == NULL) {
printf("Hết bộ nhớ\n");
thoát (0);
}
tmp->v1 = v1;
tmp->v2 = v2;

trả lại tmp;
}
Tri *make_tam giác(V2d v1, V2d v2, V2d v3){
Tri*tmp;

tmp = (Tri *) malloc(sizeof(Tri));
nếu (tmp == NULL) {
printf("Hết bộ nhớ\n");
thoát (0);
}
tmp->v1 = v1;
tmp->v2 = v2;
tmp->v3 = v3;

trả lại tmp;
}

Hình chữ nhật *make_hình chữ nhật(V2d v1, V2d v2){
Trực tràng *tmp;

tmp = (Rect *) malloc(sizeof(Rect));
nếu (tmp == NULL) {
printf("Hết bộ nhớ\n");
thoát (0);
}
tmp->v1 = v1;
tmp->v2 = v2;

trả lại tmp;
}

void myInit(void)
{
glViewport(0, 0, winwidth, winheight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,0, winwidth, 0,0, winheight);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glClearColor(1.0, 1.0, 1.0, 1.0);
glPointSize(5.0); // kích thước được sử dụng khi hiển thị điểm
glLineWidth(2.0); // chiều rộng được sử dụng khi hiển thị dòng
glLineStipple(2, 0xAAAA); // mẫu chấm được sử dụng khi vẽ đường chấm

printf("Vẽ trong %s\n", colorword[currentcolor]);

}

void vẽ(void){

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (int i = 0; i < hình dạng; i++){
if (ShapeArray[i]->id == LINE) {
// Vẽ tất cả các dòng đã được vẽ và lưu trữ trong mảng LineSegments
glColor3fv(drawingcolor[LineSegments[i]->color]);
glBegin(GL_LINES);
glVertex2i(LineSegments[i]->v1.x, LineSegments[i]->v1.y);
glVertex2i(LineSegments[i]->v2.x, LineSegments[i]->v2.y);
glEnd();

// Vẽ đoạn đang được vẽ
if (firstvert != NULL) {
glColor3fv(drawcolor[currentcolor]);
glBegin(GL_POINTS);
glVertex2i(firstvert->x, firstvert->y);
glEnd();
}

if (thứ hai != NULL) {
glColor3fv(drawcolor[currentcolor]);
glBegin(GL_POINTS);
glVertex2i(thứ hai->x, thứ hai->y);
glEnd();
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINES);
glVertex2i(firstvert->x, firstvert->y);
glVertex2i(thứ hai->x, thứ hai->y);
glEnd();
glDisable(GL_LINE_STIPPLE);
}
}
khác nếu (ShapeArray[i]->id == TRIANGLE){
glColor3fv(drawingcolor[TriangleSegments[i]->color]);
glBegin(GL_LINE_LOOP);
glVertex2i(TriangleSegments[i]->v1.x, TriangleSegments[i]->v1.y);
glVertex2i(TriangleSegments[i]->v2.x, TriangleSegments[i]->v2.y);
glVertex2i(TriangleSegments[i]->v3.x, TriangleSegments[i]->v3.y);
glEnd();

if (firstvert != NULL) {
glColor3fv(drawcolor[currentcolor]);
glBegin(GL_POINTS);
glVertex2i(firstvert->x, firstvert->y);
glEnd();
}

if (thứ hai != NULL) {
glColor3fv(drawcolor[currentcolor]);
glBegin(GL_POINTS);
glVertex2i(thứ hai->x, thứ hai->y);
glEnd();
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINE_LOOP);
glVertex2i(firstvert->x, firstvert->y);
glVertex2i(thứ hai->x, thứ hai->y);
glVertex2i(thứ ba->x, thứ ba->y);
glEnd();
glDisable(GL_LINE_STIPPLE);
}
}
khác nếu (ShapeArray[i]->id == RECTANGLE){
glColor3fv(drawingcolor[RectangleSegments[i]->color]);
glBegin(GL_LINE_LOOP);
glVertex2i(RectangleSegments[i]->v1.x, RectangleSegments[i]->v1.y);
glVertex2i(RectangleSegments[i]->v2.x, RectangleSegments[i]->v1.y);
glVertex2i(RectangleSegments[i]->v2.x, RectangleSegments[i]->v2.y);
glVertex2i(RectangleSegments[i]->v1.x, RectangleSegments[i]->v2.y);
glEnd();

if (firstvert != NULL) {
glColor3fv(drawcolor[currentcolor]);
glBegin(GL_POINTS);
glVertex2i(firstvert->x, firstvert->y);
glEnd();
}

if (thứ hai != NULL) {
glColor3fv(drawcolor[currentcolor]);
glBegin(GL_POINTS);
glVertex2i(thứ hai->x, thứ hai->y);
glEnd();
glEnable(GL_LINE_STIPPLE);
glBegin(GL_LINE_LOOP);
glVertex2i(firstvert->x, firstvert->y);
glVertex2i(thứ hai->x, thứ hai->y);
glEnd();
glDisable(GL_LINE_STIPPLE);
}
}
}
}

bàn phím void(GLFWwindow *w, phím int, int scancode, int action, int mod) {
nếu (hành động == GLFW_PRESS)
công tắc (phím) {
trường hợp GLFW_KEY_R:
currentcolor = (currentcolor != RED)?RED:BLACK;
printf("Đang vẽ ở %s\n", colorword[currentcolor]);
phá vỡ;
trường hợp GLFW_KEY_G:
currentcolor = (currentcolor != XANH)?XANH:ĐEN;
printf("Đang vẽ ở %s\n", colorword[currentcolor]);
phá vỡ;
trường hợp GLFW_KEY_B:
currentcolor = (currentcolor != BLUE)?BLUE:BLACK;
printf("Đang vẽ ở %s\n", colorword[currentcolor]);
phá vỡ;
trường hợp GLFW_KEY_ESCAPE:
trường hợp GLFW_KEY_Q:
printf("Đang thoát khỏi chương trình!\n");
glfwSetWindowShouldClose(w, GL_TRUE);
phá vỡ;
trường hợp GLFW_KEY_C:
printf("Đang xóa cửa sổ!\n");
hình dạng = 0; // hình dạng rõ ràng
for (int i = 0; i < MAXLINES; i++){
miễn phí(ShapeArray[i]);
}
phá vỡ;
trường hợp GLFW_KEY_F:
printf("Chế độ điền đã chọn\n");

phá vỡ;
trường hợp GLFW_KEY_F1:
printf("Đã chọn chế độ dòng\n");
NumVertex = 2; //Chế độ dòng
phá vỡ;
trường hợp GLFW_KEY_F2:
printf("Đã chọn chế độ tam giác\n");
NumVertex = 3 //Chế độ tam giác
phá vỡ;
trường hợp GLFW_KEY_F3:
printf("Đã chọn chế độ hình chữ nhật\n");
NumVertex = 4; //chế độ hình chữ nhật
phá vỡ;
}
}

// Gọi lại chuyển động con trỏ chỉ được sử dụng khi nhấn nút chuột.
// cho đỉnh đầu tiên và chưa được thả ra

con trỏ trống (GLFWwindow *w, con trỏ GLdoublex, con trỏ GLdouble) {
/* Khi chuột di chuyển, đỉnh thứ hai được cập nhật liên tục */
/* Miễn phí bản sao cũ của Secondvert trước khi cập nhật */

currentx = (GLint)con trỏ;
hiện tại = (GLint)chữ thảo;

miễn phí (thứ hai);
Secondvert = make_vertex(currentx, winheight - currenty);
}

// Gọi lại nút chuột

chuột trống (GLFWwindow *w, nút int, hành động int, mod int) {
nếu (nút == GLFW_MOUSE_BUTTON_LEFT) {
nếu (hành động == GLFW_PRESS) {
printf("%d\n",shapenum);
glfwGetCursorPos(w, &dx, &dy);
currentx = (GLint)dx;
hiện tại = (GLint)dy;
nếu (NumVertex == 2){
if (firstvert == NULL) {/* lưu đỉnh đầu tiên và đăng ký gọi lại chuyển động con trỏ để tạo hiệu ứng dây cao su */
firstvert = make_vertex(currentx, winheight - currenty);
glfwSetCursorPosCallback(w, con trỏ); // Đặt gọi lại chuyển động của con trỏ
}

else /* lưu đỉnh thứ hai của đoạn */
Secondvert = make_vertex(currentx, winheight - currenty);
}

khác nếu (NumVertex == 3){
if (firstvert == NULL) {/* lưu đỉnh đầu tiên và đăng ký gọi lại chuyển động con trỏ để tạo hiệu ứng dây cao su */
firstvert = make_vertex(currentx, winheight - currenty);
//glfwSetCursorPosCallback(w, con trỏ); // Đặt gọi lại chuyển động của con trỏ
}

khác nếu (secondvert == NULL){/* lưu đỉnh thứ hai của đoạn */
Secondvert = make_vertex(currentx, winheight - currenty);
//glfwSetCursorPosCallback(w, con trỏ);
}

khác nếu (thứ ba == NULL){
Thirdvert = make_vertex(currentx, winheight - currenty);
//glfwSetCursorPosCallback(w, con trỏ);
}
}
khác nếu (NumVertex == 4){
if (firstvert == NULL) {/* lưu đỉnh đầu tiên và đăng ký gọi lại chuyển động con trỏ để tạo hiệu ứng dây cao su */
firstvert = make_vertex(currentx, winheight - currenty);
glfwSetCursorPosCallback(w, con trỏ); // Đặt gọi lại chuyển động của con trỏ
}

else{/* lưu đỉnh thứ hai của đoạn */
Secondvert = make_vertex(currentx, winheight - currenty);
}
}

} /* kết thúc thao tác nhấn chuột */

khác { // ---------------------------------------------- ---- -CẦN TẬP LUYỆN-----------------
nếu (hành động == GLFW_RELEASE) {
glfwSetCursorPosCallback(w, NULL); /* Khi nút được nhả, tắt tính năng gọi lại chuyển động của con trỏ */
nếu (NumVertex == 2){
if (thứ hai != NULL) {
/* tạo một dòng mới và đặt nó vào mảng (nếu kích thước không vượt quá) Đặt màu và id của nó */
if (shapenum < MAXLINES) {
LineSegments[shapenum] = make_line(*firstvert, *secondvert);
LineSegments[shapenum]->color = currentcolor;
LineSegments[shapenum]->id = hình dạng;
ShapeArray[shapenum]->id = LINE;
hình dạng++;
đầu tiên = NULL;
thứ hai = NULL;
}
khác
printf("Đã đạt đến mức tối đa %d. Không thể vẽ thêm dòng nào nữa.\n", MAXLINES);
}
}
khác nếu (NumVertex == 3){
if (thứ ba != NULL) {
if (shapenum < MAXLINES) {
TriangleSegments[shapenum] = make_triangle(*firstvert, *secondvert, *thirdvert);
TriangleSegments[shapenum]->color = currentcolor;
Phân đoạn tam giác[shapenum]->id = hình dạng;
ShapeArray[shapenum]->id = TAM GIÁC;
hình dạng++;
đầu tiên = NULL;
thứ hai = NULL;
thứ ba = NULL;
}
khác
printf("Đã đạt đến mức tối đa %d. Không thể vẽ thêm dòng nào nữa.\n", MAXLINES);
}
}
khác nếu (NumVertex == 4){
if (thứ hai != NULL) {
if (shapenum < MAXLINES) {
RectangleSegments[shapenum] = make_hình chữ nhật(*firstvert, *secondvert);
RectangleSegments[shapenum]->color = currentcolor;
Phân đoạn hình chữ nhật[shapenum]->id = hình dạng;
ShapeArray[shapenum]->id = RECTANGLE;
hình dạng++;
đầu tiên = NULL;
thứ hai = NULL;
}
khác
printf("Đã đạt đến mức tối đa %d. Không thể vẽ thêm dòng nào nữa.\n", MAXLINES);
}
}
}
} /* kết thúc thao tác thả chuột */
} /* kết thúc thao tác click chuột trái */
}


int main(int argc, char** argv) {
cửa sổ GLFWwindow*;
trình kết xuất const GLubyte*;
phiên bản const GLubyte*;

/*Khởi tạo thư viện */
nếu (!glfwInit())
return -1;

/* Tạo cửa sổ chế độ cửa sổ và bối cảnh OpenGL của nó */
window = glfwCreateWindow(winwidth, winheight, "HW_1", NULL, NULL);
nếu (!cửa sổ)
{
glfwTerminate();
return -1;
}

for (int i = 0; i < MAXLINES; i++){
ShapeArray[i] = malloc(sizeof *ShapeArray[i]);

}

/* Làm cho ngữ cảnh của cửa sổ hiện tại */
glfwMakeContextCurrent(window);

/*lấy thông tin phiên bản*/
renderer = glGetString (GL_RENDERER); /* lấy chuỗi kết xuất */
phiên bản = glGetString (GL_VERSION); /* phiên bản dưới dạng chuỗi */
printf ("Trình kết xuất: %s\n", trình kết xuất);
printf ("Phiên bản OpenGL được hỗ trợ %s\n", phiên bản);

myInit();
glfwSetKeyCallback(window, keyboard); /* Hàm gọi lại */
glfwSetMouseButtonCallback(cửa sổ, chuột);

/* Lặp lại cho đến khi người dùng đóng cửa sổ */
while (!glfwWindowShouldClose(window))
{
/*Kết xuất ở đây*/
vẽ tranh();

/* Hoán đổi vùng đệm trước và sau */
glfwSwapBuffers(cửa sổ);

/* Thăm dò và xử lý sự kiện */
glfwPollEvents();
}

glfwTerminate();
return 0;
}

triseg.h

// struct cho các đoạn tam giác
cấu trúc tam giác typedef {
V2d v1;
V2d v2;
V2d v3;
màu int;
int id;
}Trí;

Tri *make_tam giác(V2d v1, V2d v2, V2d v3);

màu.h

enum {ĐEN, ĐỎ, XANH, XANH};

trực tràng.h

// struct cho các đoạn hình chữ nhật
cấu trúc hình chữ nhật typedef {
V2d v1;
V2d v2;
V2d v3;
V2d v4;
màu int;
int id;
} Trực tràng;

Hình chữ nhật *make_hình chữ nhật(V2d v1, V2d v2, V2d v3, V2d v4);

đoạn đường.h

// struct cho đỉnh hai chiều
typedef cấu trúc vertex2d {
int x;
int y;
} V2d;

// struct cho các đoạn đường
dòng cấu trúc typedef {
V2d v1;
V2d v2;
màu int;
int id;
}Ln;

V2d *make_vertex(int ​​x, int y);
Ln *make_line(V2d v1, V2d v2);

câu trả lời hay nhất

bạn sẽ Hình dạngMảng Được tạo dưới dạng một mảng các con trỏ,

hình dạng *ShapeArray[MAXLINES];

Nhưng tôi không thấy bất kỳ mã nào mà bạn thực sự nhận được hình dạng Phân bổ bộ nhớ. Vì vậy, khi bạn làm:

ShapeArray[shapenum]->id = LINE;

Tôi nghi ngờ bạn đã vượt qua NULL truy cập con trỏ.

Có lẽ bạn nên khai báo nó như thế này Hình dạngMảng:

hình dạng ShapeArray[MAXLINES];

Sau đó truy cập nó như thế này:

ShapeArray[shapenum].id = LINE;

Hoặc chỉ để ở đâu đóhình dạng không gian malloc.

Tôi cũng nhận thấy bạn vẽ tranh Chức năng có vẻ hơi bối rối. Bạn hiện đang sử dụng Tôi Là một trình lặp vòng lặp trong hai vòng lặp lồng nhau, điều này sẽ không thực hiện được những gì bạn mong đợi.

Tôi không nghĩ vòng lặp bên trong là cần thiết, vì vậy nếu chúng ta chỉ nhìn vào phần đầu của hàm, bạn nên làm điều gì đó giống như thế này:

void vẽ(void){
// Xóa màn hình trước khi vẽ tất cả các hình dạng
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Lặp lại từng hình.
for (int i = 0; i < hình dạng; i++){
// ĐÂY có phải là hình dạng của LINE không?
if (ShapeArray[i]->id == LINE) {
// Đúng vậy! Hãy vẽ MỘT đường thẳng.
glColor3fv(drawingcolor[LineSegments[i]->color]);
glBegin(GL_LINES);
glVertex2i(LineSegments[i]->v1.x, LineSegments[i]->v1.y);
glVertex2i(LineSegments[i]->v2.x, LineSegments[i]->v2.y);
glEnd();
}

// .... phần còn lại của hàm cũng cần sửa ...

Về c - bị kẹt trong chương trình openGL tương tác, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/39761224/

28 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress