I've been trying to make a simple game engine from scratch using OpenGL 3.3 (GLFW 3.3.8 and glad) alongside with .NET and C++ just for fun. However, when I try to render a simple triangle with a background, it won't.
It only shows the background color, but not the triangle.
I'm getting the Invalid Operation error when i use glGetError, but I can't figure out why.
Can someone help me?
CODE:
Program.cs
using System;
using System.Runtime.InteropServices;
using Engine.Modules;
namespace Engine
{
class Program
{
private static void Main(string[] args)
{
string vertexShaderSource = "#version 330 core\n" +
"layout (location = 0) in vec3 aPos;\n" +
"void main()\n" +
"{\n" +
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" +
"}\0";
string fragmentShaderSource = "#version 330 core\n" +
"out vec4 FragColor;\n" +
"void main()\n" +
"{\n" +
" FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);\n" +
"}\n\0";
float[] vertices =
{
-0.5f, -0.5f * (float)Math.Sqrt(3) / 3, 0.0f, // Lower left corner
0.5f, -0.5f * (float)Math.Sqrt(3) / 3, 0.0f, // Lower right corner
0.0f, 0.5f * (float)Math.Sqrt(3) * 2 / 3, 0.0f // Upper corner
};
int window = GLFW.CreateGLWindow(1280, 720, "Engine");
uint VAO, VBO;
uint shaderProgram;
shaderProgram = GL.ApplyShaders(vertexShaderSource, fragmentShaderSource);
VBO = GL.GetVbo();
VAO = GL.GetVao();
GL.ClearColor(0.0f, 0.5f, 0.5f, 1.0f);
GL.Clear(0);
GLFW.SwapBuffers(window);
while (!GLFW.WindowShouldClose(window))
{
GL.ClearColor(0.07f, 0.13f, 0.17f, 1.0f);
GL.Clear(0);
GL.UseProgram(shaderProgram);
GL.BindVertexArray(VAO);
GL.DrawArrays(0, 0, 3);
GLFW.SwapBuffers(window);
GLFW.PollEvents();
}
GL.DestroyVrtx(VBO, VAO, shaderProgram);
GLFW.Terminate();
}
}
}
dllmain.cpp
#include "pch.h"
#include<iostream>
#include<vector>
#include "GameWindow.h"
std::vector<GameWindow*> wVector;
unsigned int* vertexArrays = new unsigned int[2];
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
std::cout << "OpenGL C++ DLL hooked" << std::endl;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
GLFWwindow* getWindowByID(int wID)
{
return wVector[wID]->window;
}
extern "C"
{
__declspec(dllexport) int GlfwCreateGLWindow(int w, int h, const char* title)
{
std::cout << "Creating GLFW Window" << std::endl;
GameWindow* gw = new GameWindow();
gw->Create(w, h, title);
wVector.push_back(gw);
return wVector.size() - 1;
}
__declspec(dllexport) bool GlfwWindowShouldClose(int windowID)
{
return glfwWindowShouldClose(getWindowByID(windowID));
}
__declspec(dllexport) void GlfwPollEvents()
{
glfwPollEvents();
}
__declspec(dllexport) void GlfwSwapBuffers(int windowID)
{
glfwSwapBuffers(getWindowByID(windowID));
}
__declspec(dllexport) void GlfwTerminate()
{
glfwTerminate();
}
__declspec(dllexport) void GlfwMakeContextCurrent(int windowID)
{
glfwMakeContextCurrent(getWindowByID(windowID));
}
__declspec(dllexport) void GlClearColor(float r, float g, float b, float alpha)
{
glClearColor(r, g, b, alpha);
}
__declspec(dllexport) void GlClear(int type)
{
switch (type)
{
case 0:
glClear(GL_COLOR_BUFFER_BIT);
break;
default:
glClear(GL_COLOR_BUFFER_BIT);
break;
}
}
__declspec(dllexport) unsigned int GlApplyShaders(const char* vertexSource, const char* fragmentSource)
{
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return shaderProgram;
}
__declspec(dllexport) void GlVerticesToVbo(GLfloat vertices[])
{
GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
vertexArrays = new unsigned int[VAO, VBO];
}
__declspec(dllexport) unsigned int GlGetVbo()
{
return vertexArrays[1];
}
__declspec(dllexport) unsigned int GlGetVao()
{
return vertexArrays[0];
}
__declspec(dllexport) void GlDestroyVrtx(GLuint VBO, GLuint VAO, GLuint shaderProgram)
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwDestroyWindow(getWindowByID(0));
}
__declspec(dllexport) void GlUseProgram(GLuint shaderProgram)
{
glUseProgram(shaderProgram);
}
__declspec(dllexport) void GlBindVertexArray(GLuint VAO)
{
glBindVertexArray(VAO);
}
__declspec(dllexport) void GlDrawArrays(int type, int start, int count)
{
switch (type)
{
case 0:
glDrawArrays(GL_TRIANGLES, start, count);
default:
glDrawArrays(GL_TRIANGLES, start, count);
}
}
__declspec(dllexport) int GlGetError()
{
return glGetError();
}
__declspec(dllexport) void Gl()
{
}
}
GameWindow.cpp
#include<iostream>
#include "GameWindow.h"
void GameWindow::Create(int w, int h, const char* title)
{
if (!glfwInit())
{
std::cout << "BRUH ERROR" << std::endl;
return;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GameWindow::window = glfwCreateWindow(1280, 720, title, NULL, NULL);
glfwMakeContextCurrent(window);
gladLoadGL();
glViewport(0, 0, w, h);
}