Использование SDL2 и OpenGL для поворота камеры и рисование треугольника ничего не отобразят?

Я просто пытаюсь создать треугольник в центре и повернуть камеру вокруг центра. (0,0,0), код взят из нескольких учебных пособий, и я подозреваю, что проблема может быть где-то из glm::perspective/lookat или же gl:projection/model matrix перед треугольником рисует колл.
потому что именно в этом мое общее замешательство.
любая помощь очень ценится, так что я могу продолжать свою жизнь. заранее спасибо.

//sudo g++ -o sdl main.cpp -lSDL2_image -lGL -lGLU -lglut -lX11 -lGLEW `sdl2-config --cflags --libs`
#include <iostream>
#include <GL/glew.h>
#include <glm/glm.hpp>
#include "glm/gtc/matrix_transform.hpp"#include <glm/gtc/type_ptr.hpp>
#include <SDL2/SDL.h>
#include <string>
#include <GL/gl.h>std::string programName = "SDL2/OpenGL";
SDL_Window *mainWindow;
SDL_GLContext mainContext;

void Calculate()
{
float radius = 2.0f;
float camX = sin(SDL_GetTicks()*0.001) * radius;
float camZ = cos(SDL_GetTicks()*0.001) * radius;

glm::mat4 perspecive_mat = glm::perspective(
45.0f, 1.0f / 1.0f, 0.1f, 100.0f );

glm::mat4 view_mat = glm::lookAt(
glm::vec3(camX, 0.0, camZ), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0) );

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(perspecive_mat));

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(glm::value_ptr(view_mat));
}void Render()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

float vertexCoords[24] = {  // Coordinates for the vertices of a cube.
1,1,1,   1,1,-1,   1,-1,-1,   1,-1,1,
-1,1,1,  -1,1,-1,  -1,-1,-1,  -1,-1,1  };

float vertexColors[24] = {  // An RGB color value for each vertex
1,1,1,   1,0,0,   1,1,0,   0,1,0,
0,0,1,   1,0,1,   0,0,0,   0,1,1  };

int elementArray[24] = {  // Vertex numbers for the six faces.
0,1,2,3, 0,3,7,4, 0,4,5,1,
6,2,1,5, 6,5,4,7, 6,7,3,2  };

glVertexPointer( 3, GL_FLOAT, 0, vertexCoords );
glColorPointer( 3, GL_FLOAT, 0, vertexColors );

glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );

glDrawElements( GL_QUADS, 24, GL_UNSIGNED_INT, elementArray );SDL_GL_SwapWindow(mainWindow);
}

bool Loop()
{
while (true ){
SDL_Event event;
while ( SDL_PollEvent( &event ) ){
switch ( event.type ){
case SDL_QUIT :
SDL_Quit();
return 0;
case SDL_KEYDOWN :
std::cout<<"Key Down"<<std::endl;
break;
case SDL_KEYUP :
std::cout<<"Key Up"<<std::endl;
break;
case SDL_MOUSEBUTTONDOWN :
case SDL_MOUSEBUTTONUP :
case SDL_MOUSEMOTION :
default :
break;
}
}

Calculate();

Render();
}
}void CheckSDLError(int line = -1){
std::string error = SDL_GetError();

if (error != "")
{
std::cout << "SLD Error : " << error << std::endl;

if (line != -1)
std::cout << "\nLine : " << line << std::endl;

SDL_ClearError();
}
}void Cleanup(){
SDL_GL_DeleteContext(mainContext);
SDL_DestroyWindow(mainWindow );
SDL_Quit();
}

int main(int argc, char *argv[]){
if (SDL_Init(SDL_INIT_VIDEO) < 0){
std::cout << "Failed to init SDL\n";
return false;
}
mainWindow = SDL_CreateWindow(programName.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (!mainWindow )
{
std::cout << "Unable to create window\n"<< std::endl;;
CheckSDLError(__LINE__);
return false;
}

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
//SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
mainContext = SDL_GL_CreateContext(mainWindow );

// This makes our buffer swap syncronized with the monitor's vertical refresh
//      ( which means it enables v-sync)
// Setting this to 0 will disable V-sync
//      Which means our application could run at unlimited fps
SDL_GL_SetSwapInterval(1);
// Init GLEW
glewExperimental = GL_TRUE;
glewInit();
// Enable blending so that we can have transparanet object
glEnable(GL_BLEND ) ;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Enable depth testing so that closer triangles will hide the triangles farther away
glEnable( GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

Loop();
Cleanup();

return 0;
}

1

Решение

Обратите внимание, что рисунок по glBegin/glEnd Последовательности и стек конвейерной матрицы с фиксированной функцией устарели с десятилетий.
Прочитать о Трубопровод с фиксированной функцией и посмотреть Спецификация вершины а также Shader за современный способ рендеринга.

Если вы хотите использовать устаревший способ рисования, то вы должны использовать контекст профиля совместимости вместо основного профиля профиля (см. Контекст OpenGL):

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);


Далее обратите внимание, что glm::lookAt а также glm::perspective не устанавливайте состояния OpenGL или даже фиксированные матрицы функций. GLM — OpenGL Математика математическая библиотека для выполнения расчетов, связанных с OpenGL Обе функции возвращают матрицу 4 * 4.

Ты можешь использовать glLoadMatrixf загрузить матрицу, возвращаемую GLM Функция в стеке конвейера с фиксированной функцией OpenGL:

#include <glm/glm.hpp>
#include "glm/gtc/matrix_transform.hpp"#include <glm/gtc/type_ptr.hpp>
void Calculate()
{
float radius = 2.0f;
float camX = sin(SDL_GetTicks()*0.001) * radius;
float camZ = cos(SDL_GetTicks()*0.001) * radius;

glm::mat4 perspecive_mat = glm::perspective(
45.0f, 1.0f / 1.0f, 0.1f, 100.0f );

glm::mat4 view_mat = glm::lookAt(
glm::vec3(camX, 0.0, camZ), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0) );

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(glm::value_ptr(perspecive_mat));

glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(glm::value_ptr(view_mat));
}

Если вы хотите использовать основной профиль, то вам нужно создать простой Shader программа:

#include <string>

std::string sh_vert = R"(
#version 150 core

in vec3 v_pos;
in vec4 v_col;

out vec4 color;

uniform mat4 projection;
uniform mat4 view;

void main()
{
color = v_col;
gl_Position = projection * view * vec4(v_pos, 1.0);
}
)";

std::string sh_frag = R"(
#version 150 core

in vec4 color;

void main()
{
gl_FragColor = color;
}
)";

Скомпилируйте и скомпонуйте программу:

#include <vector>

GLuint CreateShader(GLenum type, const char *code)
{
GLuint shaderObj = glCreateShader(type);
glShaderSource(shaderObj, 1, &code, nullptr);
glCompileShader(shaderObj);

GLint status = GL_TRUE;
glGetShaderiv(shaderObj, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
GLint logLen;
glGetShaderiv(shaderObj, GL_INFO_LOG_LENGTH, &logLen);
std::vector< char >log(logLen);
GLsizei written;
glGetShaderInfoLog(shaderObj, logLen, &written, log.data());
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
return shaderObj;
}

GLuint CreateProgram()
{
GLuint vShObj = CreateShader(GL_VERTEX_SHADER, sh_vert.c_str());
GLuint fShObj = CreateShader(GL_FRAGMENT_SHADER, sh_frag.c_str());

GLuint progObj = glCreateProgram();
glAttachShader(progObj, vShObj);
glAttachShader(progObj, fShObj);
glLinkProgram(progObj);

GLint status = GL_TRUE;
glGetProgramiv(progObj, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
GLint logLen;
glGetProgramiv(progObj, GL_INFO_LOG_LENGTH, &logLen);
std::vector< char >log(logLen);
GLsizei written;
glGetProgramInfoLog(progObj, logLen, &written, log.data());
std::cout << "link error:" << std::endl << log.data() << std::endl;
}
return progObj;
}

Получить атрибут и единообразные локации:

GLuint prog;
GLint pos_attr, col_attr, proj_loc, view_loc;

void Init()
{
prog = CreateProgram();
pos_attr = glGetAttribLocation(prog, "v_pos");
col_attr = glGetAttribLocation(prog, "v_col");
proj_loc = glGetUniformLocation(prog, "projection");
view_loc = glGetUniformLocation(prog, "view");

// ....

}

Создать Vertex Array Object:

GLuint vao;

void Init()
{
// ....

const std::vector<float> varray
{
// x      y     z     red   green blue
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f,  0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f,  0.5f, 0.0f, 0.0f, 0.0f, 1.0f
};

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, varray.size()*sizeof(float), varray.data(), GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glVertexAttribPointer(pos_attr, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), 0);
glEnableVertexAttribArray(pos_attr);
glVertexAttribPointer(col_attr, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float)));
glEnableVertexAttribArray(col_attr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}

Устанавливает программный объект как часть текущего состояния рендеринга и устанавливает единообразные переменные:

void Calculate()
{
float radius = 2.0f;
float camX = sin(SDL_GetTicks()*0.001) * radius;
float camZ = cos(SDL_GetTicks()*0.001) * radius;

glm::mat4 perspecive_mat = glm::perspective(
45.0f, 1.0f / 1.0f, 0.1f, 100.0f );

glm::mat4 view_mat = glm::lookAt(
glm::vec3(camX, 0.0, camZ), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0) );

glUseProgram(prog);
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, glm::value_ptr(perspecive_mat));
glUniformMatrix4fv(view_loc, 1, GL_FALSE, glm::value_ptr(view_mat));
}

Наконец нарисуйте треугольник:

void Render()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);

SDL_GL_SwapWindow(mainWindow);
}

bool Loop()
{
Init();

while (true) {
// ....

Calculate();
Render();
}
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]