顶点不显示
Verticies aren't showing
我的代码有问题。没有错误,但没有绘制任何内容。我不确定发生了什么。我做错了什么?
Main.cpp
//
// MainGame.cpp
//
#include "MainGame.hpp"
#include <iostream>
#include <string>
#include "Errors.hpp"
// Constructor, initialize private variables
MainGame::MainGame() {
_window = nullptr;
_screenWidth = 1080;
_screenHeight = 720;
_gameState = GameState::PLAY;
}
MainGame::~MainGame() {
SDL_DestroyWindow(_window);
SDL_Quit();
}
// Run the game
void MainGame::run() {
initSystem();
_sprite.init(-1.0f, -1.0f, 1.0f, 1.0f);
gameLoop();
}
// Initialize SDL2, OpenGL, and whatever else
void MainGame::initSystem() {
if (0 != SDL_Init(SDL_INIT_EVERYTHING)) {
fprintf(stderr, "\nUnable to initalize SDL: %s\n", SDL_GetError());
fatalError("Unable to initiaize SDL");
}
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// Create the window...
_window = SDL_CreateWindow("My Game",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
_screenWidth,
_screenHeight,
SDL_WINDOW_OPENGL |
SDL_WINDOW_SHOWN |
SDL_WINDOW_RESIZABLE);
if (_window == nullptr) {
fatalError("Window could not be created");
}
SDL_GLContext glContext = SDL_GL_CreateContext(_window);
if (glContext == nullptr) {
fatalError("SDL_GL context could not be created!");
}
// Clear to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
initShaders();
}
void MainGame::initShaders() {
_colorProgram.compileShaders("/Shaders/colorShader.vert", "/Shaders/colorShader.frag");
_colorProgram.addAttribute("vertexPosition");
_colorProgram.linkShaders();
}
void MainGame::gameLoop() {
while (_gameState != GameState::EXIT) {
processInput();
drawGame();
}
}
// Process input with SDL2
void MainGame::processInput() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
_gameState = GameState::EXIT;
break;
case SDL_APP_DIDENTERFOREGROUND:
SDL_Log("SDL_APP_DIDENTERFOREGROUND");
break;
case SDL_APP_DIDENTERBACKGROUND:
SDL_Log("SDL_APP_DIDENTERBACKGROUND");
break;
case SDL_APP_LOWMEMORY:
SDL_Log("SDL_APP_LOWMEMORY");
break;
}
}
}
void MainGame::drawGame() {
glClearDepth(1.0f);
//glClearColor(rand() % 255 / 255.0f, rand() % 255 / 255.0f, rand() % 255 / 255.0f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_colorProgram.use();
// Draw sprite
_sprite.draw();
_colorProgram.unuse();
SDL_GL_SwapWindow(_window);
}
Sprite.cpp
//
// Sprite.cpp
//
#include "Sprite.hpp"
Sprite::Sprite() : _vboID(0) {
}
Sprite::~Sprite() {
if (_vboID != 0) {
glDeleteBuffers(1, &_vboID);
}
}
void Sprite::init(float x, float y, float width, float height) {
// Setup private vars
_x = x;
_y = y;
_width = width;
_height = height;
if (_vboID == 0) {
glGenBuffers(1, &_vboID);
}
float vertexData[12];
// First triangle
vertexData[0] = x + width;
vertexData[1] = x + height;
vertexData[2] = x;
vertexData[3] = y + height;
vertexData[4] = x;
vertexData[5] = y;
// Second triangle
vertexData[6] = x;
vertexData[7] = y;
vertexData[8] = x + width;
vertexData[9] = y;
vertexData[10] = x + width;
vertexData[11] = y + height;
// Bind vertex buffer object
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
// Upload to GPU
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
// Unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Sprite::draw() {
// Bind buffer
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
// Use first attribute array
glEnableVertexAttribArray(0);
// Point data to VBO
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
// Draw 6 verticies to screen
glDrawArrays(GL_TRIANGLES, 0, 6);
// Disable vertex attribute array
glDisableVertexAttribArray(0);
// Unbind VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
在 OpenGL > 3.3 Core Profile 中,必须使用 VAO。
通常这会给你一个 GL_INVALID_OPERATION
绘图命令错误(必须由 glGetError()
查询)
我的代码有问题。没有错误,但没有绘制任何内容。我不确定发生了什么。我做错了什么?
Main.cpp
//
// MainGame.cpp
//
#include "MainGame.hpp"
#include <iostream>
#include <string>
#include "Errors.hpp"
// Constructor, initialize private variables
MainGame::MainGame() {
_window = nullptr;
_screenWidth = 1080;
_screenHeight = 720;
_gameState = GameState::PLAY;
}
MainGame::~MainGame() {
SDL_DestroyWindow(_window);
SDL_Quit();
}
// Run the game
void MainGame::run() {
initSystem();
_sprite.init(-1.0f, -1.0f, 1.0f, 1.0f);
gameLoop();
}
// Initialize SDL2, OpenGL, and whatever else
void MainGame::initSystem() {
if (0 != SDL_Init(SDL_INIT_EVERYTHING)) {
fprintf(stderr, "\nUnable to initalize SDL: %s\n", SDL_GetError());
fatalError("Unable to initiaize SDL");
}
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// Create the window...
_window = SDL_CreateWindow("My Game",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
_screenWidth,
_screenHeight,
SDL_WINDOW_OPENGL |
SDL_WINDOW_SHOWN |
SDL_WINDOW_RESIZABLE);
if (_window == nullptr) {
fatalError("Window could not be created");
}
SDL_GLContext glContext = SDL_GL_CreateContext(_window);
if (glContext == nullptr) {
fatalError("SDL_GL context could not be created!");
}
// Clear to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
initShaders();
}
void MainGame::initShaders() {
_colorProgram.compileShaders("/Shaders/colorShader.vert", "/Shaders/colorShader.frag");
_colorProgram.addAttribute("vertexPosition");
_colorProgram.linkShaders();
}
void MainGame::gameLoop() {
while (_gameState != GameState::EXIT) {
processInput();
drawGame();
}
}
// Process input with SDL2
void MainGame::processInput() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
_gameState = GameState::EXIT;
break;
case SDL_APP_DIDENTERFOREGROUND:
SDL_Log("SDL_APP_DIDENTERFOREGROUND");
break;
case SDL_APP_DIDENTERBACKGROUND:
SDL_Log("SDL_APP_DIDENTERBACKGROUND");
break;
case SDL_APP_LOWMEMORY:
SDL_Log("SDL_APP_LOWMEMORY");
break;
}
}
}
void MainGame::drawGame() {
glClearDepth(1.0f);
//glClearColor(rand() % 255 / 255.0f, rand() % 255 / 255.0f, rand() % 255 / 255.0f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_colorProgram.use();
// Draw sprite
_sprite.draw();
_colorProgram.unuse();
SDL_GL_SwapWindow(_window);
}
Sprite.cpp
//
// Sprite.cpp
//
#include "Sprite.hpp"
Sprite::Sprite() : _vboID(0) {
}
Sprite::~Sprite() {
if (_vboID != 0) {
glDeleteBuffers(1, &_vboID);
}
}
void Sprite::init(float x, float y, float width, float height) {
// Setup private vars
_x = x;
_y = y;
_width = width;
_height = height;
if (_vboID == 0) {
glGenBuffers(1, &_vboID);
}
float vertexData[12];
// First triangle
vertexData[0] = x + width;
vertexData[1] = x + height;
vertexData[2] = x;
vertexData[3] = y + height;
vertexData[4] = x;
vertexData[5] = y;
// Second triangle
vertexData[6] = x;
vertexData[7] = y;
vertexData[8] = x + width;
vertexData[9] = y;
vertexData[10] = x + width;
vertexData[11] = y + height;
// Bind vertex buffer object
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
// Upload to GPU
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
// Unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Sprite::draw() {
// Bind buffer
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
// Use first attribute array
glEnableVertexAttribArray(0);
// Point data to VBO
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
// Draw 6 verticies to screen
glDrawArrays(GL_TRIANGLES, 0, 6);
// Disable vertex attribute array
glDisableVertexAttribArray(0);
// Unbind VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
在 OpenGL > 3.3 Core Profile 中,必须使用 VAO。
通常这会给你一个 GL_INVALID_OPERATION
绘图命令错误(必须由 glGetError()
查询)