Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.79/29: Рейтинг темы: голосов - 29, средняя оценка - 4.79
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246

Попытка сделать змейку)

16.11.2017, 02:31. Показов 8035. Ответов 125

Студворк — интернет-сервис помощи студентам
Всем привет, может кто-нибудь посмотреть код мой и посоветовать дельного чего, уверен - много косяков у меня. Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include <stdlib.h>
#include <gl/glut.h>
#include <conio.h>
#include <ctime>
#include <iostream>
 
enum direction {UP,DOWN,LEFT,RIGHT,STOP};
 
GLint Width = 800, Height = 600;
 
int amount=0;
int score=0;
bool gameover=false;
int xTail[100],yTail[100];
bool apple=true;
int rsize=40;
int asize=40;
int a1=200;
int a2=a1-asize;
int b1=200;
int b2=b1-asize;
int x1=Width/2-rsize;
int y1=Height/2+rsize/2;
int x2=x1-rsize,y2=y1-rsize;
int speed=2;
 
direction dir=STOP;
 
 
/* эта функция управляет всем выводом на экран */
void Display(void)
{
 
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
 
    // Установка вторых координат для игрока и яблока
    x2=x1-rsize;
    y2=y1-rsize;
 
    a2=a1-asize;
    b2=b1-asize;
 
    // Установка яблока
    if(apple)
    {
        glColor3ub(255,0,0);
        glRectf(a1,b1,a2,b2);
    }
 
    // Установка Игрока
    glColor3ub(0,255,0);
    glRectf(x1,y1,x2,y2);
 
    // Установка хвоста
 
    for(int i=0;i<amount;i++)
    {
 
        int u1=rand()%254+1;
        int u2=rand()%254+1;
        int u3=rand()%254+1;
        glColor3ub(u1,u2,u3);
        glRectf(xTail[i],yTail[i],xTail[i]-rsize,yTail[i]-rsize);
    }
 
    glutSwapBuffers();
}
 
 
void Reshape(GLint w, GLint h)
{
 
    glViewport(0,0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
 
 
    glOrtho(0, w, 0, h, -1.0, 1.0);
 
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
 
void update(int value)
{
    // Добавление и перестановка хвоста
    xTail[0]=x1;
    yTail[0]=y1;
    int tempX,tempY;
    tempX=xTail[0];tempY=yTail[0];
    int prevX,prevY;
    for(int i=1;i<amount;i++)
    {
        prevX=xTail[i];
        prevY=yTail[i];
        xTail[i]=tempX;
        yTail[i]=tempY;
        tempX=prevX;
        tempY=prevY;
    }
 
    // Четыре условия if увеличивают координаты в зависимоти от направления и скорости, так же проверяют на границы окна.
    if(dir==UP)
    {
        y1+=20*speed;
        if(y2>=Height)
            y1=rsize;
    }
    if(dir==DOWN)
    {
        y1-=20*speed;
        if(y2<=0)
            y1=Height;
    }
    if(dir==LEFT)
    {
        x1-=20*speed;
        if(x2<=0)
            x1=Width;
    }
    if(dir==RIGHT)
    {
        x1+=20*speed;
        if(x2>=Width)
            x1=rsize;
    }
 
    // Проверяем на столкновение с одним из сегментов хвоста
    for(int i=0;i<amount;i++)
    {
        if(x1==xTail[i] && y1==yTail[i])
            {
                gameover=true;
                if(gameover)
                {
                    exit(0);
 
                }
            }
    }
    // Если яблока заспавнилось - то проверяем на совпадение координат игрока и яблока
    if(apple)
    {
        if((x1==a1 && y1==b1) || (x2==a2 && y2==b2) )
            {
                if(amount<100)
                    amount++;
                score+=20;
                apple=false;
            }
    }
 
 
    // Если яблоко не заспавнено, то спавним его в координатах не равных координатам игрока
    if(!apple)
    {
        do{
            a1=(20*speed)*(rand()%(Width/(20*speed)-4)+2);
            b1=(20*speed)*(rand()%(Height/(20*speed)-4)+2);
        }while(a1==x1 && b1 ==y1);
        apple=true;
    }
 
 
    glutPostRedisplay();
    glutTimerFunc(100,update,1);
}
 
 
void Keyboard(unsigned char key, int x, int y)
{
#define ESCAPE '\033'
    if( key=='d' || key == 'D')
    {
        dir=RIGHT;
    }
    if( key=='a' || key == 'A')
    {
        dir=LEFT;
    }
    if( key=='w' || key == 'W')
    {
        dir=UP;
    }
    if( key=='s' || key == 'S')
    {
        dir=DOWN;
    }
    if( key=='x' || key == 'X')
    {
        dir=STOP;
    }
    if( key=='q')
    {
        if(amount<40)
        amount++;
    }
    if( key == ESCAPE )
        exit(0);
}
 
 
main(int argc, char *argv[])
{
    srand(time(0));
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowSize(Width, Height);
    glutCreateWindow("Snake");
 
    glutDisplayFunc(Display);
    glutReshapeFunc(Reshape);
    glutKeyboardFunc(Keyboard);
 
    glutTimerFunc(100,update,1);
 
    glutMainLoop();
}
Главная проблема в том, что если выставить скорость равной 1, то шаг для координат меньше, и тогда условие проверки работает криво, то змейка может на половину пройти по яблоку, а то останется - так не должно быть. Как можно сделать, что бы как бы была карта, и я не привязывался к пикселям сильно, может какой-нибудь массив, из элементов допустим при разрешении 800 на 600 - массив был бы 60 на 80. И Каждая элемент содержал бы небольшое количество пикселей, равный, допустим размеру объектов, и перемещение что бы происходило строго по этим вымышленным координатам 80 на 60. Но тогда скорость здесь будет фиксированная... В общем гляньте кто-нибудь. Управление WASD или wasd. x или X - выход . q - добавить 1 сегмент хвоста. Я только недавно начал изучать opengl, до этого писал консольную змейку, а теперь вот пытаюсь добавить немного графики в нее. Да, кстати, проблема видимо у меня осталась еще с консольной змейки, хотя там ее не замечал. После того, как съел первый фрукт, то появляется 1 хвост, но после того как съешь именно 2-ой фрукт, хвост не отрастает, не понимаю в чем проблема... а дальше все идет норм. Спасибо

Добавлено через 2 часа 37 минут
Нашел проблема по поводу, того, что 2 сегмент на рисуется, на самом деле рисуется, просто первый рисуется на месте головы, а второй рисуется на месте 1 сегмента... не знаю как теперь поправить это...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Добавление и перестановка хвоста
    xTail[0]=x1;
    yTail[0]=y1;
    int tempX,tempY;
    tempX=xTail[0];tempY=yTail[0];
    int prevX,prevY;
    for(int i=1;i<amount;i++)
    {
        prevX=xTail[i];
        prevY=yTail[i];
        xTail[i]=tempX;
        yTail[i]=tempY;
        tempX=prevX;
        tempY=prevY;
    }
Тут как-то изменить надо, для первого хвоста координаты...

Добавлено через 33 минуты
То есть я делаю неправильно - у меня первый и второй сегмент в одном месте рисуются, а вот как сделать по-другому уже второй час голову ломаю :/

Добавлено через 1 час 23 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int tempX,tempY;
 
    tempX=xTail[0];
    tempY=yTail[0];
 
    xTail[0]=x1;
    yTail[0]=y1;
 
    int prevX,prevY;
 
    for(int i=1;i<amount;i++)
    {
 
        prevX=xTail[i];
        prevY=yTail[i];
        xTail[i]=tempX;
        yTail[i]=tempY;
        tempX=prevX;
        tempY=prevY;
    }
Не знаю как - но оно работает... обидно даже... почему работает не понимаю. Сначала создаем временные переменные для хранения х и у координат начала хвоста змейки, а потом началу хвосту змейки присваиваем текущие координаты головы до движения. И вводим переменные для след.хвоста. в них считываем данные от следующем хвосте, и тут же после следующему хвосту присваиваем значение, не текущего xTail[0] yTail[0], а того который был еще до присваивания им значений коорд. головы... Не очень понимаю - как это работает? Ведь тогда в xTail[0] yTail[0] Не было еще никаких значений... Или после одного движения (апдейта) все таки туда что-то попадает? Может объяснить как это происходит? Знаю, что сам написал и не понял ничего... просто очень хочу разобраться именно в этом моменте...
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.11.2017, 02:31
Ответы с готовыми решениями:

Как сделать змейку на c++ ?
Помогите .Как можно реализовать хвост для змейки ? Я его воде бы сделал, но он не правильно работает. Сори за мой код, он ,наверно,...

Как сделать движущуюся змейку?
Змейка должна состоять из линий и передвигаться с помощью того,что последняя линия гаснет и в то же время появляется новая впереди. ...

Как сделать такую змейку
Как сделать такую змейку?

125
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
23.11.2017, 23:27  [ТС]
Студворк — интернет-сервис помощи студентам
Спасибо)

Добавлено через 15 часов 31 минуту
Сложный пример однако у вас Много информации, понятно, что подписано всё..) но.. А если взять самый простой пример? то есть вывод точки на экран. Сначала нужно инициализировать glew, потом создать шейдеры, загрузить их, скомпилировать, прикрепить, связать их с программой, использовать. А дальше уже что-то с буфером идет. Так? Я просто обычно в OpenGL использовал только несколько функций... Display,Reshape,Keyboard. Ну и естественно все начальные инициализации glut. А вот куда вставить эту функцию с инициализацией полной шейдера не понимаю, так же как и glewInit() потому, что я ее в main() вставил, но ошибка не пропала(
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
24.11.2017, 11:51
На C++ не хочет без VAO работать, пришлось добавить. Либо я что-то не так делал. Я сделал минимальную программу, которая рисует точку размером 10 пикселей с помощь VBO и VAO. Среда VS2015, FreeGLUT: DrawingPointUsingVBOAndVAO.zip

Памятка с настройками проекта. Для FreeGLUT нужно создавать тип приложения в VS "Win32 Console Application" (с отмеченной галочкой "Empty Project"). Для данного набора библиотек в папке "Libs" из примера выше настройки должны быть такими:

Configuration: All Configurations; Platforms: All Platforms
C/C++ -> Genaral -> Additional Include Directories:
$(SolutionDir).\Libs\glm-0.9.8.4
$(SolutionDir).\Libs\glew-2.0.0-win32\include
$(SolutionDir).\Libs\freeglut-MSVC-3.0.0-2.mp\freeglut\include
Linker -> Input -> Additional Dependencies
freeglut.lib
glew32s.lib

Configuration: All Configurations; Platforms: Win32
Linker -> General -> Additional Library Directories:
$(SolutionDir).\Libs\glew-2.0.0-win32\lib\Platform_Win32
$(SolutionDir).\Libs\freeglut-MSVC-3.0.0-2.mp\freeglut\lib\Platform_Win32
Build Events -> Post-Build Event
xcopy /y /d $(SolutionDir)Libs\freeglut-MSVC-3.0.0-2.mp\freeglut\freeglut_bin\Platform_Win3 2\freeglut.dll $(OutDir)

Configuration: All Configurations; Platforms: x64
Linker -> General -> Additional Library Directories:
$(SolutionDir).\Libs\glew-2.0.0-win32\lib\Platform_x64
$(SolutionDir).\Libs\freeglut-MSVC-3.0.0-2.mp\freeglut\lib\Platform_x64
Build Events -> Post-Build Event
xcopy /y /d $(SolutionDir)Libs\freeglut-MSVC-3.0.0-2.mp\freeglut\freeglut_bin\Platform_x64\ freeglut.dll $(OutDir)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#define GLEW_STATIC
 
#include <GL/glew.h>
#include <GL/freeglut.h>
 
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
 
#include <string>
#include <iostream>
using namespace std;
 
extern "C" _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
 
const char *vertexShaderSource =
"#version 330\n \
 \
in vec2 a_Position; \
 \
void main()\
{ \
    gl_Position = vec4(a_Position, 0.0, 1.0); \
    gl_PointSize = 10.0; \
}";
 
const char *fragmentShaderSource =
"#version 330\n \
 \
precision mediump float; \
out vec4 fragColor; \
 \
void main()\
{ \
    fragColor = vec4(1.0, 0.0, 0.0, 1.0); \
}";
 
void CheckShaderCompileStatus(GLuint shader)
{
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
        cerr << "Compile log: " << infoLog << endl;
        delete[] infoLog;
    }
}
 GLuint vao;
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vao);
    glDrawArrays(GL_POINTS, 0, 1);
    glutSwapBuffers();
}
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitContextVersion(3, 3);
    glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
    glutInitWindowSize(500, 500);
 
    string title = "Drawing Point Using VBO";
    glutCreateWindow(title.c_str());
    cout << title << endl;
 
    glewInit();
 
    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vShader);
    CheckShaderCompileStatus(vShader);
 
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fShader);
    CheckShaderCompileStatus(fShader);
 
    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);
    glUseProgram(program);
    GLint status;
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
 
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
        cerr << "Link log: " << infoLog << endl;
        delete[] infoLog;
    }
 
    GLfloat vertices[] = { 0.0f, 0.0f, 0.5f, 0.5f };
 
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
 
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
    GLint a_Position = glGetAttribLocation(program, "a_Position");
    glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(a_Position);
 
    glEnable(GL_PROGRAM_POINT_SIZE);
 
    glDrawArrays(GL_LINES, 0, 2);
 
    glutDisplayFunc(Display);
 
    glutMainLoop();
    return 0;
}
1
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
24.11.2017, 13:02  [ТС]
Огромное вам спасибо) сейчас гляну!

Добавлено через 10 минут
Код запустился хотя бы Ура) Оказывается я либы еще подключал не в правильном порядке...не в самой программе, а имеено в линкере :/ Жесть) А есть разница между glew32.lib и glew32s.lib

Спасибо, даже если пример простой, много незвестного) например все эти логи и проверки на ошибки ) еще vbo и vao
но все равно буду пробовать ваш код менять, и смотреть на результат) спасибо)
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
24.11.2017, 13:23
У меня небольшие ошибки есть. Из тела main нужно удалить:
C++
1
glDrawArrays(GL_LINES, 0, 2);
В этом массиве две вершины:
C++
1
GLfloat vertices[] = { 0.0f, 0.0f, 0.5f, 0.5f };
Это сделано, чтобы можно было нарисовать линию для этого в Display нужно указать, что две вершины рисовать и способ рисования GL_LINES вместо GL_POINTS:
C++
1
glDrawArrays(GL_LINES, 0, 2);
Тогда нарисует линию, но если нужна одна, то эта программа более правильная, где указаны координаты одной вершины в массиве:
C++
1
GLfloat vertices[] = { 0.0f, 0.0f };
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#define GLEW_STATIC
 
#include <GL/glew.h>
#include <GL/freeglut.h>
 
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
 
#include <string>
#include <iostream>
using namespace std;
 
extern "C" _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
 
const char *vertexShaderSource =
"#version 330\n \
 \
in vec2 a_Position; \
 \
void main()\
{ \
    gl_Position = vec4(a_Position, 0.0, 1.0); \
    gl_PointSize = 10.0; \
}";
 
const char *fragmentShaderSource =
"#version 330\n \
 \
precision mediump float; \
out vec4 fragColor; \
 \
void main()\
{ \
    fragColor = vec4(1.0, 0.0, 0.0, 1.0); \
}";
 
void CheckShaderCompileStatus(GLuint shader)
{
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
        cerr << "Compile log: " << infoLog << endl;
        delete[] infoLog;
    }
}
 GLuint vao;
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vao);
    glDrawArrays(GL_POINTS, 0, 1);
    glutSwapBuffers();
}
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitContextVersion(3, 3);
    glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
    glutInitWindowSize(500, 500);
 
    string title = "Drawing Point Using VBO";
    glutCreateWindow(title.c_str());
    cout << title << endl;
 
    glewInit();
 
    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vShader);
    CheckShaderCompileStatus(vShader);
 
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fShader);
    CheckShaderCompileStatus(fShader);
 
    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);
    glUseProgram(program);
    GLint status;
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
 
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
        cerr << "Link log: " << infoLog << endl;
        delete[] infoLog;
    }
 
    GLfloat vertices[] = { 0.0f, 0.0f };
 
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 2 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
 
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
    GLint a_Position = glGetAttribLocation(program, "a_Position");
    glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(a_Position);
 
    glEnable(GL_PROGRAM_POINT_SIZE);
 
    glutDisplayFunc(Display);
 
    glutMainLoop();
    return 0;
}
Добавлено через 4 минуты
Цитата Сообщение от Abomination_25 Посмотреть сообщение
А есть разница между glew32.lib и glew32s.lib
Да, есть. Буква 's' означает static, это значит, что либа glew будет зашита внутрь exe-ешника, в противном случае, рядом с exe должен быть DLL: glew32.dll. Тогда в среде нужно было ещё одну copy в настройках дописать, иначе бы вы не запустили и получили ошибку, что "glew32.dll не найден"

Добавлено через 3 минуты
Цитата Сообщение от Abomination_25 Посмотреть сообщение
например все эти логи и проверки на ошибки )
Провероки на ошибки можно на каждой операции писать, это помогает находить ошибки. Мне кажется, с линком программы можно проверку удалить, а вот функцию проверки скомпилировались ли шейдеры можно оставить, потому что бывают описки в программах шейдера, которые сразу не увидишь, вроде программа запускается, а ничего не рисуется и сразу не понятно, где косяк.

Добавлено через 2 минуты
Попробуйте изменить программу так, чтобы она нарисовала линию, а потом измените так, чтобы нарисовала треугольник. Нужно будет сначала написать GL_LINES и добавить вершину, а потом добавить ещё вершину и нарисовать треугольник с помощью GL_TRIANGLES
1
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
24.11.2017, 18:40  [ТС]



А получается, что все координаты мы задаем в verticels[]? А gl_Position на нужен, для передачи туда наших вершин из массива? Точнее вроде мы передаем в переменную a_Position две вершины, а потом уже a_Position участвует в формирование gl_Position? Во фрагментном шейдере вроде одна переменная на выход только? То есть цвет нужно менять только в шейдере сейчас? А вот что значит: precision mediump float? Что еще можно сделать ? Пока что еще хочется чего-нибудь сделать)
1
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
24.11.2017, 19:06
Цитата Сообщение от Abomination_25 Посмотреть сообщение
А получается, что все координаты мы задаем в verticels[]? А gl_Position на нужен, для передачи туда наших вершин из массива? Точнее вроде мы передаем в переменную a_Position две вершины, а потом уже a_Position участвует в формирование gl_Position? Во фрагментном шейдере вроде одна переменная на выход только? То есть цвет нужно менять только в шейдере сейчас? А вот что значит: precision mediump float? Что еще можно сделать ? Пока что еще хочется чего-нибудь сделать)
Здесь логика такая. Дело в том, что a_Position хранит в себе ссылку на буферный объект. В буферном объекте хранятся данные. В данном случае, в буферном объекте хранится массив координат вершин. Вершинный шейдер запускается после вызова drawArrays для каждой вершины из массива, который хранится в буферном объекте. Это значит, что когда рисуем треугольник, то при первом запуске шейдера в "in vec2 a_Position" (в шейдере) будет координата первой вершины, она присвоится внутренней переменной gl_Position. При втором вызове в a_Position будет вторая вершина, которая будет передана gl_Position и т.д. Когда вершины в буферном объекте закончатся, то в недрах видео карты будет создан геометрический объект "треугольник". Но он ещё не закрашен. Опять же в недрах видео карты будет произведена разбивка треугольника на квадратики (на фрагменты, грубо говоря, на пикселы). Этот этап называется "растеризация". Но этому массиву фрагментов нужно задать цвета. Для этого используется фрагментный шейдер, который вызывается для каждого массива фрагментов, и задаёт каждому фрагменту поочереди цвет с помощью присваивания цвета переменной fragColor.
0
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
24.11.2017, 21:09  [ТС]
Спасибо, не подскажите что еще можно сделать? Для новичка, конечно. Пока что буду всё на веру принимать, всю инициализацию и сложный код, но потом обязательно разберусь! Куб бы создать с разными гранями, но для этого нужно 12 треугольников? Еще ведь нужно его повернуть, чтобы был вид объемный, и разным цветов грани для лучшей видимости( ведь пока не умею светом пользоваться, все сливаться будет)
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
24.11.2017, 22:43
Цитата Сообщение от Abomination_25 Посмотреть сообщение
Куб бы создать с разными гранями, но для этого нужно 12 треугольников?
Змейка из кубов - интересный вариант. Сделайте сначала змейку из квадратов в 2D. Дело в том, что перейти из 2D в 3D - не такая уж сложная задача. В GLM есть всё что нужно и эта библиотека уже подлючена. Смотрете, как можно легко нарисовать квадрат, сделав в программе несколько изменений.

На картинке видно, как работает GL_TRIANGLE_STRIP:

Название: gl.TRIANGLE_STRIP.png
Просмотров: 12

Размер: 6.8 Кб

Значит, если записать в буфер четыре вершины, то получится квадрат:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#define GLEW_STATIC
 
#include <GL/glew.h>
#include <GL/freeglut.h>
 
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
 
#include <string>
#include <iostream>
using namespace std;
 
extern "C" _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
 
const char *vertexShaderSource =
"#version 330\n \
 \
in vec2 a_Position; \
 \
void main()\
{ \
    gl_Position = vec4(a_Position, 0.0, 1.0); \
}";
 
const char *fragmentShaderSource =
"#version 330\n \
 \
precision mediump float; \
out vec4 fragColor; \
 \
void main()\
{ \
    fragColor = vec4(1.0, 0.0, 0.0, 1.0); \
}";
 
void CheckShaderCompileStatus(GLuint shader)
{
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
        cerr << "Compile log: " << infoLog << endl;
        delete[] infoLog;
    }
}
 
GLuint vao;
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glutSwapBuffers();
}
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitContextVersion(3, 3);
    glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
    glutInitWindowSize(500, 500);
 
    string title = "Drawing Point Using VBO";
    glutCreateWindow(title.c_str());
    cout << title << endl;
 
    glewInit();
 
    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vShader);
    CheckShaderCompileStatus(vShader);
 
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fShader);
    CheckShaderCompileStatus(fShader);
 
    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);
    glUseProgram(program);
    GLint status;
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
 
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
        cerr << "Link log: " << infoLog << endl;
        delete[] infoLog;
    }
 
    GLfloat vertices[] = { -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f };
 
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
 
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
    GLint a_Position = glGetAttribLocation(program, "a_Position");
    glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(a_Position);
 
    glEnable(GL_PROGRAM_POINT_SIZE);
 
    glutDisplayFunc(Display);
 
    glutMainLoop();
    return 0;
}
0
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
24.11.2017, 22:51  [ТС]
Понял, а вот такой тогда вопрос, как можно изменить цвет не в самой шейдере,а в уже где-нибудь в самой программе? нужно переменную в шейдере объявить как in vec4 и туда передать значение? Вы имеете ввиду змейку, просто в длину, или что-то другое? Я пытался квадрат так сделать уже, даже попробовал сделать несколько граней для куба( переднюю и левую) Так же поменял в шейдере вершинном на вход подал vec3, думал для объема нужно. Вот код в общем, но естественно не видно ничего кроме передней грани...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#define GLEW_STATIC
 
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <string>
#include <iostream>
using namespace std;
 
extern "C" _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
 
const char *vertexShaderSource =
"#version 330\n \
 \
in vec3 a_Position; \
 \
void main()\
{ \
    gl_Position = vec4(a_Position,1.0); \
}";
 
const char *fragmentShaderSource =
"#version 330\n \
 \
precision mediump float; \
out vec4 fragColor; \
 \
void main()\
{ \
    fragColor = vec4(0.25, 1.0, 0.70, 1.0); \
}";
 
GLuint vao;
GLfloat angle=0;
 
void CheckShaderCompileStatus(GLuint shader)
{
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
        cerr << "Compile log: " << infoLog << endl;
        delete[] infoLog;
    }
}
 
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vao);
 
    glDrawArrays(GL_TRIANGLES, 0, 12);
    glutSwapBuffers();
}
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitContextVersion(3, 3);
    glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
    glutInitWindowSize(500, 500);
 
    string title = "Drawing Point Using VBO";
    glutCreateWindow(title.c_str());
    cout << title << endl;
 
    glewInit();
 
    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vShader);
    CheckShaderCompileStatus(vShader);
 
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fShader);
    CheckShaderCompileStatus(fShader);
 
    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);
    glUseProgram(program);
 
    GLint status;
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
 
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
        cerr << "Link log: " << infoLog << endl;
        delete[] infoLog;
    }
 
    int x=0;
 
    GLfloat vertices[] = {
        x-0.5,x+0.5,x+0.5,
        x+0.5,x+0.5,x+0.5,        // front side
        x-0.5,x-0.5,x+0.5,
 
        x+0.5,x-0.5,x+0.5,
        x+0.5,x+0.5,x+0.5,        // front side
        x-0.5,x-0.5,x+0.5,
 
        x+0.5,x+0.5,x+0.5,
        x+0.5,x-0.5,x+0.5,        // left side
        x+0.5,x+0.5,x-0.5,
 
        x+0.5,x-0.5,x+0.5,
        x+0.5,x-0.5,x-0.5,        // left side
        x+0.5,x+0.5,x-0.5
 
    };
 
 
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 36 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
 
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
    GLint a_Position = glGetAttribLocation(program, "a_Position");
    glVertexAttribPointer(a_Position, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(a_Position);
 
 
    glutDisplayFunc(Display);
 
    glutMainLoop();
    return 0;
}
Сейчас попробую сделать GL_TRIANGLE_STRIP
0
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
24.11.2017, 23:00  [ТС]



Тут всего 8 вершин
Жалко еще разделить их нельзя цветом, пока не знаю как сделать
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
24.11.2017, 23:42
Цитата Сообщение от Abomination_25 Посмотреть сообщение
Вы имеете ввиду змейку, просто в длину, или что-то другое? Я пытался квадрат так сделать уже, даже попробовал сделать несколько граней для куба( переднюю и левую) Так же поменял в шейдере вершинном на вход подал vec3, думал для объема нужно. Вот код в общем, но естественно не видно ничего кроме передней грани...
Давайте куб позже рассмотрим. Пока что нужно рассмотреть, как переместить квадрат в определённую позицию с помощью матрицы трансляции, которая удобно зашита в GLM. Змейка состоит из квадратов.

Цвет можно передать двумя способами: 1) через вершинный шейдер в фрагментный (для каждой вершины свой) 2) сразу в фрагментный шейдер с помощью uniform переменной (общий для всех рисуемых вершин)

Второй способ через uniform:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#define GLEW_STATIC
 
#include <GL/glew.h>
#include <GL/freeglut.h>
 
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
 
#include <string>
#include <iostream>
using namespace std;
 
extern "C" _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
 
const char *vertexShaderSource =
"#version 330\n \
 \
in vec2 a_Position; \
 \
void main()\
{ \
    gl_Position = vec4(a_Position, 0.0, 1.0); \
}";
 
const char *fragmentShaderSource =
"#version 330\n \
 \
precision mediump float; \
uniform vec3 u_Color; \
out vec4 fragColor; \
 \
void main()\
{ \
    fragColor = vec4(u_Color, 1.0); \
}";
 
void CheckShaderCompileStatus(GLuint shader)
{
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
        cerr << "Compile log: " << infoLog << endl;
        delete[] infoLog;
    }
}
 
GLuint vao;
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glutSwapBuffers();
}
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitContextVersion(3, 3);
    glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
    glutInitWindowSize(500, 500);
 
    string title = "Drawing Point Using VBO";
    glutCreateWindow(title.c_str());
    cout << title << endl;
 
    glewInit();
 
    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vShader);
    CheckShaderCompileStatus(vShader);
 
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fShader);
    CheckShaderCompileStatus(fShader);
 
    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);
    glUseProgram(program);
    GLint status;
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
 
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
        cerr << "Link log: " << infoLog << endl;
        delete[] infoLog;
    }
 
    GLfloat vertices[] = { -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f };
 
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
 
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
    GLint a_Position = glGetAttribLocation(program, "a_Position");
    glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(a_Position);
 
    GLint u_Color = glGetUniformLocation(program, "u_Color");
    glUniform3f(u_Color, 0.0, 1.0, 0.0);
 
    glEnable(GL_PROGRAM_POINT_SIZE);
 
    glutDisplayFunc(Display);
 
    glutMainLoop();
    return 0;
}
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
25.11.2017, 00:12
А первый способ - передать цвет для каждой вершине через attribute-переменную в том же буфере, что и координаты, а из вершинного шейдера передать в фрагментный. Тогда цвет будет задаваться для каждой вершины в отдельности, а не один для всех, как в случае с передачей цвета через uniform-переменную.



C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#define GLEW_STATIC
 
#include <GL/glew.h>
#include <GL/freeglut.h>
 
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
 
#include <string>
#include <iostream>
using namespace std;
 
extern "C" _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
 
const char *vertexShaderSource =
"#version 330\n \
 \
in vec2 a_Position; \
in vec3 a_Color; \
out vec3 v_Color; \
 \
void main()\
{ \
    gl_Position = vec4(a_Position, 0.0, 1.0); \
    v_Color = a_Color; \
}";
 
const char *fragmentShaderSource =
"#version 330\n \
 \
precision mediump float; \
in vec3 v_Color; \
out vec4 fragColor; \
 \
void main()\
{ \
    fragColor = vec4(v_Color, 1.0); \
}";
 
void CheckShaderCompileStatus(GLuint shader)
{
    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog);
        cerr << "Compile log: " << infoLog << endl;
        delete[] infoLog;
    }
}
 
GLuint vao;
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glutSwapBuffers();
}
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitContextVersion(3, 3);
    glutInitContextFlags(GLUT_CORE_PROFILE | GLUT_DEBUG);
    glutInitWindowSize(280, 280);
 
    string title = "Set color using attribute";
    glutCreateWindow(title.c_str());
    cout << title << endl;
 
    glewInit();
 
    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vShader);
    CheckShaderCompileStatus(vShader);
 
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fShader);
    CheckShaderCompileStatus(fShader);
 
    GLuint program = glCreateProgram();
    glAttachShader(program, vShader);
    glAttachShader(program, fShader);
    glLinkProgram(program);
    glUseProgram(program);
    GLint status;
    glGetProgramiv(program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        GLint infoLogLength;
 
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar *infoLog = new GLchar[infoLogLength];
        glGetProgramInfoLog(program, infoLogLength, NULL, infoLog);
        cerr << "Link log: " << infoLog << endl;
        delete[] infoLog;
    }
 
    GLfloat verticesAndColors[] = { 
        -0.7f, 0.7f,        // v0
        1.0f, 0.0f, 0.0f,   // Red color
        -0.7f, -0.7f,       // v1
        0.0f, 1.0f, 0.0f,   // Green color
        0.7f, 0.7f,         // v2
        0.0f, 0.0f, 1.0f,   // Blue color
        0.7f, -0.7f,        // v3
        1.0f, 1.0f, 0.0f    // Yellow color
    };
 
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 20 * sizeof(GLfloat), verticesAndColors, GL_STATIC_DRAW);
 
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
    GLint a_Position = glGetAttribLocation(program, "a_Position");
    glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(a_Position);
 
    GLint a_Color = glGetAttribLocation(program, "a_Color");
    glVertexAttribPointer(a_Color, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) (2 * sizeof(GLfloat)));
    glEnableVertexAttribArray(a_Color);
 
    glutDisplayFunc(Display);
 
    glutMainLoop();
    return 0;
}
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
25.11.2017, 00:17
Цитата Сообщение от Abomination_25 Посмотреть сообщение
Тут всего 8 вершин
Жалко еще разделить их нельзя цветом, пока не знаю как сделать
Теперь знаете. Когда сделаете, покажите, что получилось.
0
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
25.11.2017, 01:41  [ТС]
Спасибо, я уже завтра прочитаю и попробую, просто спать охота - все равно не запомню на сонную голову) Спасибо за помощь, пока что все вроде понятно) Только остался вопрос с этим : precision mediump float - понимаю, видимо что-то нужное, просто понять не могу пока зачем оно, - что с float связанное.... А так завтра попробую раскрасить куб, то есть GL_TRIANGLE_STIP из четырех вершин в разные цвета
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
25.11.2017, 11:18
Пропустили букву 'R', так правильно: GL_TRIANGLE_STRIP

Настройка "precision mediump float" задаёт точность вещественных чисел. Она необходима, без неё выдаёт ошибку. Если для расчётов не будет хватать точности mediump, то можно написать highp. Я не знаю, насколько mediump более быстрый в сравнении highp.

Пора разобраться с перемещениями. Откройте в этой книге страницу 112. Прочитайте параграф "Перемещение". Сделайте, как там написано, чтобы квадрат отрисовывался со смещением относительно начала координат. Потом я покажу, как перемещать с помощью библиотеки GLM.
0
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
25.11.2017, 11:45  [ТС]
Хорошо, сейчас попробую, просто у меня всё утро форум не работал, сейчас сначала закрашу квадрат в разные цвета)
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
25.11.2017, 11:49
Цитата Сообщение от Abomination_25 Посмотреть сообщение
просто у меня всё утро форум не работал
Значит, он ни у кого не работал.
0
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
25.11.2017, 11:58  [ТС]
Немного не понимаю вот эти строки, точнее смысл аргументов:
GLint a_Position = glGetAttribLocation(program, "a_Position");
glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(a_Position);

GLint a_Color = glGetAttribLocation(program, "a_Color");
glVertexAttribPointer(a_Color, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) (2 * sizeof(GLfloat)));
glEnableVertexAttribArray(a_Color);

Понимаю, что мы получаем расположение атрибут, дальше с указателем что-то... a_Color переменная, где хранится положение атрибута, 3 - сколько переменных в 1 веришине?дальше тип Float, gl_false Не знаю... 5 * sizeof(GLfloat) - это тоже не понимаю, у нас вроде всего 4 раза по 3 веришины, а откуда 5 не понимаю) Выше было 20 - там просто количество переменных переданных в буфер? А тут не знаю... а дальше (GLvoid*) (2 * sizeof(GLfloat))) - вообще ужас
Тоже самое и с a_Position Не понятно( Да. результат получился немного другой, как-будто артефакт какой-то
0
9991 / 2963 / 497
Регистрация: 05.10.2013
Сообщений: 8,134
Записей в блоге: 243
25.11.2017, 12:14
Эти строчки задают настройку для буфера, чтобы шейдер знал какие данные ему забирать с какой позиции в массиве.

Например:
C++
1
glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
Теперь шейдер знает, что аттрибут a_Position хранится по два значения, через пять с нулевого элемента в массиве.

Здесь:
C++
1
glVertexAttribPointer(a_Color, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*) (2 * sizeof(GLfloat)));
Шейдер узнаёт, что аттрибут a_Color хранится по три значения, через пять, начинается со второго.

Цитата Сообщение от Abomination_25 Посмотреть сообщение
А тут не знаю... а дальше (GLvoid*) (2 * sizeof(GLfloat)))
Приведение к указателя на void нужно потому что в документации на glVertexAttribPointer последний параметр (offset) требует указатель на void

sizeof(GLfloat) - это столько в байтах занимает одно значение в массиве. Потому что offset (он же pointer) и stride по документации должен быть в байтах.

Добавлено через 2 минуты
Цитата Сообщение от Abomination_25 Посмотреть сообщение
4 раза по 3 веришины, а откуда 5 не понимаю
5 потому что, например, вершины повторяются через 5.


GLfloat verticesAndColors[] = {
-0.7f, 0.7f, // v0
1.0f, 0.0f, 0.0f, // Red color
-0.7f, -0.7f, // v1
0.0f, 1.0f, 0.0f, // Green color
0.7f, 0.7f, // v2
0.0f, 0.0f, 1.0f, // Blue color
0.7f, -0.7f, // v3
1.0f, 1.0f, 0.0f // Yellow color
};
Добавлено через 4 минуты
Цитата Сообщение от Abomination_25 Посмотреть сообщение
результат получился немного другой, как-будто артефакт какой-то
Скопируйте все код в сообщение.
0
 Аватар для Abomination_25
4 / 4 / 0
Регистрация: 13.12.2016
Сообщений: 246
25.11.2017, 12:18  [ТС]
Понял) То есть мы можем с той же уверенностью сделать так: массив состоит сначала из 3 цветов , а потом двух координат.
И записать:

C++
1
2
glVertexAttribPointer(a_Color, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)*0);
glVertexAttribPointer(a_Position, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)*(2*sizeof(GLfloat)));
Разве 5 не значит количество переменных типа float? Я думал нам нужен размер элемента в массиве....

А что не так с моей программой, какой-то артефакт
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.11.2017, 12:18

Пытаюсь сделать змейку в консоли :)
Всем привет, тут набросал небольшой код, хочу сделать змейку, но столкнулся с такой проблемой: Ведь змейка есть яблоки и растёт, я добавил...

Создал змейку, но получился "шиткод", посмотрим что можно сделать?
Вот ссылка на гитхабе https://github.com/OlegNIKUA/SnakeFirst Это основной код

System.AccessViolationException: Попытка чтения или записи в защищенную память - попытка 2
В предыдущей теме некто вообразил, что код зацикливается, поэтому приходится выкладывать более широкую модель. Надеюсь, до целого проекта...

System.AccessViolationException: Попытка чтения или записи в защищенную память - попытка 3
Уже простите за некомпилируемый код, просто я переустановил Windows, и Visual Studio удалилась, только сегодня днем установил. Код там...

Попытка сделать рисунок используя graphics.h
Здравствуйте! Почему не компилируется этот код? #include &lt;graphics.h&gt; int main( ) { initwindow(400, 300,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru