#c #opengl
#c #opengl
Вопрос:
Я следую руководству, чтобы нарисовать треугольник на экране с помощью OpenGL. Я правильно выполнил все шаги, но я получаю только зеленый экран без треугольника.
Это мой текущий код. drawScene вызывается во время инициализации приложения и изменяет размер при каждом WM_DRAW. Мой вопрос: почему треугольник не отображается в моем коде?
Версия OpenGL: 4.6
#include "glew.h"
GLuint program;
GLuint VAO, VBO, EBO;
void DrawScene(HWND _hWnd);
void SetupShaders()
{
const char* vertexSource = {
"#version 130 coren"
"layout (location = 0) in vec3 iPos;n"
"void main()n"
"{n"
" gl_Position = vec4(iPos, 1.0f);n"
"}n"
""
};
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, amp;vertexSource, NULL);
glCompileShader(vertexShader);
const char* fragmentSource = {
"#version 130 coren"
"out vec4 FragColor;n"
"void main()n"
"{n"
" FragColor = vec4(1.0f, 0.0f, 1.0f, 1.0f);n"
"}n"
""
};
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, amp;fragmentSource, NULL);
glCompileShader(fragmentShader);
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "iPos");
glLinkProgram(program);
}
void SetupBuffers()
{
glGenVertexArrays(1, amp;VAO);
glGenBuffers(1, amp;VBO);
glGenBuffers(1, amp;EBO);
float vertexData[] = {
0.0f, 0.0f, 0.0f,
10.0f, 10.0f, 0.0f,
10.0f, 0.0f, 0.0f,
0.0f, 10.0f, 0.0f
};
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
unsigned int indexData[] = {
0, 1, 2,
1, 2, 3
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(float) * 3, (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void SetupScene(HWNDamp; _hWnd)
{
static PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
16, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
};
HDC hdc = GetDC(_hWnd);
int pf = ChoosePixelFormat(hdc, amp;pfd);
SetPixelFormat(hdc, pf, amp;pfd);
HGLRC hglrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hglrc);
glewInit();
ShowWindow(_hWnd, SW_SHOW);
SetForegroundWindow(_hWnd);
SetFocus(_hWnd);
SetupShaders();
SetupBuffers();
}
void ResizeScene(HWNDamp; _hWnd, size_t _width, size_t _height)
{
if (!_height)
{
_height = 1;
}
glViewport(0, 0, _width, _height);
DrawScene(_hWnd);
}
void DrawScene(HWND _hWnd)
{
HDC hdc = GetDC(_hWnd);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glUseProgram(program);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
SwapBuffers(hdc);
}
Ответ №1:
Вам действительно нужно включить уровень проверки отладки и проверять ошибки, потому что в вашем коде есть целая куча легко уловимых заблуждений:
- Не используйте
glBindAttribLocation
.iPos
уже (правильно) привязан к местоположению макета 0, вы просто нарушаете его. - Вы не отсоединяли и не удаляли свои шейдерные программы после того, как связали программу, что привело к утечке памяти.
- Не отсоединяйте буферы вершин и элементов от вашего массива вершин, в этом весь смысл его использования в первую очередь.
- Связанный с 3, не меняйте буферы вершин и элементов вашего массива вершин при каждом рендеринге. Вы настраиваете буфер вершин один раз.
- Вы сообщаете OpenGL, что ваши элементы индекса являются байтами в вашем
glDrawElements
, и вместо этого вы загружаете их как 32-разрядные целые числа. Будьте последовательны.
Комментарии:
1. Большое вам спасибо за помощь! Я искал решение в течение нескольких дней
2. Могу ли я также предложить научиться использовать Renderdoc (или аналогичный), в нем есть окно для отображения ошибок / предупреждений, и вы сможете увидеть, правильно ли интерпретируются ваши данные. Это поможет вам диагностировать проблемы, подобные # 5.
3. Ошибки / предупреждения в RenderDoc — это просто вывод уровня отладки, вы можете (и должны) получить это и в своем собственном коде.