未绘制三角形。 C++/GLEW/SDL
Triangle not being drawn. C++/GLEW/SDL
我正在尝试创建一个将在屏幕上绘制红色三角形的程序,我使用 GLFW 而不是 SDL 成功地做到了这一点,并且没有使用 类。
但是,在 SDL 中执行此操作并使用 类 时,它似乎没有绘制三角形,但构建成功并且 returns 0 应该如此。
我已经仔细扫描了我的代码,但仍然找不到解决方案。
是不是因为我根本无法在这种编程中使用 类(我对此表示怀疑)?
main.cpp
#include <iostream>
#include <GL/glew.h>
#define SDL_MAIN_HANDLED
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include "Shader.h"
#include "Shape.h"
using namespace std;
const GLint WIDTH = 800;
const GLint HEIGHT = 600;
GLuint VAO, VBO, shader;
int main() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "Error: Failed to initialize SDL!" << endl;
return 1;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_Window* mainWindow = SDL_CreateWindow("My Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
if (mainWindow == nullptr) {
cout << "Error: Failed to create window [mainWindow]" << endl;
return 1;
}
SDL_GLContext context = SDL_GL_CreateContext(mainWindow);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
cout << "Error: Failed to initialize GLEW, OpenGL error." << endl;
return 1;
}
Shader cShader;
Shape shape;
glViewport(0, 0, WIDTH, HEIGHT);
shape.CreateTriangle(VAO, VBO);
cShader.CompileShader(shader);
SDL_Event windowEvent;
while (true) {
if (SDL_PollEvent(&windowEvent)) {
if (windowEvent.type == SDL_QUIT) {
break;
}
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
SDL_GL_SwapWindow(mainWindow);
}
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(mainWindow);
SDL_Quit();
return 0;
}
Shape.h
#pragma once
#include <GL/glew.h>
class Shape
{
public:
void CreateTriangle(GLuint VAO, GLuint VBO);
};
Shape.cpp
#include "Shape.h"
#include <GL/glew.h>
void Shape::CreateTriangle(GLuint VAO, GLuint VBO) {
GLfloat triVertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(triVertices), triVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
Shader.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
class Shader
{
public:
static const char* vShader;
static const char* fShader;
void AddShader(const char* shaderCode, GLenum shaderType, GLuint shader);
void CompileShader(GLuint shader);
};
Shader.cpp
#include "Shader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <GL/glew.h>
const char* Shader::vShader = " \n\
#version 330 ck \n\
\n\
layout (location = 0) in vec3 pos; \n\
\n\
void main() \n\
{ \n\
gl_Position = vec4(0.4 * pos.x, 0.4 * pos.y, pos.z, 1.0); \n\
}";
const char* Shader::fShader = " \n\
#version 330 \n\
\n\
out vec4 colour; \n\
\n\
void main() \n\
{ \n\
colour = vec4(1.0, 0.0, 0.0, 1.0); \n\
}";
void Shader::AddShader(const char* shaderCode, GLenum shaderType, GLuint theProgram) {
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if (!result) {
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
printf("Error compiling the %d shader: %s\n", shaderType, eLog);
return;
}
glAttachShader(theProgram, theShader);
}
void Shader::CompileShader(GLuint shader) {
shader = glCreateProgram();
if (!shader) {
printf("Error creating shader!\n");
return;
}
AddShader(vShader, GL_VERTEX_SHADER, shader);
AddShader(fShader, GL_FRAGMENT_SHADER, shader);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error linking program: %s\n", eLog);
return;
}
glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error validating program: %s\n", eLog);
return;
}
}
方法的参数
void CreateTriangle(GLuint VAO, GLuint VBO);
void CompileShader(GLuint shader);
按值传递。
如果你想从方法中“取回”创建的对象(值),那么你必须通过引用传递参数:
class Shape
{
public:
void CreateTriangle(GLuint &VAO, GLuint &VBO);
};
class Shader
{
public:
// ...
void CompileShader(GLuint &shader);
};
我正在尝试创建一个将在屏幕上绘制红色三角形的程序,我使用 GLFW 而不是 SDL 成功地做到了这一点,并且没有使用 类。 但是,在 SDL 中执行此操作并使用 类 时,它似乎没有绘制三角形,但构建成功并且 returns 0 应该如此。
我已经仔细扫描了我的代码,但仍然找不到解决方案。
是不是因为我根本无法在这种编程中使用 类(我对此表示怀疑)?
main.cpp
#include <iostream>
#include <GL/glew.h>
#define SDL_MAIN_HANDLED
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include "Shader.h"
#include "Shape.h"
using namespace std;
const GLint WIDTH = 800;
const GLint HEIGHT = 600;
GLuint VAO, VBO, shader;
int main() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "Error: Failed to initialize SDL!" << endl;
return 1;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_Window* mainWindow = SDL_CreateWindow("My Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
if (mainWindow == nullptr) {
cout << "Error: Failed to create window [mainWindow]" << endl;
return 1;
}
SDL_GLContext context = SDL_GL_CreateContext(mainWindow);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
cout << "Error: Failed to initialize GLEW, OpenGL error." << endl;
return 1;
}
Shader cShader;
Shape shape;
glViewport(0, 0, WIDTH, HEIGHT);
shape.CreateTriangle(VAO, VBO);
cShader.CompileShader(shader);
SDL_Event windowEvent;
while (true) {
if (SDL_PollEvent(&windowEvent)) {
if (windowEvent.type == SDL_QUIT) {
break;
}
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
SDL_GL_SwapWindow(mainWindow);
}
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(mainWindow);
SDL_Quit();
return 0;
}
Shape.h
#pragma once
#include <GL/glew.h>
class Shape
{
public:
void CreateTriangle(GLuint VAO, GLuint VBO);
};
Shape.cpp
#include "Shape.h"
#include <GL/glew.h>
void Shape::CreateTriangle(GLuint VAO, GLuint VBO) {
GLfloat triVertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(triVertices), triVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
Shader.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
class Shader
{
public:
static const char* vShader;
static const char* fShader;
void AddShader(const char* shaderCode, GLenum shaderType, GLuint shader);
void CompileShader(GLuint shader);
};
Shader.cpp
#include "Shader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <GL/glew.h>
const char* Shader::vShader = " \n\
#version 330 ck \n\
\n\
layout (location = 0) in vec3 pos; \n\
\n\
void main() \n\
{ \n\
gl_Position = vec4(0.4 * pos.x, 0.4 * pos.y, pos.z, 1.0); \n\
}";
const char* Shader::fShader = " \n\
#version 330 \n\
\n\
out vec4 colour; \n\
\n\
void main() \n\
{ \n\
colour = vec4(1.0, 0.0, 0.0, 1.0); \n\
}";
void Shader::AddShader(const char* shaderCode, GLenum shaderType, GLuint theProgram) {
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if (!result) {
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
printf("Error compiling the %d shader: %s\n", shaderType, eLog);
return;
}
glAttachShader(theProgram, theShader);
}
void Shader::CompileShader(GLuint shader) {
shader = glCreateProgram();
if (!shader) {
printf("Error creating shader!\n");
return;
}
AddShader(vShader, GL_VERTEX_SHADER, shader);
AddShader(fShader, GL_FRAGMENT_SHADER, shader);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error linking program: %s\n", eLog);
return;
}
glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
if (!result) {
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error validating program: %s\n", eLog);
return;
}
}
方法的参数
void CreateTriangle(GLuint VAO, GLuint VBO);
void CompileShader(GLuint shader);
按值传递。
如果你想从方法中“取回”创建的对象(值),那么你必须通过引用传递参数:
class Shape
{
public:
void CreateTriangle(GLuint &VAO, GLuint &VBO);
};
class Shader
{
public:
// ...
void CompileShader(GLuint &shader);
};