未绘制三角形。 C++/GLEW/SDL [关闭]
Posted
技术标签:
【中文标题】未绘制三角形。 C++/GLEW/SDL [关闭]【英文标题】:Triangle not being drawn. C++/GLEW/SDL [closed] 【发布时间】:2019-08-29 17:07:16 【问题描述】:我正在尝试创建一个在屏幕上绘制红色三角形的程序,我使用 GLFW 而不是 SDL 并且不使用类成功地做到了这一点。 但是,在 SDL 中执行此操作并使用类时,它似乎没有绘制三角形,但构建成功并返回 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;
形状.h
#pragma once
#include <GL/glew.h>
class Shape
public:
void CreateTriangle(GLuint VAO, GLuint VBO);
;
形状.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);
着色器.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);
;
着色器.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;
【问题讨论】:
ck
后面的#version
是什么?
无关:声明着色器的更简单方法可能是使用raw string literal..
我看到的一个问题是您将着色器句柄传递给 void CompileShader(GLuint shader);
的值,而不是引用。
@HolyBlackCat 意外错误,但与无法绘制三角形无关,已删除。另外,我必须在每次使用着色器的前面加上 & 吗?
【参考方案1】:
方法的参数
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);
;
【讨论】:
谢谢! @HolyBlackCat 让我参考着色器,但我没有意识到我必须为 VAO 和 VBO 做同样的事情!以上是关于未绘制三角形。 C++/GLEW/SDL [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
GLEW + cmake 链接失败“未定义对符号 glDrawElements 的引用”+“命令行中缺少 DSO”